代码之家  ›  专栏  ›  技术社区  ›  Sossenbinder

如何将菜单栏添加到WTL对话框窗口?

  •  3
  • Sossenbinder  · 技术社区  · 8 年前

    我正在尝试将我在资源中创建的菜单栏添加到我的资源中的对话框中,但我不知道该怎么做。

    我搜索了很多关于这方面的指南,但它们似乎都只适用于

    _Module

    这似乎是一件非常古老的文物 Does ATL/WTL still require the use of a global _Module variable?

    这些指南中的大多数都希望使用这种方法来解决问题:

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

    然而,考虑到 _模块 -这种方式已经过时了。

    有人能告诉我一个解决方案吗?

    1 回复  |  直到 8 年前
        1
  •  4
  •   Georgy Pashkov    8 年前

    WinAPI函数LoadMenu的第一个参数是应该从中加载菜单的模块的HINSTANCE。如果应用程序资源位于可执行文件中(而不是单独的资源DLL),则可以通过调用 GetModuleHandle(NULL) :

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

    在其他情况下,您需要将模块名称传递给函数。

    顺便说一下,加载菜单的一种更简单的方法是:

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

    以下是如何在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;
    }
    

    因此,您可以使用 ModuleHelper 而不是 _Module 。它来自atlap.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 函数返回编译ATL的模块的句柄(若我没记错的话)。