【问题标题】:Winapi: createWindow in pluginWinapi:插件中的createWindow
【发布时间】:2012-02-06 12:58:23
【问题描述】:

我正在开发一个插件(由其他应用程序加载的 dll)。有一个特殊的函数应该返回 HWND 以便应用程序可以显示一个对话框。问题是我不知道从哪里可以得到hInstance(它没有作为参数传递给函数)。

看起来我不明白一些东西,我对所有这些东西都是新手,所以如果问题很愚蠢,请原谅。

UPD:尝试使用 getModuleHandle 获取 hInstance:

void* createLoginDialog() {
    HINSTANCE hIns = (HINSTANCE) GetModuleHandle(L"comapping");
    HWND hWnd = CreateWindow(L"Popup",
                        L"Enter login",
                        WS_POPUP,
                        20,
                        20,
                        20,
                        20,
                        NULL,
                        NULL,
                        hIns,
                        NULL);
    return hWnd;
}

我仍然遇到访问冲突。

【问题讨论】:

    标签: c++ winapi visual-c++


    【解决方案1】:

    几种获取方式:

    • 传递给 DllMain() 入口点的第一个参数,转换为 HINSTANCE
    • GetModuleHandle() 使用您的 DLL 名称,转换为 HINSTANCE
    • VirtualQuery(),传递函数的地址。将返回的 MEMORY_BASIC_INFORMATION.BaseAddress 转换为 HINSTANCE。适用于 32 位和 64 位版本的 Windows。

    【讨论】:

    • 谢谢!我尝试使用GetModuleHandle,仍然遇到访问冲突。我已经更新了问题
    【解决方案2】:

    根据CreateWindow 的文档,hInstance 参数是可选的。这意味着在这里传递NULL 是有效的。然而,正如 Simon Richter 在 cmets 中对这个答案所指出的那样,参数可能只是 NULL 窗口类是全局注册的。

    如果您正在编写一个 DLL,您也可以自己定义一个DllMain 入口点函数。此函数由 Windows 调用,将函数句柄作为第一个参数传递。您可以在某处记住此句柄,以便在创建窗口时重用它。

    【讨论】:

    • 只有当类注册为全局时才可选,这是不好的风格。使用 DLL 的实例是正确的方法,因为它还告诉系统该窗口需要 DLL 才能正确运行。
    • @Frerich,传递 NULL 导致内存冲突
    • @SimonRichter,“使用 DLL 的实例”是什么意思?
    • @SimonRichter:啊,有趣-我不知道这一点。我自己从来没有通过NULL,所以我从来没有注意到这个要求。感谢您指出了这一点;我将增加我的答案来提及这个要求。
    • 当您注册窗口类时,您应该使用包含窗口过程的模块的实例句柄——如果那是您的 DLL,请使用您在DllMain 中提供的句柄。需要将相同的句柄传递给CreateWindow
    猜你喜欢
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    相关资源
    最近更新 更多