Adding a menu to a CMDIChildWnd
-
Hi all, I'm trying to create a CMDIChildWnd-derived window with a menu, but I'm having problems. Here's the relevent code from my CMDIChildWnd-derived class's constructor: <-------------------------SNIP----------------------------- ... ... Create( NULL, strTitle, WS_CHILD | WS_OVERLAPPEDWINDOW, rectLocation, ((CMDIFrameWnd*)AfxGetMainWnd()), 0 ); VERIFY( m_menu.LoadMenu( IDR_MY_MENU ) ); if( !SetMenu( &m_menu ) ) { DWORD dwErrorCode = GetLastError(); //returns 1436 ASSERT( FALSE ); } DrawMenuBar(); ... ... <-------------------------SNIP----------------------------- The SetMenu(...) call always fails, with GetLastError() returning 1436. According to MSDN this error code is ERROR_CHILD_WINDOW_MENU - "Child windows cannot have menus.". Does this mean that it's impossible to add a menu to an CMDIChildWnd that's a child of the main window frame? If so, what are my options to get around this? The two things I can think of are: A) Draw my own menu window. No Thanks! B) convert my CMDIChildWnd class to use the MFC Doc/View pattern - AFAIK the frame window of a CView can have menus. Any other suggestions or advice? Cheers, Pete
-
Hi all, I'm trying to create a CMDIChildWnd-derived window with a menu, but I'm having problems. Here's the relevent code from my CMDIChildWnd-derived class's constructor: <-------------------------SNIP----------------------------- ... ... Create( NULL, strTitle, WS_CHILD | WS_OVERLAPPEDWINDOW, rectLocation, ((CMDIFrameWnd*)AfxGetMainWnd()), 0 ); VERIFY( m_menu.LoadMenu( IDR_MY_MENU ) ); if( !SetMenu( &m_menu ) ) { DWORD dwErrorCode = GetLastError(); //returns 1436 ASSERT( FALSE ); } DrawMenuBar(); ... ... <-------------------------SNIP----------------------------- The SetMenu(...) call always fails, with GetLastError() returning 1436. According to MSDN this error code is ERROR_CHILD_WINDOW_MENU - "Child windows cannot have menus.". Does this mean that it's impossible to add a menu to an CMDIChildWnd that's a child of the main window frame? If so, what are my options to get around this? The two things I can think of are: A) Draw my own menu window. No Thanks! B) convert my CMDIChildWnd class to use the MFC Doc/View pattern - AFAIK the frame window of a CView can have menus. Any other suggestions or advice? Cheers, Pete
Assuming a few things: You're not using MFC Doc/View You DO have a properly configured String table entry, accelerator table entry(ies), ICO entry, and MENU entry in your resource .rc file. The code below uses a class MyMDIChildWnd declared as
class MyMDIChildWnd : public CMDIChildWnd
You can create a new MDI child in you main CWinApp class like so:
MainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
// create a new MDI child window
pFrame->CreateNewChild(
RUNTIME_CLASS(MyMDIChildWnd), IDR_MYMDIWNDTYPE, m_hMDIMenu, m_hMDIAccel);Where: IDR_MYMDIWNDTYPE is the resource name for the mdi child wnd in the string table, accelerator table, menu entry, and ICO file m_hMDIMenu is a member in your CWinApp class of type HMENU m_hMDIAccel is a member in your CWinApp class of type HACCEL You should initialize m_hMDIMenu and m_hMDIAccel in your InitInstance app function like so:
HINSTANCE hInst = AfxGetResourceHandle();
m_hMDIMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_MYMDIWNDTYPE));
m_hMDIAccel = ::LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_MYMDIWNDTYPE));If you create a new MDI app from the MFC App Wizard it will do all of this for you if you DON'T choose Doc/View support. ¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned
-
Assuming a few things: You're not using MFC Doc/View You DO have a properly configured String table entry, accelerator table entry(ies), ICO entry, and MENU entry in your resource .rc file. The code below uses a class MyMDIChildWnd declared as
class MyMDIChildWnd : public CMDIChildWnd
You can create a new MDI child in you main CWinApp class like so:
MainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
// create a new MDI child window
pFrame->CreateNewChild(
RUNTIME_CLASS(MyMDIChildWnd), IDR_MYMDIWNDTYPE, m_hMDIMenu, m_hMDIAccel);Where: IDR_MYMDIWNDTYPE is the resource name for the mdi child wnd in the string table, accelerator table, menu entry, and ICO file m_hMDIMenu is a member in your CWinApp class of type HMENU m_hMDIAccel is a member in your CWinApp class of type HACCEL You should initialize m_hMDIMenu and m_hMDIAccel in your InitInstance app function like so:
HINSTANCE hInst = AfxGetResourceHandle();
m_hMDIMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_MYMDIWNDTYPE));
m_hMDIAccel = ::LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_MYMDIWNDTYPE));If you create a new MDI app from the MFC App Wizard it will do all of this for you if you DON'T choose Doc/View support. ¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned
Hi Jim, First of all, thanks for the help! OK, so I've followed your advice and am now creating my window like so: <---------------------------------------SNIP----------------------------> CMDIFrameWnd* pMainFrame = (CMDIFrameWnd *)AfxGetMainWnd(); C2DTrajMainWnd *pWnd = (C2DTrajMainWnd *)pMainFrame->CreateNewChild( RUNTIME_CLASS(C2DTrajMainWnd), IDR_2D_TRAJ, hMDIMenu, hMDIAccel ); <---------------------------------------SNIP----------------------------> However, the IDR_2D_TRAJ menu is still not being displayed. During the CreateNewChild call, in CMDIChildWnd::LoadFrame(...) MFC TRACE()'s "Warning: no shared menu/acceltable for MDI Child window." Stepping through the execution, it seems that CMDIChildWnd::LoadFrame(...) is being called with a non-NULL CDocTemplate. I don't understand why. My App does have Doc/View support, but I thought that CDocTemplate's were only used when specifically creating Doc/View instances. Am I missing something here? Thanks again for the help, Pete
-
Assuming a few things: You're not using MFC Doc/View You DO have a properly configured String table entry, accelerator table entry(ies), ICO entry, and MENU entry in your resource .rc file. The code below uses a class MyMDIChildWnd declared as
class MyMDIChildWnd : public CMDIChildWnd
You can create a new MDI child in you main CWinApp class like so:
MainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
// create a new MDI child window
pFrame->CreateNewChild(
RUNTIME_CLASS(MyMDIChildWnd), IDR_MYMDIWNDTYPE, m_hMDIMenu, m_hMDIAccel);Where: IDR_MYMDIWNDTYPE is the resource name for the mdi child wnd in the string table, accelerator table, menu entry, and ICO file m_hMDIMenu is a member in your CWinApp class of type HMENU m_hMDIAccel is a member in your CWinApp class of type HACCEL You should initialize m_hMDIMenu and m_hMDIAccel in your InitInstance app function like so:
HINSTANCE hInst = AfxGetResourceHandle();
m_hMDIMenu = ::LoadMenu(hInst, MAKEINTRESOURCE(IDR_MYMDIWNDTYPE));
m_hMDIAccel = ::LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_MYMDIWNDTYPE));If you create a new MDI app from the MFC App Wizard it will do all of this for you if you DON'T choose Doc/View support. ¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned
I'm sorry, I just stepped through the code again and realized some of what I said in my earlier reply was wrong. When CMDIChildWnd::LoadFrame(...) is called it cannot get a valid CMultiDocTemplate instance from the CreateContext that it's passed, so it says it cannot create the menu/acceltable. Sorry for the confusion!
-
Hi Jim, First of all, thanks for the help! OK, so I've followed your advice and am now creating my window like so: <---------------------------------------SNIP----------------------------> CMDIFrameWnd* pMainFrame = (CMDIFrameWnd *)AfxGetMainWnd(); C2DTrajMainWnd *pWnd = (C2DTrajMainWnd *)pMainFrame->CreateNewChild( RUNTIME_CLASS(C2DTrajMainWnd), IDR_2D_TRAJ, hMDIMenu, hMDIAccel ); <---------------------------------------SNIP----------------------------> However, the IDR_2D_TRAJ menu is still not being displayed. During the CreateNewChild call, in CMDIChildWnd::LoadFrame(...) MFC TRACE()'s "Warning: no shared menu/acceltable for MDI Child window." Stepping through the execution, it seems that CMDIChildWnd::LoadFrame(...) is being called with a non-NULL CDocTemplate. I don't understand why. My App does have Doc/View support, but I thought that CDocTemplate's were only used when specifically creating Doc/View instances. Am I missing something here? Thanks again for the help, Pete
I think that my solution only work if you are NOT using MFC's Doc/View. If you are then you have to create the child window another way (which I don't recall how at the moment). ¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned