|
|
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: /****************************** Module Header *******************************
13: * Module Name: ctrlproc.c
14: *
15: * Contains the window procedures for controls in the dialog being edited.
16: *
17: * Functions:
18: *
19: * DialogCtrlWndProc()
20: * CtrlWndProc()
21: * ChildWndProc()
22: * DrawOwnerDrawButton()
23: *
24: * Comments:
25: *
26: ****************************************************************************/
27:
28: #include "dlgedit.h"
29: #include "dlgfuncs.h"
30: #include "dlgextrn.h"
31:
32:
33:
34: /************************************************************************
35: * DialogCtrlWndProc
36: *
37: * This is the window procedure that subclasses the dialog being
38: * edited. It handles a few messages that have to be special-cased
39: * for the dialog. Most messages, however, are passed on to the
40: * generic control subclass procedure (CtrlWndProc).
41: *
42: * Arguments:
43: * HWND - Handle to the dialog window
44: * UINT - window message
45: * WPARAM - message parameter
46: * LPARAM - message parameter
47: *
48: * Returns:
49: * The default window procedure
50: *
51: ************************************************************************/
52:
53: WINDOWPROC DialogCtrlWndProc(
54: HWND hwnd,
55: UINT msg,
56: WPARAM wParam,
57: LPARAM lParam)
58: {
59: POINT pt;
60: BOOL fTracking;
61:
62: switch (msg) {
63: case WM_NCPAINT:
64: case WM_PAINT:
65: if (gfTrackRectShown) {
66: fTracking = TRUE;
67: HideTrackRect();
68: }
69: else {
70: fTracking = FALSE;
71: }
72:
73: /*
74: * Allow the dialog to paint first.
75: */
76: CallWindowProc((WNDPROC)CtrlWndProc, hwnd, msg, wParam, lParam);
77:
78: /*
79: * Draw the handles if the dialog is selected.
80: */
81: if (gfDlgSelected) {
82: HDC hDC;
83:
84: hDC = GetWindowDC(hwnd);
85: DrawHandles(hwnd, hDC, TRUE);
86: ReleaseDC(hwnd, hDC);
87: }
88:
89: if (fTracking)
90: ShowTrackRect();
91:
92: break;
93:
94: case WM_LBUTTONDOWN:
95: /*
96: * Discard all mouse messages during certain operations.
97: */
98: if (gfDisabled)
99: break;
100:
101: /*
102: * Also, be sure any outstanding changes get applied
103: * without errors.
104: */
105: if (!StatusApplyChanges())
106: break;
107:
108: /*
109: * Check to see if we are in a normal mode. If we are
110: * in some other mode, like dragging a new control,
111: * we want to ignore this mouse down and wait for the
112: * mouse up. For instance, this can happen when the
113: * Duplicate command is selected from the Edit menu.
114: */
115: if (gState == STATE_NORMAL) {
116: ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
117: MapDlgClientPoint(&pt, TRUE);
118:
119: /*
120: * Is the dialog selected and was one of its handles hit?
121: * If so, call CtrlButtonDown as if we are a drag window.
122: */
123: if (gfDlgSelected &&
124: HandleHitTest(hwnd, pt.x, pt.y) != DRAG_CENTER) {
125: CtrlButtonDown(hwnd, pt.x, pt.y, TRUE);
126: }
127: else {
128: /*
129: * If the click was within the client area and
130: * there is not a tool selected, start an outline
131: * selection operation. Otherwise call CtrlButtonDown
132: * which will either begin dragging the dialog or
133: * dragging the new control.
134: */
135: if (gCurTool == W_NOTHING &&
136: PtInRect(&grcDlgClient, pt))
137: OutlineSelectBegin(pt.x, pt.y);
138: else
139: CtrlButtonDown(hwnd, pt.x, pt.y, FALSE);
140: }
141: }
142:
143: break;
144:
145: case WM_MOUSEMOVE:
146: ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
147:
148: /*
149: * If we are not dragging a new control, then this
150: * message is for the dialog, and we map it from
151: * the dialog client to the dialog window.
152: */
153: if (gState != STATE_DRAGGINGNEW)
154: MapDlgClientPoint(&pt, TRUE);
155:
156: /*
157: * Now we process the mouse move message. If the dialog is
158: * selected, and if we are not dragging a new control, we
159: * pass in a TRUE for fDragWindow. This is because the
160: * dialog itself does not have a separate drag window like
161: * controls, and if it is selected this message needs to
162: * be processed as if a drag window was hit.
163: */
164: CtrlMouseMove(hwnd,
165: (gfDlgSelected && gState != STATE_DRAGGINGNEW) ?
166: TRUE : FALSE, pt.x, pt.y);
167:
168: break;
169:
170: case WM_LBUTTONUP:
171: ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
172:
173: /*
174: * If we are not dragging a new control, then this
175: * message is for the dialog, and we map it from
176: * the dialog client to the dialog window.
177: */
178: if (gState != STATE_DRAGGINGNEW)
179: MapDlgClientPoint(&pt, TRUE);
180:
181: CtrlButtonUp(pt.x, pt.y);
182:
183: break;
184:
185: case WM_DRAWITEM:
186: return DrawOwnerDrawButton((LPDRAWITEMSTRUCT)lParam);
187:
188: default:
189: return CallWindowProc(
190: (WNDPROC)CtrlWndProc, hwnd, msg, wParam, lParam);
191: }
192:
193: return 0L;
194: }
195:
196:
197:
198: /************************************************************************
199: * CtrlWndProc
200: *
201: * This is the window procedure that subclasses all of the controls.
202: * The dialog being edited will also pass messages that it does not
203: * handle through this procedure.
204: *
205: * Arguments:
206: * HWND - Handle to the control window
207: * UINT - window message
208: * WPARAM - message parameter
209: * LPARAM - message parameter
210: *
211: * Returns:
212: * The default window procedure
213: *
214: ************************************************************************/
215:
216: WINDOWPROC CtrlWndProc(
217: HWND hwnd,
218: UINT msg,
219: WPARAM wParam,
220: LPARAM lParam)
221: {
222: POINT pt;
223:
224: switch (msg) {
225: case WM_NCPAINT:
226: case WM_PAINT:
227: {
228: BOOL fTracking;
229:
230: if (gfTrackRectShown) {
231: fTracking = TRUE;
232: HideTrackRect();
233: }
234: else {
235: fTracking = FALSE;
236: }
237:
238: /*
239: * Allow the control to paint first.
240: */
241: CallWindowProc((WNDPROC)PCFROMHWND(hwnd)->pwcd->pfnOldWndProc,
242: hwnd, msg, wParam, lParam);
243:
244: if (fTracking)
245: ShowTrackRect();
246: }
247:
248: break;
249:
250: case WM_SETCURSOR:
251: /*
252: * Defeat the system changing cursors on us. We do it based
253: * on our own hit testing.
254: */
255: return TRUE;
256:
257: case WM_TIMER:
258: PreDragTimeout(hwnd, TRUE);
259: break;
260:
261: case WM_LBUTTONDOWN:
262: ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
263: CtrlButtonDown(hwnd, pt.x, pt.y, FALSE);
264: break;
265:
266: case WM_MOUSEMOVE:
267: ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
268: CtrlMouseMove(hwnd, FALSE, pt.x, pt.y);
269: break;
270:
271: case WM_LBUTTONUP:
272: ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
273: CtrlButtonUp(pt.x, pt.y);
274: break;
275:
276: case WM_LBUTTONDBLCLK:
277: if (gfDisabled)
278: break;
279:
280: /*
281: * Also, be sure any outstanding changes get applied
282: * without errors.
283: */
284: if (!StatusApplyChanges())
285: break;
286:
287: StylesDialog();
288:
289: break;
290:
291: case WM_NCHITTEST:
292: return HTCLIENT;
293:
294: case WM_RBUTTONDOWN:
295: case WM_MBUTTONDOWN:
296: case WM_RBUTTONDBLCLK:
297: case WM_MBUTTONDBLCLK:
298: /*
299: * Helps prevent anything from happening when
300: * the middle or right mouse buttons are pressed
301: * (or doubleclicked).
302: */
303: break;
304:
305: case WM_MOUSEACTIVATE:
306: /*
307: * Defeat this message so that mouse clicks do not activate
308: * the control.
309: */
310: return MA_NOACTIVATE;
311:
312: case WM_DESTROY:
313: /*
314: * Unsubclass the control.
315: */
316: SetWindowLong(hwnd, GWL_WNDPROC,
317: (DWORD)(WNDPROC)(PCFROMHWND(hwnd)->pwcd->pfnOldWndProc));
318:
319: UNSETPCINTOHWND(hwnd);
320:
321: break;
322:
323: default:
324: return CallWindowProc(
325: (WNDPROC)PCFROMHWND(hwnd)->pwcd->pfnOldWndProc,
326: hwnd, msg, wParam, lParam);
327: }
328:
329: return 0L;
330: }
331:
332:
333:
334: /************************************************************************
335: * ChildWndProc
336: *
337: * This is the window procedure that subclasses all of the children
338: * of controls that have them. Currently this is only comboboxes.
339: *
340: * Arguments:
341: * HWND - Handle to the child control window
342: * UINT - window message
343: * WPARAM - message parameter
344: * LPARAM - message parameter
345: *
346: * Returns:
347: * The default window procedure
348: *
349: ************************************************************************/
350:
351: WINDOWPROC ChildWndProc(
352: HWND hwnd,
353: UINT msg,
354: WPARAM wParam,
355: LPARAM lParam)
356: {
357: /*
358: * Is this a mouse message?
359: */
360: if (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) {
361: POINT pt;
362:
363: /*
364: * Yes, convert the coordinates and send it to the parent.
365: */
366: ((pt).x = (SHORT)LOWORD(lParam), (pt).y = (SHORT)HIWORD(lParam));
367: ClientToScreen(hwnd, &pt);
368: ScreenToClient(GetParent(hwnd), &pt);
369: POINT2LONG(pt, lParam);
370: SendMessage(GetParent(hwnd), msg, wParam, lParam);
371: return FALSE;
372: }
373: else if (msg == WM_SETCURSOR) {
374: /*
375: * Defeat the system changing cursors on us. We do it based
376: * on our own hit testing.
377: */
378: return TRUE;
379: }
380: else if (msg == WM_NCDESTROY) {
381: /*
382: * Unsubclass the child.
383: */
384: SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)(WNDPROC)GETCHILDPROC(hwnd));
385:
386: /*
387: * When destroying the child window, we must be sure and
388: * remove the properties associated with it.
389: */
390: UNSETCHILDPROC(hwnd);
391:
392: return 0;
393: }
394: else {
395: /*
396: * A benign message, call the class proc.
397: */
398: return CallWindowProc(GETCHILDPROC(hwnd), hwnd, msg, wParam, lParam);
399: }
400: }
401:
402:
403:
404: /************************************************************************
405: * DrawOwnerDrawButton
406: *
407: * Draws the owner-draw buttons.
408: *
409: * Arguments:
410: * LPDRAWITEMSTRUCT - owner-draw item structure
411: *
412: * Returns:
413: * TRUE if the button was drawn; FALSE if the button could not be drawn.
414: *
415: ************************************************************************/
416:
417: BOOL DrawOwnerDrawButton(
418: LPDRAWITEMSTRUCT lpdis)
419: {
420: TCHAR szText[CCHTEXTMAX];
421:
422: if (lpdis->CtlType != ODT_BUTTON || lpdis->itemAction != ODA_DRAWENTIRE)
423: return FALSE;
424:
425: RoundRect(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
426: lpdis->rcItem.right, lpdis->rcItem.bottom, 4, 4);
427:
428: GetWindowText(lpdis->hwndItem, szText, CCHTEXTMAX);
429: SetBkMode(lpdis->hDC, TRANSPARENT);
430:
431: if (gcd.hFont)
432: SelectObject(lpdis->hDC, gcd.hFont);
433:
434: DrawText(lpdis->hDC, szText, -1, &lpdis->rcItem,
435: DT_CENTER | DT_NOCLIP | DT_VCENTER | DT_SINGLELINE);
436:
437: return TRUE;
438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.