Click here to Skip to main content
Click here to Skip to main content

Tear-off menus

, 4 Dec 2003
Rate this:
Please Sign up or sign in to vote.
See how to have tear-off menus in your program.

Introduction

Microsoft introduced a new feature some Office versions ago: Popup menus you can tear off and use as toolbars. This is a good way for the user to put important functions directly on the application workspace without opening a menu each time.

Trying to implement this feature caused a lot of problems. The easiest thing was to draw the menu so it looks like you can tear it off. The next thing was how to get the mouse movements and button pressed, which caused me to stop working on this for a long time. In the November 2003 issue of the MSDN magazine Paul DiLascia wrote some code to display menu tooltips. With this code it was quite easy to get it working.

Behind the scenes

The new class CMenuTearOffManager has all the functions you need for tear-off menus. It basically maps popup menus to toolbars and handles the GUI part. Using Paul DiLascia CSubclassWnd class CMenuTearOffManager reacts on every new popup menu and checks (and modifies) it in case it has a tear-off item. Then the "caption" is calculated and painted. Let's see how it works inside: First, whenever a new popup menu is opened ( WM_INITMENUPOPUP) it goes through all items and compares them to the internal map that assigns menu items to toolbars. In case this item is found it is converted to an ownerdrawn item. For that item WM_MEASUREITEM calculates the height for the "caption" and WM_DRAWITEM paints the caption. And here's the tricky part: during painting a new window is created that lays above the menu item, so mouse moves an be trapped; each time you select a different menu item the window gets invisible. The new window is not active (which would cause the menu to close), so mouse moves are captured by WM_NCHITTEST. Moving the mouse and pressing the left mouse button closes the window and forwards the message to the toolbar control - that's it!

Using the code

First, add the CMenuTearOffManager class to the CMainFrame. In your CMainFrame::OnCreate() add all tear-off toolbars using code like this:
if (!m_wndToolBarTearOff1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD 
    |WS_VISIBLE| CBRS_TOP
    | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndToolBarTearOff1.LoadToolBar(IDR_TEAROFF1))
{
  TRACE0("Unable to create toolbar 1\n");
  return -1;
}
m_wndToolBarTearOff1.EnableDocking(CBRS_ALIGN_ANY);
ShowControlBar(&m_wndToolBarTearOff1, FALSE, FALSE);

(The last line of code causes the toolbar to be initially invisible)

Then insert a new menu item on top of each popup you'd like to act as a tear-off menu (here: ID_TEAROFFDEMO_TEAROFF2). Also insert new toolbars that are displayed for the popup menus. There's no need to have the same commands on the toolbar.

After creating all toolbars use these lines to install the class and connect it to menu items:

m_menuTOManager.Install(this, this);
m_menuTOManager.AddTearOff(ID_TEAROFFDEMO_TEAROFF1, &m_wndToolBarTearOff1);
m_menuTOManager.AddTearOff(ID_TEAROFFDEMO_TEAROFF2, &m_wndToolBarTearOff2);
...
This connects the "virtual" menu item ID_TEAROFFDEMO_TEAROFF2 to the toolbar m_wndToolBarTearOff2. All the rest is done automatically.

Please see the sample how to use it. All comments are in English, only the resources are German.

Limitations

This class has a few differences to the "original" implementation you know from e.g. Microsoft Office and some other limitations:
  • Different drawing of the tear-off caption
  • Menu closes immediately after tearing the toolbar away
  • Office products allow to doc the popup again during dragging
  • Not (yet) possible for context menus
  • Not tested for ownerdrawn menus, but it should work

Licence

Feel free to use this class in any of your projects or modify it! Please keep my credits in the source.

Credits

Paul DiLascia for his subclass class and the menu tip manager, which helped a lot developing this class!

History

  • 30.11.2003: Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alexander Bischofberger
Web Developer
Germany Germany
Ok, a few words about me:
 
I started programming on the C64 by the "trial and error" method. Years later my parents got their first PC (Atari PC4, AT 8 MHz) where I started with Turbo Pascal. The next steps led to Turbo Pascal for Windows, Visual C++ 1.52c, and finally Visual C++ 6.
 
I had several chances to code larger projects, e.g.
* stand-alone disc copy station software (Win 3.1) with automatic reboot, disc encryption, ...
* government-used strategic decision system
* MLM marketing tool (www.upline.de)
* maintenance for show planning system and other TV software (www.hse24.de)
 
A lot of code, tipps and help came from this site for my later projects. Thanks again to all who helped me, even if they don't know it. I'm trying to share code (which is worth sharing) so others can get the help I got (and still need) for everyday problems.
 
Well, I think that's enough.

Comments and Discussions

 
GeneralCould some help me - can't find the bug PinmemberAlexander Bischofberger10-Dec-03 20:51 
GeneralRe: Could some help me - can't find the bug Pinmembernohoper12-May-05 20:02 
GeneralRe: Could some help me - can't find the bug Pinmemberaycarru4-Dec-10 18:01 
GeneralMe either PinmemberRafael Fernández López10-Dec-03 11:26 
GeneralMay be a good stuff, but ... Pinmembersynopsislogic1-Dec-03 11:31 
GeneralRe: May be a good stuff, but ... PinmemberAlexander Bischofberger1-Dec-03 20:55 
GeneralIt doesn't work (Win2k) Pinmembersnakeware1-Dec-03 11:10 
GeneralDoesnt appear to work on XP too PinmemberCEx1-Dec-03 20:52 
GeneralCode doesn't compile PinmemberGrump30-Nov-03 22:17 
GeneralRe: Code doesn't compile PinmemberAlexander Bischofberger1-Dec-03 7:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 5 Dec 2003
Article Copyright 2003 by Alexander Bischofberger
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid