Menu hot-tracking requires that a menu be displayed at all times, apart from the brief interval required to switch to a new menu. However, the drop-down menu that is displayed by TrackPopupMenu is modal. Your application will continue to receive some messages directly, including WM_COMMAND, TBN_HOTITEMCHANGE, and normal menu-related messages such as WM_MENUSELECT. However, it will not receive low-level keyboard or mouse messages directly. To handle messages such as WM_MOUSEMOVE, you must set a message hook to intercept messages that are directed to the menu.
When a drop-down menu is displayed, set the message hook by calling the SetWindowsHookEx function with the idHook parameter set to WH_MSGFILTER. All messages intended for the menu will be passed to your MessageProc. For example, the following code fragment sets a message hook that will trap messages that are going to a drop-down menu. MsgHook is the name of the hook procedure, and hhookMsg is the handle to the procedure.
hhookMsg = SetWindowsHookEx(WH_MSGFILTER, MsgHook, HINST_THISDLL, 0);
Menu messages are identified by setting the hook procedure's nCode parameter to MSGF_MENU. The lParam parameter will point to a MSG structure with the message. The details of which messages need to be handled, and how, are discussed in the remainder of this topic.
Your application must pass all messages on to the next message hook by calling the CallNextHookEx function. You must also send mouse messages directly to the toolbar control, making sure to convert any point coordinates to the toolbar client coordinate space. Sending the messages directly ensures that the toolbar control receives the appropriate mouse messages. For instance, the toolbar needs to receive WM_MOUSEMOVE messages in order to hot-track its buttons.
When a new button is activated, your application must collapse the old drop-down menu with a WM_CANCELMODE message, and display a new menu. It must also collapse the drop-down menu when focus is taken from the menu bar with keyboard navigation or by clicking outside the menu area. Whenever you collapse a menu, you should free its message hook by using the UnhookWindowsHookEx function. If you need to display another drop-down menu, create a new message hook. When a command is launched, the menu will be collapsed automatically but you must explicitly free the message hook.
The following code example frees the message hook that was set in the previous example.
UnhookWindowsHookEx(hhookMsg);