Annotation of mstools/samples/cursor/cursor.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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