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