我的应用程序是一个C#Windows窗体应用程序,.Net以某种方式使我的主菜单栏和工具条按钮的默认行为是你必须先点击我的应用程序的窗口(任何地方),然后它才会让你点击菜单或工具条按钮。我怎么能改变这个?
记事本和写字板等旧应用程序不会这样做。但是所有的Microsoft Office应用程序都可以。但这太烦人了!
它变得更糟,因为我的应用程序弹出辅助窗口,每次我更换窗口时,我必须首先激活爆破窗口才能做任何事情。啊!
我希望有一些全局方法可以改变这种行为,所以我不必单独覆盖很多控件(我没试过)。有人知道吗?
请注意,我应用的对话框上的控件不会出现这种愚蠢的行为。他们为什么不同?
答案 0 :(得分:15)
好吧,我最终找到了自己的解决方案,非常简单。我得到了我自己的ToolStrip类(和MenuStrip类),如下所示:
// This version of ToolStrip enables mouse click's even when the main form is NOT active.
private class MyToolStrip : ToolStrip
{
const uint WM_LBUTTONDOWN = 0x201;
const uint WM_LBUTTONUP = 0x202;
static private bool down = false;
protected override void WndProc(ref Message m)
{
if (m.Msg==WM_LBUTTONUP && !down) {
m.Msg=(int)WM_LBUTTONDOWN; base.WndProc(ref m);
m.Msg=(int)WM_LBUTTONUP;
}
if (m.Msg==WM_LBUTTONDOWN) down=true;
if (m.Msg==WM_LBUTTONUP) down=false;
base.WndProc(ref m);
}
}
看起来,就像Mac OS X一样,Windows做出了GUI样式决定,要求首先激活一个窗口,然后才允许选择任何控件。但是,Windows仅对特定控件执行此操作,如ToolStrip和MenuStrip。当您的窗口未激活时,这些控件不会发送鼠标DOWN事件。我不确定WinForms如何强制执行此GUI指南,但它可能使用Application.AddMessageFilter()来使用消息过滤器。
无论如何,MenuStrip控制STILL获取鼠标UP事件。这激发了我的解决方案。我只是查找任何缺少它的相应DOWN事件的鼠标UP事件。当我看到这个特殊的情况时,我生成了自己的鼠标DOWN事件,而对于ToolStrip控件,世界都很开心。 : - )
答案 1 :(得分:1)
简单易用的解决方案
public class MyToolStrip : System.Windows.Forms.ToolStrip
{
protected override void OnMouseEnter(EventArgs e)
{
if (this.CanFocus && !this.Focused)
this.Focus();
base.OnMouseEnter(e);
}
}
答案 2 :(得分:0)
这似乎是更简单的解决方案:
将MainMenu组件注册到工具箱栏上,(在Visual Studio中,使用菜单“工具”,然后选择“选择工具箱项”,然后找到“MainMenu”),然后在表单而不是MenuStrip上使用它。
答案 3 :(得分:-1)
如果您订阅了MouseClick
活动,即使应用程序没有焦点,您也可以检测到表单上的点击。
然后,当您点击表单时,无论表单以前是否有焦点,您都会收到回调。
然后,您可以模拟您想要的控件上的单击。
这不是一个非常优雅的解决方案,但它应该有效。您必须确保点击不会两次发送到工具栏按钮。