|
|
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.