Annotation of q_a/samples/cursor/cursor.c, revision 1.1.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.