Die Community zu .NET und Classic VB.
Menü

Tipp-Upload: VB.NET 0019: .Net-SubClassing mit dem IMessageFilter-Interface

 von 

Über den Tipp  

Dieser Tippvorschlag ist noch unbewertet.

Der Vorschlag ist in den folgenden Kategorien zu finden:

  • Fenster

Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Subclassing, Interface, Schnittstelle, Singleton

Der Vorschlag wurde erstellt am: 31.07.2007 03:18.
Die letzte Aktualisierung erfolgte am 11.04.2008 04:47.

Zurück zur Übersicht

Beschreibung  

Gezeigt wird ein Subclassing, welches imstande ist, alle(!!) in einer Anwendung vorkommenden Window-Handles gleichzeitig zu überwachen.
Das Interface System.Windows.Forms.IMessageFilter schreibt eine Funktion "PreFilterMessage()" vor, mit der Signatur "(ByRef m As Message) As Boolean".
An eine solche Funktion kann das Application-Objekt die WindowMessages aller Windows der Anwendung senden.
Man muß dem Application-Objekt nur ein Objekt mitteilen, welches eine solche Funktion zur Verfügung stellt - Fachsprache gesprochen: "welches IMessageFilter implementiert".
Zu beachten ist, daß PreFilterMessage() möglichst schnell sein sollte, ansonsten man Gefahr läuft, seine Anwendung auszubremsen.
Daher ist der "MessageEliminator" zusätzlich nach dem sog. "Singleton-Pattern" konstruiert, was gewährleistet, daß nur ein einziges Objekt dieser Art existieren kann.
Mehrere solcher Objekte würden logischerweise dazu führen, daß das Application-Objekt jede Message auch noch mehrfach verschickte, und das soll verhindert werden.

Schwierigkeitsgrad

Schwierigkeitsgrad 1

Verwendete API-Aufrufe:

Download:

Download des Beispielprojektes [13,21 KB]

' Dieser Source stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!
'
' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird.
' In den Zip-Dateien ist er jedoch zu finden.

' ---------- Anfang Projektgruppe MessageFilter.sln ----------
' --------- Anfang Projektdatei MessageFilter.vbproj ---------
' ------------ Anfang Datei MessageEliminator.vb  ------------
''' <summary>
''' implementiert IMessageFilter. Meldet sich selbständig
''' beim Application-Objekt an bzw. auch wieder ab. 
''' </summary>
''' <remarks></remarks>
Public Class MessageEliminator

    Implements IMessageFilter

    Public Shared ReadOnly Singleton As New MessageEliminator

    Private Sub New()

    End Sub

    Private ReadOnly _SuppressedHandles As New List(Of IntPtr)

    Public Sub AddWindowHandle(ByVal Value As IntPtr)

        _SuppressedHandles.Add(Value)

        If _SuppressedHandles.Count = 1 Then

            ' Diese Instanz eines IMessageFilters beim Application-Objekt anmelden
            Application.AddMessageFilter(Me)
        End If

    End Sub

    Public Sub RemoveWindowHandle(ByVal Value As IntPtr)

        _SuppressedHandles.Remove(Value)

        If _SuppressedHandles.Count = 0 Then

            ' Filterung abstellen, wenn nicht mehr gebraucht
            Application.RemoveMessageFilter(Me)
        End If

    End Sub

    ''' <summary>
    ''' Dieser Schnittstellen-Member wird vom Application-Objekt 
    ''' aufgerufen, und zwar für alle Messages aller Windows der 
    ''' gesamten Anwendung
    ''' </summary>
    ''' <returns>
    ''' True: Message wird unterdrückt
    ''' False: Message wird weiterverarbeitet
    ''' </returns>
    Public Function PreFilterMessage(ByRef m As Message) As Boolean _
              Implements IMessageFilter.PreFilterMessage

        Return _SuppressedHandles.Contains(m.HWnd)

    End Function

End Class ' MessageEliminator

' ------------- Ende Datei MessageEliminator.vb  -------------
' ------------- Anfang Datei frmMessageFilter.vb -------------
Public Class frmMessageFilter

    Private _Eliminator As MessageEliminator = MessageEliminator.Singleton

    Private Sub ckDisableTextbox_CheckedChanged( _
              ByVal sender As System.Object, _
              ByVal e As System.EventArgs) Handles ckDisableTextbox.CheckedChanged

        If ckDisableTextbox.Checked Then
            _Eliminator.AddWindowHandle(Me.TextBox1.Handle)

        Else

            _Eliminator.RemoveWindowHandle(Me.TextBox1.Handle)
        End If

    End Sub

    Private Sub ckDisableForm_CheckedChanged( _
              ByVal sender As System.Object, _
              ByVal e As System.EventArgs) Handles ckDisableForm.CheckedChanged

        If ckDisableForm.Checked Then
            _Eliminator.AddWindowHandle(Me.Handle)

        Else

            _Eliminator.RemoveWindowHandle(Me.Handle)
        End If

    End Sub

End Class ' frmMessageFilter

' -------------- Ende Datei frmMessageFilter.vb --------------
' ---------- Ende Projektdatei MessageFilter.vbproj ----------
' ----------- Ende Projektgruppe MessageFilter.sln -----------

	

Diskussion  

Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.

Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.