Article Source: Internet Author: ggg82/csdn
Now many user interfaces use toolbar to make menu bar, younger brother recently interested in this, then from the Internet, but get help mostly is the source code of Bcgcontrolbar or Sizablerebar, for only want to be their own interface with the function of friends, This may be a good choice, just look at the demo, and then directly call someone else's class library on it, but for me and so interested in this topic, hoping to understand the context of the reader, directly to see these no detailed explanation of the source code, to make a reason for it, it is not easy to do, At least for a rookie like me, this article, for this reason, would like to offer some help to readers who are still looking for this help.
Next we look at the chat:
When we receive the ToolBarButton press message, we generally use the TrackPopupMenuEx pop-up menu, the crux of the problem is that when the menu is not closed, TrackPopupMenuEx does not return, and intercept the mouse and keyboard messages, using Spy can be seen, The toolbar doesn't receive any messages at this point, and of course it doesn't change the hotspot, which requires us to probe the mouse position and close the previous menu and display the next menu when the mouse moves to the next hotspot. Here we use the hook function SetWindowsHookEx to install the Wh_msgfilter hook before calling Trackpupupmenuex, the code is as follows:
M_hmsghook = SetWindowsHookEx (wh_msgfilter, MessageProc, 0, GetCurrentThreadID ());
Mssageproc is the hook function, the code is as follows:
LRESULT CALLBACK messageproc (int code, WPARAM WPARAM, LPARAM LPARAM)
{
if (code = = Msgf_menu)
{
Hookmessageproc (LParam);
}
Return CallNextHookEx (M_hmsghook, Code, WParam, LParam);
}
function to check the message, if it comes from the menu, pass the message to the function Hookmessageproc processing, all we have to do is detect the message wm_mousemove in the function, and test the mouse position, if the mouse has moved to another button, close the menu and display the next menu, Turn off the menu using Message Wm_cancelmode, when the menu closes, we release the hook, reinstall the hook when the next menu pops up, and the pop-up menu sample code is as follows:
void Trackpopup (HWND hwndtoolbar, int ibutton)
{
while (IButton >= 0)
{
SendMessage (hwndtoolbar,tb_sethotitem,ibutton,0);
Ipopup = IButton;
Installing hooks
G_hmsghook = SetWindowsHookEx (wh_msgfilter, MessageProc, 0, GetCurrentThreadID ());
pop-up menu
TrackPopupMenuEx (...);
Uninstall Hook
UnhookWindowsHookEx (G_hmsghook);
IButton = Inextpop; Next popup, if negative, exit
}
SendMessage (hwndtoolbar,tb_sethotitem,-1,0);
}
(Experience and Suggestion: if the button uses style Tbstyle_dropdown, do not call the function directly in message Tbn_dropdown, use intermediate messages, and then use Postmessa to send the message so that Tbn_ Dropdown can be returned directly, otherwise it is troublesome to eliminate the first highlighted hotspot. )
Ipopup for the current popup, Inextpop for the next popup, these variables need to be handled in the function Hookmessageproc, sample code as follows:
void Hookmessageproc (MSG * pMsg)
{
if (pmsg->message = = wm_mousemove)
{
int IButton, icount;
Point pt = {LoWord (pmsg->lparam), HiWord (Pmsg->lparam)};
ScreenToClient (Hwndtoolbar, &pt);
IButton = SendMessage (Hwndtoolbar, tb_hittest, 0, &pt);
icount = SendMessage (Hwndtoolbar, tb_buttoncount, 0, 0);
if (ipopup!= ibutton && IButton < icount && IButton >= 0)
{
Inextpop = IButton;
SendMessage (Hwndmain, wm_cancelmode, 0, 0);
}
Else
{
Inextpop =-1;
}
}
}
(Experience and suggestion: do not attempt to call Trackpopup here, I tried to cancel the while loop within the function, call the function directly here, resulting in the function being invoked before TrackPopupMenuEx returned)
Here, just handle the mouse mobile message, the real menu should also handle keyboard navigation messages, detailed code can refer to
Bcgcontrolbar (http://www.vckbase.com/code/downcode.asp?id=1382)
or Sizablerebar (http://www.codeproject.com/docking/sizablerebar/SizableRebar_demo.zip
)
With this underlying framework, these processes should no longer be difficult, and some of the API functions involved in this article refer to MSDN.
MSDN Related information:
Http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/faq/iemenubar.asp
Http://www.microsoft.com/msj/0199/c/c0199.aspx