Annotation of q_a/samples/polydraw/polydraw.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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