C# toolstrip在父窗体失去焦点时,点击里面的按钮无效

cresource 2009-10-30 03:08:58
第一次点击使父窗体获得焦点,第二次点击才真正引发toolstrip里面的按钮click事件,有没有什么办法让它一点就引发click.

要点两次才行,太不符合习惯了.其它标准按钮文本框什么控件,都是点一次就OK了.
...全文
476 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
rqx110 2011-07-25
  • 打赏
  • 举报
回复
/////////////////////////////////////////////
// Jim Hollenhorst, February 4, 2006
// www.ultrapico.com
// Feel free to duplicate and distribute
// Kudos to Rick Brewster and JasonD
/////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace ToolStripExtensions
{
//
// The ToolStrip and MenuStrip classes are extended to allow customization of the user interface
//
// The following new boolean properties are exposed in the designer:
//
// ClickThrough - Allow the first click to activate the control, even when the containing form is not active
// SupressHighlighting - Suppress the mouseover highlighting of the control when the containing form is not active
//
// The ideas behind this were borrowed from two items found on the Internet:
//
// Rick Brewster shows how to implement ClickThrough on his blog at:
// http://blogs.msdn.com/rickbrew/
//
// JasonD suggests the method to suppress the highlighting on at forum at:
// http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=118385&SiteID=1
//

/// <summary>
/// Define some Windows message constants
/// </summary>
public class WinConst
{
public const uint WM_MOUSEMOVE = 0x0200;
public const uint WM_MOUSEACTIVATE = 0x21;
public const uint MA_ACTIVATE = 1;
public const uint MA_ACTIVATEANDEAT = 2;
public const uint MA_NOACTIVATE = 3;
public const uint MA_NOACTIVATEANDEAT = 4;
}

/// <summary>
/// This class adds to the functionality provided in System.Windows.Forms.MenuStrip.
///
/// It allows you to "ClickThrough" to the MenuStrip so that you don't have to click once to
/// bring the form into focus and once more to take the desired action
///
/// It also implements a SuppressHighlighting property to turn off the highlighting
/// that occures on mouseover when the form is not active
/// </summary>
public class MenuStripEx : MenuStrip
{
private bool clickThrough = false;
private bool suppressHighlighting = true;

/// <summary>
/// Gets or sets whether the control honors item clicks when its containing form does
/// not have input focus.
/// </summary>
/// <remarks>
/// Default value is false, which is the same behavior provided by the base ToolStrip class.
/// </remarks>
public bool ClickThrough
{
get { return this.clickThrough; }
set { this.clickThrough = value; }
}

/// <summary>
/// Gets or sets whether the control shows highlighting on mouseover
/// </summary>
/// <remarks>
/// Default value is true, which is the same behavior provided by the base MenuStrip class.
/// </remarks>
public bool SuppressHighlighting
{
get { return this.suppressHighlighting; }
set { this.suppressHighlighting = value; }
}

/// <summary>
/// This method overrides the procedure that responds to Windows messages.
///
/// It intercepts the WM_MOUSEMOVE message
/// and ignores it if SuppressHighlighting is on and the TopLevelControl does not contain the focus.
/// Otherwise, it calls the base class procedure to handle the message.
///
/// It also intercepts the WM_MOUSEACTIVATE message and replaces an "Activate and Eat" result with
/// an "Activate" result if ClickThrough is enabled.
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
// If we don't want highlighting, throw away mousemove commands
// when the parent form or one of its children does not have the focus
if(m.Msg == WinConst.WM_MOUSEMOVE && this.suppressHighlighting && !this.TopLevelControl.ContainsFocus)
return;
else
base.WndProc(ref m);

// If we want ClickThrough, replace "Activate and Eat" with "Activate" on WM_MOUSEACTIVATE messages
if(m.Msg == WinConst.WM_MOUSEACTIVATE && this.clickThrough && m.Result == (IntPtr)WinConst.MA_ACTIVATEANDEAT)
m.Result = (IntPtr)WinConst.MA_ACTIVATE;
}
}

/// <summary>
/// This class adds to the functionality provided in System.Windows.Forms.ToolStrip.
///
/// It allows you to "ClickThrough" to the MenuStrip so that you don't have to click once to
/// bring the form into focus and once more to take the desired action
///
/// It also implements a SuppressHighlighting property to turn off the highlighting
/// that occures on mouseover when the form is not active
/// </summary>
public class ToolStripEx : ToolStrip
{
private bool clickThrough = false;
private bool suppressHighlighting = true;

/// <summary>
/// Gets or sets whether the control honors item clicks when its containing form does
/// not have input focus.
/// </summary>
/// <remarks>
/// Default value is false, which is the same behavior provided by the base ToolStrip class.
/// </remarks>
public bool ClickThrough
{
get { return this.clickThrough; }
set { this.clickThrough = value; }
}

/// <summary>
/// Gets or sets whether the control shows highlighting on mouseover
/// </summary>
/// <remarks>
/// Default value is true, which is the same behavior provided by the base MenuStrip class.
/// </remarks>
public bool SuppressHighlighting
{
get { return this.suppressHighlighting; }
set { this.suppressHighlighting = value; }
}

/// <summary>
/// This method overrides the procedure that responds to Windows messages.
///
/// It intercepts the WM_MOUSEMOVE message
/// and ignores it if SuppressHighlighting is on and the TopLevelControl does not contain the focus.
/// Otherwise, it calls the base class procedure to handle the message.
///
/// It also intercepts the WM_MOUSEACTIVATE message and replaces an "Activate and Eat" result with
/// an "Activate" result if ClickThrough is enabled.
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
// If we don't want highlighting, throw away mousemove commands
// when the parent form or one of its children does not have the focus
if(m.Msg == WinConst.WM_MOUSEMOVE && this.suppressHighlighting && !this.TopLevelControl.ContainsFocus)
return;
else
base.WndProc(ref m);

// If we want ClickThrough, replace "Activate and Eat" with "Activate" on WM_MOUSEACTIVATE messages
if(m.Msg == WinConst.WM_MOUSEACTIVATE && this.clickThrough && m.Result == (IntPtr)WinConst.MA_ACTIVATEANDEAT)
m.Result = (IntPtr)WinConst.MA_ACTIVATE;
}
}
}
sillyhennry 2011-07-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 cresource 的回复:]

引用 2 楼 foxdave 的回复:
LS正解

这也叫正解?那么多按钮,你说模拟点击那个好?

google回来的正解:
http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.windowsforms/2006-12/msg00401.html

C# code

c……
[/Quote]
谢谢3楼,3楼才是正解!
cresource 2009-10-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 foxdave 的回复:]
LS正解
[/Quote]
这也叫正解?那么多按钮,你说模拟点击那个好?

google回来的正解:
http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.windowsforms/2006-12/msg00401.html


class ToolStripEx : ToolStrip
{
protected override void WndProc(ref Message m)
{
const int WM_MOUSEACTIVATE = 0x21;

if (m.Msg == WM_MOUSEACTIVATE && this.CanFocus && !this.Focused)
this.Focus();

base.WndProc(ref m);
}
}
Justin-Liu 2009-10-30
  • 打赏
  • 举报
回复
LS正解
nnghp 2009-10-30
  • 打赏
  • 举报
回复
在form获取焦点的事件中调用toolstrip的click事件就行了

111,111

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧