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