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

Setting focus to the parent window in the OnShowWindow of the child window doesn't work

本文关键字:窗口 设置 焦点 不起作用 OnShowWindow      更新时间:2023-10-16

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

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

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

我注册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事件上?

说明

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

根据文档,WM_SHOWWINDOW

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

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

相比之下,OnSetFocus对应于WM_SETFOCUS,直到窗口获得焦点后才调用。所以当你在这里重新分配焦点时,它会工作,因为子窗口不会把焦点偷回来。

更好的主意

这解释了你所看到的行为,如你所知,当你调整OnSetFocus的焦点时,事情会很好。但这真的不是解决问题的最好方法。

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

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

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