C++ win32-对话框内部.dll

C++ win32-对话框内部.dll,c++,winapi,dll,dialog,C++,Winapi,Dll,Dialog,我想创建一个.dll,它显示一些对话框 在my.dll中,我有以下代码: HWND hDlg = CreateDialogParam(NULL, MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL); if (!hDlg) { ShowError(GetLastErrorAsString().c_str()); return false; } batherror调用消息框和GetLastErrorAsString(

我想创建一个.dll,它显示一些对话框

在my.dll中,我有以下代码:

HWND hDlg = CreateDialogParam(NULL, MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);
if (!hDlg)  {
    ShowError(GetLastErrorAsString().c_str());
    return false;
}
batherror
调用消息框和
GetLastErrorAsString()
只调用标准
GetLastError
并转换为字符串。
我有以下输出:

在映像文件中找不到指定的资源类型

然后我有一个标准的win32窗口应用程序,在那里我调用了方法,该方法调用上述代码

DialogTest test;
test.showDialog(); // calls functionality from .dll
我做错了什么?我需要将资源文件链接到.dll吗


我正在使用Visual studio 2010,并且在我的资源文件(.rc)中指定了
dialog

您指定NULL作为
CreateDialogParam
的第一个参数。如果要从Win32 Window应用程序加载对话框资源文件,则应改为使用:

HWND hDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);

但是,如果要从DLL本身加载,则应使用DLL的DllMain入口点函数中的HINSTANCE参数替换第一个参数。

您将NULL指定为
CreateDialogParam
的第一个参数。如果要从Win32 Window应用程序加载对话框资源文件,则应改为使用:

HWND hDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);

但是,如果要从DLL本身加载它,您应该使用DLL的DllMain入口点函数中的HINSTANCE参数替换第一个参数。

错误代码和消息准确:在您指示系统查找资源的位置找不到资源:用于启动进程的可执行映像,而不是DLL。行为记录在案(请参阅):

hInstance[输入,可选]

类型:HINSTANCE

包含对话框模板的模块的句柄。如果此参数为NULL,则使用当前可执行文件

由于对话框模板存储在DLL中,因此必须传递标识DLL的
HINSTANCE
。有很多方法可以获得正确的值,但是传递
NULL
GetModuleHandle(NULL)
将不起作用。这两种方法都将模块句柄返回到启动进程的可执行映像(而不是DLL)

简单的解决方案是:选择传递到您的系统中的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或静态库中。唯一的缺点是:它依赖于微软链接器的未记录功能。不过,别担心,它不会默默地失败

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISMODULE ((HINSTANCE)&__ImageBase)
HINST\u此模块将始终保持正确的值,无论在何处使用。1)

同样,也可以使用官方接口()实现。以下解决方案也可以从EXE、DLL或静态库中使用,只要您确保编译函数并将其链接到相应的模块中:

HMODULE GetCurrentModuleHandle() {
    HMODULE hModule = NULL;
    GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                       (LPCTSTR)GetCurrentModuleHandle,
                       &hModule );

    return hModule;
}
这将返回一个
HMODULE
,而不是
HINSTANCE
。但这不是一个问题,因为它们是相同的东西2)


1) 从


2)

错误代码和消息准确无误:在您指示系统查找资源的位置找不到资源:用于启动进程的可执行映像,而不是DLL。行为记录在案(请参阅):

hInstance[输入,可选]

类型:HINSTANCE

包含对话框模板的模块的句柄。如果此参数为NULL,则使用当前可执行文件

由于对话框模板存储在DLL中,因此必须传递标识DLL的
HINSTANCE
。有很多方法可以获得正确的值,但是传递
NULL
GetModuleHandle(NULL)
将不起作用。这两种方法都将模块句柄返回到启动进程的可执行映像(而不是DLL)

简单的解决方案是:选择传递到您的系统中的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或静态库中。唯一的缺点是:它依赖于微软链接器的未记录功能。不过,别担心,它不会默默地失败

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISMODULE ((HINSTANCE)&__ImageBase)
HINST\u此模块将始终保持正确的值,无论在何处使用。1)

同样,也可以使用官方接口()实现。以下解决方案也可以从EXE、DLL或静态库中使用,只要您确保编译函数并将其链接到相应的模块中:

HMODULE GetCurrentModuleHandle() {
    HMODULE hModule = NULL;
    GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                       (LPCTSTR)GetCurrentModuleHandle,
                       &hModule );

    return hModule;
}
这将返回一个
HMODULE
,而不是
HINSTANCE
。但这不是一个问题,因为它们是相同的东西2)


1) 从


2)

您正在将
hInstance
参数中的
NULL
传递给
CreateDialogParam()
。这意味着将在加载DLL的可执行文件中查找对话框资源,而不是在DLL本身中。您应该改为传递与DLL关联的
HINSTANCE
。我尝试使用GetModuleHandle(0)而不是NULL,但没有帮助。那么我如何获得dll的HINSTANCE。它作为第一个参数传递给您的
DllMain()
。好的,如果我没有DllMain()?因为my.dll是从Java代码调用的。他们在java中使用System.LoadLibrary()。这是否会导致运行我的DllMain(),然后我可以将hInstance保存到全局变量并使用它创建对话框?与资源错误无关,
ShowError(GetLastErrorAsString().c_str())是一个等待发生的错误。我假设
GetLastErrorAsString
返回
std::wstring
std::string
。这是临时的,只要
c_str()
返回,它就超出范围。然后将一个悬空指针传递到
ShowError
。将
hInstance
参数中的
NULL
传递到
CreateDialogParam()
。这意味着将在executa中查找对话框资源