Jar*_*lár 1 c++ dll winapi dialog
我想要一个创建.dll,它显示了一些对话框.
在我的.dll中我有这段代码:
HWND hDlg = CreateDialogParam(NULL, MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);
if (!hDlg) {
ShowError(GetLastErrorAsString().c_str());
return false;
}
Run Code Online (Sandbox Code Playgroud)
ShowError调用消息框,GetLastErrorAsString()只调用标准GetLastError并转换为字符串.
我有这个输出:
无法在映像文件中找到指定的资源类型.
然后我有一个标准的win32 Window应用程序,我调用方法,调用上面提到的代码.
DialogTest test;
test.showDialog(); // calls functionality from .dll
Run Code Online (Sandbox Code Playgroud)
我做错了什么?我是否需要将资源文件链接到.dll?
我正在使用Visual Studio 2010,并dialog在我的资源文件(.rc)中指定.
错误代码和消息是准确的:在您指示系统查找它的位置找不到资源:用于启动进程的可执行映像,而不是您的DLL.记录了该行为(请参阅CreateDialogParam):
hInstance [in,optional]
类型:HINSTANCE
包含对话框模板的模块句柄.如果此参数为NULL,则使用当前可执行文件.
由于您的DLL中存储了对话框模板,因此您必须传递HINSTANCE标识DLL 的对话框模板.有许多方法可以获得正确的值,但通过NULL或GetModuleHandle(NULL)不通过.这两个都将模块句柄返回到启动进程的可执行映像(而不是您的DLL).
简单的解决方案:选择传递给DllMain的hInstance并将其存储在全局变量中供以后使用.
HINSTANCE g_hInst = NULL;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {
switch ( fdwReason ) {
case DLL_PROCESS_ATTACH:
g_hInst = hinstDLL;
break;
default:
break;
}
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
强大的解决方案:此解决方案可以在任何地方,DLL,EXE或静态LIB中使用.只有缺点:它依赖于微软链接器的无证功能.不过不用担心,它不会无声地失败.
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISMODULE ((HINSTANCE)&__ImageBase)
Run Code Online (Sandbox Code Playgroud)
HINST_THISMODULE无论在何处使用,都将始终保持正确的值.1)
使用官方接口(GetModuleHandleEx)也可以实现同样的目的.以下解决方案也可以从EXE,DLL或静态LIB中使用,只要您确保将函数编译并链接到相应的模块中:
HMODULE GetCurrentModuleHandle() {
HMODULE hModule = NULL;
GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModuleHandle,
&hModule );
return hModule;
}
Run Code Online (Sandbox Code Playgroud)
这返回一个HMODULE,而不是一个HINSTANCE.但这不是问题,因为它们是相同的东西2).
| 归档时间: |
|
| 查看次数: |
1711 次 |
| 最近记录: |