我的主窗体上有一个带有 ToolStrip 的 .NET 2.0 WinForms 应用程序。有时,ToolStrip 图标不会响应第一次鼠标单击,因此我必须单击该图标两次。它只是一个带有几个图标和工具提示文本的标准 ToolStrip,我没有做任何特别的事情。这很常见吗?
问问题
5731 次
5 回答
25
前段时间我也遇到过同样的问题,我在Rick Brewster 的博客中找到了解决方案。这个想法是在派生类 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;
}
}
于 2009-12-12T10:25:58.010 回答
3
我在其他开发环境(VB6)中也有过这种情况,结果证明是因为第一次单击被工具栏吸收以获取焦点。或者,换句话说,工具栏在获得焦点之前不会响应单击。要对此进行测试,请在单击按钮之前尝试单击工具栏的空白部分。如果您在单击工具栏后不必再单击按钮两次,那么这可能就是问题所在。我认为我解决了这个问题(这是几年前的事了,所以请原谅黑客攻击)是以编程方式将焦点放在 MouseOver 事件中的工具栏上。
于 2009-01-23T09:04:48.130 回答
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
于 2015-11-11T12:44:20.973 回答
0
如果应用程序窗口没有获得焦点,您必须单击 ToolStrip 按钮两次。第一次单击将焦点设置到窗口,第二次引发单击事件。这是(不幸的是)默认行为,这是设计使然。Microsoft Word 显示相同的行为(即使 .NET ToolStrip 不是同一个控件)。
于 2009-01-23T09:20:27.520 回答
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;
}
}
}
于 2020-01-23T20:35:01.073 回答