Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Adding a menu to a CMDIChildWnd

Adding a menu to a CMDIChildWnd

Scheduled Pinned Locked Moved C / C++ / MFC
c++regexhelpquestion
5 Posts 2 Posters 5 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    moredip
    wrote on last edited by
    #1

    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

    J 1 Reply Last reply
    0
    • M moredip

      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

      J Offline
      J Offline
      Jim Crafton
      wrote on last edited by
      #2

      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

      M 2 Replies Last reply
      0
      • J Jim Crafton

        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

        M Offline
        M Offline
        moredip
        wrote on last edited by
        #3

        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

        J 1 Reply Last reply
        0
        • J Jim Crafton

          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

          M Offline
          M Offline
          moredip
          wrote on last edited by
          #4

          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!

          1 Reply Last reply
          0
          • M moredip

            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

            J Offline
            J Offline
            Jim Crafton
            wrote on last edited by
            #5

            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

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups