destroying a menu when application ends without resource-leaks

Hello,

In brief: how can a menu which was loaded from a separate resource-dll be destroyed at application-end, without leaving any resource-leaks?

I have seperate resource-DLL's for each language I want to support.
In InitInstance I post a user-defined message WM_CHANGELANGUAGE to activate the desired resource-DLL, and to activate the according menu.
This user-defined message WM_CHANGELANGUAGE is called every time the user wants to change the language of the application.
The according message-handler is OnChangeLanguage.
To avoid resource-leaks it is necessary to destroy the previously loaded menu before setting the new one.
But -for some reason- the initial (the default) menu mustn't ever be deleted, so a CMenu* to the default menu is needed to assure that the default menu isn't deleted! I get a pointer to this default-menu via the user-defined WM_GETDEFAULTMENU-message in InitInstance and OnGetDefaultMenu respectively.

The problem I have is: When closing the application the last loaded menu must be destroyed. (In CMainFrame::OnDestroy) But only if it isn't the default-menu!
But on the other hand MFC will bring an error, when it destroys the Mainframe with no menu attached at all. So I thought it would be necessary to set the default menu again to make the MFC happy, but this doesn't work either!

So: how the heck can multiple menus be handled correctly, without leaving any resource leaks?

Thanks a bunch :-)

The source code is:
void CMainFrame::OnDestroy()
{
      CMenu* pMenu = GetMenu();
      if( pMenu != m_pMenuDefault)
      {
            // Destroy the no longer used menu unless it's the default
            // menu as MFC insists on restoring that at close
            pMenu->DestroyMenu();
      }

      HINSTANCE hInstRes = AfxGetResourceHandle();
      HINSTANCE hInst = AfxGetInstanceHandle();
      if (hInstRes != hInst)
      {
            FreeLibrary (hInstRes);
            AfxSetResourceHandle (hInst);
      }

      SetMenu(m_pMenuDefault);


      CMDIFrameWnd::OnDestroy();
}

BOOL CMyApp::InitInstance()
{
      ....
      ....
      pMainFrame->PostMessage(WM_GETDEFAULTMENU);
      pMainFrame->PostMessage(WM_CHANGELANGUAGE,LANG_ENGLISH);

      // The main window has been initialized, so show and update it.
      pMainFrame->ShowWindow(m_nCmdShow);
      pMainFrame->UpdateWindow();

      return TRUE;
}

LRESULT CMainFrame::OnChangeLanguage(WPARAM wParam, LPARAM lParam)
{
CString strLangDLL;

      if (wParam == LANG_ENGLISH)      // load english resource-dll
            strLangDLL = "e:\\prj\\lang\\res_eng.dll";
      else if (wParam == LANG_GERMAN)      // load german resource-dll
            strLangDLL = "e:\\prj\\lang\\res_dts.dll";
      else
            return 0L;

      HINSTANCE hInstRes = AfxGetResourceHandle();
      HINSTANCE hInst = AfxGetInstanceHandle();
      if (hInstRes != hInst)
      {
            FreeLibrary (hInstRes);
            AfxSetResourceHandle (hInst);
      }
      if ((int)(hInstRes = AfxLoadLibrary(strLangDLL)) < HINSTANCE_ERROR)
            return 0L;
      AfxSetResourceHandle(hInstRes);

      CMenu menu;
      if( menu.LoadMenu(IDR_LANGTYPE))
      {      
            CMenu* pMenu = GetMenu();
            if( pMenu != m_pMenuDefault)
            {
                  // Destroy the no longer used menu unless it's the default
                  // menu as MFC insists on restoring that at close
                  pMenu->DestroyMenu();
            }
            SetMenu(&menu);
            menu.Detach();
      }
      m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));
      m_wndStatusBar.UpdateWindow();

      return 0L;
}

LRESULT CMainFrame::OnGetDefaultMenu(WPARAM wParam, LPARAM lParam)
{
      m_pMenuDefault = AfxGetMainWnd()->GetMenu();
      return 0L;
}

SherpaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AVaulinCommented:
May be it's stupid answer... But how about this idea: use ModifyMenu CMenu method (or API function) to modify menu items text. If you use StatusBar and ToolBar and you want to change description text language you can copy all string resource and modify them (say if you have IDM_FILE add IDM_FILE1 item and use it as nIDNewItem). Also you need to handle both IDM_FILE and IDM_FILE1 commands (use say OnFile method for both). I've used this idea in my program. All work fine.
Try and good luck.
0
AVaulinCommented:
OK! I propose you also one way. Add flobal integer variable which contain menu loading number and init it with zero. When you are load menu increase it, when destroy - at first check that this variable more then zero and if yes - destroy menu and decrease variable. I hope this will help. Good luck.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.