Annotation of q_a/samples/cursor/cursor.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /****************************************************************************
        !            13: 
        !            14:     PROGRAM: Cursor.c
        !            15: 
        !            16:     PURPOSE: Demonstrates how to manipulate a cursor and select a region
        !            17: 
        !            18:     FUNCTIONS:
        !            19: 
        !            20:         WinMain() - calls initialization function, processes message loop
        !            21:         InitApplication() - initializes window data and registers window
        !            22:         InitInstance() - saves instance handle and creates main window
        !            23:         MainWndProc() - processes messages
        !            24:         About() - processes messages for "About" dialog box
        !            25:         sieve() - time consuming function, generates primes
        !            26: 
        !            27: ****************************************************************************/
        !            28: 
        !            29: #include <windows.h>
        !            30: #include <string.h>
        !            31: #include "cursor.h"
        !            32: 
        !            33: HANDLE hInst;
        !            34: 
        !            35: CHAR str[255];                              /* general-purpose string buffer */
        !            36: 
        !            37: HCURSOR hSaveCursor;                        /* handle to current cursor      */
        !            38: HCURSOR hHourGlass;                         /* handle to hourglass cursor    */
        !            39: 
        !            40: BOOL bTrack = FALSE;                        /* TRUE if left button clicked   */
        !            41: INT OrgX = 0, OrgY = 0;                     /* original cursor position      */
        !            42: INT PrevX = 0, PrevY = 0;                   /* current cursor position       */
        !            43: INT X = 0, Y = 0;                           /* last cursor position          */
        !            44: RECT Rect;                                  /* selection rectangle           */
        !            45: 
        !            46: MPOINT ptCursor;                            /* x and y coordinates of cursor */
        !            47: INT repeat = 1;                             /* repeat count of keystroke     */
        !            48: 
        !            49: /****************************************************************************
        !            50: 
        !            51:     FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
        !            52: 
        !            53:     PURPOSE: calls initialization function, processes message loop
        !            54: 
        !            55: ****************************************************************************/
        !            56: 
        !            57: int APIENTRY WinMain(
        !            58:     HANDLE hInstance,
        !            59:     HANDLE hPrevInstance,
        !            60:     LPSTR lpCmdLine,
        !            61:     int nCmdShow
        !            62:     )
        !            63: {
        !            64:     MSG msg;                                 /* message                      */
        !            65: 
        !            66:     UNREFERENCED_PARAMETER( lpCmdLine );
        !            67: 
        !            68:     if (!hPrevInstance)
        !            69:         if (!InitApplication(hInstance))
        !            70:             return (FALSE);
        !            71: 
        !            72:     if (!InitInstance(hInstance, nCmdShow))
        !            73:         return (FALSE);
        !            74: 
        !            75:     MessageBox (
        !            76:           GetFocus ()
        !            77:         , "Use the mouse button in this program for an example of graphics "
        !            78:                         "selection, or the <Enter> key for an example of "
        !            79:                         "using a special cursor to reflect a program state."
        !            80:         , "Cursor Sample Application"
        !            81:         , MB_ICONASTERISK | MB_OK
        !            82:     );
        !            83: 
        !            84:     while (GetMessage(&msg, NULL, 0, 0)) {
        !            85:         TranslateMessage(&msg);
        !            86:         DispatchMessage(&msg);
        !            87:     }
        !            88:     return (msg.wParam);
        !            89: }
        !            90: 
        !            91: 
        !            92: /****************************************************************************
        !            93: 
        !            94:     FUNCTION: InitApplication(HANDLE)
        !            95: 
        !            96:     PURPOSE: Initializes window data and registers window class
        !            97: 
        !            98: ****************************************************************************/
        !            99: 
        !           100: BOOL InitApplication(HANDLE hInstance)
        !           101: {
        !           102:     WNDCLASS  wc;
        !           103: 
        !           104:     wc.style = 0;
        !           105:     wc.lpfnWndProc = (WNDPROC) MainWndProc;
        !           106:     wc.cbClsExtra = 0;
        !           107:     wc.cbWndExtra = 0;
        !           108:     wc.hInstance = hInstance;
        !           109:     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        !           110:     wc.hCursor = LoadCursor(hInstance, "bullseye");
        !           111:     wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
        !           112:     wc.lpszMenuName =  "CursorMenu";
        !           113:     wc.lpszClassName = "CursorWClass";
        !           114: 
        !           115:     return (RegisterClass(&wc));
        !           116: }
        !           117: 
        !           118: 
        !           119: /****************************************************************************
        !           120: 
        !           121:     FUNCTION:  InitInstance(HANDLE, int)
        !           122: 
        !           123:     PURPOSE:  Saves instance handle and creates main window
        !           124: 
        !           125: ****************************************************************************/
        !           126: 
        !           127: BOOL InitInstance(
        !           128:     HANDLE          hInstance,
        !           129:     INT             nCmdShow)
        !           130: {
        !           131:     HWND            hWnd;
        !           132: 
        !           133:     hInst = hInstance;
        !           134: 
        !           135:     strcpy(str,"");
        !           136: 
        !           137:     hHourGlass = LoadCursor(NULL, IDC_WAIT);  
        !           138: 
        !           139:     hWnd = CreateWindow(
        !           140:         "CursorWClass",
        !           141:         "Cursor Sample Application",
        !           142:         WS_OVERLAPPEDWINDOW,
        !           143:         CW_USEDEFAULT,
        !           144:         CW_USEDEFAULT,
        !           145:         CW_USEDEFAULT,
        !           146:         CW_USEDEFAULT,
        !           147:         NULL,
        !           148:         NULL,
        !           149:         hInstance,
        !           150:         NULL
        !           151:     );
        !           152: 
        !           153:     if (!hWnd)
        !           154:         return (FALSE);
        !           155: 
        !           156:     ShowWindow(hWnd, nCmdShow);
        !           157:     UpdateWindow(hWnd);
        !           158:     return (TRUE);
        !           159: 
        !           160: }
        !           161: 
        !           162: /****************************************************************************
        !           163: 
        !           164:     FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
        !           165: 
        !           166:     PURPOSE:  Processes messages
        !           167: 
        !           168:     MESSAGES:
        !           169: 
        !           170:         WM_COMMAND     - application menu (About dialog box)
        !           171:         WM_CHAR        - ASCII key value received
        !           172:         WM_LBUTTONDOWN - left mouse button
        !           173:         WM_MOUSEMOVE   - mouse movement
        !           174:         WM_LBUTTONUP   - left button released
        !           175:         WM_KEYDOWN     - key pressed
        !           176:         WM_KEYUPS      - key released
        !           177:         WM_PAINT       - update window
        !           178:         WM_DESTROY     - destroy window
        !           179: 
        !           180:     COMMENTS:
        !           181: 
        !           182:         When the left mouse button is pressed, btrack is set to TRUE so that
        !           183:         the code for WM_MOUSEMOVE will keep track of the mouse and update
        !           184:         the box accordingly.  Once the button is released, btrack is set to
        !           185:         FALSE, and the current position is saved.  Holding the SHIFT key
        !           186:         while pressing the left button will extend the current box rather
        !           187:         then erasing it and starting a new one.
        !           188: 
        !           189:         When an arrow key is pressed, the cursor is repositioned in the
        !           190:         direction of the arrow key.  A repeat count is kept so that the
        !           191:         longer the user holds down the arrow key, the faster it will move.
        !           192:         As soon as the key is released, the repeat count is set to 1 for
        !           193:         normal cursor movement.
        !           194: 
        !           195: ****************************************************************************/
        !           196: 
        !           197: LONG APIENTRY MainWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)
        !           198: {
        !           199:     FARPROC lpProcAbout;
        !           200:     POINT pt;
        !           201:     HDC hDC;
        !           202: 
        !           203:     switch (message) {
        !           204:         case WM_COMMAND:
        !           205:             // LOWORD added for portability
        !           206:             if (LOWORD(wParam) == IDM_ABOUT) {
        !           207:                 lpProcAbout = MakeProcInstance((FARPROC)About, hInst);
        !           208: 
        !           209:                 DialogBox(hInst,
        !           210:                     "AboutBox",
        !           211:                     hWnd,
        !           212:                     lpProcAbout);
        !           213: 
        !           214:                 FreeProcInstance(lpProcAbout);
        !           215:                 break;
        !           216:             }
        !           217:             else
        !           218:                 return (DefWindowProc(hWnd, message, wParam, lParam));
        !           219: 
        !           220:         case WM_CHAR:
        !           221:             if (wParam == '\r') {
        !           222:                 SetCapture(hWnd);
        !           223: 
        !           224:                 /* Set the cursor to an hourglass */
        !           225: 
        !           226:                 hSaveCursor = SetCursor(hHourGlass);
        !           227: 
        !           228:                 strcpy (str, "Calculating prime numbers...");
        !           229:                 InvalidateRect (hWnd, NULL, TRUE);
        !           230:                 UpdateWindow (hWnd);
        !           231:                 wsprintf(str, "Calculated %d primes.       ", sieve());
        !           232:                 InvalidateRect (hWnd, NULL, TRUE);
        !           233:                 UpdateWindow (hWnd);
        !           234: 
        !           235:                 SetCursor(hSaveCursor);          /* Restores previous cursor */
        !           236:                 ReleaseCapture();
        !           237:             }
        !           238:             break;
        !           239: 
        !           240:         case WM_LBUTTONDOWN:
        !           241:             bTrack = TRUE;
        !           242:             strcpy (str, "");
        !           243:             PrevX = LOWORD(lParam);
        !           244:             PrevY = HIWORD(lParam);
        !           245:             if (!(wParam & MK_SHIFT)) {       /* If shift key is not pressed */
        !           246:                 OrgX = LOWORD(lParam);
        !           247:                 OrgY = HIWORD(lParam);
        !           248:             }
        !           249:             InvalidateRect (hWnd, NULL, TRUE);
        !           250:             UpdateWindow (hWnd);
        !           251: 
        !           252:             /* Capture all input even if the mouse goes outside of window */
        !           253: 
        !           254:             SetCapture(hWnd);
        !           255:             break;
        !           256: 
        !           257:         case WM_MOUSEMOVE:
        !           258:             {
        !           259:                 RECT        rectClient;
        !           260:                 INT         NextX;
        !           261:                 INT         NextY;
        !           262: 
        !           263:                 if (bTrack) {
        !           264:                     NextX = (SHORT)LOWORD(lParam);
        !           265:                     NextY = (SHORT)HIWORD(lParam);
        !           266: 
        !           267:                     /* Do not draw outside the window's client area */
        !           268: 
        !           269:                     GetClientRect (hWnd, &rectClient);
        !           270:                     if (NextX < rectClient.left) {
        !           271:                         NextX = rectClient.left;
        !           272:                     } else if (NextX >= rectClient.right) {
        !           273:                         NextX = rectClient.right - 1;
        !           274:                     }
        !           275:                     if (NextY < rectClient.top) {
        !           276:                         NextY = rectClient.top;
        !           277:                     } else if (NextY >= rectClient.bottom) {
        !           278:                         NextY = rectClient.bottom - 1;
        !           279:                     }
        !           280: 
        !           281:                     /* If the mouse position has changed, then clear the */
        !           282:                     /* previous rectangle and draw the new one.          */
        !           283: 
        !           284:                     if ((NextX != PrevX) || (NextY != PrevY)) {
        !           285:                         hDC = GetDC(hWnd);
        !           286:                         SetROP2(hDC, R2_NOT);          /* Erases the previous box */
        !           287:                         MoveToEx(hDC, OrgX, OrgY, NULL);
        !           288:                         LineTo(hDC, OrgX, PrevY);
        !           289:                         LineTo(hDC, PrevX, PrevY);
        !           290:                         LineTo(hDC, PrevX, OrgY);
        !           291:                         LineTo(hDC, OrgX, OrgY);
        !           292: 
        !           293:                         /* Get the current mouse position */
        !           294: 
        !           295:                         PrevX = NextX;
        !           296:                         PrevY = NextY;
        !           297:                         MoveToEx(hDC, OrgX, OrgY, NULL); /* Draws the new box */
        !           298:                         LineTo(hDC, OrgX, PrevY);
        !           299:                         LineTo(hDC, PrevX, PrevY);
        !           300:                         LineTo(hDC, PrevX, OrgY);
        !           301:                         LineTo(hDC, OrgX, OrgY);
        !           302:                         ReleaseDC(hWnd, hDC);
        !           303:                     }
        !           304:                 }
        !           305:             }
        !           306:             break;
        !           307: 
        !           308:         case WM_LBUTTONUP:
        !           309:             bTrack = FALSE;                 /* No longer creating a selection */
        !           310:             ReleaseCapture();               /* Releases hold on mouse input */
        !           311: 
        !           312:             X = LOWORD(lParam);             /* Saves the current value      */
        !           313:             Y = HIWORD(lParam);
        !           314:             break;
        !           315: 
        !           316:         case WM_KEYDOWN:
        !           317:             if (wParam != VK_LEFT && wParam != VK_RIGHT
        !           318:                     && wParam != VK_UP && wParam != VK_DOWN)
        !           319:                 break;
        !           320: 
        !           321:             MPOINT2POINT(ptCursor, pt);
        !           322:             GetCursorPos(&pt);
        !           323: 
        !           324:             /* Convert screen coordinates to client coordinates */
        !           325: 
        !           326:             ScreenToClient(hWnd, &pt);
        !           327:             POINT2MPOINT(pt, ptCursor);
        !           328:             repeat++;                           /* Increases the repeat rate */
        !           329: 
        !           330:             switch (wParam) {
        !           331: 
        !           332:             /* Adjust cursor position according to which key was pressed. */
        !           333: 
        !           334:                 case VK_LEFT:
        !           335:                     ptCursor.x -= repeat;
        !           336:                     break;
        !           337: 
        !           338:                 case VK_RIGHT:
        !           339:                     ptCursor.x += repeat;
        !           340:                     break;
        !           341: 
        !           342:                 case VK_UP:
        !           343:                     ptCursor.y -= repeat;
        !           344:                     break;
        !           345: 
        !           346:                 case VK_DOWN:
        !           347:                     ptCursor.y += repeat;
        !           348:                     break;
        !           349: 
        !           350:             }
        !           351: 
        !           352:             /* Get the client boundaries */
        !           353: 
        !           354:             GetClientRect(hWnd, &Rect);
        !           355: 
        !           356:             /* Do not draw outside the window's client area */
        !           357: 
        !           358:             MPOINT2POINT(ptCursor, pt);
        !           359:             if (pt.x >= Rect.right)
        !           360:                 pt.x = Rect.right - 1;
        !           361:             else if (pt.x < Rect.left)
        !           362:                 pt.x = Rect.left;
        !           363:             if (pt.y >= Rect.bottom)
        !           364:                 pt.y = Rect.bottom - 1;
        !           365:             else if (pt.y < Rect.top)
        !           366:                 pt.y = Rect.top;
        !           367: 
        !           368:             /* Convert the coordinates to screen coordinates */
        !           369: 
        !           370:             ClientToScreen(hWnd, &pt);
        !           371:             SetCursorPos(pt.x, pt.y);
        !           372:             break;
        !           373: 
        !           374:         case WM_KEYUP:
        !           375:             repeat = 1;                          /* Clears the repeat count. */
        !           376:             break;
        !           377: 
        !           378:         case WM_ACTIVATE:
        !           379:             if (!GetSystemMetrics(SM_MOUSEPRESENT)) {
        !           380:                 if (!HIWORD(wParam)) {
        !           381:                     // LOWORD added for portability
        !           382:                     if (LOWORD(wParam)) {
        !           383:                         SetCursor(LoadCursor(hInst, "bullseye"));
        !           384:                         pt.x = X;
        !           385:                         pt.y = Y;
        !           386:                         ClientToScreen(hWnd, &pt);
        !           387:                         SetCursorPos(pt.x, pt.y);
        !           388:                     }
        !           389:                     ShowCursor(wParam);
        !           390:                 }
        !           391:             }
        !           392:             break;
        !           393: 
        !           394:         case WM_PAINT:
        !           395:             {
        !           396:                 PAINTSTRUCT     ps;
        !           397: 
        !           398:                 hDC = BeginPaint (hWnd, &ps);
        !           399:                 if (OrgX != PrevX || OrgY != PrevY) {
        !           400:                     MoveToEx(hDC, OrgX, OrgY, NULL);
        !           401:                     LineTo(hDC, OrgX, PrevY);
        !           402:                     LineTo(hDC, PrevX, PrevY);
        !           403:                     LineTo(hDC, PrevX, OrgY);
        !           404:                     LineTo(hDC, OrgX, OrgY);
        !           405:                 }
        !           406:                 TextOut (hDC, 1, 1, str, strlen (str));
        !           407:                 EndPaint (hWnd, &ps);
        !           408:             }
        !           409:             break;
        !           410: 
        !           411:         case WM_DESTROY:
        !           412:             PostQuitMessage(0);
        !           413:             break;
        !           414: 
        !           415:         default:
        !           416:             return (DefWindowProc(hWnd, message, wParam, lParam));
        !           417:     }
        !           418:     return (0);
        !           419: }
        !           420: 
        !           421: 
        !           422: /****************************************************************************
        !           423: 
        !           424:     FUNCTION: About(HWND, unsigned, WORD, LONG)
        !           425: 
        !           426:     PURPOSE:  Processes messages for "About" dialog box
        !           427: 
        !           428:     MESSAGES:
        !           429: 
        !           430:         WM_INITDIALOG - initialize dialog box
        !           431:         WM_COMMAND    - Input received
        !           432: 
        !           433: ****************************************************************************/
        !           434: 
        !           435: BOOL APIENTRY About(HWND hDlg, UINT message, UINT wParam, LONG lParam)
        !           436: {
        !           437:     switch (message) {
        !           438:         case WM_INITDIALOG:
        !           439:             return (TRUE);
        !           440: 
        !           441:         case WM_COMMAND:
        !           442:             // LOWORD added for portability
        !           443:             if (LOWORD(wParam) == IDOK
        !           444:                 || LOWORD(wParam) == IDCANCEL) {
        !           445:                 EndDialog(hDlg, TRUE);
        !           446:                 return (TRUE);
        !           447:             }
        !           448:             break;
        !           449:     }
        !           450:     return (FALSE);
        !           451:         UNREFERENCED_PARAMETER(lParam);
        !           452: }
        !           453: 
        !           454: 
        !           455: /****************************************************************************
        !           456: 
        !           457:     FUNCTION: Sieve()
        !           458: 
        !           459:     PURPOSE:  Example of time consuming process
        !           460: 
        !           461:     COMMENTS:
        !           462: 
        !           463:         Sieve of Eratosthenes, BYTE, Volume 8, Number 1, by Jim Gilbreath
        !           464:         and Gary Gilbreath.  Code changed to give correct results.
        !           465: 
        !           466:         One could return the count, and after restoring the cursor, use
        !           467:         sprintf() to copy the information to a string which could then be
        !           468:         put up in a MessageBox().
        !           469: 
        !           470: ****************************************************************************/
        !           471: 
        !           472: #define NITER   20                                 /* number of iterations */
        !           473: #define SIZE    8190
        !           474: 
        !           475: CHAR flags[SIZE+1]={ 0};
        !           476: 
        !           477: INT sieve() {
        !           478:     INT i,k;
        !           479:     INT iter, count;
        !           480: 
        !           481:     for (iter = 1; iter <= NITER; iter++) {      /* Does sieve NITER times */
        !           482:         count = 0;
        !           483:         for (i = 0; i <= SIZE; i++)              /* Sets all flags TRUE    */
        !           484:             flags[i] = TRUE;
        !           485: 
        !           486:         for (i = 2; i <= SIZE; i++) {
        !           487:             if (flags[i] ) {                        /* Found a prime?       */
        !           488:                 for (k = i + i; k <= SIZE; k += i)
        !           489:                     flags[k] = FALSE;              /* Cancelsits multiples */
        !           490:                 count++;
        !           491:             }
        !           492:         }
        !           493:     }
        !           494:     return (count);
        !           495: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.