【问题标题】:Windows requires a click to activate a window before a second click will select a button. How can I change this?Windows 需要单击以激活窗口,然后再单击以选择按钮。我怎样才能改变这个?
【发布时间】:2010-08-06 20:47:23
【问题描述】:

我的应用程序是一个 C# Windows 窗体应用程序,而 .Net 以某种方式使我的主菜单栏和工具条按钮的默认行为是您必须首先单击我的应用程序窗口(任何位置),然后它才会让您单击菜单或工具条按钮。我该如何更改?

记事本和写字板等旧应用程序的行为方式并非如此。但所有 Microsoft Office 应用程序都可以。但这太烦人了!

情况变得更糟,因为我的应用程序会弹出辅助窗口,并且每次我更改窗口时,我都必须先激活爆破窗口,然后才能执行任何操作。啊!

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

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

【问题讨论】:

  • 这听起来像是在使用 Mac OS X 下的任何程序。

标签: .net winforms


【解决方案1】:

好吧,我最终找到了自己的解决方案,它非常简单。我派生了自己的 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 控件仍然会获得鼠标 UP 事件。这启发了我的解决方案。我只是查找缺少相应的 DOWN 事件的任何鼠标 UP 事件。当我看到这种特殊情况时,我生成了自己的鼠标 DOWN 事件,并且对于 ToolStrip 控件,整个世界都很开心。 :-)

【讨论】:

  • 我试过了,效果很好。这也困扰了我一段时间。
  • 我也觉得这种行为真的很烦人而且前后矛盾。 Office 内置控件有什么解决方案吗?
  • 感谢 AZDean。你拯救了我的一天。
【解决方案2】:

简单干净的解决方案

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

        base.OnMouseEnter(e);
    }
}

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      然后,当您单击表单时,无论表单先前是否具有焦点,您都会收到回调。

      然后你就可以模拟你想要的控件的点击了。

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

      【讨论】:

        猜你喜欢
        • 2019-08-27
        • 1970-01-01
        • 1970-01-01
        • 2017-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-10
        相关资源
        最近更新 更多