win32模态与非模态对话框

10 篇文章 0 订阅

一、模态对话框与非模态对话框的区别

使用DialogBox、DialogBoxIndirect、DialogBoxParam、DialogBoxIndirectParam创建模态对话框时,系统会首先将此模态窗口的父窗口disable掉,然后启动和运行一个消息循环,接受和拆分消息。在EndDialog调用时结束消息循环,设置结束模式对话框的返回值,销毁窗口。
使用CreateDialog、CreateDialogIndirect、CreateDialogParam、CreateDialogIndirectParam创建非模态对话框时,不会在内部启动消息循环,而是创建了非模态对话框之后就立刻返回。需要使用DestroyWindow来销毁对话框。

msdn里对于DialogBoxParam函数实现模态对话框的一些描述,如下所示:

// MSDN Remarks
The DialogBoxParam function uses the CreateWindowEx function to create the dialog box. DialogBoxParam then sends a WM_INITDIALOG message to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and starts its own message loop to retrieve and dispatch messages for the dialog box.

When the dialog box procedure calls the EndDialog function, DialogBoxParam destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the value of the nResult parameter specified by the dialog box procedure when it called EndDialog.

Windows Embedded CE does not support all styles in the DLGTEMPLATE structure. This structure is in the template identified by the lpTemplate parameter*.*
二、模拟实现模态窗口

但是如果需要在win32里直接将一个窗口模态显示,没有找到现成的API,于是只能参照msdn里对以上几个api在模态下执行的操作自己来实现了。

1. 非阻塞的方式实现窗口的模态
void DoModal(HWND hwnd) {
    HWND hParentWnd = GetParent(hwnd);
    while (hParentWnd != NULL) {
        EnableWindow(hParentWnd, FALSE);
        hParentWnd = GetParent(hParentWnd);
    }
    ShowWindow(hwnd, SW_SHOW);
    BringWindowToTop(hWnd);
}

void EndModal(HWND hwnd) {
    HWND hParentWnd = GetParent(hwnd);
    while (hParentWnd != NULL) {
        EnableWindow(hParentWnd, TRUE);
        hParentWnd = GetParent(hParentWnd);
    }
    ShowWindow(hwnd, SW_HIDE);
}
2. 阻塞的方式实现窗口的模态

static int nReturnCode = -1; // 退出状态码
static bool isBlocking = false; // 是否阻塞
int BlockDlgDoModal(HWND hWnd) {
    isBlocking = TRUE;
    DoModal(hWnd);

    //消息循环
    while (isBlocking) {
        MSG msg;
        if (!GetMessage(&msg, NULL, 0, 0))
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    //退出阻塞,恢复状态
    EndModal(hWnd);
    return nReturnCode;
}

void BlockDlgEndModal(int nCode) {
    nReturnCode = nCode;
    isBlocking = FALSE;
    PostMessage(NULL, WM_NULL, 0, 0);
}

对话框相关的一些参考链接:

Using Dialog Boxes
DialogBoxParam

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值