AppBar焦点问题
我创建了一个应用程序栏。 AppBar 始终保持在顶部,当它失去焦点时,要返回到 AppBar 需要单击两次而不是一次。我相信第一次单击会激活表单,然后第二次单击我会收到鼠标单击事件(如预期)。你能给出任何想法吗?这里可能出了什么问题?我的问题与此应用栏和焦点问题类似。不幸的是,该链接中的OP尚未发布他的解决方案,悲伤。
我根据 CodeProject 的这篇文章创建了 AppBar C# 执行 Shell,第 3 部分。
我用 Spy++ 调查了它,但不知道为什么会发生这种情况。这是我测试此场景时获得的 Spy++ 日志(第一次单击不起作用,第二次单击起作用)。
<00001> 00090CFE S WM_PARENTNOTIFY fwEvent:WM_LBUTTONDOWN xPos:25 yPos:17
<00002> 00090CFE R WM_PARENTNOTIFY
<00003> 00090CFE S WM_WINDOWPOSCHANGING lpwp:0418EAE4
<00004> 00090CFE R WM_WINDOWPOSCHANGING
<00005> 00090CFE S WM_ACTIVATEAPP fActive:True dwThreadID:00000000
<00006> 00090CFE R WM_ACTIVATEAPP
<00007> 00090CFE S WM_NCACTIVATE fActive:True
<00008> 00090CFE R WM_NCACTIVATE
<00009> 00090CFE S WM_ACTIVATE fActive:WA_CLICKACTIVE fMinimized:False hwndPrevious:(null)
<00010> 00090CFE S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<00011> 00090CFE S WM_IME_NOTIFY dwCommand:IMN_OPENSTATUSWINDOW dwCommand:00000002 dwData:00000000
<00012> 00090CFE R WM_IME_NOTIFY
<00013> 00090CFE R WM_IME_SETCONTEXT
<00014> 00090CFE S WM_SETFOCUS hwndLoseFocus:(null)
<00015> 00090CFE R WM_SETFOCUS
<00016> 00090CFE R WM_ACTIVATE
Now happens the second click (which works)
<00017> 00090CFE S WM_PARENTNOTIFY fwEvent:WM_LBUTTONDOWN xPos:25 yPos:17
<00018> 00090CFE R WM_PARENTNOTIFY
<00019> 00090CFE S WM_WINDOWPOSCHANGING lpwp:0418E40C
<00020> 00090CFE R WM_WINDOWPOSCHANGING
查看 Spy++ 日志,我认为问题在于激活,我认为如果窗口被激活,它只会收到 WM_LBUTTONDOWN 事件。但是为什么其他窗口没有被激活,但它们仍然可以通过单击(即我不必先单击它)来工作。
编辑:我认为问题出在ToolStrip上。我的 AppBar 中有一个 ToolStrip。现在我如何验证这一点?在同一个表单上,我创建了一个按钮并在其单击事件中显示了一个消息框,并且工作正常。现在该如何补救呢?
I have created an AppBar. The AppBar always stays on top, when it loses focus, then to get back to the AppBar requires two clicks instead of one. I believe the first click activates the form and then with second click I receive the mouse click events (as expected). Can you give any ideas, what can be wrong here? My problem is similar to this one Appbar and focus issues. Unfortunately the OP in that link hasn't posted his solution, sad.
I created the AppBar following this article from CodeProject
C# does Shell, Part 3.
I looked into it with Spy++ but don't have any idea why this is happening. Here is the Spy++ log which I obtained testing out this scenario (first click doesn't works, second does).
<00001> 00090CFE S WM_PARENTNOTIFY fwEvent:WM_LBUTTONDOWN xPos:25 yPos:17
<00002> 00090CFE R WM_PARENTNOTIFY
<00003> 00090CFE S WM_WINDOWPOSCHANGING lpwp:0418EAE4
<00004> 00090CFE R WM_WINDOWPOSCHANGING
<00005> 00090CFE S WM_ACTIVATEAPP fActive:True dwThreadID:00000000
<00006> 00090CFE R WM_ACTIVATEAPP
<00007> 00090CFE S WM_NCACTIVATE fActive:True
<00008> 00090CFE R WM_NCACTIVATE
<00009> 00090CFE S WM_ACTIVATE fActive:WA_CLICKACTIVE fMinimized:False hwndPrevious:(null)
<00010> 00090CFE S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<00011> 00090CFE S WM_IME_NOTIFY dwCommand:IMN_OPENSTATUSWINDOW dwCommand:00000002 dwData:00000000
<00012> 00090CFE R WM_IME_NOTIFY
<00013> 00090CFE R WM_IME_SETCONTEXT
<00014> 00090CFE S WM_SETFOCUS hwndLoseFocus:(null)
<00015> 00090CFE R WM_SETFOCUS
<00016> 00090CFE R WM_ACTIVATE
Now happens the second click (which works)
<00017> 00090CFE S WM_PARENTNOTIFY fwEvent:WM_LBUTTONDOWN xPos:25 yPos:17
<00018> 00090CFE R WM_PARENTNOTIFY
<00019> 00090CFE S WM_WINDOWPOSCHANGING lpwp:0418E40C
<00020> 00090CFE R WM_WINDOWPOSCHANGING
Looking at the Spy++ logs, I believe the problem is with activation, I think that it only receives WM_LBUTTONDOWN event if the window is activated. But how come other windows aren't activated but they still work with one click (i.e. I don't have to click it first).
EDIT: I think the problem is with the ToolStrip. I have a ToolStrip in my AppBar. Now how I verified this? Well on the same form I created a button and showed a message box in its click event and it is working fine. Now how to remedy that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我终于弄清楚了(为了后代的利益)这就是发生的事情。问题不在于Form,而是在于ToolStrip(我相信可以在Word中重现)。此功能是设计使然,并非错误。在 WM_MOUSEACTIVATE消息,在 ToolStrip 的 WndProc 中,它返回激活窗口的 MA_ACTIVATEANDEAT,即为其提供焦点,但丢弃鼠标消息,这就是为什么我们必须单击两次,因为第一个鼠标消息被丢弃。
现在解决方案?重写派生类中 ToolStrip 的 WndProc,而不是将 Message.Result 属性设置为 MA_ACTIVATEANDEAT,而是将其设置为 MA_ACTIVATE< /强>。这是有关如何操作的教程。 如何为 .NET 2.0 ToolStrip 和 MenuStrip 启用“点击通过”
希望有帮助:)
Alrighty, I figured it out finally and (in the interest of posterity) this is what's happening. The issue is not with the Form rather with the ToolStrip (can be reproduced in Word, I believe). This feature is by design and not a bug. In the WM_MOUSEACTIVATE message, inside ToolStrip's WndProc, it returns the MA_ACTIVATEANDEAT which activates your window, i.e. gives it focus, but discards the mouse message that's why we have to click twice because the first mouse message is discarded.
Now the solution? Override the WndProc of ToolStrip in your derived class and instead of setting the Message.Result property to MA_ACTIVATEANDEAT, set it to MA_ACTIVATE. Here is a tutorial on how to do it. How to enable "click through" for .NET 2.0 ToolStrip and MenuStrip
Hope that helps :)