home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / demo / toolbar / toolbar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-16  |  14.7 KB  |  472 lines

  1. #define  STRICT
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <commctrl.h>
  7. #include "tbdemo2.h"
  8. #include <winver.h>
  9.  
  10. /*****************************************
  11.   Toolbar Demo Program by Eric Heimburg
  12.   To compile, create a project, and place  
  13.   TBDEMO2.C (this file) and TBDEMO2.RC
  14.   in the project's file list. If compiling
  15.   with Watcom C/C++, also include the file
  16.   \watcom\lib386\nt\comctl32.lib.
  17.  
  18.   Key to abbreviations:
  19.     TB  = Tool Bar
  20.     CB  = Combo Box
  21.     EB  = Edit Box
  22.     IDX = Index
  23.     CMD = Command ID
  24. *****************************************/
  25.  
  26. /* global variables */
  27.  
  28. HINSTANCE hInstance;
  29. HWND hMainWnd, hTB, hCB, hEB;
  30. LONG OldProc = 0;
  31. HBITMAP hPicBmp;
  32.  
  33. /* toolbar definitions */
  34.  
  35. #define CBWIDTH               125 /* width of combobox */
  36. #define CBEXTRAHEIGHT         200 /* amount CB should hang
  37.                                      down below TB*/
  38. #define EBWIDTH               75  /* width of edit box */
  39. #define EBEXTRAHEIGHT         0   /* amount EB should hang
  40.                                      down below TB*/
  41. #define ID_TB                 10  /* Cmd. ID of toolbar */
  42. #define ID_CB                 110 /* Cmd. ID of combobox */
  43.  
  44. /* These specify the registry location (inside
  45.   HKEY_CURRENT_USER) to which the toolbar configuration
  46.   is to be saved and restored. */
  47.   
  48. #define SAVERESTORE_SUBKEY    "TBDEMO"
  49. #define SAVERESTORE_ENTRY     "TBDEMO Configuration"
  50.  
  51.  
  52. /* Btns[] is the master TBBUTTON list. It contains info
  53.   about every button that can appear on the toolbar. */
  54.   
  55. TBBUTTON Btns[] =
  56. {
  57.  {IDX_BOMB,      CMD_BOMB,      TBSTATE_ENABLED,
  58.     TBSTYLE_CHECK,  "", 0, 0},
  59.  {IDX_GREENFLAG, CMD_GREENFLAG, TBSTATE_ENABLED,
  60.     TBSTYLE_CHECK,  "", 0, 0},
  61.  {IDX_YELLOWFLAG,CMD_YELLOWFLAG,TBSTATE_ENABLED,
  62.     TBSTYLE_CHECK,  "", 0, 0},
  63.  {IDX_PHONE,     CMD_PHONE,     TBSTATE_ENABLED,
  64.     TBSTYLE_BUTTON, "", 0, 0},
  65.  {IDX_FLOPPYDISK,CMD_FLOPPYDISK,TBSTATE_ENABLED,
  66.     TBSTYLE_BUTTON, "", 0, 0},
  67.  {IDX_FOLDER,    CMD_FOLDER,    TBSTATE_ENABLED,
  68.     TBSTYLE_BUTTON, "", 0, 0},
  69.  {IDX_OPENFOLDER,CMD_OPENFOLDER,TBSTATE_ENABLED,
  70.     TBSTYLE_BUTTON, "", 0, 0},
  71.  {IDX_DOCUMENTS, CMD_DOCUMENTS, TBSTATE_ENABLED,
  72.     TBSTYLE_BUTTON, "", 0, 0},
  73.  {EBWIDTH,       CMD_EB,        TBSTATE_ENABLED,
  74.     TBSTYLE_SEP,    "", 0, 0},
  75.  {CBWIDTH,       CMD_CB,        TBSTATE_ENABLED,
  76.     TBSTYLE_SEP,    "", 0, 0}
  77. };
  78. #define NUMBTNS            (sizeof(Btns) / sizeof(TBBUTTON))
  79.  
  80.  
  81. /* IdxStartBtns[] contains indices into the master TBBUTTON
  82.   list. These are the controls that appear on the toolbar
  83.   at startup, or when the toolbar is told to reset itself.*/
  84.  
  85. #define NUMSTARTBTNS          7
  86. int IdxStartBtns[NUMSTARTBTNS] = { IDX_CB, IDX_BOMB, IDX_EB,
  87.   IDX_FOLDER, IDX_GREENFLAG, IDX_YELLOWFLAG, IDX_DOCUMENTS};
  88.  
  89.  
  90.  
  91. /**********************************************************
  92.   RestoreToolbar - loads a saved toolbar configuration from
  93.     the registry. Replaces TB_SAVERESTORE's
  94.     restoration capability, which is flawed (see article).
  95.  
  96.   Parameters:
  97.     hTB     = handle of toolbar being restored
  98.     List    = pointer to program's master TBBUTTON list
  99.     nList   = number of entries in List
  100.     hKey    = handle of key to get value from
  101.               (typically HKEY_CURRENT_USER)
  102.     SubKey  = text name of subkey to get value from
  103.               (or NULL to use hKey)
  104.     Value   = text name of value
  105.  
  106.   Note that the last three parameters directly correspond
  107.   to the three fields of the TBSAVEPARAMS structure, which
  108.   is passed to TB_SAVERESTORE.
  109. **********************************************************/
  110.  
  111. void RestoreToolbar(HWND hTB, TBBUTTON *List, int nList,
  112.   HKEY hKey, LPCSTR SubKey, LPCSTR ValueName)
  113. {
  114.   TBBUTTON Btn, DefBtn;
  115.   HKEY hOpenKey = 0;
  116.   DWORD BufSize, dwType;
  117.   DWORD *Buffer;
  118.   int loop, loop2, temp;
  119.  
  120.   if (RegOpenKeyEx(hKey, SubKey, 0, KEY_ALL_ACCESS,
  121.                    &hOpenKey) != ERROR_SUCCESS)
  122.     return; /* key doesn't exist */
  123.  
  124.   memset(&DefBtn, 0, sizeof(DefBtn));
  125.   DefBtn.fsState = TBSTATE_ENABLED;
  126.   DefBtn.fsStyle = TBSTYLE_SEP;
  127.  
  128.   /*call RegQueryValueEx once to get size of stored value*/
  129.   if ((RegQueryValueEx(hOpenKey, ValueName, 0, 0, 0,
  130.        &BufSize) == ERROR_SUCCESS) && (BufSize != 0))
  131.   {
  132.     Buffer = (DWORD*)malloc(BufSize);
  133.     RegQueryValueEx(hOpenKey, ValueName, 0, &dwType,
  134.       (BYTE*)Buffer, &BufSize);
  135.  
  136.     /* Ok, the entry exists. Clear off the toolbar... */
  137.     temp = SendMessage(hTB, TB_BUTTONCOUNT, 0, 0);
  138.     for (loop = 0; loop < temp; loop++)
  139.       SendMessage(hTB, TB_DELETEBUTTON, 0, 0);
  140.  
  141.     /* ... and add the new buttons. */
  142.     for (loop = 0; loop < (BufSize / sizeof(DWORD)); loop++)
  143.     {
  144.       Btn = DefBtn;
  145.       for (loop2 = 0; loop2 < nList; loop2++)
  146.         if ((List[loop2].idCommand) == Buffer[loop])
  147.         {
  148.           Btn = Btns[loop2];
  149.           break;
  150.         }
  151.       SendMessage(hTB, TB_ADDBUTTONS, 1, (LPARAM)&Btn);
  152.     }
  153.  
  154.     /* deallocate the buffer */
  155.     free((void*)Buffer);
  156.   }
  157.   RegCloseKey(hOpenKey);
  158. }
  159.  
  160.  
  161. /**********************************************************
  162.   bVersionCorrect - function to check the version of the
  163.     common control DLL. Returns TRUE if it is the correct
  164.     version. This function only checks the DLL the first
  165.     time it is called; it uses a static variable to store
  166.     that result, and immediately return it on subsequent
  167.     calls of the function.
  168. **********************************************************/
  169.  
  170. BOOL bVersionCorrect(void)
  171. {
  172.   DWORD dwDummy, dwSize;
  173.   char *ptr;
  174.   VS_FIXEDFILEINFO *p;
  175.   static int bVersionOk = -1;
  176.  
  177.   if (bVersionOk == -1)  {
  178.     dwSize = GetFileVersionInfoSize("comctl32.dll", &dwDummy);
  179.     if (!dwSize) return FALSE; /* couldn't find file! */
  180.     ptr = (char*)malloc(dwSize);
  181.     GetFileVersionInfo("comctl32.dll", 0, dwSize, ptr);
  182.     VerQueryValue(ptr, "\\", (void**)&p, (UINT*)&dwDummy);
  183.     bVersionOk = ((p->dwFileVersionMS == 0x40000)  &&
  184.                   (p->dwFileVersionLS == 950) &&
  185.                   (p->dwProductVersionMS == 0x40000) &&
  186.                   (p->dwProductVersionLS == 950));
  187.     free((void*)ptr);
  188.   }
  189.   return (BOOL)bVersionOk;
  190. }
  191.  
  192.  
  193. /**********************************************************
  194.   FixTBCntrlPos - function to position a control in a
  195.     toolbar over the control's "host" separator.
  196.  
  197.   Parameters:
  198.     hTB     = handle of the toolbar
  199.     hCntrl  = handle of the control to be positioned
  200.     HostCmd = command ID of the control's host separator
  201.     YExtra  = amount, in pixels, that the control
  202.               (indicated by hCntrl) should hang extend down
  203.               below the toolbar. This is primarily useful
  204.               for comboboxes, so that when they are clicked
  205.               on, they have a larger area in which to
  206.               display their list.
  207. **********************************************************/
  208.  
  209. void FixTBCntrlPos(HWND hTB, HWND hCntrl, int HostCmd,
  210.        int YExtra)
  211. {
  212.   RECT r;
  213.   int n = SendMessage(hTB, TB_COMMANDTOINDEX, HostCmd, 0);
  214.   if (n == -1)
  215.     ShowWindow(hCntrl, SW_HIDE);
  216.   else {
  217.     SendMessage(hTB, TB_GETITEMRECT, n, (LPARAM)&r);
  218.     SetWindowPos(hCntrl, NULL, r.left, r.top,
  219.         r.right - r.left, r.bottom - r.top + YExtra,
  220.         SWP_NOZORDER | SWP_SHOWWINDOW);
  221.   }
  222. }
  223.  
  224.  
  225. /**********************************************************
  226.   CustomizeProc - the window procedure used when
  227.     subclassing the "Customize Toolbar" dialog. See article
  228.     for more information.
  229. **********************************************************/
  230.  
  231. LRESULT CALLBACK CustomizeProc(HWND hwnd, UINT Msg,
  232.     WPARAM WParam, LPARAM LParam)
  233. {
  234.   DWORD result, itemID;
  235.   DRAWITEMSTRUCT *pDraw;
  236.  
  237.   if (Msg == WM_DRAWITEM) {
  238.     pDraw = (DRAWITEMSTRUCT*)LParam;
  239.     if (LOWORD(pDraw->itemData) == 0xFFFF) {
  240.       itemID = HIWORD(pDraw->itemData);
  241.       if ((itemID==IDX_EB) || (itemID==IDX_CB)) {
  242.         SendMessage(pDraw->hwndItem,
  243.           LB_SETITEMDATA, pDraw->itemID,
  244.           MAKELONG(itemID, HIWORD(pDraw->itemData)));
  245.         InvalidateRect(pDraw->hwndItem, NULL, FALSE);
  246.       }
  247.     }
  248.   }
  249.   result = CallWindowProc((WNDPROC)OldProc, hwnd,
  250.       Msg, WParam, LParam);
  251.   if (Msg == WM_DESTROY) {
  252.     SetWindowLong(hwnd, GWL_WNDPROC, OldProc);
  253.     OldProc = (DWORD)NULL;
  254.   }
  255.   return result;
  256. }
  257.  
  258.  
  259. /**********************************************************
  260.   DoToolbarNotify - procedure to process notifications
  261.     from the toolbar.
  262.  
  263.   Parameters:
  264.     pHdr    = pointer to TBNOTIFY structure (sent as the
  265.               LPARAM of the WM_NOTIFY message).
  266. **********************************************************/
  267.  
  268. LRESULT DoToolbarNotify(TBNOTIFY *pHdr)
  269. {
  270.   static char buf[128]; /* used in TBN_GETBUTTONINFO */
  271.   HWND htemp; /* used when finding HWND of customize dlg. */
  272.   UINT dwtemp;
  273.   TOOLTIPTEXT *pTT;
  274.  
  275.   TBBUTTON StartBtns[NUMSTARTBTNS];
  276.   int loop, count;
  277.  
  278.   if ((pHdr->hdr.hwndFrom==hTB) || (pHdr->hdr.code==TTN_NEEDTEXT)) {
  279.     switch (pHdr->hdr.code) {
  280.       case TBN_QUERYDELETE:
  281.         return TRUE;
  282.  
  283.       case TBN_QUERYINSERT:
  284.         if ((OldProc == 0) && (bVersionCorrect())) {
  285.           htemp = FindWindow("#32770", "Customize Toolbar");
  286.           if (htemp)
  287.             OldProc = SetWindowLong(htemp, GWL_WNDPROC,
  288.               (LONG)CustomizeProc);
  289.         }
  290.         return TRUE;
  291.  
  292.       case TBN_GETBUTTONINFO:
  293.         if (pHdr->iItem < NUMBTNS) {
  294.           pHdr->tbButton = Btns[pHdr->iItem];
  295.           dwtemp = SendMessage(pHdr->hdr.hwndFrom,
  296.             TB_GETSTATE, Btns[pHdr->iItem].idCommand, 0);
  297.           if (dwtemp != -1)
  298.             pHdr->tbButton.fsState = (BYTE)dwtemp;
  299.           if (pHdr->pszText == NULL) {
  300.             pHdr->pszText = buf;
  301.             pHdr->cchText = sizeof(buf);
  302.           }
  303.           if (LoadString(hInstance, Btns[pHdr->iItem].idCommand,
  304.             pHdr->pszText, pHdr->cchText) == 0)
  305.               strcpy(pHdr->pszText, "Unknown");
  306.           return TRUE;
  307.         }
  308.         else
  309.           return FALSE;
  310.  
  311.       case TBN_RESET:
  312.         /* reset toolbar to startup defaults. remove btns
  313.           from toolbar, then put startup buttons back on */
  314.         count = SendMessage(hTB, TB_BUTTONCOUNT, 0, 0);
  315.         for (loop = 0; loop < count; loop++)
  316.           SendMessage(hTB, TB_DELETEBUTTON, 0, 0);
  317.  
  318.         for (loop = 0; loop < NUMSTARTBTNS; loop++)
  319.           StartBtns[loop] = Btns[IdxStartBtns[loop]];
  320.         SendMessage(hTB, TB_ADDBUTTONS, NUMSTARTBTNS, (LPARAM)StartBtns);
  321.  
  322.         /* "break" statement purposefully missing */
  323.       case TBN_TOOLBARCHANGE:
  324.         FixTBCntrlPos(hTB, hCB, CMD_CB,CBEXTRAHEIGHT);
  325.         FixTBCntrlPos(hTB, hEB, CMD_EB, EBEXTRAHEIGHT);
  326.         break;
  327.  
  328.       case TTN_NEEDTEXT:
  329.         pTT = (TOOLTIPTEXT*)pHdr;
  330.         pTT->lpszText = pTT->szText;
  331.         pTT->hinst = NULL;
  332.         if (LoadString(hInstance, pTT->hdr.idFrom,
  333.           pTT->szText, sizeof(pTT->szText)) == 0)
  334.             strcpy(pTT->szText, "Unknown");
  335.         break;
  336.     }
  337.   }
  338.   return 0;
  339. }
  340.  
  341.  
  342. /**********************************************************
  343.   MainWndProc - main window procedure
  344. **********************************************************/
  345.  
  346. LRESULT CALLBACK MainWndProc( HWND hwnd, UINT Msg,
  347.     WPARAM WParam, LPARAM LParam )
  348. {
  349.   TBBUTTON StartBtns[NUMSTARTBTNS];
  350.   int loop;
  351.   TBSAVEPARAMS sp;
  352.   sp.hkr = HKEY_CURRENT_USER;
  353.   sp.pszSubKey = SAVERESTORE_SUBKEY;
  354.   sp.pszValueName = SAVERESTORE_ENTRY;
  355.  
  356.   switch (Msg)
  357.   {
  358.     case WM_CREATE:
  359.       /* fill startup button array, create toolbar */
  360.       for (loop = 0; loop < NUMSTARTBTNS; loop++)
  361.         StartBtns[loop] = Btns[IdxStartBtns[loop]];
  362.       hTB = CreateToolbarEx(hwnd,
  363.         WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS|CCS_ADJUSTABLE,
  364.         ID_TB, NUM_PICTURES, hInstance, RES_PICTURES,
  365.         StartBtns, NUMSTARTBTNS, 0, 0,
  366.         PICTURE_WIDTH, PICTURE_HEIGHT, sizeof(TBBUTTON));
  367.  
  368.       /* create combo box, fill it, attach it to toolbar */
  369.       hCB = CreateWindow("COMBOBOX", "",
  370.        WS_CHILD | WS_VSCROLL | WS_BORDER | CBS_DROPDOWNLIST,
  371.        0, 0, 0, 0, hwnd, (HMENU)IDX_CB, hInstance, NULL);
  372.       SendMessage(hCB, CB_DIR, 0, (LPARAM)"*.*");
  373.       SetParent(hCB, hTB);
  374.  
  375.       /* position combobox over host separator */
  376.       FixTBCntrlPos(hTB, hCB, CMD_CB, CBEXTRAHEIGHT);
  377.  
  378.       /* create edit box, attach it to toolbar */
  379.       hEB = CreateWindow("EDIT", "Edit Box",
  380.         WS_CHILD | WS_BORDER, 0, 0, 0, 0,
  381.         hwnd, (HMENU)IDX_EB, hInstance, NULL);
  382.       SetParent(hEB, hTB);
  383.  
  384.       /* position edit box over host separator */
  385.       FixTBCntrlPos(hTB, hEB, CMD_EB, EBEXTRAHEIGHT);
  386.       break;
  387.  
  388.     case WM_DESTROY:
  389.       PostQuitMessage( 0 );
  390.       break;
  391.  
  392.     case WM_SIZE:
  393.       SendMessage(hTB, WM_SIZE, 0, 0);
  394.       break;
  395.  
  396.     case WM_COMMAND:
  397.       switch (LOWORD(WParam))
  398.       {
  399.         case CMD_SAVE:
  400.           SendMessage(hTB, TB_SAVERESTORE, 1, (LPARAM)&sp);
  401.           break;
  402.  
  403.         case CMD_RESTORE:
  404.           RestoreToolbar(hTB, Btns, NUM_PICTURES,
  405.             HKEY_CURRENT_USER, SAVERESTORE_SUBKEY,
  406.             SAVERESTORE_ENTRY);
  407.           FixTBCntrlPos(hTB, hCB, CMD_CB, CBEXTRAHEIGHT);
  408.           FixTBCntrlPos(hTB, hEB, CMD_EB, EBEXTRAHEIGHT);
  409.           break;
  410.  
  411.         case CMD_CUSTOMIZE:
  412.           SendMessage(hTB, TB_CUSTOMIZE, 0, 0);
  413.           break;
  414.  
  415.         case CMD_EXIT:
  416.           SendMessage(hwnd, WM_CLOSE, 0, 0);
  417.           break;
  418.       }
  419.       break;
  420.  
  421.     case WM_NOTIFY:
  422.       return DoToolbarNotify((TBNOTIFY*)LParam);
  423.  
  424.     default:
  425.       return DefWindowProc( hwnd, Msg, WParam, LParam );
  426.   }
  427.   return 0;
  428. }
  429.  
  430.  
  431. /**********************************************************
  432.   WinMain - program's entry point
  433. **********************************************************/
  434.  
  435. #pragma argsused
  436. int PASCAL WinMain( HINSTANCE hInst, HINSTANCE hPrevInst,
  437.     LPSTR CmdLine, int nCmdShow )
  438. {
  439.   WNDCLASS wndclass;
  440.   MSG msg;
  441.  
  442.   hInstance = hInst;
  443.   if (!hPrevInst) {
  444.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  445.     wndclass.lpfnWndProc   = MainWndProc;
  446.     wndclass.cbClsExtra    = 0;
  447.     wndclass.cbWndExtra    = 0;
  448.     wndclass.hInstance     = hInstance;
  449.     wndclass.hIcon         = LoadIcon( NULL, IDI_WINLOGO );
  450.     wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW );
  451.     wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  452.     wndclass.lpszMenuName  = "MainMenu";
  453.     wndclass.lpszClassName = "TBDEMO";
  454.     if ( !RegisterClass( &wndclass ) )
  455.       return 0;
  456.   }
  457.  
  458.   hMainWnd = CreateWindowEx( 0, "TBDEMO", "Toolbar Demo",
  459.       WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT,
  460.       0, NULL, NULL, hInstance, NULL );
  461.       
  462.   ShowWindow(hMainWnd, nCmdShow);
  463.   UpdateWindow(hMainWnd);
  464.  
  465.   while( GetMessage( &msg, NULL, 0, 0 ) ) {
  466.     TranslateMessage( &msg );
  467.     DispatchMessage( &msg );
  468.   }
  469.   return msg.wParam;
  470. }
  471.  
  472.