利用Application.AddMessageFilter屏蔽消息

来源:互联网 发布:网络教育招生学校 编辑:程序博客网 时间:2024/06/05 17:16

 

很早时候就注意到ApplicationAddMessageFilter,苦于自己基础差,测试不出好结果来。今天看贴,有人想屏蔽Form上凡TextBox的右键消息,于是重新看了看这个话题。只是还是没有得出什么好效果来,只能将就着实现。

 

 

Application.AddMessageFilter主要的功能是添加消息筛选器以便在向目标传送 Windows 消息时监视这些消息。

 

 

(哎,本来想按自己的理解说这些含义的,怕误人了,受骂也多了,汲取教训,还是照贴MSDN的原字吧。可怜的我,本来就不是专业人士,也只能是入俗,僧不僧俗不俗的,乡巴佬戴领带入城,可怜哪。)

 

 

注意:向应用程序的消息泵添加消息筛选器会降低性能。(警告之类的我是一般不管的,有用就用,管它)

 

 

使用Application.AddMessageFilter与一般的方法调用不一样,它的参数Message有这样的要求:若要防止调度某消息,传递给该方法的 value 参数实例必须用处理该消息的代码重写 PreFilterMessage 方法。该方法必须返回 false

 

 

以屏蔽Form上凡TextBox的右键消息为例,下面交待一下主要做法。

 

 

一、实现ImessageFilter接口。如下。

 

为什么做了个传递Form的属性,只要是用来判断当前控件是不是TextBox用的。这种效果并不理想,需要改进。本来是不需要引进这个属性的,用Message.GetLParam方法就可以得知当前消息的对象是不是TextBox,可怜我不知道那个Structure该如何写,若是你给我贴出来补正,小人感激不尽。

 

 

Public Class TextBoxRButtonMessageFilter

 

    Implements System.Windows.Forms.IMessageFilter

 

    Const WM_RBUTTONDOWN As Integer = &H204

 

    Const WM_RBUTTONUP As Integer = &H205

 

    Private m_Form As System.Windows.Forms.Form

 

    Public WriteOnly Property [Form]() As System.Windows.Forms.Form

 

        Set(ByVal Value As System.Windows.Forms.Form)

 

            m_Form = Value

 

        End Set

 

    End Property

 

 

    Public Function RButtonFilterMessage(ByRef m As System.Windows.Forms.Message)

 

    As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage

 

        If (m.Msg = WM_RBUTTONDOWN OrElse m.Msg = WM_RBUTTONUP) AndAlso m_Form.ActiveControl.GetType.Name.Equals("TextBox") Then

 

         Return True

 

        Else

 

            Return False

 

        End If

 

    End Function

 

End Class

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

二、向应用程序的消息泵添加消息筛选器。

 

 

#Region " Windows 窗体设计器生成的代码 "

 

Public Sub New()

 

    MyBase.New()

 

   '该调用是 Windows 窗体设计器所必需的。

 

    InitializeComponent()

 

    ' InitializeComponent() 调用之后添加任何初始化

 

    mMsgFilter.Form = Me

 

    System.Windows.Forms.Application.AddMessageFilter(mMsgFilter)

 

End Sub

 

……

 

#End Region

 

Private mMsgFilter As New TextBoxRButtonMessageFilter

 

 

 

 

 

 

 

 

 

 

 

 

 

 

就这么简单。问题是怎么使用Message.GetLParam的,请指教。

 

 

三、以下用Handle来代替ActiveControl

 

 

#Region " Windows 窗体设计器生成的代码 "

 

Public Sub New()

 

    MyBase.New()

 

    '该调用是 Windows 窗体设计器所必需的。

 

    InitializeComponent()

 

    ' InitializeComponent() 调用之后添加任何初始化

 

    MsgFilterInit()

 

End Sub

 

.......

 

#End Region

 

Private mMsgFilter As New TextBoxRButtonMessageFilter

 

Private Sub MsgFilterInit()

 

    Dim ctr As System.Windows.Forms.Control

 

    For Each ctr In Me.Controls

 

        If TypeOf ctr Is TextBox Then

 

            mMsgFilter.SetFilterHandles(ctr.Handle)

 

        End If

 

    Next

 

    System.Windows.Forms.Application.AddMessageFilter(mMsgFilter)

 

End Sub

 

End Class

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Public Class TextBoxRButtonMessageFilter

 

    Implements System.Windows.Forms.IMessageFilter

 

    Const WM_RBUTTONDOWN As Integer = &H204

 

    Const WM_RBUTTONUP As Integer = &H205

 

    Private m_HWnds As New Hashtable

 

    Public Sub SetFilterHandles(ByVal mHWnd As IntPtr)

 

        m_HWnds.Add(mHWnd, Nothing)

 

    End Sub

 

    Public Function RButtonFilterMessage(ByRef m As System.Windows.Forms.Message) _

 

    As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage

 

        If (m.Msg = WM_RBUTTONDOWN OrElse m.Msg = WM_RBUTTONUP) AndAlso m_HWnds.Contains(m.HWnd) Then

 

            Return True

 

        Else

 

            Return False

 

        End If

 

    End Function

 

End Class

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击