TOOLBOX.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:18k
源码类别:

Windows编程

开发平台:

Visual C++

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