Ein MDI-Form im Vollbildmodus, ohne Titelleiste, ohne Rahmen,
sogar die Taskbar überdeckend? Visual Basic will uns das nicht so
einfach machen. Dem MDI-Form fehlen nämlich die
Eigenschaften, mit denen Sie bei einem normalen Form das Gewünschte
erreichen können (BorderStyle, ControlMenu, MinButton, MaxButton).
Aber mit Hilfe einer guten Hand voll API-Funktionen können Sie ein MDI-Form
zum Abspecken bewegen.
Praktischerweise packen wir das alles in eine Hilfsprozedur,
MDIFullScreen genannt, der Sie mindestens das betreffende MDI-Form
als Parameter übergeben. Im optionalen Parameter AllowMinimize
legen Sie fest, ob das MDI-Form nach wie vor über das
Menü des Taskleisten-Sysmbols minimiert werden darf (Voreinstellung
False). Genau so legen Sie im optionalen Parameter AllowClose fest,
ob das MDI-Form über das Menü geschlossen werden darf
(hier ist die Voreinstellung True). Soll das MDI-Form nicht den
kompletten Bildschirm überdecken, sondern sich in die freie
Arbeitsfläche innerhalb der an den Bildschirmrand angedockte(n)
Taskbar(s) einpassen, geben Sie dies im optionalen
Parameter OnlyWorkArea an (Voreinstellung False). Auf eine
Menüzeile brauchen Sie nicht zu verzichten. Damit diese aber nicht
an der Oberkante angeschnitten wird, müssen Sie das der Prozedur im
letzten optionalen Parameter HasMenu bekannt geben. Der Anschnitt
ist erforderlich, um das MDI-Form leicht zu
vergrößern, damit der verbleibende Rahmen aus dem
Bildschirmbereich hinausgeschoben wird.
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function DrawMenuBar Lib "user32" _
(ByVal hWnd As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" _
(ByVal hMenu As Long) As Long
Private Declare Function GetSystemMenu Lib "user32" _
(ByVal hWnd As Long, ByVal bRevert As Long) As Long
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) _
As Long
Private Declare Function RemoveMenu Lib "user32" _
(ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags 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 Function SystemParametersInfo Lib "user32" _
Alias "SystemParametersInfoA" (ByVal uAction As Long, _
ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) _
As Long
Private Const GWL_STYLE = (-16)
Private Const MF_BYCOMMAND = &H0
Private Const MF_BYPOSITION = &H400
Private Const MF_REMOVE = &H1000&
Private Const SC_CLOSE = &HF060
Private Const SC_MAXIMIZE = &HF030
Private Const SC_MINIMIZE = &HF020
Private Const SC_MOVE = &HF010
Private Const SC_RESTORE = &HF120
Private Const SC_SEPARATOR = &HF00F
Private Const SPI_GETWORKAREA& = 48
Private Const WS_SYSMENU = &H80000
Private Const WS_BORDER = &H800000
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_THICKFRAME = &H40000
Public Sub MDIFullScreen(MDI As Form, _
Optional ByVal AllowMinimize As Boolean, _
Optional ByVal AllowClose As Boolean = True, _
Optional ByVal OnlyWorkArea As Boolean, _
Optional ByVal HasMenu As Boolean)
Dim nStyle As Long
Dim nRect As RECT
Dim nMenu As Long
Dim nCount As Long
Const kFrame = 90
With MDI
Zunächst wird mit der API-Funktion GetWindowLong
die aktuelle Einstellung des Fensterstils ausgelesen. Die störenden
Elemente werden gelöscht und mit SetWindowLong
wird die bereinigte Stileinstellung zurückgeschrieben.
nStyle = GetWindowLong(.hWnd, GWL_STYLE)
nStyle = nStyle And Not (WS_MAXIMIZEBOX Or WS_MINIMIZEBOX _
Or WS_THICKFRAME Or WS_BORDER)
SetWindowLong .hWnd, GWL_STYLE, nStyle
If OnlyWorkArea Then
Soll sich das MDI-Form in die Arbeitsfläche einpassen, wird
deren Größe mit einem Aufruf der Funktion SystemParametersInfo
ermittelt.
SystemParametersInfo SPI_GETWORKAREA, 0&, nRect, 0&
With nRect
.Right = (.Right - .Left) * Screen.TwipsPerPixelX
.Bottom = (.Bottom - .Top) * Screen.TwipsPerPixelY
.Left = .Left * Screen.TwipsPerPixelX
.Top = .Top * Screen.TwipsPerPixelY
If HasMenu Then
MDI.Move .Left - kFrame, .Top, .Right + 2 * kFrame, _
.Bottom + kFrame
Else
MDI.Move .Left - kFrame, .Top - kFrame, _
.Right + 2 * kFrame, .Bottom + 2 * kFrame
End If
End With
Else
If HasMenu Then
.Move -kFrame, 0, Screen.Width + 2 * kFrame, _
Screen.Height + kFrame
Else
.Move -kFrame, -kFrame, Screen.Width + 2 * kFrame, _
Screen.Height + 2 * kFrame
End If
End If
Schließlich entfernen wir noch die nicht benötigten und die
nicht gewünschten Elemente aus dem Systemmenü. Das Handle des
Systemmenüs des MDI-Forms liefert uns die Funktion GetSystemMenu.
Auf jeden Fall entfernen wir mit der Funktion RemoveMenu
die Menüpunkte zum Verschieben und Maximieren.
nMenu = GetSystemMenu(.hWnd, 0)
RemoveMenu nMenu, SC_MOVE, MF_REMOVE Or MF_BYCOMMAND
RemoveMenu nMenu, SC_MAXIMIZE, MF_REMOVE Or MF_BYCOMMAND
Falls gewünscht, wird auch der Menüpunkt zum Minimieren samt
seinem Gegenstück zum Wiederherstellen entfernt.
If Not AllowMinimize Then
RemoveMenu nMenu, SC_MINIMIZE, MF_REMOVE Or MF_BYCOMMAND
RemoveMenu nMenu, SC_RESTORE, MF_REMOVE Or MF_BYCOMMAND
Die auch noch zu beseitigende Trennlinie ermitteln wir über die
verbleibende Anzahl der Menüelemente - die Anzahl wird uns von der
Funktion GetMenuItemCount
geliefert.
nCount = GetMenuItemCount(nMenu)
RemoveMenu nMenu, nCount - 2, MF_REMOVE Or MF_BYPOSITION
End If
Falls auch gewünscht, wird der Menüpunkt zum Schließen
entfernt. Auch hier löschen wir die Trennlinie.
If Not AllowClose Then
RemoveMenu nMenu, SC_CLOSE, MF_REMOVE Or MF_BYCOMMAND
nCount = GetMenuItemCount(nMenu)
RemoveMenu nMenu, nCount - 1, MF_REMOVE Or MF_BYPOSITION
End If
Damit die Änderungen im Systemmenü gültig werden, wird es mit DrawMenuBar
aktualisiert.
DrawMenuBar .hWnd
End With
End Sub
|