将焦点设置到子窗口的OnShowWindow中的父窗口不起作用

时间:2014-05-14 10:47:46

标签: c++ windows winapi mfc focus

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

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

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

我注册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事件不会保留焦点?

1 个答案:

答案 0 :(得分:1)

解释

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

根据the documentationWM_SHOWWINDOW

  

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

这意味着在窗口实际显示之前发送。因此,当您将焦点设置到OnShowWindow函数内的父窗口时,实际上没有任何事情发生,因为父窗口已经具有焦点。然后,在OnShowWindow完成运行后,将显示子窗口并要求焦点。就好像你从未试图改变焦点一样。

相比之下,OnSetFocus对应WM_SETFOCUS,在窗口获得焦点之后才被调用。因此,当你在这里重新分配焦点时,它会起作用,因为子窗口不会将焦点移回。

更好的主意

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

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

听起来我想要防止子窗口在创建时获得焦点。而且有一种方法可以做到这一点。

当你显示子窗口时,可能是通过在MFC中调用ShowWindow函数或其道德等价物,你应该传递SW_SHOWNA标志。这会导致窗口显示而不用激活它(即授予它焦点)。