Search code examples
c++atlwtl

How do I add a menubar to my WTL dialog window?


I am trying to add a menubar I created in my resource to a dialog from my resource, but I can't quite figure out how to.

I searched a lot of guides on that, but they all seem to be working only with

_Module

which seems to be a very old relic according to Does ATL/WTL still require the use of a global _Module variable?

Most of these guides want to tackle the problem using this method:

CMenu menu;
menu.Attach( LoadMenu( _Module.GetResourceInstance(),MAKEINTRESOURCE(<Menubar ID>)));
SetMenu( menu );

However, I would like to know what the "modern" way would be then, considering the _Module-way is outdated.

Can anyone point me to a solution?


Solution

  • First argument of WinAPI function LoadMenu is HINSTANCE of the module from which the menu should be loaded. If your app resources are in the executable (as opposed to a separate resource DLL), you can get its instance by calling GetModuleHandle(NULL):

    menu.Attach(LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(<Menubar ID>)));
    

    In other cases, you will need to pass module name to the function.

    By the way, an easier way to load a menu is:

    CMenu menu;
    menu.LoadMenu(MAKEINTRESOURCE(<ID>));
    

    Here is how it is implemented in atluser.h:

    BOOL LoadMenu(ATL::_U_STRINGorID menu)
    {
        ATLASSERT(m_hMenu == NULL);
        m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
        return (m_hMenu != NULL) ? TRUE : FALSE;
    }
    

    So you can use the ModuleHelper thing instead of _Module. It comes from atlapp.h:

    inline HINSTANCE GetResourceInstance()
    {
    #if (_ATL_VER >= 0x0700)
        return ATL::_AtlBaseModule.GetResourceInstance();
    #else // !(_ATL_VER >= 0x0700)
        return ATL::_pModule->GetResourceInstance();
    #endif // !(_ATL_VER >= 0x0700)
    }
    

    ATL::_AtlBaseModule.GetResourceInstance function returns handle of the module in which ATL was compiled (if I remember correctly).