Formulare ohne Titelleiste verschiebbar gestalten

Veröffentlicht: 21. Aug 2002 | Aktualisiert: 22. Jun 2004

Von Mathias Schiffer

Nehmen Sie einer Visual-Basic-Form die Titelleiste, kann der Anwender sie nicht mehr mit der Maus verschieben. Dieser MSDN Quickie zeigt Ihnen, wie Sie ein solches Formular wieder mit einem "Mausgriff" versehen.

Eine Form ohne Titelleiste können Sie in Visual Basic erzeugen, indem Sie ihre Eigenschaft ControlBox im Eigenschaftenfenster auf False und die Eigenschaft BorderStyle der Form auf den Wert 0 setzen.

Gemeinsam mit der Titelleiste entschwinden hiermit nicht nur die Buttons zum Minimieren, Maximieren und Schließen der Form nebst dem Systemmenü. Der Anwender wird auch der Möglichkeit beraubt, die Form mit der Maus über der Titelleiste zu verschieben.

Um dem Anwender ein Verschieben dennoch zu ermöglichen, können Sie die API-Funktionen ReleaseCapture und SendMessage im MouseMove-Ereignis der Form verwenden. Auf diese Weise können Sie den gesamten Bereich der Form für Verschiebeoperationen aktiv schalten:

' --- Notwendige API-Deklarationen
' WM_NCLBUTTONDOWN: Linke Maustaste wurde im
' Nicht-Clientbereich der Form betätigt
Private Const WM_NCLBUTTONDOWN As Long = &HA1&
' HTCAPTION: Die Position im Nicht-Clientbereich
' ist die Titelleiste.
Private Const HTCAPTION As Long = 2&
Private Declare Function SendMessage _
  Lib "User32" Alias "SendMessageA" ( _
  ByVal hWnd As Long, _
  ByVal Message As Long, _
  ByVal wParam As Long, _
  ByRef lParam As Any _
  ) As Long
Private Declare Sub ReleaseCapture _
  Lib "User32" ()
' ---
Private Sub Form_MouseMove(Button As Integer, _
                           Shift As Integer, _
                           X As Single, Y As Single)
  ' Verschiebung der Form mit dem Mauszeiger über der Form
  If Button = vbLeftButton Then
    Call ReleaseCapture
    Call SendMessage(Me.hWnd, WM_NCLBUTTONDOWN, _
                     HTCAPTION, ByVal 0&)
  End If
End Sub

Anwendungsbeispiel: Eine individuelle Titelleiste entwerfen
Natürlich können Sie auf diese Art auch einen individuellen Ersatz für die Funktionalität der Titelleiste zur Verfügung stellen. Etwa, indem Sie ein PictureBox-Steuerelement entsprechend auf Ihrer Form positionieren, das die Aufgabe übernimmt. In dessen MouseMove-Ereignis verwenden Sie die obige Lösung dann einfach analog.

Das folgende Beispiel demonstriert diesen Ansatz: Positionieren Sie auf einer Form ein PictureBox- und ein CommandButton-Steuerelement (hier als Ersatz für den Schließen-Button vorgesehen), setzen Sie die Form-Eigenschaft ControlBox im Eigenschaftenfenster auf False und kopieren Sie diesen Sourcecode in das Codemodul der Form:

' --- Notwendige API-Deklarationen
' WM_NCLBUTTONDOWN: Linke Maustaste wurde im
' Nicht-Clientbereich der Form betätigt
Private Const WM_NCLBUTTONDOWN As Long = &HA1&
' HTCAPTION: Die Position im Nicht-Clientbereich
' ist die Titelleiste.
Private Const HTCAPTION As Long = 2&
Private Declare Function SendMessage _
  Lib "User32" Alias "SendMessageA" ( _
  ByVal hWnd As Long, _
  ByVal Message As Long, _
  ByVal wParam As Long, _
  ByRef lParam As Any _
  ) As Long
Private Declare Sub ReleaseCapture _
  Lib "User32" ()
' ---
Private Sub Form_Load()
  ' Darstellung einer etwas eigenwilligen Titelzeile
  ' als Ersatz für eine Form ohne Titelzeile:
  ' Platzieren Sie ein PictureBox- und ein
  ' CommandButton-Steuerelement auf der Form.
  ' Setzen Sie im Eigenschaftenfenster der Form
  ' die Eigenschaft ControlBox auf False.
  BorderStyle = 0                ' Form ist rahmenlos
  Caption = "Titelleistenersatz" ' Beschriftung des
                                 ' Taskbar-Buttons
  ' Picture1 als Titelleisten-Ersatz positionieren
  With Picture1
    .BorderStyle = 0
    .Move 0, 0, ScaleWidth, ScaleY(20, vbPixels, ScaleMode)
    .BackColor = vbBlue
    ' Caption-Ersatz
    .ForeColor = vbWhite
    .Font.Name = "Courier"
    .Font.Size = 16
    .AutoRedraw = True
    Picture1.Print " Titelleistenersatz"
  End With
  ' Command1 wird als Schließen-Button verwendet
  With Command1
    Set .Container = Picture1 ' In die PictureBox setzen
    ' CommandButton positionieren
    .Width = ScaleX(16, vbPixels, ScaleMode)
    .Move Picture1.Width - .Width - _
          ScaleX(2, vbPixels, ScaleMode), _
          ScaleY(2, vbPixels, ScaleMode), _
          ScaleX(16, vbPixels, ScaleMode), _
          ScaleY(16, vbPixels, ScaleMode)
    ' Die Schriftart "Marlett" enthält Windows-Symbole,
    ' an Position des Buchstabens "r" findet sich das
    ' Schließen-Kreuz.
    .Font.Name = "Marlett"
    .Font.Size = 8
    .Caption = "r"
  End With
End Sub
Private Sub Command1_Click()
  ' Form entladen
  Unload Me
End Sub
Private Sub Picture1_MouseMove(Button As Integer, _
                               Shift As Integer, _
                               X As Single, Y As Single)
  ' Verschiebung der Form mit dem Mauszeiger
  If Button = vbLeftButton Then
    Call ReleaseCapture
    Call SendMessage(Me.hWnd, WM_NCLBUTTONDOWN, _
                     HTCAPTION, ByVal 0&)
  End If
End Sub