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

1.1       root        1: /**************************************************************************\
                      2: *  polydraw.c -- sample program demonstrating PolyDraw().
                      3: *
1.1.1.2 ! root        4: *         Steve Firebaugh
        !             5: *         Microsoft Developer Support
        !             6: *         Copyright (c) 1992 Microsoft Corporation
        !             7: *
1.1       root        8: * The user is able to place control points on the screen, and then
                      9: *  drag them.  The PolyDraw() call is made to dynamically show the
                     10: *  resulting curve.
                     11: \**************************************************************************/
                     12: 
                     13: #include <windows.h>
                     14: #include "polydraw.h"
                     15: 
                     16: 
                     17: 
                     18: /**************************************************************************\
                     19: *
                     20: *  function:  WinMain()
                     21: *
                     22: *  input parameters:  c.f. generic sample
                     23: *
                     24: \**************************************************************************/
                     25: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     26:                      LPSTR lpCmdLine, int nCmdShow)
                     27: {
                     28:     HANDLE hInst;
                     29:     HWND   hwndMain;
                     30:     MSG   msg;
                     31: 
                     32:     UNREFERENCED_PARAMETER( lpCmdLine );
                     33: 
                     34: 
                     35:     /* Check for previous instance.  If none, then register class. */
                     36:     if (!hPrevInstance) {
                     37:         WNDCLASS  wc;
                     38: 
                     39:         wc.style = CS_VREDRAW;
                     40:         wc.lpfnWndProc = (WNDPROC)MainWndProc;
                     41: 
                     42:         wc.cbClsExtra = 0;
                     43:         wc.cbWndExtra = 0;
                     44:         wc.hInstance = hInstance;
                     45:         wc.hIcon = LoadIcon(hInstance, "polydrawIcon");
                     46:         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
                     47:         wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
                     48:         wc.lpszMenuName =  NULL;
                     49:         wc.lpszClassName = "polydraw";
                     50: 
                     51:         if (!RegisterClass(&wc)) return (FALSE);
                     52:     }  /* class registered o.k. */
                     53: 
                     54: 
                     55:     /* Create the main window.  Return false if CreateWindow() fails */
                     56:     hInst = hInstance;
                     57: 
                     58:     hwndMain = CreateWindow(
                     59:         "polydraw",
                     60:         "PolyDraw",
                     61:         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                     62:         CW_USEDEFAULT,
                     63:         CW_USEDEFAULT,
                     64:         CW_USEDEFAULT,
                     65:         CW_USEDEFAULT,
                     66:         NULL,
                     67:         NULL,
                     68:         hInstance,
                     69:         NULL);
                     70: 
                     71:     if (!hwndMain) return (FALSE);
                     72:     ShowWindow(hwndMain, nCmdShow);
                     73:     UpdateWindow(hwndMain);
                     74: 
                     75: 
                     76:     /* Loop getting messages and dispatching them. */
                     77:     while (GetMessage(&msg,NULL, NULL, NULL)) {
                     78:         TranslateMessage(&msg);
                     79:         DispatchMessage(&msg);
                     80:     }
                     81: 
                     82:     return (msg.wParam);
                     83: }
                     84: 
                     85: 
                     86: 
                     87: /**************************************************************************\
                     88: *
                     89: *  function:  MainWndProc()
                     90: *
                     91: *  input parameters:  normal window procedure parameters.
                     92: *
                     93: *  global variables: none.
                     94: *
                     95: *  static variables:
                     96: *   svPoints[] - array that stores the points for the GDI calls.
                     97: *   svTypes[]  - array of bytes to store the type for the PolyDraw() calls.
                     98: *   svIndex    - when tracking, the index of the point we are modifying.
                     99: *   svNumDown  - the number of points currently in the client area.
                    100: *   hPen*     - Pens to draw the lines, curves, or erase with.
                    101: *
                    102: * The PolyDraw() function is different from PolyBezier in that the current
                    103: *  point is taken to be the first point, and the first point passed in in
                    104: *  the array is actually the second point in the bezier or line or whatever,
                    105: *  thus ...
                    106: *        PolyDraw (hdc, &svPoints[1], &svTypes[1], svNumDown);
                    107: *  instead of ...
                    108: *        PolyDraw (hdc, svPoints, svTypes, svNumDown+1);
                    109: *
                    110: \**************************************************************************/
1.1.1.2 ! root      111: LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1       root      112: {
                    113: static HANDLE hPenGrey, hPenLine, hPenpolydraw;
                    114: static POINT svPoints [MAXPOINTS];
                    115: static BYTE  svTypes  [MAXPOINTS];
                    116: static int   svNumDown;
                    117: static int   svIndex;
                    118: 
                    119:   switch (message) {
                    120: 
                    121: 
                    122:     /**********************************************************************\
                    123:     *  WM_CREATE
                    124:     *
                    125:     * Initialize the static variables.
                    126:     *  Then create three pens for drawing with later.
                    127:     \**********************************************************************/
                    128:     case WM_CREATE:
                    129:         svNumDown = NONE;
                    130:         svIndex = NONE;
                    131:         hPenLine     = CreatePen (PS_SOLID, 1, (COLORREF) 0x0100000f);
                    132:         hPenpolydraw = CreatePen (PS_SOLID, 1, (COLORREF) 0x01000005);
                    133:         hPenGrey     = CreatePen (PS_SOLID, 1, (COLORREF) 0x01000007);
                    134:     break;
                    135: 
                    136: 
                    137:     /**********************************************************************\
                    138:     *  WM_DESTROY
                    139:     *
                    140:     * Complement of the WM_CREATE message.  Delete the pens that were
                    141:     *  created and then call postquitmessage.
                    142:     \**********************************************************************/
                    143:     case WM_DESTROY:
                    144:       DeleteObject (hPenLine);
                    145:       DeleteObject (hPenpolydraw);
                    146:       DeleteObject (hPenGrey);
                    147: 
                    148:       PostQuitMessage(0);
                    149:     break;
                    150: 
                    151: 
                    152: 
                    153: 
                    154:     /**********************************************************************\
                    155:     *  WM_LBUTTONDOWN
                    156:     *
                    157:     * Hittest to see if the user is selecting an existing point.
                    158:     *  If not, check for point overflow.
                    159:     *  If o.k. then add a new point to the current list.
                    160:     \**********************************************************************/
                    161:     case WM_LBUTTONDOWN: {
                    162:       int i;
                    163:       RECT rectNear;
                    164: 
                    165:       /* Construct a rectangle around the mouse point. */
                    166:       rectNear.left   = LOWORD(lParam) - HITSIZE;
                    167:       rectNear.right  = LOWORD(lParam) + HITSIZE;
                    168:       rectNear.top    = HIWORD(lParam) - HITSIZE;
                    169:       rectNear.bottom = HIWORD(lParam) + HITSIZE;
                    170: 
                    171:       /* step through all points so far.  hittest mouse location against
                    172:        *  each one.  If we hit one, set index, capture mouse and exit
                    173:        *  window procedure.
                    174:        */
                    175:       for (i = 0; i<= svNumDown; i++) {
                    176:         if (PtInRect (&rectNear, svPoints[i])) {
                    177:           svIndex = i;
                    178:           SetCapture (hwnd);
                    179:           return NULL;
                    180:         }
                    181:       }
                    182: 
                    183:       /* we did not hit an old point, watch for overflow. */
                    184:       if (svNumDown == (MAXPOINTS-1)) {
                    185:         MessageBox (hwnd,
                    186:                     "Points may be dragged with left mouse button.",
                    187:                     "No more points allowed",
                    188:                     MB_OK | MB_ICONSTOP);
                    189:         return NULL;
                    190:       }
                    191: 
                    192:       /* don't have old point, still room for more.  Put down one more. */
                    193:       if (GetCapture() != hwnd) {
                    194:         svNumDown++;
                    195:         svPoints[svNumDown].x = LOWORD(lParam);
                    196:         svPoints[svNumDown].y = HIWORD(lParam);
                    197: 
                    198:         /* set the type value in the array dependent upon keyboard state. */
                    199:         if (wParam & MK_SHIFT)        svTypes [svNumDown] = PT_MOVETO;
                    200:         else if (wParam & MK_CONTROL) svTypes [svNumDown] = PT_BEZIERTO;
                    201:         else                          svTypes [svNumDown] = PT_LINETO;
                    202: 
                    203:         InvalidateRect (hwnd, NULL, TRUE);
                    204:       }
                    205: 
                    206:     }break;
                    207: 
                    208: 
                    209:     /**********************************************************************\
                    210:     *  WM_MOUSEMOVE
                    211:     *
                    212:     * If the curve is tracking the mouse, the erase the old curve by drawing
                    213:     *  over it with the grey pen.  Redraw the new curves with the proper pens.
                    214:     \**********************************************************************/
                    215:     case WM_MOUSEMOVE: {
                    216:       if (GetCapture() == hwnd) {
                    217:         HDC hdc;
                    218: 
                    219:         hdc = GetDC (hwnd);
                    220:         MoveToEx (hdc, svPoints[0].x, svPoints[0].y, NULL);
                    221: 
                    222:         /* Erase the old lines and curves. */
                    223:         SelectObject(hdc, hPenGrey);
                    224:         Polyline (hdc, svPoints, svNumDown+1);
                    225:         PolyDraw (hdc, &svPoints[1], &svTypes[1], svNumDown);
                    226: 
                    227:         /* Change the point to match the new mouse position. */
1.1.1.2 ! root      228:         svPoints[svIndex].x = (int)(short)LOWORD(lParam);
        !           229:         svPoints[svIndex].y = (int)(short)HIWORD(lParam);
1.1       root      230: 
                    231:         MoveToEx (hdc, svPoints[0].x, svPoints[0].y, NULL);
                    232:         SelectObject(hdc, hPenLine);
                    233:         Polyline (hdc, svPoints, svNumDown+1);
                    234:         SelectObject(hdc, hPenpolydraw);
                    235:         PolyDraw (hdc, &svPoints[1], &svTypes[1], svNumDown);
                    236: 
                    237:         ReleaseDC (hwnd, hdc);
                    238:       }
                    239:     }break;
                    240: 
                    241: 
                    242: 
                    243:     /**********************************************************************\
                    244:     *  WM_LBUTTONUP
                    245:     *
                    246:     * Finished tracking.  Release the mouse capture, and force repaint.
                    247:     \**********************************************************************/
                    248:     case WM_LBUTTONUP:
                    249:       if (GetCapture() == hwnd) {
                    250:         SetCapture (NULL);
                    251:         InvalidateRect (hwnd, NULL, FALSE);
                    252:       }
                    253:     break;
                    254: 
                    255: 
                    256:     /**********************************************************************\
                    257:     *  WM_RBUTTONDOWN
                    258:     *
                    259:     * Re-Initialize the static variables, and force a repaint
                    260:     \**********************************************************************/
                    261:     case WM_RBUTTONDOWN:
                    262:       svNumDown = NONE;
                    263:       svIndex = NONE;
                    264:       InvalidateRect (hwnd, NULL, TRUE);
                    265:     break;
                    266: 
                    267: 
                    268: 
                    269:     /**********************************************************************\
                    270:     *  WM_PAINT
                    271:     *
                    272:     * Write the instructions at the bottom of the window.  (Note that these
                    273:     *  lines may be erased by user MOUSEMOVE actions.)  Draw the polyline
                    274:     *  then draw the PolyDraw.
                    275:     \**********************************************************************/
                    276:     case WM_PAINT: {
                    277:       HDC hdc;
                    278:       PAINTSTRUCT ps;
                    279:       RECT  rect;
                    280:       int   height,x,y;
                    281: 
                    282:       hdc = BeginPaint(hwnd, &ps);
                    283: 
                    284:       /* set the background mode, the write out the 4 instruction strings. */
                    285:       SetBkMode (hdc, TRANSPARENT);
                    286:       height = GetSystemMetrics (SM_CYCAPTION);
                    287:       GetClientRect (hwnd, &rect);
                    288:       x = rect.left + 10;
                    289:       y = rect.bottom - 4*height;
                    290:       TextOut (hdc, x,y, instructions0,sizeof(instructions0)-1);
                    291:       y = rect.bottom - 3*height;
                    292:       TextOut (hdc, x,y, instructions1,sizeof(instructions1)-1);
                    293:       y = rect.bottom - 2*height;
                    294:       TextOut (hdc, x,y, instructions2,sizeof(instructions2)-1);
                    295:       y = rect.bottom - 1*height;
                    296:       TextOut (hdc, x,y, instructions3,sizeof(instructions3)-1);
                    297: 
                    298: 
                    299:       /* Move to the first point in the array and then call polydraw */
                    300:       MoveToEx (hdc, svPoints[0].x, svPoints[0].y, NULL);
                    301: 
                    302:       SelectObject(hdc, hPenLine);
                    303:       Polyline (hdc, svPoints, svNumDown+1);
                    304:       SelectObject(hdc, hPenpolydraw);
                    305:       PolyDraw (hdc, &svPoints[1], &svTypes[1], svNumDown);
                    306: 
                    307:       EndPaint (hwnd, &ps);
                    308:     } return FALSE;
                    309: 
                    310: 
                    311:     default:
                    312:       return (DefWindowProc(hwnd, message, wParam, lParam));
                    313:     }
                    314:     return (NULL);
                    315: }

unix.superglobalmegacorp.com

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