This article shows a technique to disable top-level popup menus embedded in the Command Bar of PocketPC 2002 applications built with MFC. This is the result of my continuing discussions with John Simmons / outlaw programmer about the "ease of use" of the PocketPC 2002 User Interface API under MFC. On our last take at these issues, we found that disabling top-level popup menus is not a trivial task. Here is one solution.
Top-level popup menus
They are not popup menus. They are fakes. They are toolbar buttons! I reached this conclusion by looking at how
CCeCommandBar::LoadToolBar is implemented. The menu resource you supply is broken into its popups, and a text toolbar button is created for each one of them. So it is useless to try and use
CMenu methods to enable or disable these, you have to manipulate the underlying buttons.
Popup menu buttons are created with standard IDs starting with 0xF000 for the first one, and are incremented by 1 for the next ones. So, in order to know what button you want to access, you have to know its ordinal position. If you are using the "shared new" button, 0xF000 will be the first one to the right of it.
My first approach was to use the
TB_ENABLEBUTTON message. It seemed to work until John Simmons noticed that some of the button's texts were being truncated when grayed. In fact, when the toolbar disables a text button, it paints it in gray with a white shadow, making the text one pixel wider. Needless to say that the rectangle that holds this text is not changed and the text is clipped...
The next approach was based on the
SetButtonInfo methods of the
CToolBarCtrl that supports all toolbars. With these, I set a number of properties of the
TBBUTTONINFO structure, namely
cx. The first one is used to set the button state (enabled or disabled), where the second is used to increase the button size when it is disabled, and to decrease it back when it is enabled.
I encapsulated the solution in the
CCeCommandBarEx class that has only one method (besides standard constructor and destructor):
EnablePopupMenu. The implementation is as follows:
BOOL CCeCommandBarEx::EnablePopupMenu(int iIndex, BOOL bEnable)
CToolBarCtrl& rToolBar = GetToolBarCtrl();
int nID = 0xf000 + iIndex;
tbi.cbSize = sizeof(tbi);
tbi.dwMask = TBIF_STATE | TBIF_SIZE | TBIF_COMMAND;
tbi.idCommand = nID;
bRval = rToolBar.GetButtonInfo(nID, &tbi);
if(tbi.fsState & TBSTATE_ENABLED)
tbi.cx += bEnable ? 0 : 1;
tbi.cx -= bEnable ? 1 : 0;
tbi.fsState |= TBSTATE_ENABLED;
tbi.fsState &= ~TBSTATE_ENABLED;
Note that I have to call
SetSizes to avoid an incomprehensible bug I found: when increasing the popup menu button size, all other buttons would change their sizes as well.
The demo project
You will find that the demo project is an adaptation of the same project I used in my other article Multiple Toolbars in the PocketPC 2002 , but with some changes namely:
- Tool tips on all toolbars
- Toolbars are now exclusively shown