CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Jan 2011
    Posts
    15

    [RESOLVED] Trouble with MDI GetSubMenu

    I have a MDI program that is setup to support multiple languages. This app is configured to allow the operator to swap the language on-the-fly and all the menus/dialogs/etc will automatically switch to the newly selected language.

    There are multiple types of document / view classes, and each class has its own menu. Also, I have a function that will return the translation (for the selected language) that is keyed off of the operator specified language.

    Everything works fine when I have only 1 document open, but if there are 2 documents, then the program crashes (because GetSubMenu returns a NULL) when I switch to the 2nd document.

    Each CScrollView type that I have uses a function such as OnActivateView bellow...
    Code:
    void CDocType1View::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
    {
    	if (bActivate)
    		MainFramePtr->ShowType1Tools(); // changes the toolbar just bellow the menu
    
    
    	CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView);
    
    	if (bActivate && (nPrevLang != larray.nLangIdx))
    		RebuildMenu();
    }
    nPrevLang is a private int variable for CDocType1View
    larray is a structure containing all my translations, a function "L" that return the translated text, and nLangIdx which keeps track of the selected language

    The problem is in RebuildMenu(), when I first assign submenu2 (in the "Edit" section)...
    Code:
    void CDocType1View::RebuildMenu()
    {
    	if (nPrevLang == larray.nLangIdx)
    		return;
    
    	nPrevLang = larray.nLangIdx;
    
    	CMenu	*pMenu = AfxGetApp()->m_pMainWnd->GetMenu(), 
    			*submenu = NULL, 
    			*submenu2 = NULL, 
    			*submenu3 = NULL, 
    			*submenu4 = NULL;
    	CString	szTemp;
    
    // File
    	submenu = pMenu->GetSubMenu(0);
    	szTemp = larray.L(_T("&File"));
    	pMenu->ModifyMenu(0, MF_BYPOSITION, MF_STRING, szTemp);
    		szTemp = larray.L(_T("&Open...\tCtrl O"));
    		submenu->ModifyMenu(ID_FILE_OPEN, MF_BYCOMMAND, ID_FILE_OPEN, szTemp);
    		szTemp = larray.L(_T("&Print...\tCtrl P"));
    		submenu->ModifyMenu(ID_FILE_PRINT, MF_BYCOMMAND, ID_FILE_PRINT, szTemp);
    		szTemp = larray.L(_T("Print Pre&view"));
    		submenu->ModifyMenu(ID_FILE_PRINT_PREVIEW, MF_BYCOMMAND, ID_FILE_PRINT_PREVIEW, szTemp);
    		szTemp = larray.L(_T("P&rint Setup..."));
    		submenu->ModifyMenu(ID_FILE_PRINT_SETUP, MF_BYCOMMAND, ID_FILE_PRINT_SETUP, szTemp);
    		szTemp = larray.L(_T("E&xit"));
    		submenu->ModifyMenu(ID_APP_EXIT, MF_BYCOMMAND, ID_APP_EXIT, szTemp);
    
    // Edit
    	submenu = pMenu->GetSubMenu(1);
    	szTemp = larray.L(_T("&Edit"));
    	pMenu->ModifyMenu(1, MF_BYPOSITION, MF_STRING, szTemp);
    		szTemp = larray.L(_T("Change Co&mments\tQ"));
    		submenu->ModifyMenu(ID_EDIT_CHANGECOMMENTS, MF_BYCOMMAND, ID_EDIT_CHANGECOMMENTS, szTemp);
    		submenu2 = submenu->GetSubMenu(1);
    
    // this is where I'm failing on the 2nd document initialization, GetSubMenu return NULL
    
    		szTemp = larray.L(_T("Grouping"));
    		submenu->ModifyMenu(1, MF_BYPOSITION, MF_STRING, szTemp);
    			szTemp = larray.L(_T("Group 1"));
    			submenu2->ModifyMenu(ID_EDIT_GROUP1, MF_BYCOMMAND, ID_EDIT_GROUP1, szTemp);
    			szTemp = larray.L(_T("Group 2"));
    			submenu2->ModifyMenu(ID_EDIT_GROUP2, MF_BYCOMMAND, ID_EDIT_GROUP2, szTemp);
    		submenu2 = submenu->GetSubMenu(2);
    		szTemp = larray.L(_T("Typing"));
    		submenu->ModifyMenu(2, MF_BYPOSITION, MF_STRING, szTemp);
    			szTemp = larray.L(_T("Type 1"));
    			submenu2->ModifyMenu(ID_EDIT_TYPE1, MF_BYCOMMAND, ID_EDIT_TYPE1, szTemp);
    			szTemp = larray.L(_T("Type 2"));
    			submenu2->ModifyMenu(ID_EDIT_TYPE2, MF_BYCOMMAND, ID_EDIT_TYPE2, szTemp);
    
    // ... I have clipped the rest of the code between the "Edit->Typing" through "Help", but it is very similar in style and substance.  There are more cascades of menus that require me to use 4 submenu pointers.
    
    // Help
    	submenu = pMenu->GetSubMenu(5);
    	szTemp = larray.L(_T("&Help"));
    	pMenu->ModifyMenu(5, MF_BYPOSITION, MF_STRING, szTemp);
    		szTemp = larray.L(_T("&Help Topics"));
    		submenu->ModifyMenu(ID_HELP_FINDER, MF_BYCOMMAND, ID_HELP_FINDER, szTemp);
    		szTemp = larray.L(_T("&About Display..."));
    		submenu->ModifyMenu(ID_APP_ABOUT, MF_BYCOMMAND, ID_APP_ABOUT, szTemp);
    }
    Can anyone tell me why this is failing when I switch to my 2nd document / view?

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: Trouble with MDI GetSubMenu

    I'd suggest you to redesign...
    It's a very bad idea to hard code the texts (not only for menus!). You should just load the menu for appropriate language and destroy the existent one after you changed the language.
    Victor Nijegorodov

  3. #3
    Join Date
    Jan 2011
    Posts
    15

    Re: Trouble with MDI GetSubMenu

    The translations are not hard coded. There is a database that the operator is able to modify so that they can have their own "custom" translations if need be. Because of that, I can't really create separate resources for different languages... there are far too many possibilities and I would have to re-deploy any time someone wanted to tweak their wording.

  4. #4
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Trouble with MDI GetSubMenu

    If it were me then, I'd probably set up the CCmdUI update mechanism, call GetText() when it's about to display, look up the value in the database then use SetText() to display the command in the correct language.

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by vandy_mike View Post
    Each CScrollView type that I have uses a function such as OnActivateView bellow...
    Code:
    void CDocType1View::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
    {
    	if (bActivate)
    		MainFramePtr->ShowType1Tools(); // changes the toolbar just bellow the menu
    
    
    	CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView);
    
    	if (bActivate && (nPrevLang != larray.nLangIdx))
    		RebuildMenu();
    }
    Why don't you check the view to be activated? (it sounds like you are trying to RebuildMenu for the deactivated view too!)
    Victor Nijegorodov

  6. #6
    Join Date
    Jan 2011
    Posts
    15

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by GCDEF View Post
    If it were me then, I'd probably set up the CCmdUI update mechanism, call GetText() when it's about to display, look up the value in the database then use SetText() to display the command in the correct language.
    Wouldn't that just update the text once you mouse over? I want the text to change as soon as the operator changes from English -> Spanish (etc.), not when they actually go through the menu system.

  7. #7
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by vandy_mike View Post
    Wouldn't that just update the text once you mouse over? I want the text to change as soon as the operator changes from English -> Spanish (etc.), not when they actually go through the menu system.
    It would change the text whenever the menu item was about to be displayed. It's not necessary to change the text on items they can't see. All you'd need to do is have the correct database or translation table in place and the OnUpdate handler would ensure the correct text was displayed whenever necessary.

  8. #8
    Join Date
    Jan 2011
    Posts
    15

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by VictorN View Post
    Why don't you check the view to be activated? (it sounds like you are trying to RebuildMenu for the deactivated view too!)
    Isn't this what I'm doing in "OnActivateView" right before the call to "RebuildMenu"? I would think that the condition of bActivate == TRUE would take care of this.

    Quote Originally Posted by vandy_mike View Post
    Code:
    void CDocType1View::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
    {
    	if (bActivate)
    		MainFramePtr->ShowType1Tools(); // changes the toolbar just bellow the menu
    
    
    	CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView);
    
    	if (bActivate && (nPrevLang != larray.nLangIdx))
    		RebuildMenu();
    }

  9. #9
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by vandy_mike View Post
    Isn't this what I'm doing in "OnActivateView" right before the call to "RebuildMenu"? I would think that the condition of bActivate == TRUE would take care of this.
    No.
    You should also check the (pActivateView == this) condition.
    Victor Nijegorodov

  10. #10
    Join Date
    Jan 2011
    Posts
    15

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by VictorN View Post
    No.
    You should also check the (pActivateView == this) condition.
    This had no impact at all. It looks like my check to bActivate was probably sufficient... but I'm still getting a crash.

  11. #11
    Join Date
    Jan 2011
    Posts
    15

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by GCDEF View Post
    It would change the text whenever the menu item was about to be displayed. It's not necessary to change the text on items they can't see. All you'd need to do is have the correct database or translation table in place and the OnUpdate handler would ensure the correct text was displayed whenever necessary.
    so then you would suggest changing ALL of the functions such as...
    Code:
    void CDocType1View::OnUpdateEditGroup1(CCmdUI *pCmdUI)
    {
    	CMenu	*pMenu = AfxGetApp()->m_pMainWnd->GetMenu();
    
    	pCmdUI->Enable(bAllowGrouping);     
    	
    	pMenu->CheckMenuItem(ID_EDIT_GROUP1, ((bAllowGrouping && bIsGroup1) ? MF_CHECKED : MF_UNCHECKED));
    }
    to...

    Code:
    void CDocType1View::OnUpdateEditGroup1(CCmdUI *pCmdUI)
    {
    	CString	szCurrentText;
    	CMenu	*pMenu = AfxGetApp()->m_pMainWnd->GetMenu();
    
    	pCmdUI->Enable(bAllowGrouping);     
    	
    	pMenu->GetMenuString(ID_EDIT_GROUP1, szCurrentText, 255, MF_BYCOMMAND);
    	szCurrentText = larray.L(szCurrentText);
    
    // either
    	pCmdUI->SetText(szCurrentText);
    // or
    	pMenu->ModifyMenu(ID_EDIT_GROUP1, MF_BYCOMMAND, ID_EDIT_GROUP1, szCurrentText);
    
    	pMenu->CheckMenuItem(ID_EDIT_GROUP1, ((bAllowGrouping && bIsGroup1) ? MF_CHECKED : MF_UNCHECKED));
    }
    I think this would only update when the operator went to that section of the menu. So the menu would be a strange combination of English / Spanish (etc.) until the operator had moused-over each item.

  12. #12
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by vandy_mike View Post
    so then you would suggest changing ALL of the functions such as...
    Code:
    void CDocType1View::OnUpdateEditGroup1(CCmdUI *pCmdUI)
    {
    	CMenu	*pMenu = AfxGetApp()->m_pMainWnd->GetMenu();
    
    	pCmdUI->Enable(bAllowGrouping);     
    	
    	pMenu->CheckMenuItem(ID_EDIT_GROUP1, ((bAllowGrouping && bIsGroup1) ? MF_CHECKED : MF_UNCHECKED));
    }
    to...

    Code:
    void CDocType1View::OnUpdateEditGroup1(CCmdUI *pCmdUI)
    {
    	CString	szCurrentText;
    	CMenu	*pMenu = AfxGetApp()->m_pMainWnd->GetMenu();
    
    	pCmdUI->Enable(bAllowGrouping);     
    	
    	pMenu->GetMenuString(ID_EDIT_GROUP1, szCurrentText, 255, MF_BYCOMMAND);
    	szCurrentText = larray.L(szCurrentText);
    
    // either
    	pCmdUI->SetText(szCurrentText);
    // or
    	pMenu->ModifyMenu(ID_EDIT_GROUP1, MF_BYCOMMAND, ID_EDIT_GROUP1, szCurrentText);
    
    	pMenu->CheckMenuItem(ID_EDIT_GROUP1, ((bAllowGrouping && bIsGroup1) ? MF_CHECKED : MF_UNCHECKED));
    }
    I think this would only update when the operator went to that section of the menu. So the menu would be a strange combination of English / Spanish (etc.) until the operator had moused-over each item.
    Not really. You seem to be missing that the OnUpdate handler is called before the menu is displayed so you could change the text to whatever you want before the user sees it.

    I would just add a line like
    Code:
     
    pCmdUI->SetText(TranslateText(pCmdUI->GetText());
    where TranslateText would be a function that does the lookup and translation in your app.

  13. #13
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: Trouble with MDI GetSubMenu

    The only problem with CCmdUI update mechanism is it won't update the menu bar items.
    Victor Nijegorodov

  14. #14
    Join Date
    Jan 2011
    Posts
    15

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by GCDEF View Post
    Not really. You seem to be missing that the OnUpdate handler is called before the menu is displayed so you could change the text to whatever you want before the user sees it.

    I would just add a line like
    Code:
     
    pCmdUI->SetText(TranslateText(pCmdUI->GetText());
    where TranslateText would be a function that does the lookup and translation in your app.
    First...

    pCmdUI->GetText() does not exist... so I would still have to do something like GetMenuString.

    Second...

    That doesn't help me for "pop-up" menus, only the items in the pop-up.


    The root problem is that I can't access my "nested" pop-up menus.

    For instance, if there is a menu pop-up item called "Operations" as a subset of "Edit", and there is a menu pop-up item called "Math" inside operations... and Math has 2 menu items called "Add" (ID_OPER_MATH_ADD) and "Subtract" (ID_OPER_MATH_SUB)...

    Edit -> Operations -> Math -> Add
    Edit -> Operations -> Math -> Subtract

    I can translate these using ModifyMenu from my originally posted code, such as...
    Code:
    szTemp = larray.L(_T("Add"));
    pMenu->ModifyMenu(ID_OPER_MATH_ADD, MF_BYCOMMAND, ID_OPER_MATH_ADD, szTemp);
    //pMenu is OK whenever using MF_BYCOMMAND
    And I can translate Edit such as...
    Code:
    szTemp = larray.L(_T("&Edit"));
    pMenu->ModifyMenu(1, MF_BYPOSITION, MF_STRING, szTemp);
    //using pMenu so no problem
    And I can translate Operations such as...
    Code:
    submenu = pMenu->GetSubMenu(1);// Edit submenu
    szTemp = larray.L(_T("Operations"));
    submenu->ModifyMenu(0, MF_BYPOSITION, MF_STRING, szTemp);
    //succeeds at getting the submenu of pMenu
    But I fail (2nd document/view) when I try to translate Math...
    Code:
    submenu2 = submenu ->GetSubMenu(0);// Operations submenu
    szTemp = larray.L(_T("Math"));
    submenu2->ModifyMenu(0, MF_BYPOSITION, MF_STRING, szTemp);
    //fails to get submenu2 from the pointer to submenu
    As I said, this all works correctly for the 1st document/view, but when I change to the 2nd window that I have open... my application crashes.

  15. #15
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: Trouble with MDI GetSubMenu

    Quote Originally Posted by vandy_mike View Post
    ...
    As I said, this all works correctly for the 1st document/view, but when I change to the 2nd window that I have open... my application crashes.
    Perhaps, because the 2nd document uses another menu?
    Victor Nijegorodov

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured