如何在不将焦点转移到另一个窗口的情况下显示 MFC 对话框

Posted

技术标签:

【中文标题】如何在不将焦点转移到另一个窗口的情况下显示 MFC 对话框【英文标题】:How to show a MFC dialog without stealing focus on the other window 【发布时间】:2010-01-23 05:41:06 【问题描述】:

我的对话框显示为 ShowWindow(hWnd, SW_SHOWNOACTIVATE); 但是不行,新的对话框还是抢焦点,这是为什么呢?

这是我程序中的一些代码 sn-ps,QueryWindow 是与对话框链接的 MFC 对话框类:

QueryWindow window;
//window.DoModal();
window.Create(QueryWindow::IDD);
window.ShowWindow(SW_SHOWNOACTIVATE);

【问题讨论】:

QueryWindow 有 OnInitDialog 方法吗?如果是这样,请尝试在方法结束时返回 FALSE 而不是 TRUE。 我认为我们需要更多代码来找出问题所在。您可以发布 QueryWindow 源代码吗?什么样的对话? 【参考方案1】:

有几种方法可以跳过对话获得焦点:

让你 OnInitDialog() 返回零值。示例:

BOOL QueryWindow::OnInitDialog()

    CDialog::OnInitDialog();

    return FALSE; // return 0 to tell MFC not to activate dialog window

这是最好最正确的解决方案。

将 WS_EX_NOACTIVATE 样式添加到对话窗口。您可以编辑对话框资源属性或在运行时更改它:

BOOL QueryWindow::PreCreateWindow(CREATESTRUCT& cs)

    cs.dwExStyle |= WS_EX_NOACTIVATE;

    return CDialog::PreCreateWindow(cs);

副作用:您可以在窗口上使用控件,但它看起来好像没有被激活。

最后一种方法是在创建对话框之前保存前景窗口 并在最后设置前景窗口:

BOOL QueryWindow::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)

    CWnd* pForeground = GetForegroundWindow();

    const BOOL bRes = CAlertDialog::Create(lpszTemplateName, pParentWnd);

    if(pForeground)
        pForeground->SetForegroundWindow();
    return bRes;

这是值得的解决方案,因为您可能会得到闪烁。

重要!

不要忘记控制以下 API 调用:

ShowWindow - 您可以使用 SW_SHOWNOACTIVATE,但不能使用 SW_SHOW SetWindowPos - 添加标志 SWP_NOACTIVATE

【讨论】:

非常感谢@Sergey,你拯救了我的一天。这个答案值得更多的赞成票。

以上是关于如何在不将焦点转移到另一个窗口的情况下显示 MFC 对话框的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript / DOM:如果焦点丢失到另一个窗口(应用程序),如何防止模糊事件

将焦点从一个组件转移到另一个组件

如何在不将其添加到目录的情况下在多个团队中安装机器人?

如何在不从当前活动选项卡中获取焦点的情况下将子窗口添加到 QMdiArea(设置为 TAB 模式)?

如何在不将 UIScrollView 的 delaysContentTouches 设置为 NO 的情况下快速点击它时使 UIScrollView 中的按钮突出显示

如何在不将页面滚动条重置为顶部的情况下使用 jQuery 为固定 div 设置动画