更新工具栏按钮状态会窃取另一个窗口的焦点

Posted

技术标签:

【中文标题】更新工具栏按钮状态会窃取另一个窗口的焦点【英文标题】:Updating toolbar button state steals focus of another window 【发布时间】:2012-11-05 16:41:01 【问题描述】:

我正在开发一个 MDI 应用程序,其中更新工具栏按钮会弄乱拖动矩形的绘制。

在 ON_WM_LBUTTONDOWN 中调用 SetCapture(),在 ON_WM_MOUSEMOVE 中更新拖动矩形,在 ON_WM_LBUTTONUP 中擦除矩形并调用 ReleaseCapture()。

大多数情况下,此过程运行良好,但如果在此拖动操作期间,特定工具栏按钮将其状态从启用切换为禁用,则初始窗口会失去焦点并且不会收到 WM_LBUTTONUP。

这里是调用栈的一部分

MyApp.exe!MyWindow::OnCaptureChanged(CWnd * pWnd=0x00000000)
...
mfc90d.dll!CWnd::EnableWindow(int bEnable=0x00000000)  Line 352 + 0x11 bytes C++
mfc90d.dll!CMFCToolBarEditBoxButton::SetStyle(unsigned int nStyle=0x00040000)  Line 470 C++
mfc90d.dll!CMFCToolBar::SetButtonStyle(int nIndex=0x00000001, unsigned int nStyle=0x00040000)  Line 1268 C++
mfc90d.dll!CMFCToolBarCmdUI::Enable(int bOn=0x00000000)  Line 2560 C++
MyApp.exe!MyToolbar::OnUpdateButton(CCmdUI * pCmd=0x0012faa8)
...
mfc90d.dll!CWinApp::OnIdle(long lCount=0x00000000)

由于在软件移至 mfc 功能包之前代码一直在工作,我可以想象原因是工具栏按钮设置错误(例如错误的窗口样式)?

或者我应该在绘制拖动矩形时阻止对 OnIdle 的调用(如果是,是否有一些标准方法可以实现这一点?)。

【问题讨论】:

【参考方案1】:

据我所知,工具栏没有获得焦点。我怀疑您的更新处理程序本身在您的一个窗口上调用EnableWindow。也许你在你的工具栏中放了一个自定义的HWND

【讨论】:

有问题的按钮是CMFCToolBarEditBoxButton(我更新了调用堆栈以澄清这一点)。正如您所指出的,这个按钮可能在内部托管了一些 HWND。现在,我怎样才能避免这个窗口偷走焦点? 使用GetHwnd() 找到HWND 并禁用它。需要时重新启用它。

以上是关于更新工具栏按钮状态会窃取另一个窗口的焦点的主要内容,如果未能解决你的问题,请参考以下文章

如何让我的窗口从另一个在 MacOS 上拖动的窗口中窃取焦点?

更新谷歌地图会从表单元素中窃取焦点

如何防止新的 WPF 表单窃取焦点?

调试开始时停止 Eclipse 窃取焦点

更新工具栏按钮状态 MFC

NSCollectionView 在 selectable=YES 时窃取焦点