[英]win32 - Dialog inside .dll
我想要一個 create.dll,它顯示一些對話框。
在 my.dll 中我有這段代碼:
HWND hDlg = CreateDialogParam(NULL, MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);
if (!hDlg) {
ShowError(GetLastErrorAsString().c_str());
return false;
}
ShowError
調用消息框,而GetLastErrorAsString()
僅調用標准的GetLastError
並轉換為字符串。
我有這個輸出:
在圖像文件中找不到指定的資源類型。
然后我有一個標准的 win32 Window 應用程序,在那里我調用了調用上述代碼的方法。
DialogTest test;
test.showDialog(); // calls functionality from .dll
我做錯了什么? 我需要將資源文件鏈接到.dll 嗎?
我正在使用 Visual Studio 2010,並且在我的資源文件 (.rc) 中指定了dialog
。
錯誤代碼和消息是准確的:無法在您指示系統尋找資源的位置找到資源:用於啟動進程的可執行映像,而不是您的 DLL。 該行為已記錄(請參閱CreateDialogParam ):
hInstance [輸入,可選]
類型:實例
包含對話框模板的模塊的句柄。 如果此參數為 NULL,則使用當前可執行文件。
由於您將對話框模板存儲在 DLL 中,因此您必須傳遞標識 DLL 的HINSTANCE
。 有多種方法可以獲得正確的值,但傳遞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;
}
強大的解決方案:此解決方案可以在任何地方使用,在 DLL、EXE 或靜態 LIB 中。 唯一的缺點:它依賴於 Microsoft 鏈接器的未記錄功能。 不過別擔心,它不會悄無聲息地失敗。
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISMODULE ((HINSTANCE)&__ImageBase)
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;
}
這將返回一個HMODULE
,而不是一個HINSTANCE
。 不過,這不是問題,因為它們是同一回事2) 。
您將 NULL 指定為CreateDialogParam
的第一個參數。 如果你想從 Win32 窗口應用程序加載對話框資源文件,你應該使用它:
HWND hDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);
但是,如果要從 DLL 本身加載它,則應將第一個參數替換為 DLL 的 DllMain 入口點函數中的 HINSTANCE 參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.