C++ Winapi:插件中的createWindow

C++ Winapi:插件中的createWindow,c++,winapi,visual-c++,C++,Winapi,Visual C++,我正在开发一个插件(由其他应用程序加载的dll)。有一个特殊的函数应该返回HWND,这样应用程序就可以显示一个对话框。问题是我不知道从哪里可以获得hInstance(它没有作为参数传递给函数) 看起来我不明白什么,我对这些东西都不熟悉,所以如果这个问题很愚蠢,请原谅 UPD:尝试使用getModuleHandle获取hInstance: void* createLoginDialog() { HINSTANCE hIns = (HINSTANCE) GetModuleHandle(L"c

我正在开发一个插件(由其他应用程序加载的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;
}

我仍然遇到访问冲突。

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


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

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


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

获得它的几种方法:

  • 第一个参数传递到DllMain()入口点,强制转换为HINSTANCE
  • GetModuleHandle()使用DLL名称,强制转换为HINSTANCE
  • VirtualQuery(),传递函数的地址。将返回的内存\u BASIC\u INFORMATION.BaseAddress强制转换为HINSTANCE。适用于32位和64位版本的Windows

获得它的几种方法:

  • 第一个参数传递到DllMain()入口点,强制转换为HINSTANCE
  • GetModuleHandle()使用DLL名称,强制转换为HINSTANCE
  • VirtualQuery(),传递函数的地址。将返回的内存\u BASIC\u INFORMATION.BaseAddress强制转换为HINSTANCE。适用于32位和64位版本的Windows

只有当类注册为全局时才是可选的,这是一种糟糕的样式。使用DLL实例是正确的方法,因为它还告诉系统此窗口需要DLL才能正常运行。@Frerich,传递
NULL
会导致内存不足violation@SimonRichter,你说“使用DLL的实例”是什么意思?@SimonRichter:啊,很有趣-我没有意识到这一点。我自己从来没有通过
NULL
,所以我从来没有注意到这个要求。谢谢你指出这一点;我将补充我的回答以提及此要求。注册窗口类时,应使用包含窗口过程的模块的实例句柄——如果这是您的DLL,请使用
DllMain
中给出的句柄。需要将相同的句柄传递给
CreateWindow
。只有当类注册为全局时,该句柄才是可选的,这是错误的样式。使用DLL实例是正确的方法,因为它还告诉系统此窗口需要DLL才能正常运行。@Frerich,传递
NULL
会导致内存不足violation@SimonRichter,你说“使用DLL的实例”是什么意思?@SimonRichter:啊,很有趣-我没有意识到这一点。我自己从来没有通过
NULL
,所以我从来没有注意到这个要求。谢谢你指出这一点;我将补充我的回答以提及此要求。注册窗口类时,应使用包含窗口过程的模块的实例句柄——如果这是您的DLL,请使用
DllMain
中给出的句柄。需要将相同的句柄传递给
CreateWindow
。谢谢!我试图使用
GetModuleHandle
,但仍然获取访问冲突。我已经更新了问题,谢谢!我试图使用
GetModuleHandle
,但仍然获取访问冲突。我已经更新了问题