Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ToolStrip sometimes not responding to a mouse click

I have a .NET 2.0 WinForms application with a ToolStrip on my main form. Sometimes, the ToolStrip icons don't respond to the first mouse click, so I have to click the icon twice. It's just a standard ToolStrip with several icons and tooltip texts, I don't do anything special. Is this common?

like image 608
user20353 Avatar asked Jan 23 '09 08:01

user20353


2 Answers

I had the same problem some times ago, and I found a solution in Rick Brewster's blog. The idea is to overwrite 'WndProc' in a derived class ToolStripEx. The core of that solution looks like this:

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;
    }
}
like image 149
Doc Brown Avatar answered Sep 19 '22 15:09

Doc Brown


You can create your own class that inherits from the ToolStrip and use a custom property ClickThrough to switch the behaviour on or off:

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
like image 26
Matt Wilko Avatar answered Sep 17 '22 15:09

Matt Wilko