c# – 如何在不窃取焦点和没有PInvoke的情况下将消息(例如鼠标滚轮)转发到另一个控件?

c# – 如何在不窃取焦点和没有PInvoke的情况下将消息(例如鼠标滚轮)转发到另一个控件?,第1张

概述当我用鼠标控制此控件时,我想转发一条消息(例如WM_MOUSEWHEEL),而不会窃取焦点.使用IMessageFilter(要添加到应用程序消息泵)并使用P / Invoke(d)SendMessage()转发消息,可以轻松解决此问题.问题是:我可以不使用P / Invoke做同样的事情(我在StackOverflow中找到的解决方案使用P / Invoke)吗?如果没有,为什么? 下面的代码是 当我用鼠标控制此控件时,我想转发一条消息(例如WM_MOUSEWHEEL),而不会窃取焦点.使用IMessageFilter(要添加到应用程序消息泵)并使用P / Invoke(d)SendMessage()转发消息,可以轻松解决此问题.问题是:我可以不使用P / Invoke做同样的事情(我在StackOverflow中找到的解决方案使用P / Invoke)吗?如果没有,为什么?

下面的代码是我用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的情况下将消息(例如鼠标滚轮)转发到另一个控件?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1262698.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存