下面的代码是我用P / Invoke的解决方案.我只使用新的MessageForwarder(控件,0x20A).
/// <summary>/// This class implements a filter for the windows.Forms message pump allowing a/// specific message to be forwarded to the Control specifIEd in the constructor./// Adding and removing of the filter is done automatically./// </summary>public class MessageForwarder : IMessageFilter{#region FIEldsprivate Control _Control;private Control _PrevIoUsParent;private HashSet<int> _Messages;private bool _IsMouSEOverControl;#endregion // FIElds#region Constructorspublic MessageForwarder(Control control,int message) : this(control,new int[] { message }) { }public MessageForwarder(Control control,IEnumerable<int> messages){ _Control = control; _Messages = new HashSet<int>(messages); _PrevIoUsParent = control.Parent; _IsMouSEOverControl = false; control.ParentChanged += new EventHandler(control_ParentChanged); control.MouseEnter += new EventHandler(control_MouseEnter); control.MouseLeave += new EventHandler(control_MouseLeave); control.Leave += new EventHandler(control_Leave); if (control.Parent != null) Application.AddMessageFilter(this);}#endregion // Constructors#region IMessageFilter memberspublic bool PreFilterMessage(ref Message m){ if (_Messages.Contains(m.Msg) && _Control.CanFocus && !_Control.Focused && _IsMouSEOverControl) { SendMessage(_Control.Handle,m.Msg,m.WParam,m.LParam); return true; } return false;}#endregion // IMessageFilter#region Event handlersvoID control_ParentChanged(object sender,EventArgs e){ if (_Control.Parent == null) Application.RemoveMessageFilter(this); else { if (_PrevIoUsParent == null) Application.AddMessageFilter(this); } _PrevIoUsParent = _Control.Parent;}voID control_MouseEnter(object sender,EventArgs e){ _IsMouSEOverControl = true;}voID control_MouseLeave(object sender,EventArgs e){ _IsMouSEOverControl = false;}voID control_Leave(object sender,EventArgs e){ _IsMouSEOverControl = false;}#endregion // Event handlers#region Support[Dllimport("user32.dll")]private static extern IntPtr SendMessage(IntPtr hWnd,int msg,IntPtr wp,IntPtr lp);#endregion // Support
}
编辑:我的答案完全解决方案
解决方法 找到一个方法:你必须继承NativeWindow,在你以任何你喜欢的方式拦截一个消息之后,将所选控件的句柄分配给它,调用受保护的WndProc(在我的例子中,继承的类甚至是一个IMessageFilter所以我可以轻松将其插入应用程序).我使用它与新的MessageForwarder(anycontrol,0x20A)重定向鼠标滚轮.因此,可以在没有p / invoke的情况下拦截和转发消息到任何控件.虽然这很隐蔽.
/// <summary>/// This class implements a filter for the windows.Forms message pump allowing a/// specific message to be forwarded to the Control specifIEd in the constructor./// Adding and removing of the filter is done automatically./// </summary>public class MessageForwarder : NativeWindow,IMessageFilter{ #region FIElds private Control _Control; private Control _PrevIoUsParent; private HashSet<int> _Messages; private bool _IsMouSEOverControl; #endregion // FIElds #region Constructors public MessageForwarder(Control control,int message) : this(control,new int[] { message }) { } public MessageForwarder(Control control,IEnumerable<int> messages) { _Control = control; AssignHandle(control.Handle); _Messages = new HashSet<int>(messages); _PrevIoUsParent = control.Parent; _IsMouSEOverControl = false; control.ParentChanged += new EventHandler(control_ParentChanged); control.MouseEnter += new EventHandler(control_MouseEnter); control.MouseLeave += new EventHandler(control_MouseLeave); control.Leave += new EventHandler(control_Leave); if (control.Parent != null) Application.AddMessageFilter(this); } #endregion // Constructors #region IMessageFilter members public bool PreFilterMessage(ref Message m) { if (_Messages.Contains(m.Msg) && _Control.CanFocus && !_Control.Focused && _IsMouSEOverControl) { m.HWnd = _Control.Handle; WndProc(ref m); return true; } return false; } #endregion // IMessageFilter #region Event handlers voID control_ParentChanged(object sender,EventArgs e) { if (_Control.Parent == null) Application.RemoveMessageFilter(this); else { if (_PrevIoUsParent == null) Application.AddMessageFilter(this); } _PrevIoUsParent = _Control.Parent; } voID control_MouseEnter(object sender,EventArgs e) { _IsMouSEOverControl = true; } voID control_MouseLeave(object sender,EventArgs e) { _IsMouSEOverControl = false; } voID control_Leave(object sender,EventArgs e) { _IsMouSEOverControl = false; } #endregion // Event handlers}总结
以上是内存溢出为你收集整理的c# – 如何在不窃取焦点和没有P / Invoke的情况下将消息(例如鼠标滚轮)转发到另一个控件?全部内容,希望文章能够帮你解决c# – 如何在不窃取焦点和没有P / Invoke的情况下将消息(例如鼠标滚轮)转发到另一个控件?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)