|
|
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: toolbox.c ! 14: * ! 15: * Contains routines that handle the toolbox. ! 16: * ! 17: * Functions: ! 18: * ! 19: * ToolboxShow() ! 20: * ToolboxOnTop() ! 21: * ToolboxWndProc() ! 22: * ToolBtnWndProc() ! 23: * ToolboxSelectTool() ! 24: * ToolboxCreate() ! 25: * ToolboxDrawBitmap() ! 26: * ! 27: * Comments: ! 28: * ! 29: ****************************************************************************/ ! 30: ! 31: #include "dlgedit.h" ! 32: #include "dlgfuncs.h" ! 33: #include "dlgextrn.h" ! 34: ! 35: #include "dialogs.h" ! 36: ! 37: ! 38: #define TOOLBOXMARGIN 2 // Pixels around the buttons in the Toolbox. ! 39: #define TOOLBOXCOLUMNS 2 // Columns in the Toolbox. ! 40: ! 41: /* ! 42: * Style of the toolbox window. ! 43: */ ! 44: #define TOOLBOXSTYLE (WS_POPUP | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU) ! 45: ! 46: STATICFN VOID ToolboxCreate(VOID); ! 47: STATICFN VOID ToolboxDrawBitmap(HDC hDC, INT type); ! 48: ! 49: /* ! 50: * Dimensions of a tool button bitmap. ! 51: */ ! 52: static INT cxToolBtn; ! 53: static INT cyToolBtn; ! 54: ! 55: ! 56: ! 57: /**************************************************************************** ! 58: * ToolboxShow ! 59: * ! 60: * This function shows or hides the toolbox window. It will create ! 61: * the Toolbox if necessary. ! 62: * ! 63: * Arguments: ! 64: * BOOL fShow - whether to show or hide the toolbox window. ! 65: * ! 66: ****************************************************************************/ ! 67: ! 68: VOID ToolboxShow( ! 69: BOOL fShow) ! 70: { ! 71: if (fShow) { ! 72: /* ! 73: * Don't allow a toolbox to be shown in Translate mode. ! 74: */ ! 75: if (gfTranslateMode) ! 76: return; ! 77: ! 78: /* ! 79: * Create it if it doesn't exist yet. ! 80: */ ! 81: if (!ghwndToolbox) ! 82: ToolboxCreate(); ! 83: ! 84: if (ghwndToolbox) ! 85: ShowWindow(ghwndToolbox, SW_SHOWNA); ! 86: } ! 87: else { ! 88: if (ghwndToolbox) ! 89: ShowWindow(ghwndToolbox, SW_HIDE); ! 90: } ! 91: } ! 92: ! 93: ! 94: ! 95: /**************************************************************************** ! 96: * ToolboxOnTop ! 97: * ! 98: * This function positions the toolbox window on top. It needs to be ! 99: * called any time that a new dialog window is created to be sure the ! 100: * dialog does not cover the toolbox. ! 101: * ! 102: * It can be called even if the toolbox is not created yet (it will ! 103: * be a noop in that case). ! 104: * ! 105: ****************************************************************************/ ! 106: ! 107: VOID ToolboxOnTop(VOID) ! 108: { ! 109: if (ghwndToolbox) { ! 110: SetWindowPos(ghwndToolbox, NULL, 0, 0, 0, 0, ! 111: SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); ! 112: } ! 113: } ! 114: ! 115: ! 116: ! 117: /**************************************************************************** ! 118: * ToolboxCreate ! 119: * ! 120: * This function creates the toolbox window. ! 121: * ! 122: ****************************************************************************/ ! 123: ! 124: STATICFN VOID ToolboxCreate(VOID) ! 125: { ! 126: BITMAP bmp; ! 127: INT i; ! 128: INT x; ! 129: INT y; ! 130: INT cx; ! 131: INT cy; ! 132: INT cxDummy; ! 133: INT cyDummy; ! 134: RECT rc; ! 135: RECT rcSubClient; ! 136: BOOL fMaximized; ! 137: ! 138: /* ! 139: * Load the bitmaps. ! 140: */ ! 141: if (!(ghbmPointerToolUp = LoadBitmap(ghInst, ! 142: MAKEINTRESOURCE(IDBM_TUPOINTR))) || ! 143: !(ghbmPointerToolDown = LoadBitmap(ghInst, ! 144: MAKEINTRESOURCE(IDBM_TDPOINTR)))) ! 145: return; ! 146: ! 147: for (i = 0; i < CCONTROLS; i++) { ! 148: if (!(awcd[i].hbmToolBtnUp = LoadBitmap(ghInst, ! 149: MAKEINTRESOURCE(awcd[i].idbmToolBtnUp)))) ! 150: return; ! 151: ! 152: if (!(awcd[i].hbmToolBtnDown = LoadBitmap(ghInst, ! 153: MAKEINTRESOURCE(awcd[i].idbmToolBtnDown)))) ! 154: return; ! 155: } ! 156: ! 157: /* ! 158: * Get the dimensions of the tool button bitmaps. ! 159: */ ! 160: GetObject(awcd[0].hbmToolBtnUp, sizeof(BITMAP), &bmp); ! 161: cxToolBtn = bmp.bmWidth; ! 162: cyToolBtn = bmp.bmHeight; ! 163: ! 164: /* ! 165: * Calculate the required window size for the client area ! 166: * size we want. The size leaves room for a margin, and ! 167: * assumes that adjacent buttons overlap their borders by ! 168: * one pixel. ! 169: */ ! 170: rc.left = 0; ! 171: rc.top = 0; ! 172: rc.right = TOOLBOXMARGIN + ((cxToolBtn - 1) * 2) + 1 + TOOLBOXMARGIN; ! 173: rc.bottom = TOOLBOXMARGIN + ((cyToolBtn - 1) * ! 174: ((CCONTROLS / 2) + 1)) + 1 + TOOLBOXMARGIN; ! 175: AdjustWindowRect(&rc, TOOLBOXSTYLE, FALSE); ! 176: cx = rc.right - rc.left; ! 177: cy = rc.bottom - rc.top; ! 178: ! 179: /* ! 180: * Get the saved position of the Toolbox. Note that we throw away ! 181: * the size fields, because we just calculated the required size. ! 182: */ ! 183: if (!ReadWindowPos(szTBPos, &x, &y, &cxDummy, &cyDummy, &fMaximized)) { ! 184: /* ! 185: * The previous position of the Toolbox couldn't be found. ! 186: * Position the toolbox to the upper right corner of the ! 187: * "client" area of the editor, but make sure it is completely ! 188: * visible. ! 189: */ ! 190: GetWindowRect(ghwndSubClient, &rcSubClient); ! 191: x = rcSubClient.right - cx - (2 * TOOLBOXMARGIN); ! 192: y = rcSubClient.top + (2 * TOOLBOXMARGIN); ! 193: SetRect(&rc, x, y, x + cx, y + cy); ! 194: FitRectToScreen(&rc); ! 195: x = rc.left; ! 196: y = rc.top; ! 197: } ! 198: ! 199: /* ! 200: * Create the toolbox window. ! 201: */ ! 202: if (!(ghwndToolbox = CreateWindow(szToolboxClass, NULL, TOOLBOXSTYLE, ! 203: x, y, cx, cy, ghwndMain, NULL, ghInst, NULL))) ! 204: return; ! 205: ! 206: /* ! 207: * Create the Pointer (W_NOTHING) button. ! 208: */ ! 209: CreateWindow(szToolBtnClass, NULL, ! 210: WS_CHILD | WS_VISIBLE, ! 211: TOOLBOXMARGIN, TOOLBOXMARGIN, (cxToolBtn * 2) - 1, cyToolBtn, ! 212: ghwndToolbox, (HMENU)W_NOTHING, ghInst, NULL); ! 213: ! 214: /* ! 215: * Create the other buttons. ! 216: */ ! 217: x = TOOLBOXMARGIN; ! 218: y = TOOLBOXMARGIN + cyToolBtn - 1; ! 219: for (i = 0; i < CCONTROLS; i++) { ! 220: CreateWindow(szToolBtnClass, NULL, ! 221: WS_CHILD | WS_VISIBLE, ! 222: x, y, cxToolBtn, cyToolBtn, ! 223: ghwndToolbox, (HMENU)i, ghInst, NULL); ! 224: ! 225: if (x == TOOLBOXMARGIN) { ! 226: x += cxToolBtn - 1; ! 227: } ! 228: else { ! 229: x = TOOLBOXMARGIN; ! 230: y += cyToolBtn - 1; ! 231: } ! 232: } ! 233: } ! 234: ! 235: ! 236: ! 237: /**************************************************************************** ! 238: * ToolboxWndProc ! 239: * ! 240: * This is the window procedure for the toolbox window. ! 241: * ! 242: ****************************************************************************/ ! 243: ! 244: WINDOWPROC ToolboxWndProc( ! 245: HWND hwnd, ! 246: UINT msg, ! 247: WPARAM wParam, ! 248: LPARAM lParam) ! 249: { ! 250: switch (msg) { ! 251: case WM_CREATE: ! 252: { ! 253: HMENU hmenu = GetSystemMenu(hwnd, FALSE); ! 254: ! 255: RemoveMenu(hmenu, 7, MF_BYPOSITION); // Second separator. ! 256: RemoveMenu(hmenu, 5, MF_BYPOSITION); // First separator. ! 257: ! 258: RemoveMenu(hmenu, SC_RESTORE, MF_BYCOMMAND); ! 259: RemoveMenu(hmenu, SC_SIZE, MF_BYCOMMAND); ! 260: RemoveMenu(hmenu, SC_MINIMIZE, MF_BYCOMMAND); ! 261: RemoveMenu(hmenu, SC_MAXIMIZE, MF_BYCOMMAND); ! 262: RemoveMenu(hmenu, SC_TASKLIST, MF_BYCOMMAND); ! 263: } ! 264: ! 265: return 0; ! 266: ! 267: case WM_KEYDOWN: ! 268: { ! 269: INT iToolNext; ! 270: ! 271: switch (wParam) { ! 272: case VK_UP: ! 273: if ((GetKeyState(VK_SHIFT) & 0x8000) || ! 274: (GetKeyState(VK_CONTROL) & 0x8000)) ! 275: break; ! 276: ! 277: /* ! 278: * Go up a row, but don't go beyond the top. ! 279: */ ! 280: iToolNext = gCurTool - TOOLBOXCOLUMNS; ! 281: if (iToolNext < 0) ! 282: iToolNext = W_NOTHING; ! 283: ! 284: ToolboxSelectTool(iToolNext, FALSE); ! 285: ! 286: break; ! 287: ! 288: case VK_DOWN: ! 289: if ((GetKeyState(VK_SHIFT) & 0x8000) || ! 290: (GetKeyState(VK_CONTROL) & 0x8000)) ! 291: break; ! 292: ! 293: if (gCurTool == W_NOTHING) { ! 294: iToolNext = 0; ! 295: } ! 296: else { ! 297: /* ! 298: * Go down a row, but don't go beyond the bottom. ! 299: */ ! 300: iToolNext = gCurTool + TOOLBOXCOLUMNS; ! 301: if (iToolNext >= CCONTROLS) ! 302: break; ! 303: } ! 304: ! 305: ToolboxSelectTool(iToolNext, FALSE); ! 306: ! 307: break; ! 308: ! 309: case VK_LEFT: ! 310: if ((GetKeyState(VK_SHIFT) & 0x8000) || ! 311: (GetKeyState(VK_CONTROL) & 0x8000)) ! 312: break; ! 313: ! 314: if (gCurTool == W_NOTHING || ! 315: !(gCurTool % TOOLBOXCOLUMNS)) ! 316: break; ! 317: ! 318: /* ! 319: * Go left a column. ! 320: */ ! 321: ToolboxSelectTool(gCurTool - 1, FALSE); ! 322: ! 323: break; ! 324: ! 325: case VK_RIGHT: ! 326: if ((GetKeyState(VK_SHIFT) & 0x8000) || ! 327: (GetKeyState(VK_CONTROL) & 0x8000)) ! 328: break; ! 329: ! 330: if (gCurTool == W_NOTHING || ! 331: (gCurTool % TOOLBOXCOLUMNS) == ! 332: TOOLBOXCOLUMNS - 1) ! 333: break; ! 334: ! 335: /* ! 336: * Go right a column. ! 337: */ ! 338: ToolboxSelectTool(gCurTool + 1, FALSE); ! 339: ! 340: break; ! 341: ! 342: case VK_TAB: ! 343: if (GetKeyState(VK_CONTROL) & 0x8000) ! 344: break; ! 345: ! 346: /* ! 347: * Is the shift key pressed also? ! 348: */ ! 349: if (GetKeyState(VK_SHIFT) & 0x8000) { ! 350: if (gCurTool == W_NOTHING) ! 351: iToolNext = CCONTROLS - 1; ! 352: else if (gCurTool == 0) ! 353: iToolNext = W_NOTHING; ! 354: else ! 355: iToolNext = gCurTool - 1; ! 356: } ! 357: else { ! 358: if (gCurTool == W_NOTHING) ! 359: iToolNext = 0; ! 360: else if (gCurTool == CCONTROLS - 1) ! 361: iToolNext = W_NOTHING; ! 362: else ! 363: iToolNext = gCurTool + 1; ! 364: } ! 365: ! 366: ToolboxSelectTool(iToolNext, FALSE); ! 367: ! 368: break; ! 369: ! 370: case VK_END: ! 371: if ((GetKeyState(VK_SHIFT) & 0x8000) || ! 372: (GetKeyState(VK_CONTROL) & 0x8000)) ! 373: break; ! 374: ! 375: ToolboxSelectTool(CCONTROLS - 1, FALSE); ! 376: ! 377: break; ! 378: ! 379: case VK_HOME: ! 380: case VK_ESCAPE: ! 381: if ((GetKeyState(VK_SHIFT) & 0x8000) || ! 382: (GetKeyState(VK_CONTROL) & 0x8000)) ! 383: break; ! 384: ! 385: ToolboxSelectTool(W_NOTHING, FALSE); ! 386: ! 387: break; ! 388: } ! 389: } ! 390: ! 391: break; ! 392: ! 393: case WM_ACTIVATE: ! 394: if (LOWORD(wParam)) ! 395: gidCurrentDlg = DID_TOOLBOX; ! 396: ! 397: break; ! 398: ! 399: case WM_CLOSE: ! 400: /* ! 401: * The user closed the toolbox from the system menu. ! 402: * Hide the toolbox (we don't actually destroy it so ! 403: * that it will appear in the same spot when they show ! 404: * it again). ! 405: */ ! 406: ToolboxShow(FALSE); ! 407: gfShowToolbox = FALSE; ! 408: break; ! 409: ! 410: case WM_DESTROY: ! 411: { ! 412: INT i; ! 413: RECT rc; ! 414: ! 415: DeleteObject(ghbmPointerToolUp); ! 416: ghbmPointerToolUp = NULL; ! 417: DeleteObject(ghbmPointerToolDown); ! 418: ghbmPointerToolDown = NULL; ! 419: ! 420: for (i = 0; i < CCONTROLS; i++) { ! 421: DeleteObject(awcd[i].hbmToolBtnUp); ! 422: awcd[i].hbmToolBtnUp = NULL; ! 423: DeleteObject(awcd[i].hbmToolBtnDown); ! 424: awcd[i].hbmToolBtnDown = NULL; ! 425: } ! 426: ! 427: /* ! 428: * Save the position of the toolbox. ! 429: */ ! 430: GetWindowRect(hwnd, &rc); ! 431: WriteWindowPos(&rc, FALSE, szTBPos); ! 432: ! 433: /* ! 434: * Null out the global window handle for the toolbox ! 435: * for safety's sake. ! 436: */ ! 437: ghwndToolbox = NULL; ! 438: } ! 439: ! 440: break; ! 441: ! 442: default: ! 443: return DefWindowProc(hwnd, msg, wParam, lParam); ! 444: } ! 445: ! 446: return 0; ! 447: } ! 448: ! 449: ! 450: ! 451: /**************************************************************************** ! 452: * ToolBtnWndProc ! 453: * ! 454: * This is the window procedure for the buttons in the toolbox window. ! 455: * ! 456: ****************************************************************************/ ! 457: ! 458: WINDOWPROC ToolBtnWndProc( ! 459: HWND hwnd, ! 460: UINT msg, ! 461: WPARAM wParam, ! 462: LPARAM lParam) ! 463: { ! 464: switch (msg) { ! 465: case WM_LBUTTONDOWN: ! 466: /* ! 467: * Be sure any outstanding changes get applied ! 468: * without errors. ! 469: */ ! 470: if (!StatusApplyChanges()) ! 471: return TRUE; ! 472: ! 473: /* ! 474: * Select the tool that was clicked on. If the Ctrl ! 475: * key is down, lock the tool also. ! 476: */ ! 477: ToolboxSelectTool((UINT)GetWindowLong((hwnd), GWL_ID), ! 478: (GetKeyState(VK_CONTROL) & 0x8000) ? TRUE : FALSE); ! 479: ! 480: break; ! 481: ! 482: case WM_PAINT: ! 483: { ! 484: HDC hDC; ! 485: PAINTSTRUCT ps; ! 486: ! 487: hDC = BeginPaint(hwnd, &ps); ! 488: ToolboxDrawBitmap(hDC, (UINT)GetWindowLong((hwnd), GWL_ID)); ! 489: EndPaint(hwnd, &ps); ! 490: } ! 491: ! 492: break; ! 493: ! 494: default: ! 495: return DefWindowProc(hwnd, msg, wParam, lParam); ! 496: } ! 497: ! 498: return 0; ! 499: } ! 500: ! 501: ! 502: ! 503: /**************************************************************************** ! 504: * ToolboxDrawBitmap ! 505: * ! 506: * Draws the current tool bitmap. ! 507: * ! 508: * Arguments: ! 509: * HDC hDC - handle to the DC for the toolbox window. ! 510: * INR type - type of bitmap to draw. ! 511: * ! 512: ****************************************************************************/ ! 513: ! 514: STATICFN VOID ToolboxDrawBitmap( ! 515: HDC hDC, ! 516: INT type) ! 517: { ! 518: HDC hMemDC; ! 519: HBITMAP hbm; ! 520: HBITMAP hbmOld; ! 521: INT cxBitmap; ! 522: ! 523: if (type == W_NOTHING) { ! 524: hbm = (type == gCurTool) ? ghbmPointerToolDown : ghbmPointerToolUp; ! 525: ! 526: /* ! 527: * Note that the size of the Pointer tool is twice the width ! 528: * of the other bitmaps, but less one pixel. This is because ! 529: * the other tools overlap their adjacent borders. ! 530: */ ! 531: cxBitmap = (cxToolBtn * 2) - 1; ! 532: } ! 533: else { ! 534: hbm = (type == gCurTool) ? ! 535: awcd[type].hbmToolBtnDown : awcd[type].hbmToolBtnUp; ! 536: cxBitmap = cxToolBtn; ! 537: } ! 538: ! 539: /* ! 540: * Draw the image. ! 541: */ ! 542: hMemDC = CreateCompatibleDC(hDC); ! 543: hbmOld = SelectObject(hMemDC, hbm); ! 544: BitBlt(hDC, 0, 0, cxBitmap, cyToolBtn, hMemDC, 0, 0, SRCCOPY); ! 545: SelectObject(hMemDC, hbmOld); ! 546: DeleteDC(hMemDC); ! 547: } ! 548: ! 549: ! 550: ! 551: /**************************************************************************** ! 552: * ToolboxSelectTool ! 553: * ! 554: * This function selects a tool to be the current tool. ! 555: * ! 556: * Arguments: ! 557: * INT type - Type of control (one of the W_* defines). ! 558: * BOOL fLock - TRUE if the tool should be locked down. ! 559: * ! 560: ****************************************************************************/ ! 561: ! 562: VOID ToolboxSelectTool( ! 563: INT type, ! 564: BOOL fLock) ! 565: { ! 566: PWINDOWCLASSDESC pwcd; ! 567: ! 568: if (gCurTool != type) { ! 569: /* ! 570: * Set the current wcd global for the current tool type. ! 571: * This will point to the WINDOWCLASSDESC structure of the ! 572: * current tool. If the Custom tool was selected, the user ! 573: * is asked which of the installed custom controls that they ! 574: * really want. ! 575: */ ! 576: if (type == W_CUSTOM) { ! 577: /* ! 578: * There are no custom controls installed. Beep and ! 579: * return without doing anything. ! 580: */ ! 581: if (!gpclHead) { ! 582: MessageBeep(0); ! 583: return; ! 584: } ! 585: ! 586: /* ! 587: * If there are multiple custom controls installed, ! 588: * ask the user which one they want. Note that they ! 589: * can press Cancel and return NULL! ! 590: */ ! 591: if (gpclHead->pclNext) { ! 592: if (!(pwcd = SelCustDialog())) ! 593: return; ! 594: ! 595: gpwcdCurTool = pwcd; ! 596: } ! 597: else { ! 598: /* ! 599: * Since there is only one type of custom control ! 600: * installed, there is no need to ask the user ! 601: * which one they want. ! 602: */ ! 603: gpwcdCurTool = gpclHead->pwcd; ! 604: } ! 605: } ! 606: else { ! 607: gpwcdCurTool = (type == W_NOTHING) ? NULL : &awcd[type]; ! 608: } ! 609: ! 610: /* ! 611: * Force the previous and current buttons to repaint. ! 612: */ ! 613: if (ghwndToolbox) { ! 614: InvalidateRect(GetDlgItem(ghwndToolbox, gCurTool), NULL, FALSE); ! 615: InvalidateRect(GetDlgItem(ghwndToolbox, type), NULL, FALSE); ! 616: } ! 617: ! 618: /* ! 619: * Set the current tool type global. This will be W_CUSTOM for ! 620: * all custom controls. ! 621: */ ! 622: gCurTool = type; ! 623: } ! 624: ! 625: gfToolLocked = fLock; ! 626: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.