回 帖 发 新 帖 刷新版面

主题:dll中对话框的显示问题

我在dll中导出函数中使用了对话框,在exe中调用函数时,对话框却显示不出来(不通过dll导出时函数调用时,对话框可以显示出来),不知道什么原因。我把代码贴出来,大家帮忙看看吧:

#include <windows.h>
#include "resource.h"


#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

BOOL WINAPI DllEntryPoint(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    return TRUE;
}


EXPORT BOOL __cdecl GetPageInfo(HWND hwnd, DEVMODE *lpDevMode, LPRECT lprtMargin)
{
    PAGESETUPDLG psd;

    if(!lpDevMode && !lprtMargin) return FALSE;
    SecureZeroMemory(&psd,sizeof(psd));
    psd.lStructSize = sizeof(psd);
    psd.hwndOwner = hwnd;
    psd.Flags = PSD_INHUNDREDTHSOFMILLIMETERS|PSD_RETURNDEFAULT;
    if(PageSetupDlg(&psd))
    {
        if(psd.hDevMode)
        {
            CopyMemory(lpDevMode,GlobalLock(psd.hDevMode),sizeof(DEVMODE));
            GlobalUnlock(psd.hDevMode);
            GlobalFree(psd.hDevMode); 
        }
        if(psd.hDevNames) GlobalFree(psd.hDevNames);
        if(lprtMargin) *lprtMargin = psd.rtMargin;
        return TRUE;
    }
    return FALSE;
}

EXPORT BOOL __cdecl SetPageInfo(HWND hwnd, DEVMODE *lpDevMode, LPRECT lprtMargin)
{
    PAGESETUPDLG psd;
    HRESULT hResult;

    if(!lpDevMode && !lprtMargin) return FALSE;    
    SecureZeroMemory(&psd,sizeof(psd));
    psd.lStructSize = sizeof(psd);
    psd.hwndOwner = hwnd;
    psd.hInstance = GetModuleHandle(NULL);
    psd.lpPageSetupTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);
    psd.Flags = PSD_INHUNDREDTHSOFMILLIMETERS|PSD_ENABLEPAGESETUPTEMPLATE;
    //psd.Flags = PSD_INHUNDREDTHSOFMILLIMETERS;
    if(lprtMargin)
    {
        psd.Flags |= PSD_MARGINS;
        psd.rtMargin = *lprtMargin;
    }
    if(lpDevMode)
    {        
        psd.hDevMode = GlobalAlloc(GMEM_MOVEABLE,sizeof(DEVMODE));
        if(!psd.hDevMode) return FALSE;
        CopyMemory(GlobalLock(psd.hDevMode),lpDevMode,sizeof(DEVMODE));
        GlobalUnlock(psd.hDevMode);
    }
    if(hResult = PageSetupDlg(&psd))
    {
        if(psd.hDevMode && lpDevMode)
        {
            CopyMemory(lpDevMode,GlobalLock(psd.hDevMode),sizeof(DEVMODE));
            GlobalUnlock(psd.hDevMode);             
        }        
        if(lprtMargin) *lprtMargin = psd.rtMargin;
    }
    if(psd.hDevMode) GlobalFree(psd.hDevMode);
    if(psd.hDevNames) GlobalFree(psd.hDevNames);
    return hResult;
}

回复列表 (共3个回复)

沙发

// Dialog
//

IDD_DIALOG1 DIALOGEX 32, 32, 276, 146
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "页面设置"
FONT 9, "宋体", 400, 0, 0x86
BEGIN
    GROUPBOX        "纸张",grp2,7,5,178,56
    LTEXT           "大小(&Z):",stc2,15,20,32,8
    COMBOBOX        cmb2,50,18,125,150,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    LTEXT           "来源(&S):",stc3,15,40,32,8
    COMBOBOX        cmb3,50,38,125,150,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    GROUPBOX        "方向",grp1,7,63,54,56
    CONTROL         "纵向(&O)",rad1,"Button",BS_AUTORADIOBUTTON,15,77,43,10
    CONTROL         "横向(&A)",rad2,"Button",BS_AUTORADIOBUTTON,15,98,43,10
    GROUPBOX        "页边距(毫米)",grp4,65,63,120,56
    LTEXT           "左(&L):",stc15,73,78,24,8
    EDITTEXT        edt4,98,76,24,12
    LTEXT           "右(&R):",stc16,126,78,24,8
    EDITTEXT        edt6,151,76,24,12
    LTEXT           "上(&T):",stc17,73,100,24,8
    EDITTEXT        edt5,98,98,24,12
    LTEXT           "下(&B):",stc18,126,100,24,8
    EDITTEXT        edt7,151,98,24,12
    GROUPBOX        "预览",grp3,191,5,75,114
    CONTROL         "",rct1,"Static",SS_WHITERECT,205,35,42,59
    CONTROL         "",rct2,"Static",SS_GRAYRECT,252,32,3,65
    CONTROL         "",rct3,"Static",SS_GRAYRECT,205,99,45,3
    DEFPUSHBUTTON   "确定",IDOK,81,124,56,14
    PUSHBUTTON      "取消",IDCANCEL,146,124,56,14
    PUSHBUTTON      "打印机(&P)...",psh3,210,124,56,14
END

板凳

#include <windows.h>
#include <tchar.h>


typedef BOOL (__cdecl * MYPROC1)(HWND, DEVMODE *, LPRECT);

MYPROC1 SetPageInfo,GetPageInfo;


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
    HINSTANCE hInstLib;    
    DEVMODE DevMode;
    RECT rtMargin;

    hInstLib = LoadLibrary(TEXT("DllDialog.dll"));
    if(hInstLib)
    {
        SetPageInfo = (MYPROC1)GetProcAddress(hInstLib, "SetPageInfo");
        GetPageInfo = (MYPROC1)GetProcAddress(hInstLib, "GetPageInfo");

        GetPageInfo(NULL,&DevMode,&rtMargin);
        SetPageInfo(NULL,&DevMode,&rtMargin);
        FreeLibrary(hInstLib); 
    }    
    return 0;
}

3 楼

真失望,没人知道。
这可是dll的常见问题。
不过,在网上查找相关问题几天,加上msdn,终于找到了原因:
GetModuleHandle(NULL)获得的实例句柄是exe文件的,使用dll文件中的资源要使用dll的实例句柄,表示在dll中查找资源(网上有很多dll中使用对话框的,都是MFC的,什么切换模块,都是用的宏,人都晕了,找到最实质的东西就行了,万变不离其宗)。

我来回复

您尚未登录,请登录后再回复。点此登录或注册