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