vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Mails senden, abrufen und decodieren - ganz easy ;-)  
 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, VB609.05.01
Fenstergröße einschränken

Mit dieser Routine kann man die Größenänderung eines Fenster auf ein Minium/Maximum einschränken.

Autor:   Wolfgang KlugeBewertung:     [ Jetzt bewerten ]Views:  24.134 
www.vbwelt.deSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Manchmal ist es notwendig oder erwünscht, daß zwar ein Fenster in der Größe vberändert werden darf, jedoch mit zwei Einschränkungen:
1. das Fenster darf nicht kleiner sein als eine bestimmte Größe,
2. das Fenster darf auch nicht größer werden als eine bestimmte Größe.

Das naheliegendste ist dann natürlich im Resize-Ereignis die aktuellen Width- und Height-Eigenschaften auszulesen und gegebenenfalls zu korrigieren. Das "Dumme" daran ist, daß das wirklich nicht gerade schön aussieht. Es flackert und tut und macht - bloß nicht das, was es soll.

Die nächste Überlegung ist, vor dem Resize-Ereignis das gleiche zu tun. Und das geht mit dem AdressOf-Operator - jedoch erst ab VB5. Die API-Funktion SetWindowLong bietet an, einen Pointer auf eine Funktion zu setzten, die dann alle Windows-Funktionen aufnimmt.

Man lege sich also ein Modul in einem Projekt an, in dem folgendes stehtDas sieht jetzt alles sehr kryptisch aus, aber im Grunde ist es ganz einfach...ehrlich)

Option Explicit
 
Private WinOldProcMinMax
Private Const GWL_WNDPROC = (-4)
 
' Die Nachricht WM_GETMINMAXINFO wird an ein Fenster
' geschickt, bevor es vergrößert bzw. verkleinert wird
Private Const WM_GETMINMAXINFO = &H24
 
Private lX1 As Long
Private lX2 As Long
Private lY1 As Long
Private lY2 As Long
 
Private Type POINTAPI
  x As Long
  y As Long
End Type
 
Private Type MINMAXINFO
  ptReserved As POINTAPI
  ptMaxSize As POINTAPI
  ptMaxPosition As POINTAPI
  ptMinTrackSize As POINTAPI  ' Minimale Größe
  ptMaxTrackSize As POINTAPI  ' Maximale Größe
End Type
 
Private Declare Function DefWindowProc Lib "user32" _
  Alias "DefWindowProcA" ( _
  ByVal hWnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long) As Long
 
Private Declare Function CallWindowProc Lib "user32" _
  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 SetWindowLong Lib "user32" _
  Alias "SetWindowLongA" ( _
  ByVal hWnd As Long, _
  ByVal nIndex As Long, _
  ByVal dwNewLong As Long) As Long
 
Private Declare Sub CopyMemory Lib "kernel32" _
  Alias "RtlMoveMemory" ( _
  ByVal Destination As Any, _
  ByVal Source As Any, _
  ByVal Length As Long)
 
Private Declare Sub CopyMemory1 Lib "kernel32" _
  Alias "RtlMoveMemory" ( _
  Destination As MINMAXINFO, _
  ByVal Source As Long, _
  ByVal Length As Long)
 
Private Declare Sub CopyMemory2 Lib "kernel32" _
  Alias "RtlMoveMemory" ( _
  ByVal Destination As Long, _
  Source As MINMAXINFO, _
  ByVal Length As Long)

Aktiviert wird das ganze mit dem AdressOf-Operator.
Deswegen auch erst ab VB5.

Alle nachfolgenden Prozeduren müssen noch im Modul "abgelegt" werden.

' AufrufProzedur
' Am besten im Form_Load-Ereignis aufrufen
Public Sub SetMinMax(Form As Form, x1 As Long, _
  y1 As Long, x2 As Long, y2 As Long)
 
  WinOldProcMinMax = SetWindowLong(Form.hWnd, _
    GWL_WNDPROC, AddressOf WindowProcMinMax)
 
  lX1 = x1
  lX2 = x2
  lY1 = y1
  lY2 = y2
End Sub
 
' Normalzustand wiederherstellen
' WICHTIG! Vor dem Beenden der Form aufrufen
Public Sub UnloadMinMax(Form As Form)
  SetWindowLong Form.hWnd, GWL_WNDPROC, _
    WinOldProcMinMax
End Sub
 
' Hier kommen alle Nachrichten an, die an daß Fenster
' geschickt werden
Private Function WindowProcMinMax(ByVal hWnd As Long, _
  ByVal uMsg As Long, ByVal wParam As Long, _
  ByVal lParam As Long) As Long
 
  Dim ret As Long
  Dim MM As MINMAXINFO
 
  If uMsg = WM_GETMINMAXINFO Then
    CopyMemory1 MM, lParam, Len(MM)
    With MM
      .ptMinTrackSize.x = lX1
      .ptMinTrackSize.y = lY1
      .ptMaxTrackSize.x = lX2
      .ptMaxTrackSize.y = lY2
    End With
    CopyMemory2 lParam, MM, Len(MM)
    ret = DefWindowProc(hWnd, uMsg, wParam, lParam)
  Else
    ' Wenn andere Nachricht, dann "durchlassen"
    ret = CallWindowProc(WinOldProcMinMax, hWnd, uMsg, _
      wParam, lParam)
  End If
  WindowProcMinMax = ret
End Function

Ab hier braucht es nur noch den Aufruf aus (irgend-)einer Form, der am besten im Form_Load-Ereignis steht. Natürlich kann der Maximalwert auch weit über dem Windows-Standard liegen...

Damit Windows keinen Grund zum Beschweren hat, sollte spätestens im Form_QueryUnload-Ereignis der UnloadMinMax-Aufruf erfolgen.

' Größeneinschränkung festlegen
Private Sub Form_Load()
  SetMinMax Me, 200, 200, 500, 500
End Sub
 
' WICHTIG: Normalzustand wiederherstellen
Private Sub Form_QueryUnload(Cancel As Integer, _
  UnloadMode As Integer)
 
  UnloadMinMax Me
End Sub

So, das ist das Grundprinzip der Funktion.

Im Modul (Download-File) gehts noch einen paar Schritte weiter.
Dort werden mehrere Formen auf einmal unterstützt (in einem Array gespeichert) und man kann auch nur eine Größe angeben (die anderen bleiben dann auf dem Windows-Standard). Auch ist es möglich, die Werte während der Laufzeit zu verändern. Desweiteren kann man wahlweiße den Minimieren-, den Maximieren-, den Wiederherstellen- und/oder den Schließen-Button deaktivieren. Im Normalfall nicht wichtig, da dies auch in den Eigenschaften der Form geschehen kann, doch hier gehts auch in MDI-Childformen.

Das einzigste, das man jetzt noch beachten muß, ist daß man seine Programme beim Debuggen nicht in der IDE beendet (Stop), ohne vorher den Aufruf UnloadMinMax gesetzt zu haben. Ein Unload-Ereignis tritt beim Beenden aus der IDE nämlich nicht ein.

Viel Spaß beim Probieren.
 

Dieser Tipp wurde bereits 24.134 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