Toolbar Control Updates in Internet Explorer

Toolbar Control Updates in Internet Explorer


Toolbar controls in Microsoft® Internet Explorer support the following new features.

Image List Support
Toolbar controls can use up to three different image lists to display buttons in various states:
Normal Buttons in their default state.
Hot Buttons that are under the pointer or pressed. Hot items are only supported in toolbar controls that have the TBSTYLE_FLAT style.
Disabled Buttons that are disabled.

Applications can still use bitmaps for toolbar buttons. Image list support is offered to allow the control to have greater flexibility. An application sets and retrieves toolbar image lists for normal buttons with the TB_SETIMAGELIST and TB_GETIMAGELIST messages, respectively. Similarly, the TB_SETHOTIMAGELIST, TB_GETHOTIMAGELIST, TB_SETDISABLEDIMAGELIST, and TB_GETDISABLEDIMAGELIST messages perform the same actions for hot and disabled button image lists.

Transparent Toolbars
Toolbar controls support a new, transparent look. An application can create a transparent toolbar control by including the TBSTYLE_FLAT style. With the TBSTYLE_FLAT style in place, the control displays buttons while allowing the client area under the toolbar to show through.

Transparent toolbar controls feature hot tracking. That is, when the user moves the pointer over a toolbar button, the button's appearance changes. The control displays a border around the "hot" button and, if a hot image list is set, switches the image under the pointer.

The following illustration shows a transparent toolbar control with four buttons.

Transparent toolbar control with four buttons.

For more information on transparent toolbars, see Creating a Transparent Toolbar Control later in this section.

Drop-Down Toolbar Buttons
Toolbar controls support drop-down style buttons. Drop-down buttons have the TBSTYLE_DROPDOWN style. When the user clicks a drop-down button, the toolbar control sends its parent a TBN_DROPDOWN notification message. If the parent is going to display a drop-down menu, it can display one using the TrackPopupMenuEx function and return zero to the notification message. For more information, see Supporting Drop-Down Toolbar Buttons later in this section.
Insertion Marks
Toolbar controls now support insertion marks. An insertion mark provides a visual indication where an item will be inserted. This is useful for dragging and dropping items into a toolbar. Insertion marks are implemented using the TB_SETINSERTMARK, TB_GETINSERTMARK, and TB_INSERTMARKHITTEST messages.

Creating a Transparent Toolbar Control

To create a transparent toolbar control, use the CreateWindowEx function, specifying TOOLBARCLASSNAME as the window class. You must first register the window class by calling the InitCommonControlsEx function, while specifying the ICC_BAR_CLASSES bit in the accompanying INITCOMMONCONTROLSEX structure.

An application must prepare a toolbar control by sending messages it uses to manage memory and format its display. The CreateTransparentToolbar sample function creates a normal or list style transparent toolbar control. It accepts style bits in the dwStyle parameter that are used to determine which type of toolbar it will create.

To support button text and list style buttons, CreateTransparentToolbar calls the following application-defined functions:

The CreateTransparentToolbar Sample Function

The CreateTransparentToolbar application-defined function creates and initializes a transparent toolbar.

// CreateTransparentToolbar Function
//     Creates a transparent toolbar control based on the owner's
//     window handle and a supplied set of styles that is assumed
//     to be a combination of TBSTYLE_FLAT and TBSTYLE_LIST flags.
//
// Accepts:
//    HWND: The handle to the parent window.
//    DWORD:  Style values that are included in CreateWindowEx.
//
// Returns:
//    HWND to the newly created toolbar. The owner must resize it.

HWND WINAPI CreateTransparentToolbar(HWND hwndOwner, DWORD dwStyle.)
{
   HWND         hwndTB;
   HIMAGELIST   himl, himlHot;   
   TBBUTTON     tbArray[MAX_BUTTONS];
   int          i, iListSpace;
   INITCOMMONCONTROLSEX icex;

   LPTSTR lpszStrList, 
          pszStrArray[4] = { "Button 1",
                             "Button 2",
                             "Button 3",
                             "Button 4"};

   icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
   icex.dwICC  = ICC_BAR_CLASSES;
   InitCommonControlsEx(&icex);

   // Create the toolbar control.
   hwndTB=CreateWindowEx(WS_EX_TOOLWINDOW,
                         TOOLBARCLASSNAME,
                         NULL,
                         WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | 
                         WS_CLIPSIBLINGS | CCS_NODIVIDER
                         |CCS_NOPARENTALIGN | CCS_NORESIZE | dwStyle, 
                         0,0,0,0,  // Make it zero, Let owner resize it.
                         hwndOwner,
                         NULL, g_hinst, NULL); 
   
   // Sets the size of the TBBUTTON structure.
   SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);

   // Set the maximum number of text rows and bitmap size.
   SendMessage(hwndTB, TB_SETMAXTEXTROWS, 1, 0L);
   SendMessage(hwndTB, TB_SETBITMAPSIZE,
               0, (LPARAM)MAKELONG(MYICON_CX, MYICON_CY));

   // Create, fill, and assign the image list for default buttons.
   himl = ImageList_Create(MYICON_CX,MYICON_CY,ILC_COLOR8,0,4);
   ImageList_Add(himl,
                 LoadBitmap(g_hinst,MAKEINTRESOURCE(IDB_DEF1)),NULL);
   ImageList_Add(himl,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_DEF2)),NULL);
   ImageList_Add(himl,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_DEF3)),NULL);
   ImageList_Add(himl,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_DEF4)),NULL);

   SendMessage(hwndTB, TB_SETIMAGELIST, 0, (LPARAM)himl);

   // Create, fill, and assign the image list for hot buttons.
   himlHot = ImageList_Create(MYICON_CX,MYICON_CY,ILC_COLOR8,0,4);
   ImageList_Add(himlHot,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_HOT1)),NULL);
   ImageList_Add(himlHot,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_HOT2)),NULL);
   ImageList_Add(himlHot,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_HOT3)),NULL);
   ImageList_Add(himlHot,
                 LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_HOT4)),NULL);
   
   SendMessage(hwndTB, TB_SETHOTIMAGELIST, 0, (LPARAM)himlHot);
   
   // Loop to fill the array of TBBUTTON structures.
   for(i=0;i<MAX_BUTTONS;i++){
      tbArray[i].iBitmap   = i;
      tbArray[i].idCommand = IDM_BUTTONSTART + i;
      tbArray[i].fsState   = TBSTATE_ENABLED;
      tbArray[i].fsStyle   = TBSTYLE_DROPDOWN;//BUTTON;
      tbArray[i].dwData    = 0;
      tbArray[i].iString   = i;
   }
   
   // Put button text in the correct format for TB_ADDSTRING.
   lpszStrList = BuildStrList(pszStrArray);

   SendMessage(hwndTB, TB_ADDSTRING, 0,(LPARAM)lpszStrList);

   // If this is a list style toolbar, add buffer pixels 
   // to make room for button text.
   iBufferPix=(dwStyle & TBSTYLE_LIST)?WidestBtn(pszStrArray, hwndTB):0;

   // Add the buttons, and then set the minimum and maximum button widths.
   SendMessage(hwndTB,
               TB_ADDBUTTONS, (UINT)MAX_BUTTONS, (LPARAM)tbArray);

   SendMessage(hwndTB,
               TB_SETBUTTONWIDTH, 0, 
               (LPARAM)MAKELONG(MYICON_CX+iBufferPix,
               MYICON_CX+iBufferPix));

   return (hwndTB);
}

The BuildStrList Sample Function

The BuildStrList application-defined function creates and fills a buffer based on a static array of strings. The calling function uses the resulting buffer with the TB_ADDSTRING message.

// BuildStrList Function
//    Creates a list of null-terminated strings from a passed-in
//    array of strings. See the documentation about TB_ADDSTRING
//    for specific information about this format.
//
// Accepts:
//    LPTSTR *: Address of the array of strings.
//
// Returns:
//    LPTSTR to the newly created list of button text strings.

LPTSTR WINAPI BuildStrList(LPTSTR * ppszStrArray, INT iStrCount)
{
   LPTSTR pScan,
          pszStrList;

   int i;

   pScan = pszStrList = malloc((size_t)37 * sizeof(char));

   for (i=0;i<iStrCount;i++){
      strcpy(pScan,ppszStrArray[i]);
      pScan += strlen(pScan)+1;
   }
   *pScan = '\0';

   return(pszStrList);
}

The WidestBtn Sample Function

The WidestBtn application-defined function calculates the button width necessary to completely display the widest button text string.

// WidestBtn Function
//     Calculates the width, in pixels, of the widest button in the
//     toolbar. Since toolbar controls use the same width for all
//     buttons, the return value is used when sending the 
//     TB_SETBUTTONWIDTH message.
//
// Accepts:
//    LPTSTR *: Address of the array of button text strings.
//    HWND: The handle to the parent window.
//
// Returns:
//    An INT value representing the minimum width, in pixels,
//    a button must be to allow room for the button text.

INT WINAPI WidestBtn(LPTSTR *pszStrArray, HWND hwndOwner)
{
// The toolbar reserves pixels for space between buttons,
// text, and so on. This value is added to the return value
// to compensate.
#define EXTRA_PIXELS 8

   INT      i, iStrMax_cx = 0;
   SIZE     sz;
   LOGFONT  lf;
   HFONT    hFont;
   HDC      hdc;

   // Get the font used to display button text, and then select it into
   // a device context to be passed to GetTextExtentPoint32.
   SystemParametersInfo(SPI_GETICONTITLELOGFONT,sizeof(LOGFONT),&lf,0);

   hdc = GetDC(hwnd);
   hFont = CreateFontIndirect(&lf);
   SelectObject(hdc,hFont);

   // Loop to find the widest string.
   for(i=0;i<MAX_BUTTONS;i++){
      GetTextExtentPoint32(hdc, pszStrArray[i],
                           strlen(pszStrArray[i]), &sz);
      if(sz.cx > iStrMax_cx) iStrMax_cx = sz.cx;
   }

   // Release the DC and font.
   ReleaseDC(hwnd, hdc);
   DeleteObject(hFont);
   
   // Return the sum of the string width, the border, and extra pixels.
   return (iStrMax_cx + GetSystemMetrics(SM_CXBORDER) + EXTRA_PIXELS);}

Supporting Drop-Down Toolbar Buttons

When the user clicks a toolbar button that uses the TBSTYLE_DROPDOWN style, the toolbar control sends its parent a TBN_DROPDOWN notification message. The following DoNotify application-defined function illustrates how an application can support a drop-down button in a toolbar control by responding to this notification message.

If the incoming notification message is TBN_DROPDOWN, DoNotify retrieves the bounding rectangle of the button the user clicked by sending the TB_GETRECT message. When sending the message, DoNotify specifies the command identifier of the drop-down button as the wParam parameter of the SendMessage function. (The button's command identifier was retrieved from the iItem member of the NMTOOLBAR structure that lParam points to.) After DoNotify retrieves the bounding rectangle, it calls MapWindowPoints to convert the rectangle from client coordinates to screen coordinates. It then retrieves the pop-up menu from a menu resource by using the GetSubMenu function and calls the TrackPopupMenuEx function to display the menu. Note that DoNotify positions the menu under the correct button by using the rectangle it retrieved earlier. It also includes the TPM_VERTICAL flag to ensure that the menu is displayed so that it doesn't overlap the button.

BOOL WINAPI DoNotify(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
#define lpnm   ((LPNMHDR)lParam)
#define lpnmTB ((LPNMTOOLBAR)lParam)

   RECT      rc;
   TPMPARAMS tpm;
   HMENU     hPopupMenu = NULL;
   BOOL      bRet = FALSE;

   switch(lpnm->code){
      case TBN_DROPDOWN:
         SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT,
                     (WPARAM)lpnmTB->iItem, (LPARAM)&rc);

         MapWindowPoints(lpnmTB->hdr.hwndFrom,
                         HWND_DESKTOP, (LPPOINT)&rc, 2);                         

         tpm.cbSize = sizeof(TPMPARAMS);
         tpm.rcExclude.top    = rc.top;
         tpm.rcExclude.left   = rc.left;
         tpm.rcExclude.bottom = rc.bottom;
         tpm.rcExclude.right  = rc.right;
         
         hPopupMenu = 
           GetSubMenu( LoadMenu(g_hinst,MAKEINTRESOURCE(IDR_POPUP)),0);

         TrackPopupMenuEx(hPopupMenu,
                          TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,               
                          rc.left, rc.bottom, g_hwndMain, &tpm);
         
         return (FALSE);
   }

   return FALSE;
}

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.