windows对话框有以下几种:
HWND CreateDialogParamA([in, optional] HINSTANCE hInstance,[in] LPCSTR lpTemplateName,[in, optional] HWND hWndParent,[in, optional] DLGPROC lpDialogFunc,[in] LPARAM dwInitParam
);
HWND CreateDialogIndirectParamA([in, optional] HINSTANCE hInstance,[in] LPCDLGTEMPLATEA lpTemplate,[in, optional] HWND hWndParent,[in, optional] DLGPROC lpDialogFunc,[in] LPARAM dwInitParam
);
void CreateDialogIndirectA([in, optional] hInstance,[in] lpTemplate,[in, optional] hWndParent,[in, optional] lpDialogFunc
);
void CreateDialogA([in, optional] hInstance,[in] lpName,[in, optional] hWndParent,[in, optional] lpDialogFunc
);
INT_PTR DialogBoxParamA([in, optional] HINSTANCE hInstance,[in] LPCSTR lpTemplateName,[in, optional] HWND hWndParent,[in, optional] DLGPROC lpDialogFunc,[in] LPARAM dwInitParam
);
从winuser.h中可得,CreateDialogA是一个宏,调用了CreateDialogParamA。
#define CreateDialogA(hInstance, lpName, hWndParent, lpDialogFunc) \
CreateDialogParamA(hInstance, lpName, hWndParent, lpDialogFunc, 0L)
#define CreateDialogW(hInstance, lpName, hWndParent, lpDialogFunc) \
CreateDialogParamW(hInstance, lpName, hWndParent, lpDialogFunc, 0L)
#ifdef UNICODE
#define CreateDialog CreateDialogW
#else
#define CreateDialog CreateDialogA
#endif // !UNICODE#define CreateDialogIndirectA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
CreateDialogIndirectParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#define CreateDialogIndirectW(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
CreateDialogIndirectParamW(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#ifdef UNICODE
#define CreateDialogIndirect CreateDialogIndirectW
#else
#define CreateDialogIndirect CreateDialogIndirectA
#endif // !UNICODE
因此,主要有三个函数:
CreateDialogParamACreateDialogIndirectParamADialogBoxParamA
其中,DialogBoxParamA是模态对话框,另外两种是非模态对话框。
模态对话框的意思就是,调用者直接调用就可以创建对话框,不需要像窗口那样分发消息。而非模态对话框需要手动实现消息传递和分发消息。
模态对话框调用后,系统自动提供消息分发机制,程序会自动进入消息分发机制循环,所以程序会卡在这一行。点击关闭按钮后,对话框被销毁,程序从下一行继续运行。我的建议是使用DialogBoxParamA这种模态对话框,消息处理中需要注意的细节太多,可能会有各种意外的发生。
如下代码是非模态对话框的消息分发机制:
MSG msg;while ((ret = GetMessage(&msg, 0, 0, 0)) != 0) {if (ret == -1) {return -1;}if (ret == 0){break;}ret = IsDialogMessage(dialog->m_hwnd, &msg);if (ret){TranslateMessage(&msg);DispatchMessage(&msg);}}
而模态对话框就不需要这样做。
CreateDialogIndirectParamA和CreateDialogParamA的区别在于,CreateDialogIndirectParamA函数需要调用者提供对话框的模板。对话框模板是如下数据结构:
typedef struct {DWORD style;DWORD dwExtendedStyle;WORD cdit;short x;short y;short cx;short cy;
} DLGTEMPLATE;
扩展模板结构如下:
typedef struct {WORD dlgVer;WORD signature;DWORD helpID;DWORD exStyle;DWORD style;WORD cDlgItems;short x;short y;short cx;short cy;sz_Or_Ord menu;sz_Or_Ord windowClass;WCHAR title[titleLen];WORD pointsize;WORD weight;BYTE italic;BYTE charset;WCHAR typeface[stringLen];
} DLGTEMPLATEEX;