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

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
1.1.1.3 ! root       14:        sieve() - time consuming function, generates primes
1.1       root       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: {
1.1.1.3 ! root       53:     MSG msg;                                 /* message                      */
1.1       root       54: 
                     55:     UNREFERENCED_PARAMETER( lpCmdLine );
                     56: 
                     57:     if (!hPrevInstance)
                     58:        if (!InitApplication(hInstance))
                     59:            return (FALSE);
                     60: 
                     61:     if (!InitInstance(hInstance, nCmdShow))
1.1.1.3 ! root       62:        return (FALSE);
1.1       root       63: 
                     64:     MessageBox (
1.1.1.3 ! root       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
1.1       root       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(
1.1.1.3 ! root      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
1.1       root      140:     );
                    141: 
                    142:     if (!hWnd)
1.1.1.3 ! root      143:        return (FALSE);
1.1       root      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)
1.1.1.3 ! root      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
1.1       root      167:        WM_DESTROY     - destroy window
                    168: 
                    169:     COMMENTS:
                    170: 
1.1.1.3 ! root      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.
1.1       root      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: 
1.1.1.3 ! root      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 */
1.1       root      276:                        MoveToEx(hDC, OrgX, OrgY, NULL);
1.1.1.3 ! root      277:                        LineTo(hDC, OrgX, PrevY);
        !           278:                        LineTo(hDC, PrevX, PrevY);
        !           279:                        LineTo(hDC, PrevX, OrgY);
        !           280:                        LineTo(hDC, OrgX, OrgY);
1.1       root      281: 
1.1.1.3 ! root      282:                        /* Get the current mouse position */
1.1       root      283: 
1.1.1.3 ! root      284:                        PrevX = NextX;
        !           285:                        PrevY = NextY;
1.1       root      286:                        MoveToEx(hDC, OrgX, OrgY, NULL); /* Draws the new box */
1.1.1.3 ! root      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;
1.1       root      296: 
1.1.1.3 ! root      297:        case WM_LBUTTONUP:
        !           298:            bTrack = FALSE;                 /* No longer creating a selection */
        !           299:            ReleaseCapture();               /* Releases hold on mouse input */
1.1       root      300: 
1.1.1.3 ! root      301:            X = LOWORD(lParam);             /* Saves the current value      */
        !           302:            Y = HIWORD(lParam);
        !           303:            break;
1.1       root      304: 
1.1.1.3 ! root      305:        case WM_KEYDOWN:
        !           306:            if (wParam != VK_LEFT && wParam != VK_RIGHT
        !           307:                    && wParam != VK_UP && wParam != VK_DOWN)
        !           308:                break;
1.1       root      309: 
1.1.1.3 ! root      310:            MPOINT2POINT(ptCursor, pt);
        !           311:            GetCursorPos(&pt);
1.1       root      312: 
1.1.1.3 ! root      313:            /* Convert screen coordinates to client coordinates */
1.1       root      314: 
1.1.1.3 ! root      315:            ScreenToClient(hWnd, &pt);
        !           316:            POINT2MPOINT(pt, ptCursor);
        !           317:            repeat++;                           /* Increases the repeat rate */
1.1       root      318: 
1.1.1.3 ! root      319:            switch (wParam) {
1.1       root      320: 
1.1.1.3 ! root      321:            /* Adjust cursor position according to which key was pressed. */
1.1       root      322: 
1.1.1.3 ! root      323:                case VK_LEFT:
        !           324:                    ptCursor.x -= repeat;
        !           325:                    break;
1.1       root      326: 
1.1.1.3 ! root      327:                case VK_RIGHT:
        !           328:                    ptCursor.x += repeat;
        !           329:                    break;
1.1       root      330: 
1.1.1.3 ! root      331:                case VK_UP:
        !           332:                    ptCursor.y -= repeat;
        !           333:                    break;
1.1       root      334: 
1.1.1.3 ! root      335:                case VK_DOWN:
        !           336:                    ptCursor.y += repeat;
        !           337:                    break;
1.1       root      338: 
1.1.1.3 ! root      339:            }
1.1       root      340: 
1.1.1.3 ! root      341:            /* Get the client boundaries */
1.1       root      342: 
1.1.1.3 ! root      343:            GetClientRect(hWnd, &Rect);
1.1       root      344: 
1.1.1.3 ! root      345:            /* Do not draw outside the window's client area */
1.1       root      346: 
1.1.1.3 ! root      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;
1.1       root      356: 
1.1.1.3 ! root      357:            /* Convert the coordinates to screen coordinates */
1.1       root      358: 
1.1.1.3 ! root      359:            ClientToScreen(hWnd, &pt);
        !           360:            SetCursorPos(pt.x, pt.y);
        !           361:            break;
1.1       root      362: 
1.1.1.3 ! root      363:        case WM_KEYUP:
        !           364:            repeat = 1;                          /* Clears the repeat count. */
        !           365:            break;
1.1       root      366: 
1.1.1.3 ! root      367:        case WM_ACTIVATE:
1.1       root      368:            if (!GetSystemMetrics(SM_MOUSEPRESENT)) {
                    369:                if (!HIWORD(wParam)) {
                    370:                    // LOWORD added for portability
                    371:                    if (LOWORD(wParam)) {
1.1.1.3 ! root      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;
1.1       root      386: 
1.1.1.3 ! root      387:                hDC = BeginPaint (hWnd, &ps);
        !           388:                if (OrgX != PrevX || OrgY != PrevY) {
1.1       root      389:                    MoveToEx(hDC, OrgX, OrgY, NULL);
1.1.1.3 ! root      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;
1.1       root      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: 
1.1.1.3 ! root      461: #define NITER   20                                 /* number of iterations */
        !           462: #define SIZE    8190
1.1       root      463: 
                    464: CHAR flags[SIZE+1]={ 0};
                    465: 
                    466: INT sieve() {
                    467:     INT i,k;
                    468:     INT iter, count;
                    469: 
1.1.1.3 ! root      470:     for (iter = 1; iter <= NITER; iter++) {      /* Does sieve NITER times */
1.1       root      471:        count = 0;
1.1.1.3 ! root      472:        for (i = 0; i <= SIZE; i++)              /* Sets all flags TRUE    */
1.1       root      473:            flags[i] = TRUE;
                    474: 
                    475:        for (i = 2; i <= SIZE; i++) {
1.1.1.3 ! root      476:            if (flags[i] ) {                        /* Found a prime?       */
1.1       root      477:                for (k = i + i; k <= SIZE; k += i)
1.1.1.3 ! root      478:                    flags[k] = FALSE;              /* Cancelsits multiples */
1.1       root      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.