QUESTION:
I'm writing a MDI application and I have problems to get a pointer to the actual menu
bar. The normal construction doesn't seem to work in MDI:
- CMenu *menu;
menu = GetMenu()->GetSubMenu(0);
How can I get a pointer to the menu bar to update the menu?ANSWER:
- AfxGetApp()->m_pMainWnd->GetMenu()->GetSubMenu(n);
mlinar@pollux.usc.edu, Mitch Mlinar, 6/8/95
- ///////////////////////////////////////////////////////////////////
// WM_RBUTTONDOWN handler.
//
// Trap this message and display the button properties popup menu.
// The main frame receives the popup menu messages. This allows the
// status bar to be updated with the help text.
// ///////////////////////////////////////////////////////////////////
void CAppButton::OnRButtonDown(UINT flags, CPoint point)
{
CMenu menu;
CMenu *submenu;
// load the menu
menu.LoadMenu(IDR_LAUNCH);
// get the popup menu
submenu = menu.GetSubMenu(0);
// convert to screen coordinates
ClientToScreen(&point);
// post the menu
submenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
point.x, point.y,
AfxGetApp()->m_pMainWnd,NULL);
}
johnm@unipalm.co.uk, programmer.win32, 7/12/95
It's better to use RBUTTONUP instead, however right-clicking on dialog controls doesn't
generate RBUTTONUP and RBUTTONDOWN messages.
If it's necessary to treat this situation too, a program have to catch WM_PARENTNOTIFY
message in Win3.x and WinNT and WM_CONTEXTMENU in Windows 95. Here's a code:
- // May be dialog too:
BEGIN_MESSAGE_MAP(CMyPropertyPage, CPropertyPage)
//{{AFX_MSG_MAP(CMyPropertyPage)
ON_WM_RBUTTONUP()
ON_WM_PARENTNOTIFY()
ON_MESSAGE(WM_CONTEXTMENU, OnContextMenu)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
-
- void CMyPropertyPage::OnRButtonUp(UINT nFlags, CPoint
point)=20
{
PopupMenu (&point);
}
void CMyPropertyPage::OnParentNotify(UINT message, LPARAM lParam)
{
if (message !=3D WM_RBUTTONDOWN)
CPropertyPage::OnParentNotify(message, lParam);
else
{
CPoint pt(LOWORD(lParam),HIWORD(lParam));
PopupMenu (&pt);
}
}
LONG CMyPropertyPage::OnContextMenu (UINT wParam, LONG lParam)
{
CPoint pt(LOWORD(lParam),HIWORD(lParam));
ScreenToClient (&pt);
PopupMenu (&pt);
return 0;
}
//*****************************************************************
void CMyPropertyPage::PopupMenu(CPoint* pt)
{
ASSERT(m_idContextMenu !=3D 0);
ASSERT(nSubMenu >=3D 0);
ClientToScreen (pt);
CMenu FloatingMenu;
VERIFY(FloatingMenu.LoadMenu(ID_POPUP_MENU));
CMenu* pPopupMenu =3D FloatingMenu.GetSubMenu (0);
ASSERT(pPopupMenu !=3D NULL);
pPopupMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON,=20
pt->x, pt->y, this);
}
PaulACost@msn.com - via email, 10/15/95
- CMenu newMenu;
newMenu.LoadMenu (IDR_MENU1);
AfxGetMainWnd()->SetMenu( &newMenu );
AfxGetMainWnd()->DrawMenuBar();
newMenu.Detach ();
Arun Rao, MSMFC, 6/27/95
{Note the original question talked about dialogs, but you can interpolate this
code to any kind of window that you want to have change the menu.}
One of the ways to do this is as follows……
- Declare a variable CMenu pNewMenu in one of the dialog class.
- Handle the WM_INITDIALOG and WM_CLOSE messages in the dialog class as follows.
-
- BOOL CMydlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Load the IDR_MYFRAME menu
pNewMenu = new CMenu;
pNewMenu->LoadMenu(IDR_MYFRAME);
// Set the mainframe menu to mainframe.
((CMainFrame *)AfxGetMainWnd())->SetMenu(pNewMenu);
return TRUE;
}
And
- void CMydlg::OnClose()
{
// Detach the previous HMenu handle from the object.
pNewMenu->Detach();
pNewMenu->LoadMenu(IDR_MAINFRAME);
// Restore the mainframe menu.
((CMainFrame *)AfxGetMainWnd())->SetMenu(pNewMenu);
CDialog::OnClose();
}
If there are other methods of closing the dialog (example- By
clicking a button in the Dialog), then The code given above in OnClose handler, must be
put in the button click handler.
Sanjeev Kumar, MSMFC, 6/23/95