无模态对话框
来源:互联网 发布:阿里云 开发主机 编辑:程序博客网 时间:2024/06/05 23:41
现在来看看CreateDialog(),它是DialogBox()的姐妹函数.区別在于DialogBox()拥有自己的消息循环并且直到对话框关闭才返回,CreateDialog()则更加像CreateWindowEx()创建的一个窗口,立即返回并向你的消息循环发送消息,就像是你的主窗口发的消息样.这就是所谓的无模态,而DialogBox()创建的是模态对话框.
创建的资源如下:
IDD_TOOLBAR DIALOGEX 0, 0, 98, 52STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTIONEXSTYLE WS_EX_TOOLWINDOWCAPTION "My Dialog Toolbar"FONT 8, "MS Sans Serif"BEGIN PUSHBUTTON "&Press This Button",IDC_PRESS,7,7,84,14 PUSHBUTTON "&Or This One",IDC_OTHER,7,31,84,14END
你可以看到资源编辑器把DIALOG換成了DIALOGEX表明我们要为我们的对话框设置扩展风格.
接下来想在程序运行的时候创建对话框,想要对话框可视,所以在WM_CREATE的消息处理中创建它.我们也需要声明一个全局变量来保持从CreateDialog()返回的窗口句柄以便在后面使用它.DialogBox()不向我们返回句柄因为DialogBox()在窗口销毀的时候才返回.
HWND g_hToolbar = NULL; case WM_CREATE: g_hToolbar = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_TOOLBAR), hwnd, ToolDlgProc); if(g_hToolbar != NULL) { ShowWindow(g_hToolbar, SW_SHOW); } else { MessageBox(hwnd, "CreateDialog returned NULL", "Warning!", MB_OK | MB_ICONINFORMATION); } break;
要检查返回值,这什么时候总是一个好的习惯,如果是正确的(不为NULL)我们就用ShowWindow()来显示这个窗口,要是用DiaglogBox(),这一步就是不必要的,因为系统为我们调用了ShowWindow().
现在我需要为工具栏写一个对话过程.
BOOL CALLBACK ToolDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){ switch(Message) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_PRESS: MessageBox(hwnd, "Hi!", "This is a message", MB_OK | MB_ICONEXCLAMATION); break; case IDC_OTHER: MessageBox(hwnd, "Bye!", "This is also a message", MB_OK | MB_ICONEXCLAMATION); break; } break; default: return FALSE; } return TRUE;}
大多数适用于DialogBox()的消息处理规则也适用于CreateDialog(),不调用DefWindowProc(),对不处理的消息返回FALSE,处理的返回TRUE.
有个攺变就是不为无模态窗口调用EndDialog(),可以像对常规的窗口一样调用DestroyWindow().在主窗口的WndProc()中这样写...
case WM_DESTROY: DestroyWindow(g_hToolbar); PostQuitMessage(0); break;
还有一点,希望在任何时候显示或隠藏我们的工具栏,所以我在菜单上加上了两个命令来做这件事情,并这样处理:
case WM_COMMAND: switch(LOWORD(wParam)) { case ID_DIALOG_SHOW: ShowWindow(g_hToolbar, SW_SHOW); break; case ID_DIALOG_HIDE: ShowWindow(g_hToolbar, SW_HIDE); break; //... other command handlers } break;
如果在此时运行你的程序并试图在两个按钮间切換的话,就会注意到不行,按Alt+P和Alt+O来激活按钮都不行.为什么? 因为DialogBox()有自己的消息循环并默认地处理这些事件,CreateDialog()卻沒有.但是可以通过在消息循环中调用可以为做默认处理的IsDialogMessage()来自己处理它们.
while(GetMessage(&Msg, NULL, 0, 0)) { if(!IsDialogMessage(g_hToolbar, &Msg)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } }
这里我们首先将消息传给IsDialogMessage(),如果消息是为工具栏的(由我们传进的窗口的句柄来指示),系统就作默认的处理并返回TRUE.这种情況下消息已经被处理了所以我们不需要再调用TranslateMessage()或DispatchMessage()了.如果消息是为另外一个窗口就照常处理.
值得提出来的是IsDialogMessage()也可以用于不是对话框的窗口来给它们一些像对话框的功能.记住,对话框就是一个窗口,并且大多数(如果不是全部的话)对话框的API可以工作于任何窗口.
贴个完整的代码吧 有点长:
资源文件的建立如上。
#include <windows.h>#define IDD_TOOLBAR 101#define IDC_OTHER 9003#define IDC_PRESS 9004#define ID_DIALOG_SHOW 9005#define ID_DIALOG_HIDE 9006HWND g_hToolbar = NULL;const char g_szClassName[] = "myWindowClass";BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){switch(Message){case WM_INITDIALOG:return TRUE;case WM_COMMAND:switch(LOWORD(wParam)){case IDC_PRESS:MessageBox(hwnd,"you press a button!","this is message",MB_OK | MB_ICONINFORMATION);break;case IDC_OTHER:MessageBox(hwnd,"you press a other button!","this is message",MB_OK | MB_ICONINFORMATION);case IDOK:EndDialog(hwnd, IDOK);break;case IDCANCEL:EndDialog(hwnd, IDCANCEL);break;}break;default:return FALSE;}return TRUE;}LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_CREATE:{HMENU hmenu,hSubMenu;hmenu = CreateMenu();hSubMenu = CreatePopupMenu();AppendMenu(hSubMenu,MF_STRING,ID_DIALOG_SHOW,"&Show");AppendMenu(hSubMenu,MF_STRING,ID_DIALOG_HIDE,"&Hide");AppendMenu(hmenu,MF_STRING | MF_POPUP,(UINT)hSubMenu,"&Dialog");SetMenu(hwnd,hmenu);g_hToolbar = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_TOOLBAR),hwnd,AboutDlgProc);if(g_hToolbar != NULL)ShowWindow(g_hToolbar,SW_HIDE);elseMessageBox(hwnd,"CreateDialog return NULL","Warning",MB_OK | MB_ICONINFORMATION);}break;case WM_COMMAND:switch(LOWORD(wParam)){case ID_DIALOG_SHOW:ShowWindow(g_hToolbar, SW_SHOW);break;case ID_DIALOG_HIDE:ShowWindow(g_hToolbar, SW_HIDE);break;}break;case WM_LBUTTONDOWN:{char szFileName[MAX_PATH];HINSTANCE hInstance = GetModuleHandle(NULL);GetModuleFileName(hInstance, szFileName, MAX_PATH);MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);}break;case WM_CLOSE:DestroyWindow(hwnd);break;case WM_DESTROY:DestroyWindow(g_hToolbar);PostQuitMessage(0);break;default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){WNDCLASSEX wc;HWND hwnd;MSG Msg;wc.cbSize = sizeof(WNDCLASSEX);wc.style = 0;wc.lpfnWndProc = WndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.lpszMenuName = NULL;wc.lpszClassName = g_szClassName;wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);if(!RegisterClassEx(&wc)){MessageBox(NULL, "Window Registration Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;}hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"The title of my window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,NULL, NULL, hInstance, NULL);if(hwnd == NULL){MessageBox(NULL, "Window Creation Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);return 0;}ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);while(GetMessage(&Msg, NULL, 0, 0) > 0){if(!IsDialogMessage(g_hToolbar,&Msg)){TranslateMessage(&Msg);DispatchMessage(&Msg);}}return Msg.wParam;}
- 无模态对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 对话框
- 字符串实现四则运算
- smarty 的模版配置文件的使用
- 刚刚弄明白,原来block是回调的
- Java Concurrency / Multithreading - Tutorial
- CSS中Position的属性介绍
- 无模态对话框
- 构建高性能ASP.NET站点 网站优化需要考虑的方面二
- 面向对象的三个基本特征
- 中国移动如何用Java做开发
- oracle的oci和thin区别
- UTF8编码字符串转换成Unicode编码字符串算法
- Tracer Example
- 开始在CSDN扎根,以后和大牛们为伍
- CDC、CClientDC、CPaintDC、CWindowDC区别及相关操作