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

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,
        !           201:                    (WNDPROC)lpProcAbout);
        !           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.