当前位置:编程学习 > C/C++ >>

无模态对话框

现在来看看CreateDialog(),它是DialogBox()的姐妹函数.区別在于DialogBox()拥有自己的消息循环并且直到对话框关闭才返回,CreateDialog()则更加像CreateWindowEx()创建的一个窗口,立即返回并向你的消息循环发送消息,就像是你的主窗口发的消息样.这就是所谓的无模态,而DialogBox()创建的是模态对话框.
  创建的资源如下:
[cpp] 
IDD_TOOLBAR DIALOGEX 0, 0, 98, 52 
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION 
EXSTYLE WS_EX_TOOLWINDOW 
CAPTION "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,14 
END 
  你可以看到资源编辑器把DIALOG換成了DIALOGEX表明我们要为我们的对话框设置扩展风格.
  接下来想在程序运行的时候创建对话框,想要对话框可视,所以在WM_CREATE的消息处理中创建它.我们也需要声明一个全局变量来保持从CreateDialog()返回的窗口句柄以便在后面使用它.DialogBox()不向我们返回句柄因为DialogBox()在窗口销毀的时候才返回.
[cpp] view plaincopyprint?
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().
  现在我需要为工具栏写一个对话过程.
[cpp]
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()中这样写...
[cpp]

case WM_DESTROY: 
    DestroyWindow(g_hToolbar); 
    PostQuitMessage(0); 
break; 
  还有一点,希望在任何时候显示或隠藏我们的工具栏,所以我在菜单上加上了两个命令来做这件事情,并这样处理:
[cpp] view plaincopyprint?
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()来自己处理它们.
[cpp]
while(GetMessage(&Msg, NULL, 0, 0)) 

    if(!IsDialogMessage(g_hToolbar, &Msg)) 
    { 
        TranslateMessage(&Msg); 
        DispatchMessage(&Msg); 
    } 

  这里我们首先将消息传给IsDialogMessage(),如果消息是为工具栏的(由我们传进的窗口的句柄来指示),系统就作默认的处理并返回TRUE.这种情況下消息已经被处理了所以我们不需要再调用TranslateMessage()或DispatchMessage()了.如果消息是为另外一个窗口就照常处理.
  值得提出来的是IsDialogMessage()也可以用于不是对话框的窗口来给它们一些像对话框的功能.记住,对话框就是一个窗口,并且大多数(如果不是全部的话)对话框的API可以工作于任何窗口.
贴个完整的代码吧 有点长:
资源文件的建立如上。
[cpp]
#include <windows.h> 
#define IDD_TOOLBAR                     101 
#define IDC_OTHER 9003 
#define IDC_PRESS   9004 
#define ID_DIALOG_SHOW 9005 
#define ID_DIALOG_HIDE 9006 
 
HWND 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: 
          &n

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,