|
|
1.1 root 1: /**************************************************************************\
2: * paths.c -- sample program demonstrating paths.
3: *
4: * written Feb 92 by Steve Firebaugh
5: *
6: * As of 2/14/92 the SelectClipPath() API is not working.
7: * Instead use:
8: *
9: * SelectClipRgn (hdc, PathToRegion(hdc));
10: \**************************************************************************/
11:
12:
13: #include <windows.h>
14: #include <string.h>
15: #include "paths.h"
16:
17:
18: /**************************************************************************\
19: *
20: * function: WinMain()
21: *
22: * input parameters: c.f. generic sample
23: *
24: \**************************************************************************/
25: int APIENTRY WinMain(HANDLE hInstance, HANDLE 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_HREDRAW | 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, "pathsIcon");
46: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
47: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
48: wc.lpszMenuName = NULL;
49: wc.lpszClassName = "paths";
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: "paths",
60: "Paths",
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: * This is a very simple window. On create it creates pens to draw with.
94: * They are later destroyed at destroy time. The only interesting code
95: * is in the paint message. We draw 6 different paths into the client
96: * area demonstrating various features of paths.
97: *
98: * global variables: none.
99: \**************************************************************************/
100: LONG APIENTRY MainWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
101: {
102: static HANDLE hPenFill, hPenPath;
103:
104:
105: switch (message) {
106:
107:
108: /**********************************************************************\
109: * WM_CREATE
110: *
111: * Create three pens for drawing with later.
112: \**********************************************************************/
113: case WM_CREATE:
114: hPenPath = CreatePen (PS_SOLID, 2, (COLORREF) 0x01000005);
115: hPenFill = CreatePen (PS_SOLID, 1, (COLORREF) 0x01000002);
116: break;
117:
118:
119: /**********************************************************************\
120: * WM_DESTROY
121: *
122: * Complement of the WM_CREATE message. Delete the pens that were
123: * created and then call postquitmessage.
124: \**********************************************************************/
125: case WM_DESTROY:
126: DeleteObject (hPenFill);
127: DeleteObject (hPenPath);
128:
129: PostQuitMessage(0);
130: break;
131:
132:
133: /**********************************************************************\
134: * WM_PAINT
135: *
136: * Query the client rectangle. Divide it into six sub rectangles
137: * (only actually compute the top left sixth). Now, set the origin
138: * for each one of these, write text describing the operation, and
139: * then stroke or fill or whatever the path.
140: \**********************************************************************/
141: case WM_PAINT: {
142: HDC hdc;
143: PAINTSTRUCT ps;
144: RECT rect;
145: HRGN hrgn;
146: int i;
147:
148: hdc = BeginPaint(hwnd, &ps);
149: SetBkMode (hdc, TRANSPARENT);
150:
151: GetClientRect (hwnd, &rect);
152: rect.bottom /= 2;
153: rect.right /= 3;
154: SelectObject(hdc, hPenPath);
155:
156: /* 1. Just stroke the path */
157: SetViewportOrgEx (hdc, 0, 0, NULL);
158: TextOut (hdc, 2, 10, STROKEPATH, sizeof (STROKEPATH)-1);
159: DrawPath(hdc, &rect);
160: StrokePath (hdc);
161:
162:
163: /* 2. Fill the path */
164: SetViewportOrgEx (hdc, 0, rect.bottom, NULL);
165: TextOut (hdc, 2, 10, FILLPATH, sizeof (FILLPATH)-1);
166: DrawPath(hdc, &rect);
167: FillPath (hdc);
168:
169: /* 3. Stroke and fill the path */
170: SetViewportOrgEx (hdc,rect.right, 0, NULL);
171: SetPolyFillMode (hdc, WINDING);
172: TextOut (hdc, 2, 10, STROKEANDFILLWIND, sizeof (STROKEANDFILLWIND)-1);
173: DrawPath(hdc, &rect);
174: StrokeAndFillPath (hdc);
175:
176: /* 4. Stroke and fill it again, but with different mode. */
177: SetViewportOrgEx (hdc,rect.right, rect.bottom, NULL);
178: SetPolyFillMode (hdc, ALTERNATE);
179: TextOut (hdc, 2, 10, STROKEANDFILLALT, sizeof (STROKEANDFILLALT)-1);
180: DrawPath(hdc, &rect);
181: StrokeAndFillPath (hdc);
182:
183:
184: /* 5. Set the clipping region based on the path. */
185: SetViewportOrgEx (hdc,rect.right*2, 0, NULL);
186: SetPolyFillMode (hdc, WINDING);
187: TextOut (hdc, 2, 10, CLIPPATHWIND, sizeof (CLIPPATHWIND)-1);
188: SelectObject(hdc, hPenFill);
189: DrawPath(hdc, &rect);
190: hrgn = PathToRegion(hdc);
191: SelectClipRgn (hdc, hrgn);
192: DeleteObject (hrgn);
193: MoveToEx (hdc, rect.right/2, rect.bottom/2, NULL);
194: for (i = 0; i < rect.right; i += 5)
195: AngleArc (hdc, rect.right/2, rect.bottom/2, i, (FLOAT)0.0, (FLOAT)360.0);
196:
197: /* 6. Set the clipping region based on the path, with different mode. */
198: SetViewportOrgEx (hdc,rect.right*2, rect.bottom, NULL);
199: SetPolyFillMode (hdc, ALTERNATE);
200: /* clear the clip region so that TextOut() shows up. */
201: ExtSelectClipRgn (hdc, NULL, RGN_COPY);
202: TextOut (hdc, 2, 10, CLIPPATHALT, sizeof (CLIPPATHALT)-1);
203: DrawPath(hdc, &rect);
204: hrgn = PathToRegion(hdc);
205: SelectClipRgn (hdc, hrgn);
206: DeleteObject (hrgn);
207: MoveToEx (hdc, rect.right/2, rect.bottom/2, NULL);
208: for (i = 0; i < rect.right; i += 5)
209: AngleArc (hdc, rect.right/2, rect.bottom/2, i, (FLOAT)0.0, (FLOAT)360.0);
210:
211: EndPaint (hwnd, &ps);
212:
213: } return FALSE;
214:
215:
216: default:
217: return (DefWindowProc(hwnd, message, wParam, lParam));
218: }
219: return (NULL);
220: }
221:
222:
223:
224: /**************************************************************************\
225: *
226: * function: DrawPath()
227: *
228: * The path used here is a simple rectangle with an ellipse inside of it.
229: * The InflateRect() calls have nothing to do with the path, but are just
230: * used for convenience.
231: \**************************************************************************/
232: void DrawPath(HDC hdc, PRECT prect)
233: {
234: RECT destRect;
235:
236: /* make a copy that we can modify with impunity. */
237: CopyRect (&destRect, prect);
238:
239: BeginPath (hdc);
240:
241: InflateRect (&destRect, ((destRect.left- destRect.right)/5),
242: ((destRect.top- destRect.bottom)/5));
243:
244: Rectangle (hdc, destRect.left, destRect.top,
245: destRect.right, destRect.bottom);
246:
247: InflateRect (&destRect, ((destRect.left- destRect.right)/4),
248: ((destRect.top- destRect.bottom)/4));
249:
250: Ellipse (hdc, destRect.left, destRect.top,
251: destRect.right, destRect.bottom);
252:
253: EndPath (hdc);
254: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.