VB.NET-Tipp 0029: Subclassing mit API-Funktionen
von Herfried Wagner
Beschreibung
Dieses Beispiel zeigt wie einfach sich "alte" VB6-Codes nach VB.net portieren lassen, obwohl dies nicht immer so ist. Es muss allerdings angemerkt werden, dass das .NET-Framework über die WndProc-Funktion einer Form ein wesentlich flexibleres Mittel für Subclassing bietet.
Für neuere Framework-Versionen empfehlen wir die Verwendung von Subclassing mit .NET-Bordmitteln [Tipp 0028].
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5 | .NET-Version(en): Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008 | Download: |
' Dieser Quellcode 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! ' Projektversion: Visual Studio 2002/2003 ' Option Strict: An ' Option Explicit: An ' ' Referenzen: ' - System ' - System.Drawing ' - System.Windows.Forms ' ' ############################################################################## ' ################################ MainForm.vb ################################# ' ############################################################################## Option Explicit On Option Strict On Option Compare Binary Imports System Imports System.Windows.Forms ' <remarks> ' Hauptformular der Anwendung. ' </remarks> Public Class MainForm Inherits System.Windows.Forms.Form #Region " Delegat-Deklarationen " Private Delegate Function SubWndProcDelegate( _ ByVal hWnd As IntPtr, _ ByVal msg As Int32, _ ByVal wParam As Int32, _ ByVal lParam As Int32) As Int32 #End Region #Region " API-Deklarationen " ' Um die Möglichkeit offen zu lassen, auch einen "echten" Funktionszeiger ' in Form einer Variablen vom Typ IntPtr an das API zu übergeben, wird der ' Name SetWindowLong überladen. Private Declare Function SetWindowLong _ Lib "user32.dll" Alias "SetWindowLongA" ( _ ByVal hWnd As IntPtr, _ ByVal nIndex As Int32, _ ByVal dwNewLong As IntPtr) As Int32 Private Declare Function SetWindowLong _ Lib "user32.dll" Alias "SetWindowLongA" ( _ ByVal hWnd As IntPtr, _ ByVal nIndex As Int32, _ ByVal dwNewLong As SubWndProcDelegate) As IntPtr Private Declare Function CallWindowProc _ Lib "user32.dll" Alias "CallWindowProcA" ( _ ByVal lpPrevWndFunc As IntPtr, _ ByVal hWnd As IntPtr, _ ByVal msg As Int32, _ ByVal wParam As Int32, _ ByVal lParam As Int32) As Int32 Private Const GWL_WNDPROC As Int32 = -&H4 Private Const WM_NCLBUTTONDBLCLK As Int32 = &HA3 Private Const WM_NCLBUTTONDOWN As Int32 = &HA1 Private Const WM_NCLBUTTONUP As Int32 = &HA2 #End Region Private m_intptrPrevWndProc As IntPtr Private Sub MainForm_Load( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Subclassing starten. InitializeSubclassing(Me.Handle) End Sub ' <summary> ' Initialisieren des Subclassing. ' </summary> ' <param name="hWnd">Handle des zu ' subclassenden Fensters.</param> Public Sub InitializeSubclassing( _ ByVal hWnd As IntPtr) m_intptrPrevWndProc = SetWindowLong( _ hWnd, _ GWL_WNDPROC, _ AddressOf SubWndProc) End Sub ' <summary> ' Beenden des Subclassing durch ' Zurücksetzen des Funktionszeigers ' auf die echte Fensterprozedur. ' </summary> ' <param name="hWnd">Handle des Fensters, ' dessen Subclassing entfernt werden soll.</param> Public Sub TerminateSubclassing( _ ByVal hWnd As IntPtr) SetWindowLong(hWnd, _ GWL_WNDPROC, _ m_intptrPrevWndProc) End Sub ' <summary> ' Unsere Fensterprozedur, hier wird die ' Doppelklick-Meldung auf dem Non-Client-Bereich ' des Formulars angefangen. ' </summary> ' <param name="hWnd">Siehe Dokumentation zum Platform SDK.</param> ' <param name="msg">Siehe Dokumentation zum Platform SDK.</param> ' <param name="wParam">Siehe Dokumentation zum Platform SDK.</param> ' <param name="lParam">Siehe Dokumentation zum Platform SDK.</param> ' <returns>Siehe Dokumentation zum Platform SDK.</returns> Private Function SubWndProc( _ ByVal hWnd As IntPtr, _ ByVal msg As Int32, _ ByVal wParam As Int32, _ ByVal lParam As Int32) As Int32 ' Die Meldung besagt, dass der ' Non-Client-Bereich des Formulars doppelt ' angeklickt wurde. If msg = WM_NCLBUTTONDBLCLK Then MessageBox.Show( _ "Der Non-Client-Bereich wurde doppelt angeklickt.", _ "SubWndProc") ' Wenn der Benutzer will, dass die Meldung ' unterdrückt wird, dann steigen ' wir hier aus, ohne sie an Windows weiterzugeben. If chkNoWindowStateChange.Checked Then Return 0 End If End If ' Weiterreichen der Messages an Windows. ' Hier besteht auch die Möglichkeit, ' Meldungen zu unterdrücken, indem man ' sie nicht weiterleitet. Return CallWindowProc(m_intptrPrevWndProc, hWnd, msg, wParam, lParam) End Function End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 1 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von David Ewelt am 17.01.2005 um 23:31
Hallo,
leider muss ich Melden das dieser Tipp (beim mir) nicht funktioniert.
Die Meldungen werden zwar erfolgreich abgefangen und wieder weitergesendet, aber wenn man sich ewtas länger mit der Maus auf dem Formular bewegt wird manchmal ein "Runtime.InteropServices.SEHException" Fehler ausgelößt der Angibt das die externe Komponente einen Fehler auslößte oder das Programm beendet sich ganz still von alleine.
Ich benutze Windows 2000 mit SP4.
Mfg
David Ewelt