mCtrl
0.11.1
|
Go to the source code of this file.
Menu bar control (MC_WC_MENUBAR
).
The MC_WC_MENUBAR
is implantation of a control generally known as Internet Explorer-Style Menu Bar. It is a control which can host a menu (here represented by a menu handle, HMENU
), but which generally works as a toolbar.
The standard menus take whole width of the window for their menubars, and there can only be used one menu in a top-level windows. Child windows can not have a menu at all (well, we are not talking about pop-up menus).
The MC_WC_MENUBAR
offers solution to these limitations. It has been designed especially with following use cases in mind:
COMCTL32.DLL
.Actually the MC_WC_MENUBAR
is implemented as a superclass of the standard toolbar (from COMCTL32.DLL
) control, so you can use its style, and also some toolbar messages.
Of course there are also differences: The menubar control automatically sets some toolbar styles when created, as it sees fit for its purpose. Application still can reset it with SetWindowLong
and GWL_STYLE
.
Furthermore the menubar control does not support toolbar messages which add, modify or remove toolbar buttons. The control just manages them automatically to reflect the installed menu.
I.e. sending any of these toolbar messages to the control always fails:
TB_ADDBITMAP
TB_ADDSTRING
TB_ADDBUTTONS
TB_BUTTONSTRUCTSIZE
TB_CHANGEBITMAP
TB_CUSTOMIZE
TB_DELETEBUTTON
TB_ENABLEBUTTON
TB_HIDEBUTTON
TB_INDETERMINATE
TB_INSERTBUTTON
TB_LOADIMAGES
TB_MARKBUTTON
TB_MOVEBUTTON
TB_PRESSBUTTON
TB_REPLACEBITMAP
TB_SAVERESTORE
TB_SETANCHORHIGHLIGHT
TB_SETBITMAPSIZE
TB_SETBOUNDINGSIZE
TB_SETCMDID
TB_SETDISABLEDIMAGELIST
TB_SETHOTIMAGELIST
TB_SETIMAGELIST
TB_SETINSERTMARK
TB_SETPRESSEDIMAGELIST
TB_SETSTATE
To install a menu in the menubar, you may set parameter lpParam
of CreateWindow()
or CreateWindowEx()
to the handle of the menu (HMENU
). Or, after the menubar is created, you may install a menu with the message MC_MBM_SETMENU.
Either way the application is responsible to keep the menu handle valid as long as the menubar exists (or until other menu is installed in the menubar).
Note however that changes to the menu are not automatically reflected in the menubar. If application programatically changes top-level items of the menu (for example add new pop-ups, disable some of them etc.), it then has to send MC_MBM_REFRESH to reflect the changes.
The control sends notifications of both, the toolbar and menu.
To handle the actions corresponding to the menu items, application uses the notification WM_COMMAND
as with a normal menu. It can also take use of WM_MENUSELECT
and WM_INITMENU
.
Toolbar notifications are sent through WM_NOTIFY
. For example, TBN_DROPDOWN
or TBN_HOTITEMCHANGE
are sent as any other notifications normal toolbar fires.
All the notifications are sent by default to a window which was parent of the menubar when creating the menubar. One exception is if the parent is a ReBar control: Because it will often be the case and the ReBar control cannot handle the notifications properly, they are then sent to the grand-father of the menubar (i.e. parent of the ReBar).
Application can also explicitly set the target window of the notifications with the standard toolbar message TB_SETPARENT
.
To work as intended, the control requires some cooperation with the application. The message loop in the application should call the function mcIsMenubarMessage
to handle hot keys of the menu items and allow to activate the menu with the key F10
.
Hence code of the message loop in applications using the menubar control should be similar to the example below:
Application may often need to embed the menubar control in a ReBar control. To do so, the application developer need to embed the menubar control in a Rebar control band. That is usually performed with a code similar to this one:
If the application developer desires to support chevron on the band hosting the menubar, additional steps are required:
TBSTYLE_EX_HIDECLIPPEDBUTTONS:
band.fStyle
in the code above has to specify RBBS_USECHEVRON
in addition.band.cxIdeal
has to be initialized in the REBARBANDINFO
above, before inserting the new band: RBN_CHEVRONPUSHED
notification from the rebar control. If the notification is about the band hosting a menubar, the function mcMenubar_HandleRebarChevronPushed()
should be called in response. These standard messages are handled by the control:
CCM_SETNOTIFYWINDOW
These standard notifications are sent by the control:
NM_OUTOFMEMORY
Initialization Functions | |
BOOL | mcMenubar_Initialize (void) |
void | mcMenubar_Terminate (void) |
Related Functions | |
BOOL | mcIsMenubarMessage (HWND hwndMenubar, LPMSG lpMsg) |
Determines whether a message is intended for the specified menubar control and, if it is, processes the message. More... | |
BOOL | mcMenubar_HandleRebarChevronPushed (HWND hwndMenubar, NMREBARCHEVRON *lpRebarChevron) |
Helper function for ReBar chevron support. More... | |
Window Class | |
#define | MC_WC_MENUBARW L"mCtrl.menubar" |
#define | MC_WC_MENUBARA "mCtrl.menubar" |
Control Messages | |
#define | MC_MBM_SETMENU (MC_MBM_FIRST + 0) |
Install a menu into the menubar. More... | |
#define | MC_MBM_REFRESH (MC_MBM_FIRST + 1) |
Updates the menubar to reflect changes in the installed menu. More... | |
Unicode Resolution | |
#define | MC_WC_MENUBAR MCTRL_NAME_AW(MC_WC_MENUBAR) |
#define MC_WC_MENUBARW L"mCtrl.menubar" |
Window class name (Unicode variant).
#define MC_WC_MENUBARA "mCtrl.menubar" |
Window class name (ANSI variant).
#define MC_MBM_SETMENU (MC_MBM_FIRST + 0) |
Install a menu into the menubar.
wParam | Reserved, set to zero. | |
[in] | lParam | (HMENU ) The menu to install. |
BOOL
) TRUE
on success, FALSE
otherwise. #define MC_MBM_REFRESH (MC_MBM_FIRST + 1) |
Updates the menubar to reflect changes in the installed menu.
Application has to send this messages after it changes the top-level menu items (e.g. adds or deletes a sub-menu, enables or disables a sub-menu etc.).
Note that it is needed only if the top-level items changes (i.e. the items directly visible on the horizontal menubar. Contents of pop-up menus can be changed without sending this notification.
wParam | Reserved, set to zero. |
lParam | Reserved, set to zero. |
BOOL
) TRUE
on success, FALSE
otherwise. #define MC_WC_MENUBAR MCTRL_NAME_AW(MC_WC_MENUBAR) |
Unicode-resolution alias.
BOOL mcMenubar_Initialize | ( | void | ) |
Registers window class of the control.
TRUE
on success, FALSE
on failure. void mcMenubar_Terminate | ( | void | ) |
Unregisters window class of the control.
BOOL mcIsMenubarMessage | ( | HWND | hwndMenubar, |
LPMSG | lpMsg | ||
) |
Determines whether a message is intended for the specified menubar control and, if it is, processes the message.
The application typically calls this function in main message loop.
hwndMenubar | The menubar control. |
lpMsg | The message. |
TRUE
, if the message has been processed; FALSE
otherwise. BOOL mcMenubar_HandleRebarChevronPushed | ( | HWND | hwndMenubar, |
NMREBARCHEVRON * | lpRebarChevron | ||
) |
Helper function for ReBar chevron support.
Application can embed the menubar control in a ReBar control. In such case the application may want to support the chevron (ReBar window style RBBS_USECHEVRON
).
In such case the application gets the notification RBN_CHEVRONPUSHED
whenever the ReBar band is too small for complete menubar and user clicks the chevron button. In such case the application should propagate the notification (when about the band with the menubar) to this function, which creates and opens a pop-up for all the menu items not visible due the insufficient space.
In case of success (the function returns TRUE
), the function returns only after the chevron popup menu was closed.
hwndMenubar | The menubar control, or NULL . If menubar handle is provided, the function verifies that the notification is about the menubar and returns FALSE if it is not. When NULL , it is responsibility of the application to ensure the notification is about the band hosting a menubar control. |
lpRebarChevron | Pointer to the structure NMREBARCHEVRON associated with the RBN_CHEVRONPUSHED notification. |
TRUE
if the pop-up menu for the chevron button has been created and opened, FALSE
otherwise.hwndMenubar
is NULL
and the lpRebarChevron
is notification about a ReBar band which hosts other window then a menubar control, the application behavior is undefined. The application may crash.