问题 在第二次单击选择按钮之前,Windows需要单击才能激活窗口。我怎么能改变这个?


我的应用程序是一个C#Windows窗体应用程序和.Net以某种方式使我的主菜单栏和工具条按钮的默认行为是你必须先点击我的应用程序的窗口(任何地方),然后才能让你点击菜单或工具条按钮。我怎么能改变这个?

像记事本和写字板这样的旧应用程序不会这样做。但是所有的Microsoft Office应用程序都可以。但这太烦人了!

它变得更糟,因为我的应用程序弹出辅助窗口,每次我更换窗口时,我必须首先激活爆破窗口,然后我才能做任何事情。啊!

我希望有一些全局方法来改变这种行为,所以我不必单独覆盖许多控件(我没有尝试过)。有人知道吗?

请注意,我的应用程序对话框上的控件不会表现出这种愚蠢的行为。他们为什么不同?


2550
2017-08-06 20:47


起源

这听起来像在Mac OS X下使用任何程序。 - Guttsy


答案:


好吧,我最终找到了自己的解决方案,非常简单。我推导出自己的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控件,世界都很开心。 :-)


13
2017-08-09 19:21



我试过这个,效果很好。这也困扰了我一段时间。 - Isaac Bolinger
我也觉得这种行为真的很烦人且不一致。是否有内置Office控件的解决方案? - Denis Howe
谢谢AZDean。你救了我的一天。 - Jason Ching


简单清洁的解决方案

public class MyToolStrip : System.Windows.Forms.ToolStrip
{
    protected override void OnMouseEnter(EventArgs e)
    {
        if (this.CanFocus && !this.Focused)
            this.Focus();

        base.OnMouseEnter(e);
    }
}

1
2018-05-24 13:53





这似乎是更简单的解决方案:

将MainMenu组件注册到工具箱栏上,(在Visual Studio中,使用菜单“工具”,然后选择“选择工具箱项”,然后找到“MainMenu”),然后在表单而不是MenuStrip上使用它。


0
2018-06-08 00:58





即使应用程序没有焦点,您也可以检测表单上的点击,如果您订阅了 MouseClick 事件。

然后,当您单击表单时,无论表单以前是否具有焦点,您都将获得回调。

然后,您可以模拟所需的控件上的单击。

这不是一个非常优雅的解决方案,但它应该工作。您必须确保点击不会两次发送到工具栏按钮。


-1
2017-08-06 21:35