【问题标题】:How to show a MFC dialog without stealing focus on the other window如何在不将焦点转移到另一个窗口的情况下显示 MFC 对话框
【发布时间】: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 源代码吗?什么样的对话?

标签: c++ mfc


【解决方案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,你拯救了我的一天。这个答案值得更多的赞成票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
相关资源
最近更新 更多