Many commercial applications developed for Windows allow the user to customize the menus of the application. This ability introduces some complexity when the application must update particular menu items at certain times. Here we discuss how to perform this task.
Windows sends a WM_INITMENUPOPUP message just before a pop-up menu is displayed.We can modify menus dynamically by handling WM_INITMENUPOPUP message on our own. A sample code to achieve this is shown below:
// OnInitMenuPopup() is the framework provided handling function for WM_INITMENUPOPUP
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
if(if( m_bFirstTime )
{
if( 0 == nIndex ) // Menu index....
pPopupMenu->InsertMenu(0, // Position to insert
MF_BYPOSITION,
1000 // ID of the new menu item…This should be unique..
_T("My menu item") );
m_bFirstTime = false;
}
}
The above code will insert the specified string into the menu with index 0( Usually File menu ). In OnInitMenuPopup() function, we receive the pointer to the menu that is being expanded. So we can use this pointer to add, insert or delete items from that menu at will.
Now there is a question of how to add a command-handler for this new item. We can’t add code into the message map since the menu is added dynamically. For that we may resort to the OnCmdMsg() viirtual function provided by the framework. We have to override it in our application. This function is called by the framework, each time a user selects a menu command or the menu is being updated. So we can handle menu commands as well as enable/disable menu items using this function. The following is a glance on how to implement this function ourselves:
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if(1000 == nID && CN_COMMAND == nCode )
AfxMessageBox( "My menu item accessed. ");
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
No comments:
Post a Comment