ToolStrip有时不响应鼠标点击

时间:2009-01-23 08:59:07

标签: .net winforms toolstrip

我的主表单上有一个带有ToolStrip的.NET 2.0 WinForms应用程序。有时,ToolStrip图标不会响应第一次鼠标单击,因此我必须单击两次图标。它只是一个带有几个图标和工具提示文本的标准ToolStrip,我没有做任何特别的事情。这是常见的吗?

5 个答案:

答案 0 :(得分:22)

我之前遇到过同样的问题,我在Rick Brewster's blog找到了一个解决方案。我们的想法是在派生类ToolStripEx中覆盖'WndProc'。该解决方案的核心如下:

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == NativeConstants.WM_MOUSEACTIVATE &&
        m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT)
    {
        m.Result = (IntPtr)NativeConstants.MA_ACTIVATE;
    }
}

答案 1 :(得分:3)

我已经在其他开发环境(VB6)中使用了它,结果是因为第一次点击被工具栏吸收以获得焦点。或者,换句话说,工具栏不会响应点击,直到它有焦点。要对此进行测试,请在单击按钮之前单击工具栏的空白部分。如果您在单击工具栏后无需在按钮上单击两次,则可能是问题所在。我认为他们绕过它(这是几年前,所以请原谅黑客)是以编程方式将焦点放在MouseOver事件的工具栏中。

答案 2 :(得分:2)

您可以创建自己的继承自ToolStrip的类,并使用自定义属性ClickThrough来打开或关闭行为:

Public Class ToolStripExtended : Inherits ToolStrip
    Private Const WM_MOUSEACTIVATE As UInteger = &H21
    Private Const MA_ACTIVATE As UInteger = 1
    Private Const MA_ACTIVATEANDEAT As UInteger = 2
    Private Const MA_NOACTIVATE As UInteger = 3
    Private Const MA_NOACTIVATEANDEAT As UInteger = 4

    Private _clickThrough As Boolean = False

    Public Sub New()
        MyBase.New()
    End Sub

    ''' <summary>
    ''' Gets or sets whether the ToolStripEx honours item clicks when its containing form does
    ''' not have input focus.
    ''' </summary>
    ''' <remarks>
    ''' Default value is false, which is the same behaviour provided by the base ToolStrip class.
    ''' </remarks>
    Public Property ClickThrough() As Boolean
        Get
            Return Me._clickThrough
        End Get

        Set(value As Boolean)
            Me._clickThrough = value
        End Set
    End Property

    Protected Overrides Sub WndProc(ByRef m As Message)
        MyBase.WndProc(m)

        If _clickThrough AndAlso m.Msg = WM_MOUSEACTIVATE AndAlso m.Result = New IntPtr(MA_ACTIVATEANDEAT) Then
            m.Result = New IntPtr(MA_ACTIVATE)
        End If
    End Sub
End Class

答案 3 :(得分:1)

如果应用程序窗口没有焦点,则必须单击ToolStrip按钮两次。第一次单击将焦点设置为窗口,第二次单击会引发单击事件。这是(不幸的)默认行为,它是设计的。 Microsoft Word显示相同的行为(即使.NET ToolStrip不是相同的控件)。

答案 4 :(得分:0)

这是@Doc Brown解决方案的实现:

public class ToolStripX : ToolStrip
{
    private const int WM_MOUSEACTIVATE = 0x0021;
    private const int MA_ACTIVATEANDEAT = 2;
    private const int MA_ACTIVATE = 1;

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        if (m.Msg == WM_MOUSEACTIVATE &&
            m.Result == (IntPtr)MA_ACTIVATEANDEAT)
        {
            m.Result = (IntPtr)MA_ACTIVATE;
        }
    }
}