目录
模态对话框
模态对话框阻塞父窗口的原因
DialogBox
DialogProc
GetModuleHandle
非模态对话框
CreateDialog
总结
创建的步骤:
对话框过程函数:对话框也属于一个窗口,有自己的过程处理函数。在创建对话框的时候需要绑定过程处理函数。函数作用:处理对话框产生的消息。处理返回TRUE,不处理返回FALSE由系统进行内定处理。
从对话框模板资源创建模式对话框。 在指定的回调函数通过调用 EndDialog 函数终止模式对话框之前,DialogBox 不会返回控件。
void DialogBoxA(
[in, optional] hInstance,
[in] lpTemplate,
[in, optional] hWndParent,
[in, optional] lpDialogFunc
);
参数说明:
返回值:无
代码示例
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
在WM_CLOSE消息处理中,关闭对话框
if (uMsg == WM_CLOSE) {
EndDialog(hwndDlg, 0);
return TRUE;
}
用于用来处理发送到模态或无模型对话框的消息。过程函数,该对话框中的所有消息都通过该过程函数来进行处理。
BOOL CALLBACK DialogProc(
HWND hwndDlg, //指向该对话框的句柄
UINT uMsg, //消息ID
WPARAM wParam, //其他消息
LPARAM lParam //其他消息
);
检索指定模块的模块句柄。 模块必须已由调用进程加载
HMODULE GetModuleHandleA(
[in, optional] LPCSTR lpModuleName
);
加载的模块的名称 (.dll 或 .exe 文件) 。 如果省略文件扩展名,则会追加默认库扩展名 .dll。 文件名字符串可以包含尾随点字符 (.) ,以指示模块名称没有扩展名。 字符串不必指定路径。 指定路径时,请务必使用反斜杠 (\) ,而不是使用 /) (正斜杠。 名称 (大小写独立比较,) 当前映射到调用进程的地址空间的模块的名称。
如果此参数为 NULL, 则 GetModuleHandle 返回用于创建调用进程 (.exe 文件) 的文件的句柄。
创建的步骤:
非模态对话框不会阻塞父窗口的原因:
从对话框模板资源创建无模式对话框。
void CreateDialogA(
[in, optional] hInstance,
[in] lpName,
[in, optional] hWndParent,
[in, optional] lpDialogFunc
);
参数说明:
返回值:无
CreateDialog 将发送WM_INITDIALOG消息,该消息在显示对话框之前立即发送到对话框过程。 对话框过程通常使用此消息来初始化控件并执行影响对话框外观的任何其他初始化任务。
销毁对话框
DestroyWindow(hwndDlg);
代码如下:
#include
#include
#include "resource.h"
HINSTANCE g_hInstance;
INT_PTR CALLBACK DialogProc2(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == WM_CLOSE) {
EndDialog(hwndDlg, 0);
return TRUE;
}
return FALSE;
}
//非模态,模态对话框测试
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_COMMAND:
//OutputDebugString(_T("[51asm] WM_COMMAND\n"));
if (LOWORD(wParam) == ID_SAVE) {
TCHAR szBuf[MAXBYTE];
TCHAR szTitle[MAXWORD];
LoadString(g_hInstance, IDS_SAVE, szBuf, sizeof(szBuf));
LoadString(g_hInstance, IDS_Title, szTitle, sizeof(szTitle));
MessageBox(hwndDlg, szBuf,szTitle, MB_OK);
}
else if (LOWORD(wParam) == IDB_LOGIN) {
//DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG2), NULL, DialogProc);
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG2), hwndDlg, DialogProc2);
}
break;
case WM_INITDIALOG:
OutputDebugString(_T("[51asm] WM_INITDIALOG\n"));
return TRUE;
case WM_CLOSE:
OutputDebugString(_T("[51asm] WM_CLOSE\n"));
//EndDialog(hwndDlg, 0);// 模态对话框需要这个
DestroyWindow(hwndDlg);// 非模态对话框调用这个
return TRUE;
case WM_DESTROY:
OutputDebugString(_T("[51asm] WM_DESTROY\n"));
PostQuitMessage(0);
return TRUE;
}
return FALSE; //交给系统默认处理
}
int WINAPI wWinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nShowCmd)
{
g_hInstance = hInstance;
// 创建模态对话框,只能操作当前窗口
// DialogBox自带有消息循环,里面封装的有消息循环,阻塞
/*DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);*/
// 非模态对话框,也可以操作别的窗口,需要自己写消息处理,类似WinMain
HWND hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
// 加载快捷键资源
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
// 加载菜单资源,模态对话框无法加载快捷键
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
SetMenu(hDlg, hMenu);
ShowWindow(hDlg, SW_SHOWNORMAL);
BOOL bRet;
MSG msg;
// 消息循环是以线程为单位的
while ((bRet = GetMessage(&msg,NULL,0,0)) != 0) {
if (bRet == -1) {
break;
}
else {
if (!TranslateAccelerator(hDlg, hAccel, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
}