Loading... 这次的任务仍是创建按钮并响应,不过是在对话框里。用图形界面设计窗口,这将会很有趣。 ## 模态对话框 > 这种对话框强制要求用户回应,否则用户不能再继续进行操作,直到与该对话框完成交互。这种对话框设计用于程序运行必须停下来,直到从用户获得一些额外的信息,然后才可以继续进行的操作,或可能只想确认使用者想要进行一项具有潜在危险性的操作。有模式对话框一般被视为坏的设计方案,因为以一种用户不喜欢看到方式出现,或是被习惯不去注意对话框提示的用户忽略,导致无法避免危险操作。 摘自维基百科 在Visual Studio中创建对话框资源模板,添加并调整控件  然后打开`视图/工具箱`,选择要添加的控件 添加完成后,选中控件,右键打开属性,即可编辑。在这里可以调整控件的外观,ID等  接下来看cpp,我们只需要在WinMain中调用`DialogBox`函数。请注意这个函数的第二个参数,是`LPCWSTR`类型或`LPCTSTR`类型,据设置而定。一般需要类型转换:强制类型转换或使用`MAKEINTRESOURCEA`宏。 详见[官方文档](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dialogboxa) Dlgproc回调函数如果处理了消息,则应返回TRUE,否则应返回FALSE。 需要注意的是,当模态对话框被创建时会传出`WM_INITDIALOG`消息。当用户关闭这个模态对话框会传出`IDCANCEL`消息,此时销毁模态对话框应该用`EndDialog`函数而非`PostQuitMessage`! 具体请见下方代码或自行查阅官方文档。此处只列出代码,省略了对话框资源模板 ``` #include <windows.h> #include <tchar.h> #include "resource.h" INT_PTR WINAPI Dlgproc(HWND, UINT, WPARAM, LPARAM); int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DialogBox(hInstance, (LPCWSTR)IDD_DIALOG1, NULL, Dlgproc); return 0; } INT_PTR WINAPI Dlgproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BUTTON1: MessageBox(hwnd, L"按钮1 向你致敬", L"提示", MB_OK); break; case IDC_BUTTON2: MessageBox(hwnd, L"按钮2 向你致敬", L"提示", MB_OK); break; case IDCANCEL: EndDialog(hwnd, 0); break; default: break; } return TRUE; } break; } return FALSE; } ``` ## 非模态对话框 > 这是一种非强制回应的对话框,用于向用户请求非必须资料。即可以不理会这种对话框或不向其提供任何信息而继续进行当前工作,所以窗口均可打开并处于活动状态或是获得焦点(人机交互热点)。一类无模式对话框表现为工具栏,比如设置用于文字颜色的设置。查找/替换对话框可算是无模式对话框,也可以设计为工具栏。 摘自维基百科 非模态对话框和模态对话框有许多共通之处,这里不再多赘述。 注意:在处理`IDCANCEL`消息时使用`DestroyWindow`函数销毁非模态对话框,但进程可能并不会退出。所以同时使用`PostQuitMessage`函数 ``` #include <windows.h> #include <tchar.h> #include "resource.h" INT_PTR CALLBACK Dlgproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BUTTON1: MessageBox(hwnd, L"按钮1 向你致敬", L"提示", MB_OK); break; case IDC_BUTTON2: MessageBox(hwnd, L"按钮2 向你致敬", L"提示", MB_OK); break; case IDCANCEL: DestroyWindow(hwnd); PostQuitMessage(0); break; default: break; } return TRUE; } break; } return FALSE; } int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND dlghwnd = CreateDialog(NULL, (LPCWSTR)IDD_DIALOG1, NULL, Dlgproc); ShowWindow(dlghwnd, SW_SHOW); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessageW(&msg); } return 0; } ``` ## 对话框和窗口对比 1. 窗口创建 * 模态对话框-DialogBox函数,是一个阻塞函数 * 非模态对话框-CreateDialog * 普通窗口-CreateWindow/CreateWindowEx 2. 窗口处理函数 * 对话框-DlgProc,被缺省的对话框窗口处理函数调用 * 普通窗口-WndProc,需要调用缺省的窗口处理函数(DefWindowProc) 3. 窗口初始化消息 * 对话框-WM_INITDIALOG * 普通窗口-WM_CREATE 4. 窗口关闭 * 模态对话框-EndDialog * 非模态对话框-DestroyWindow © 允许规范转载 赞赏 如果我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 微信支付