|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.