![]() |
1
4
根据 this thread ,一个标准的Windows GroupBox(即具有b_GroupBox样式的按钮控件)似乎返回httransparent以响应wm_nchittest。因为控件声称是透明的,所以Windows会将鼠标移动事件发送到其父窗口。 线程确认,如果您自己处理wm-nchittest并返回htclient,那么groupbox将获得鼠标移动事件。他们使用的是MFC,但它可能也适用于WinForms。 不清楚的是 为什么? 默认情况下,Windows返回httransparent,但至少已独立确认问题。 |
![]() |
2
2
您可以通过Reflector看到这个,key属性是createParams和内部ownerDraw属性。GroupBox通常在ownerDraw=true的情况下工作,除非设置了flatStyle=system。然后你会得到一个老式的Windows分组框,一个类名为button的窗口,其b_GroupBox样式位被打开。 如果你用spy++,你会发现控件根本没有收到任何鼠标信息。不知道为什么会这样,sdk文档没有提到它。我想这可以追溯到Windows2.x,在那里每一个周期都计算在内。但它确实解释了为什么mousemove事件是隐藏的,当选择系统样式时它不能启动。单击和向上/向下相同。flatStyle属性设置器也通过关闭control.userMouse控件样式来将其固定下来。 总之,如果你想要鼠标信息,你需要避免系统风格。 |
![]() |
3
0
分组框是一个静态控件,其中包含其他控件。它的设计纯粹是为了将事物“分组”在一起,以便在布局正确时使用户界面直观。因此,可以代表GroupBox使用的事件很少。 您可以创建继承自GroupBox的新类,并将其子类化以截获鼠标移动事件。我以前使用过一个非常有用的类,它非常容易执行子类化并触发mousemove事件。
看看这个
here
要了解子类化是如何工作的……好吧,它是用vb.net编写的,但是很容易将其转换为c如果您愿意,我想象的代码如下所示:
编辑: 作为对JoeWhite的评论的回应,我已经包含了修改过的代码,它确实发送了wm_mousemove…请看下面的步骤,了解我如何在Vs2008 Pro下复制这个代码。 public class MyGroupBox : System.Windows.Forms.GroupBox { private SubClass sc; private const int WM_MOUSEMOVE = 0x200; public delegate void MyMouseMoveEventHandler(object sender, System.EventArgs e); public event MyMouseMoveEventHandler MyMouseMove; public MyGroupBox() : base() { sc = new SubClass(this.Handle, true); sc.SubClassedWndProc += new SubClass.SubClassWndProcEventHandler(sc_SubClassedWndProc); } protected override void Dispose(bool disposing) { if (sc.SubClassed) { sc.SubClassedWndProc -= new SubClass.SubClassWndProcEventHandler(sc_SubClassedWndProc); sc.SubClassed = false; } base.Dispose(disposing); } private void OnMyMouseMove() { if (this.MyMouseMove != null) this.MyMouseMove(this, System.EventArgs.Empty); } void sc_SubClassedWndProc(ref Message m) { if (m.Msg == WM_MOUSEMOVE) this.OnMyMouseMove(); } } #region SubClass Classing Handler Class public class SubClass : System.Windows.Forms.NativeWindow { public delegate void SubClassWndProcEventHandler(ref System.Windows.Forms.Message m); public event SubClassWndProcEventHandler SubClassedWndProc; private bool IsSubClassed = false; public SubClass(IntPtr Handle, bool _SubClass) { base.AssignHandle(Handle); this.IsSubClassed = _SubClass; } public bool SubClassed { get { return this.IsSubClassed; } set { this.IsSubClassed = value; } } protected override void WndProc(ref Message m) { if (this.IsSubClassed) { OnSubClassedWndProc(ref m); } base.WndProc(ref m); } #region HiWord Message Cracker public int HiWord(int Number) { return ((Number >> 16) & 0xffff); } #endregion #region LoWord Message Cracker public int LoWord(int Number) { return (Number & 0xffff); } #endregion #region MakeLong Message Cracker public int MakeLong(int LoWord, int HiWord) { return (HiWord << 16) | (LoWord & 0xffff); } #endregion #region MakeLParam Message Cracker public IntPtr MakeLParam(int LoWord, int HiWord) { return (IntPtr)((HiWord << 16) | (LoWord & 0xffff)); } #endregion private void OnSubClassedWndProc(ref Message m) { if (SubClassedWndProc != null) { this.SubClassedWndProc(ref m); } } } #endregion
private void groupBox1_MyMouseMove(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine("MyMouseMove!"); } 运行应用程序,每次在GroupBox中移动鼠标时,都会看到输出“mymousemove!”. 希望这能给你提示, 最好的问候, 汤姆。 |
![]() |
4
0
我注意到,许多特定控件的事件无法通过vs中的“事件”选项卡(在“属性”下)访问。您只需在父窗体的设计器中的
这将触发以下方法:
|