Customizing a Toolbar

You can support toolbar customization if you create your toolbar with the CCS_ADJUSTABLE style. The customization features allow the user to drag a button to a new position or to remove a button by dragging it off the toolbar. In addition, the user can double-click the toolbar to display the Customize Toolbar dialog box, which makes it easy to add, delete, and rearrange toolbar buttons. An application can display the dialog box by using the TB_CUSTOMIZE message (or MFC's Customize member function) in response to a double-click on the toolbar.

Handling toolbar customization in your application involves handling various notifications that are sent through the WM_NOTIFY message. In my sample application, I decided to support the following:

The following code from the MFCTOOL sample demonstrates how you can support minimal customization:

LRESULT CMfctoolView::WindowProc (UINT message, WPARAM wParam,
LPARAM lParam)
{
static CHAR szBuf [128];
LPTOOLTIPTEXT lpToolTipText;

if (message == WM_NOTIFY)
{
switch (((LPNMHDR)lParam)->code)
{
case TTN_NEEDTEXT:
// Display the ToolTip text.
lpToolTipText = (LPTOOLTIPTEXT)lParam;
::LoadString (AfxGetResourceHandle (),
lpToolTipText->hdr.idFrom, // string ID == cmd ID
szBuf,
sizeof (szBuf));
lpToolTipText->lpszText = szBuf;
break;

case TBN_QUERYDELETE:
// Toolbar customization--can we delete this button?
return TRUE;
break;

case TBN_GETBUTTONINFO:
// The toolbar needs information about a button.
return FALSE;
break;

case TBN_QUERYINSERT:
// Can this button be inserted? Just say yo.
return TRUE;
break;

case TBN_CUSTHELP:
// Need to display custom Help.
AfxMessageBox ("This Help is custom.");
break;

case TBN_TOOLBARCHANGE:
// The user finished dragging a bitmap to the toolbar.
m_ToolBar.AutoSize ();
break;

default:
return TRUE;
break;
}
}
return CView::WindowProc (message, wParam, lParam);
}

If you want to have more control over customization, your application can handle many other notifications that I did not include in my sample. For instance, if you want to do your own button dragging, you can trap the TBN_BEGINDRAG and TBN_ENDDRAG notifications. You might also want to save the state of the toolbar and allow the user to reset its configuration. You can do this by using the TB_SAVERESTORE message to save the current state of the toolbar and waiting for a TBN_RESET notification to signal that the toolbar needs to be reset to its previous state.