|
|
1.1 root 1: /*
2: * GIZMOBAR.C
3: * GizmoBar Version 1.00, March 1993
4: *
5: * Contains the main window procedure of the GizmoBar control
6: * that handles mouse logic and Windows messages.
7: *
8: * Copyright (c)1992 Microsoft Corporation, All Rights Reserved
9: *
10: * Kraig Brockschmidt, Software Design Engineer
11: * Microsoft Systems Developer Relations
12: *
13: * Internet : [email protected]
14: * Compuserve: >INTERNET:[email protected]
15: */
16:
17: #ifdef WIN32
18: #define _INC_OLE
19: #define __RPC_H__
20: #endif
21:
22:
23: #define STRICT
24: #include <windows.h>
25: #include "gizmoint.h"
26:
27:
28:
29: /*
30: * GizmoBarWndProc
31: *
32: * Purpose:
33: * Window Procedure for the GizmoBar custom control. Handles all
34: * messages like WM_PAINT just as a normal application window would.
35: * Any message not processed here should go to DefWindowProc.
36: *
37: * Parameters:
38: * Standard
39: *
40: * Return Value:
41: * Standard
42: */
43:
44: LRESULT FAR PASCAL GizmoBarWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
45: {
46: BOOL fSuccess;
47: BOOL fTemp;
48: LPCREATESTRUCT pCreate;
49: PGIZMOBAR pGB;
50: PGIZMO pGizmo;
51: RECT rc;
52: short x, y;
53: COLORREF cr;
54:
55: COMMANDPARAMS(wID, wCode, hWndMsg);
56:
57: //This will be valid for all messages except WM_NCCREATE
58: pGB=(PGIZMOBAR)GetWindowLong(hWnd, GBWL_STRUCTURE);
59:
60: //Pass control messages onto another function for processing.
61: if (iMsg >= WM_USER)
62: return GBMessageHandler(hWnd, iMsg, wParam, lParam, pGB);
63:
64: //Handle standard Windows messages.
65: switch (iMsg)
66: {
67: case WM_NCCREATE:
68: pCreate=(LPCREATESTRUCT)lParam;
69:
70: pGB=GizmoBarPAllocate((LPINT)&fSuccess, hWnd, pCreate->hInstance
71: , pCreate->hwndParent, pCreate->style, 0);
72:
73: if (!fSuccess)
74: {
75: GizmoBarPFree(pGB);
76: return -1L;
77: }
78: else
79: SetWindowLong(hWnd, GBWL_STRUCTURE, (LONG)pGB);
80:
81: return DefWindowProc(hWnd, iMsg, wParam, lParam);
82:
83:
84: case WM_DESTROY:
85: /*
86: * We want to clean up before DestroyWindow nukes all the
87: * children, so WM_DESTROY is a better to do it than
88: * WM_NCDESTROY.
89: */
90: GizmoBarPFree(pGB);
91: break;
92:
93:
94: case WM_ERASEBKGND:
95: /*
96: * Eat this message to avoid erasing portions that
97: * we are going to repaint in WM_PAINT. Part of a
98: * change-state-and-repaint strategy is to rely on
99: * WM_PAINT to do anything visual, which includes
100: * erasing invalid portions. Letting WM_ERASEBKGND
101: * erase the background is redundant.
102: */
103: return TRUE;
104:
105: #ifdef WIN32
106: case WM_CTLCOLORBTN:
107: case WM_CTLCOLORSTATIC:
108: #else
109: case WM_CTLCOLOR:
110: /*
111: * Change the color of static text on the GizmoBar.
112: */
113: if (HIWORD(lParam)==CTLCOLOR_STATIC || HIWORD(lParam)==CTLCOLOR_BTN)
114: #endif
115: {
116: cr=GetSysColor(COLOR_BTNFACE);
117: SetTextColor((HDC)wParam, GetSysColor(COLOR_BTNTEXT));
118: SetBkColor((HDC)wParam, cr);
119:
120: /*
121: * If the system colors have changed, then crFace will
122: * not be equal to COLOR_BTNFACE, so we reinitialize the
123: * background brush. This scheme handles system color
124: * changes appropriately without processing WM_WININICHANGE
125: * and without blindly creating a new brush on every
126: * WM_CTLCOLOR message.
127: */
128: if (cr!=pGB->crFace)
129: {
130: pGB->crFace=cr;
131:
132: if (NULL!=pGB->hBrFace)
133: DeleteObject(pGB->hBrFace);
134:
135: pGB->hBrFace=CreateSolidBrush(pGB->crFace);
136: }
137:
138: return (LONG)(UINT)pGB->hBrFace;
139: }
140:
141: return DefWindowProc(hWnd, iMsg, wParam, lParam);
142:
143:
144: case WM_PAINT:
145: GizmoBarPaint(hWnd, pGB);
146: break;
147:
148:
149: case WM_SETFONT:
150: /*
151: * wParam has the new font that we now send to all other
152: * windows controls in us. We control repaints here to
153: * prevent a lot of repainting for each control.
154: */
155: DefWindowProc(hWnd, WM_SETREDRAW, FALSE, 0L);
156: #ifdef WIN32
157: if ( (WPARAM)NULL != wParam)
158: #else
159: if ((WPARAM)NULL!=wParam && IsGDIObject((HFONT)wParam))
160: #endif
161: {
162: pGB->hFont=(HFONT)wParam;
163: GizmoPEnum(&pGB->pGizmos, FEnumChangeFont, (DWORD)(LPSTR)pGB);
164:
165: DefWindowProc(hWnd, WM_SETREDRAW, TRUE, 0L);
166: InvalidateRect(hWnd, NULL, FALSE);
167: UpdateWindow(hWnd);
168: }
169: break;
170:
171:
172: case WM_GETFONT:
173: return (LRESULT)(UINT)pGB->hFont;
174:
175:
176: case WM_ENABLE:
177: /*
178: * wParam has the new enable flag that we use to enable
179: * or disable ALL controls in us at one time. We also turn
180: * the redraw off to prevent a lot of flicker.
181: */
182: DefWindowProc(hWnd, WM_SETREDRAW, FALSE, 0L);
183:
184: pGB->fEnabled=(BOOL)wParam;
185: GizmoPEnum(&pGB->pGizmos, FEnumEnable, (DWORD)(LPSTR)pGB);
186:
187: DefWindowProc(hWnd, WM_SETREDRAW, TRUE, 0L);
188: InvalidateRect(hWnd, NULL, FALSE);
189: UpdateWindow(hWnd);
190: break;
191:
192:
193: case WM_CANCELMODE:
194: pGizmo=pGB->pGizmoTrack;
195:
196: pGB->fTracking=FALSE;
197: pGB->fMouseOut=FALSE;
198:
199: if (NULL!=pGizmo)
200: GizmoPStateSet(hWnd, pGizmo, COMMANDBUTTON_UP);
201:
202: ReleaseCapture();
203: break;
204:
205:
206: case WM_LBUTTONDBLCLK:
207: case WM_LBUTTONDOWN:
208: //Get the mouse coordinates.
209: x=LOWORD(lParam);
210: y=HIWORD(lParam);
211:
212:
213: /*
214: * See if we hit a command or attribute gizmo or not. Anything
215: * else that is a control will get the message instead of
216: * us anyway, so we don't have to check. FEnumHitTest also
217: * validates drawn gizmos, enabled, and visible, so we don't.
218: */
219: pGizmo=GizmoPEnum(&pGB->pGizmos, FEnumHitTest, lParam);
220:
221: if (NULL==pGizmo)
222: break; //Didn't hit one matching our needs.
223:
224: /*
225: * Inform the associate that a command was hit like a menu item.
226: */
227: if (NULL!=pGB->hWndAssociate)
228: {
229: if (pGizmo->fNotify)
230: SendMenuSelect(pGB->hWndAssociate, pGizmo->uID, 0, 0);
231: }
232:
233: /*
234: * We hit a button. If it's a command or attribute, then change
235: * the state and start tracking.
236: */
237: pGB->fTracking=TRUE;
238: pGB->pGizmoTrack=pGizmo;
239: pGB->fMouseOut=FALSE;
240: SetCapture(hWnd);
241:
242: pGizmo->uStateOrg=pGizmo->uState;
243: GizmoPStateSet(hWnd, pGizmo, ATTRIBUTEBUTTON_MOUSEDOWN);
244:
245: break;
246:
247:
248: case WM_MOUSEMOVE:
249: {
250: POINT point;
251: #ifdef WIN32
252: point.x = (LONG)(SHORT)LOWORD(lParam);
253: point.y = (LONG)(SHORT)HIWORD(lParam);
254: #else
255: point.x = LOWORD(lParam);
256: point.y = HIWORD(lParam);
257: #endif
258: if (!pGB->fTracking)
259: break;
260:
261: pGizmo=pGB->pGizmoTrack;
262: SetRect(&rc, pGizmo->x, pGizmo->y, pGizmo->x+pGizmo->dx, pGizmo->y+pGizmo->dy);
263:
264: fTemp=pGB->fMouseOut;
265: pGB->fMouseOut=!PtInRect(&rc, point);
266:
267: //If the mouse went out, change state to the original.
268: if (!fTemp && pGB->fMouseOut)
269: {
270: GizmoPStateSet(hWnd, pGizmo, pGizmo->uStateOrg);
271:
272: if (NULL!=pGB->hWndAssociate)
273: {
274: //Notify that we left the button
275: if (pGizmo->fNotify)
276: SendMenuSelect(pGB->hWndAssociate, 0x0000, 0xFFFF, 0);
277: }
278: }
279:
280: if (fTemp && !pGB->fMouseOut)
281: {
282: GizmoPStateSet(hWnd, pGizmo, ATTRIBUTEBUTTON_MOUSEDOWN);
283:
284: if (NULL!=pGB->hWndAssociate)
285: {
286: //Notify that we pressed down again
287: if (pGizmo->fNotify)
288: SendMenuSelect(pGB->hWndAssociate, pGizmo->uID, 0x0000, 0);
289: }
290: }
291:
292: break;
293: }
294:
295: case WM_LBUTTONUP:
296: if (!pGB->fTracking)
297: break;
298:
299: pGB->fTracking=FALSE;
300: pGizmo=pGB->pGizmoTrack;
301: ReleaseCapture();
302:
303:
304: /*
305: * Repaint if we were actually below the mouse when this
306: * occurred. For command buttons, pop the button up. For
307: * attributes, either toggle the state (inclusive buttons)
308: * or check the selected one (exclusive buttons).
309: */
310:
311: if (!pGB->fMouseOut)
312: {
313: //Command buttons always come up.
314: if (GIZMOTYPE_BUTTONCOMMAND==pGizmo->iType)
315: GizmoPStateSet(hWnd, pGizmo, COMMANDBUTTON_UP);
316:
317: //Attribute inclusive buttons toggle
318: if (GIZMOTYPE_BUTTONATTRIBUTEIN==pGizmo->iType)
319: GizmoPCheck(hWnd, pGizmo, !(BUTTONGROUP_DOWN & pGizmo->uStateOrg));
320:
321: //Attribure exclusive buttons are always checked.
322: if (GIZMOTYPE_BUTTONATTRIBUTEEX==pGizmo->iType)
323: GizmoPCheck(hWnd, pGizmo, TRUE);
324:
325: //Only send messages if notify is ON.
326: if (NULL!=pGB->hWndAssociate && pGizmo->fNotify)
327: {
328: SendMenuSelect(pGB->hWndAssociate, 0, 0xFFFF, 0);
329: SendCommand(pGB->hWndAssociate, pGizmo->uID, BN_CLICKED, hWnd);
330: }
331: }
332:
333: break;
334:
335:
336: case WM_COMMAND:
337: //Pass control messages on if the gizmo's notify is ON.
338: if (NULL!=pGB->hWndAssociate)
339: {
340: pGizmo=PGizmoFromHwndID(hWnd, wID);
341:
342: if (NULL!=pGizmo)
343: {
344: if (pGizmo->fNotify)
345: SendMessage(pGB->hWndAssociate, iMsg, wParam, lParam);
346: }
347: }
348: break;
349:
350: default:
351: return DefWindowProc(hWnd, iMsg, wParam, lParam);
352: }
353:
354: return 0L;
355: }
356:
357:
358:
359:
360:
361: /*
362: * FEnumChangeFont
363: *
364: * Purpose:
365: * Enumeration callback for all the gizmos we know about in order to
366: * send a new font to them that's stored in PGIZMOBAR in dw.
367: *
368: * Parameters:
369: * pGizmo PGIZMO to draw.
370: * iGizmo UINT index on the GizmoBar of this gizmo.
371: * dw DWORD extra data passed to GizmoPEnum, in our case
372: * the GizmoBar's pGB.
373: *
374: * Return Value:
375: * BOOL TRUE to continue the enumeration, FALSE otherwise.
376: */
377:
378: BOOL FAR PASCAL FEnumChangeFont(PGIZMO pGizmo, UINT iGizmo, DWORD dw)
379: {
380: PGIZMOBAR pGB=(PGIZMOBAR)dw;
381:
382: //We only need to change fonts in windowed controls using WM_SETFONT
383: if (NULL!=pGizmo->hWnd)
384: SendMessage(pGizmo->hWnd, WM_SETFONT, (WPARAM)pGB->hFont, 1L);
385:
386: return TRUE;
387: }
388:
389:
390:
391:
392:
393:
394: /*
395: * FEnumEnable
396: *
397: * Purpose:
398: * Enumeration callback for all the gizmos we know about in order to
399: * enable or disable them from the WM_ENABLE message.
400: *
401: * Parameters:
402: * pGizmo PGIZMO to draw.
403: * iGizmo UINT index on the GizmoBar of this gizmo.
404: * dw DWORD extra data passed to GizmoPEnum, in our case
405: * the GizmoBar's pGB.
406: *
407: * Return Value:
408: * BOOL TRUE to continue the enumeration, FALSE otherwise.
409: */
410:
411: BOOL FAR PASCAL FEnumEnable(PGIZMO pGizmo, UINT iGizmo, DWORD dw)
412: {
413: PGIZMOBAR pGB=(PGIZMOBAR)dw;
414: BOOL fEnable=pGB->fEnabled;
415:
416: //NOTE: This code is duplicated in GBGizmoEnable in API.C
417: if (NULL!=pGizmo->hWnd)
418: EnableWindow(pGizmo->hWnd, fEnable);
419: else
420: {
421: //If we're not down, command and attribute buttons act the same.
422: if (!(BUTTONGROUP_DOWN & pGizmo->uState))
423: {
424: GizmoPStateSet(pGB->hWnd, pGizmo
425: , fEnable ? COMMANDBUTTON_UP : COMMANDBUTTON_DISABLED);
426: }
427: else
428: {
429: //Attribute buttons are a little more sensitive with DOWNDISABLED
430: GizmoPStateSet(pGB->hWnd, pGizmo
431: , fEnable ? ATTRIBUTEBUTTON_DOWN : ATTRIBUTEBUTTON_DOWNDISABLED);
432: }
433: }
434:
435: return TRUE;
436: }
437:
438:
439:
440:
441:
442:
443:
444: /*
445: * FEnumHitTest
446: *
447: * Purpose:
448: * Enumeration callback for all the gizmos we know about in order to
449: * hit-test them.
450: *
451: * Parameters:
452: * pGizmo PGIZMO to draw.
453: * iGizmo UINT index on the GizmoBar of this gizmo.
454: * dw DWORD extra data passed to GizmoPEnum, in our case
455: * the hDC on which to draw.
456: *
457: * Return Value:
458: * BOOL TRUE to continue the enumeration, FALSE otherwise.
459: */
460:
461: BOOL FAR PASCAL FEnumHitTest(PGIZMO pGizmo, UINT iGizmo, DWORD dw)
462: {
463: RECT rc;
464: POINT point;
465: #ifdef WIN32
466: point.x = (LONG)(SHORT)LOWORD(dw);
467: point.y = (LONG)(SHORT)HIWORD(dw);
468: #else
469: point.x = LOWORD(dw);
470: point.y = HIWORD(dw);
471: #endif
472:
473:
474: //Hit tests have to happen on visible, enabled, and drawn controls only.
475: if (GIZMOTYPE_DRAWN & pGizmo->iType
476: && !pGizmo->fHidden && !(BUTTONGROUP_DISABLED & pGizmo->uState))
477: {
478: SetRect(&rc, pGizmo->x, pGizmo->y, pGizmo->x+pGizmo->dx, pGizmo->y+pGizmo->dy);
479:
480: //Stop enumeration if we have a hit.
481: return !PtInRect(&rc, point);
482: }
483:
484: return TRUE;
485: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.