Guides & Tutorials (beta)

Adding A Drop Arrow To A Toolbar Button

by Kirk Stowell Visual C++ Created on 11/16/2007  |  Updated on 07/31/2024 0/5 ( 0 votes )

If you want to add a drop menu like the ones seen in Internet Explorer, it is pretty straight forward. This approach will work for both Visual C++ 5 and 6, however you may want to read up on the enhancements to the toolbar class for VC 6.0. Also, make sure you read the article Q190501 "BUG: Resizing CToolbar with Dropdown Arrow Buttons Freezes Apps" in the MS Knowledge Base.

Toolbar Drop Arrow

First off, after your toolbar has been created in CMainFrame::OnCreate(), you will need to make a call to the following

// Set the drop arrow.
DWORD dwExStyle = TBSTYLE_EX_DRAWDDARROWS;
m_wndToolBar.GetToolBarCtrl().SendMessage(
    TB_SETEXTENDEDSTYLE, 0, (LPARAM)dwExStyle);

This will enable your toolbar to handle drop arrows. The next thing you will need to do is to actually add the drop arrow to your desired button. This will be done via the SetButtonStyle() method:

DWORD dwStyle = m_wndToolBar.GetButtonStyle(
   m_wndToolBar.CommandToIndex(ID_FILE_OPEN));

   dwStyle |= TBSTYLE_DROPDOWN;
   m_wndToolBar.SetButtonStyle(
        m_wndToolBar.CommandToIndex(ID_FILE_OPEN), dwStyle);

return 0;
}

Now, you will need to add a message handler for the drop arrow, as well a menu to the application resources. Assuming you already know how to create a menu, ( if not, click on the resource tab, select the resource name IE: MyApp Resources, then right click. Select insert, then select Menu, then press the New button ) and assuming that the resource id for our menu is IDR_MENU1, add the following code to CMainFrame's message map:

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
   //{{AFX_MSG_MAP(CMainFrame)
   ON_WM_CREATE()
   ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Add the following method to CMainFrame's .cpp file:

void CMainFrame::OnToolbarDropDown(
       NMTOOLBAR* pnmtb, LRESULT *plr)
{
  CWnd *pWnd;
  UINT nID;

  // Switch on button command id's .
  switch (pnmtb->iItem)
  {
   case ID_FILE_OPEN:
      pWnd = &m_wndToolBar;
      nID  = IDR_MENU1;
      break;
   default:
      return;

   }

   // load and display popup menu
   CMenu menu;
   menu.LoadMenu(nID);
   CMenu* pPopup = menu.GetSubMenu(0);
   ASSERT(pPopup);

   CRect rc;
   pWnd->SendMessage(TB_GETRECT,
             pnmtb->iItem, (LPARAM)&rc);
   pWnd->ClientToScreen(&rc);

   pPopup->TrackPopupMenu(
     TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
     rc.left, rc.bottom, this, &rc);
}

Then add the following to CMainFrame's .h file:

// Generated message map functions
protected:
  //{{AFX_MSG(CMainFrame)
  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  //}}AFX_MSG
  afx_msg void OnToolbarDropDown(
                 NMTOOLBAR* pnmh, LRESULT* plRes);
 DECLARE_MESSAGE_MAP()
};

User Comments

No comments yet, sign in to comment.

Secure Transactions

Online transactions are secure and protected.


Ssl seal 1
This site is protected by Trustwave's Trusted Commerce program
CompliAssure Secured

Money Back Guarantee

If you are not 100% happy with your purchase within 30 days, you can return it for any reason. Your satisfaction is our priority!


Satisfication Guarantee

Contact sales@codejock.com for more details.