Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Menu at MDI application Collapse All
Subject Author Date
Olga Burlakova Nov 10, 2004 - 8:26 AM

Hello.

I created MDI application.

I want to use one menu (IDR_MAINFRAME) for all type of opened (created) documents. I change name of each menu item as :
void CMainFrame::OnCreate(....)
{
....
CExtBarButton * pExtButton = NULL;
CExtCmdItem * pCmdItem = NULL;.
pExtButton = m_wndMenuBar.GetButton(0);
nIDTmp = pExtButton->GetCmdID();
pCmdItem = g_CmdManager->CmdGetPtr(g_CmdManager->ProfileNameFromWnd(m_wndMenuBar.GetSafeHwnd()),nIDTmp);
            pCmdItem->m_sToolbarText = "Item One";

return 0;
}

When I create a new document (window) the menu is changing to IDR_... menu of document, I deleted all menu from resource except IDR_MAINFRAME. All looks like Ok. But when I try to maximize the child window, all Items at topmenu is changing name to default how they defined at resource.

How I can to solve this problem?

Olga Burlakova Nov 11, 2004 - 7:28 AM

I use Doc/View architecture.

The problem is, that after I have renamed the name of items of the menu(main menu) in a method CMainFrame:: OnCreate at maximize of child window there is a change of the name of all items of the menu (main) on initial (as they are defined in resources)


Example : Menu is defined as:
     File | Edit | View |
    Open
    New
    ....
I change name "File"to "Item One"
    Item One | Edit | View |
    Open
    New
    ....
When I maximize child window names "Item One" was change to File.
How to redraw menubar or do something else that so that after change of the size(maximize/ minimize) of child window was kept "Item One"?

Technical Support Nov 10, 2004 - 11:14 AM

Dear Olga,

To implement a single menu line for all types of MDI windows/documents is not difficult. First of all, please make sure that you have removed all document menu resources like IDR_somethingTYPE. You need only the IDR_MAINFRAME resource. Of course, you may create any other menu resources like context menus.

A. If your app is NOT based on the document/view architecture, you should use the following code in the CYourApp::InitInstance method:

HINSTANCE hInst = AfxGetResourceHandle();
m_hMDIMenu  =
   ::LoadMenu( hInst, MAKEINTRESOURCE(IDR_MAINFRAME) );
m_hMDIAccel =
   ::LoadAccelerators( hInst, 
    MAKEINTRESOURCE(IDR_MAINFRAME) 
   ); 


And the code responsible for creating new MDI child windows may look like:
void CYourApp::OnFileNew() 
{
CMainFrame * pFrame =
   STATIC_DOWNCAST( CMainFrame, m_pMainWnd );
   pFrame->CreateNewChild(
      RUNTIME_CLASS(CChildFrame),
      IDR_MAINFRAME,
      m_hMDIMenu,
      m_hMDIAccel
   );
}

You may take a look at the MDI sample application and easily convert it into a single-menu-based application if you remove the IDR_MDITYPE resource and replace this preprocessor symbol with IDR_MAINFRAME in all source files of this sample. You also need to remove the following lines at the beginning of the CMainFrame::OnCreate method:
VERIFY(
   g_CmdManager->UpdateFromMenu(
     pApp->m_pszProfileName,
     IDR_MDITYPE
     )
); 

B. If your app is based on the document/view architecture, then replace IDR_somethingTYPE with IDR_MAINFRAME when the document template is registered:
CMultiDocTemplate * pDocTemplate =
   new CMultiDocTemplate(
      IDR_MAINFRAME,
      RUNTIME_CLASS(CYourDoc),
      RUNTIME_CLASS(CChildFrame),
      RUNTIME_CLASS(CYourView)
      );
AddDocTemplate( pDocTemplate ); 

This is usually done in the CYourApp::InitInstance method. Additionally you should not update the command manager from the IDR_somethingTYPE menu. Now you can safely remove the menu from your document/view based MDI application.

In any case, you should not access buttons in the menu bar because it automatically rebuild them when the active MDI child window is changed, closed, or opened. If you have separate accelerator tables for documents in your application, then you may also safely remove them.

Olga Burlakova Nov 11, 2004 - 7:34 AM

I use Doc/View architecture.

The problem is, that after I have renamed the name of items of the menu(main menu) in a method CMainFrame:: OnCreate at maximize of child window there is a change of the name of all items of the menu (main) on initial (as they are defined in resources)


Example : Menu is defined as:
     File | Edit | View |
    Open
    New
    ....
I change name "File"to "Item One"
    Item One | Edit | View |
    Open
    New
    ....
When I maximize child window names "Item One" was change to File.
How to redraw menubar or do something else that so that after change of the size(maximize/ minimize) of child window was kept "Item One"?

Technical Support Nov 12, 2004 - 2:23 AM

To set custom text for a button in the menu bar without having to repaint the menu bar window, create a new class derived from CExtMenuControlBar and override the _UpdateMenuBar internal virtual method in this way:

BOOL CYourMenuControlBar::_UpdateMenuBar(
    BOOL bDoRecalcLayout // = TRUE
    )
{
    // Invoke the parent’s method to reinitialize
    // all the buttons as is
   BOOL bRetVal =
      CYourMenuControlBar::_UpdateMenuBar( FALSE );
   // Find the first button
   int nCount = GetButtonsCount();
   for( int nIdx = 0; nIdx < nCount; nIdx++ )
   {
       CExtBarButton * pTBB = GetButton( nIdx );
       ASSERT_VALID( pTBB );
       if( pTBB->IsKindOf(
             RUNTIME_CLASS(CExtBarMdiDocButton)
           )
        ||  pTBB->IsKindOf(
             RUNTIME_CLASS(CExtBarMdiRightButton)
           )
          )
          continue;
      // First button found, get its command item from
     // the command manager and update the command 
    //item’s text in the toolbar
       CExtCmdItem * pCmdItem =
          g_CmdManager->CmdGetPtr(
            g_CmdManager->ProfileNameFromWnd( m_hWnd ),
            pTBB->GetCmdID( false )
          );
       ASSERT( pCmdItem != NULL );
       pCmdItem->m_sToolbarText = _T("Item One");
       break;
   }
   // Recalculate layout if needed
   if( bDoRecalcLayout )
   {
      Invalidate();
      _RecalcLayoutImpl();
      UpdateWindow();
   }
   return bRetVal;
}
This method is called each time when the menu bar needs to be updated. So, you have complete control over the properties of all buttons in the menu bar.