vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevAniGif - als kostenlose Vollversion auf unserer vb@rchiv CD Vol.5  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Oberfläche · Fenster   |   VB-Versionen: VB5, VB602.08.04
FormMove- und FormBeforeMove-Ereignis in VB

Per Subclassing lässt sich das in VB fehlende FormMove-Ereignis relativ leicht nachrüsten, sogar optional mit der Möglichkeit das Verschieben der Form zu unterbinden!

Autor:   Dieter OtterBewertung:     [ Jetzt bewerten ]Views:  12.490 
www.tools4vb.deSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Immer wieder wird in unserem Diskussionsforum die Frage gestellt: "Warum gibt es in VB keine Benachrichtigung, wenn eine Form verschoben wird und wie kann ich dennoch ermitteln, wann eine Form verschoben wird?"

Die Lösung für hierzu lautet wie so oft: Subclassing der Form, d.h. man muss die Fensternachrichten von Windows "abhorchen". Und wenn wir schon beim "Abhören" der Fensternachrichten sind: was würde näher liegen, als bspw. dann sogar das Verschieben des Fensters zu unterbinden?

Fügen Sie dem Projekt ein neues Modul mit folgendem Code hinzu:

Option Explicit
 
' benötigte API's
Private Declare Function SetWindowLong Lib "user32.dll" _
  Alias "SetWindowLongA" ( _
  ByVal hwnd As Long, _
  ByVal nIndex As Long, _
  ByVal dwNewLong As Long) As Long
 
Private Declare Function CallWindowProc Lib "user32.dll" _
  Alias "CallWindowProcA" ( _
  ByVal lpPrevWndFunc As Long, _
  ByVal hwnd As Long, _
  ByVal Msg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long) As Long
 
Private Declare Function ReleaseCapture Lib "user32" () As Long
 
Private Const GWL_WNDPROC As Long = -4
Private Const WM_MOVE = &H3
Private Const WM_MOVING = &H216
 
Private PrevWndProc As Long
Private oForm As Form
' Fensternachrichten an die Prozedur WndProc "umleiten"
Public Function InitSubclassing(Form As Object) As Long
  Set oForm = Form
  PrevWndProc = SetWindowLong(oForm.hwnd, _
    GWL_WNDPROC, AddressOf WndProc)
End Function
' Subclassing beenden
Public Sub EndSubclassing(Form As Object)
  Call SetWindowLong(oForm.hwnd, GWL_WNDPROC, PrevWndProc)
  Set oForm = Nothing
End Sub
' Hier kommen alle Fensternachrichten an
Public Function WndProc(ByVal hwnd As Long, _
  ByVal Msg As Long, ByVal wParam As Long, _
  ByVal lParam As Long) As Long
 
  Static bNoMoveEvent As Boolean
  Dim bCancel As Boolean
 
  On Error Resume Next  
  If Msg = WM_MOVING Then
    ' Meldung an die Form schicken, 
    ' dass das Fenster verschoben werden soll
    bCancel = False
    oForm.FormBeforeMove bCancel
 
    If bCancel Then
      ' Nachricht als "verarbeitet" kennzeichnen,
      ' um das Verschieben zu verhindern
      bNoMoveEvent = True
      ReleaseCapture
      WndProc = 1
      Exit Function
    Else
      bNoMoveEvent = False
    End If
 
  ElseIf Msg = WM_MOVE Then
    ' Fenster wurde verschoben
    ' Meldung an die Form weiterleiten
    If Not bNoMoveEvent Then
      oForm.FormMove
    End If
  End If
 
  ' Nachricht an die Original-Fensterprozedur weiterleiten
  WndProc = CallWindowProc(PrevWndProc, hwnd, Msg, wParam, ByVal lParam)
End Function

Damit die Form selbst über die Nachricht "Achtung! Fenster soll verschoben werden!" oder "Achtung! Fenster wurde verschoben" benachrichtigt werden kann, müssen nachfolgende Prozeduren als öffentliche Prozeduren in den Codeteil der Form eingefügt werden:

Public Sub FormBeforeMove(bCancel As Boolean)
  Debug.Print "Form soll verschoben werden"
 
  ' Um das Verschieben der Form zu unterbinden
  ' einfach den Parameter bCancel = True setzen
  ' bCancel = True
End Sub
Public Sub FormMove()
  Debug.Print "Fenster wird verschoben!"
End Sub

Damit die Fensternachrichten abgehört werden können, muss beim Laden der Form das "Subclassing" gestartet werden. Wichtig ist auch das korrekte Beenden des Subclassings - am besten im Form_QueryUnload-Ereignis.

Private Sub Form_Load()
  ' Subclassing starten
  InitSubclassing Me
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  ' Wichtig! Subclassing beenden
  EndSubclassing Me
End Sub

Dieser Tipp wurde bereits 12.490 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel