【问题标题】:Setting focus to the parent window in the OnShowWindow of the child window doesn't work在子窗口的 OnShowWindow 中设置焦点到父窗口不起作用
【发布时间】:2014-05-14 10:47:46
【问题描述】:

通常我有一些按钮可以打开子窗口,第二次按下这个按钮应该关闭它。我用的是触摸屏。

问题是当我尝试按下关闭子窗口的按钮时,第一次没有按下,所以我需要再次点击。

为了解决这个问题,我试图在打开子窗口后将焦点返回到父窗口。

我注册OnShowWindow消息并在父窗口上调用SetFocus

void CFlashGuidanceSteps::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CDialog::OnShowWindow(bShow, nStatus);
    GetParent()->SetFocus();
}

调用函数时(我可以在调试器中看到),焦点不会返回到父窗口。

但是,它适用于 OnSetFocus 事件:

void CFlashGuidanceSteps::OnSetFocus(CWnd* pOldWnd)
{
    CDialog::OnSetFocus(pOldWnd);
    GetParent()->SetFocus();
}

为什么OnShowWindow 事件没有保留焦点?

【问题讨论】:

    标签: c++ windows winapi mfc focus


    【解决方案1】:

    解释

    MFC 中的通常规则是调用OnXxx 函数以响应类似命名的窗口消息,例如WM_Xxx。所以OnShowWindow 将被调用以响应WM_SHOWWINDOW

    而根据the documentationWM_SHOWWINDOW

    当窗口即将被隐藏或显示时发送到窗口。

    这意味着它是在窗口实际显示之前发送的。因此,当您将焦点设置到 OnShowWindow 函数内的父窗口时,实际上什么都不会发生,因为父窗口已经拥有焦点。然后,OnShowWindow 运行完毕后,子窗口就会显示出来并请求焦点。就好像你从未尝试过改变焦点一样。

    相比之下,对应于WM_SETFOCUSOnSetFocus 直到窗口获得焦点后才被调用。因此,当您在此处重新分配焦点时,它会起作用,因为子窗口不会偷回焦点。

    更好的主意

    这解释了您所看到的行为,并且如您所知,当您在 OnSetFocus 中调整焦点时一切正常。但这确实不是解决问题的最佳方法。

    当窗口获得和/或失去焦点时手动更改焦点会以错误的方式解决问题,并且通常容易出错。你会得到各种难以调试的与焦点相关的错误。你最好寻找一些方法来防止焦点在你不想要的时候改变。

    在我看来,您想阻止子窗口在创建时获得焦点。有一种方法可以做到这一点。

    当您显示子窗口时,大概是通过调用 ShowWindow 函数或其在 MFC 中的道德等效项,您应该传递 SW_SHOWNA 标志。这会导致显示窗口不激活它(即授予它焦点)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多