windows对话框
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
因此,主要有三个函数:
CreateDialogParamA
CreateDialogIndirectParamA
DialogBoxParamA
其中,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;