VB 5/6-Tipp 0652: Größenänderungen in MDI-Parent-Formularen unterbinden
von Helge Rex
Beschreibung
Dieser Tipp macht es möglich, auch bei MDI-Parent-Formularen die Schaltflächen zum Minimieren und Maximieren des Fensters zu deaktivieren. Zusätzlich kann gleichzeitg das Ändern der Größe unterbunden werden.
Schwierigkeitsgrad: | Verwendete API-Aufrufe: DrawMenuBar, EnableMenuItem, GetMenuItemCount, GetMenuItemInfoA (GetMenuItemInfo), GetSystemMenu, GetWindowLongA (GetWindowLong), RemoveMenu, SetWindowLongA (SetWindowLong) | 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! '------------- Anfang Projektdatei Projekt1.vbp ------------- '--------- Anfang Formular "Form1" alias Form1.frm --------- ' Steuerelement: Kontrollkästchen-Steuerelement "chkBlockResize" ' Steuerelement: Schaltfläche "Command3" ' Steuerelement: Schaltfläche "Command2" ' Steuerelement: Schaltfläche "Command1" Option Explicit Private Sub Command1_Click() SetMinMaxButtons Me.hWnd, False, True, (chkBlockResize.Value = 1) End Sub Private Sub Command2_Click() SetMinMaxButtons Me.hWnd, True, False, (chkBlockResize.Value = 1) End Sub Private Sub Command3_Click() SetMinMaxButtons Me.hWnd, False, False, (chkBlockResize.Value = 1) End Sub '---------- Ende Formular "Form1" alias Form1.frm ---------- '--- Anfang Modul "mod_ButtonState" alias mod_Buttonstate.bas --- ' ******************************************************************** ' Modul : mod_ButtonState ' Beschreibung : Dieses Modul setzt einige WindowStyles neu, damit ' ein Dialog nicht mehr maximiert oder minimiert ' werden kann. Optional kann auch gleich das Ändern ' der Größe verhindert werden. ' Autor : Helge Rex ' Email : helge@activevb.de ' Datum : 07.10.2004 (1. Version) ' 25.11.2004 (BugFix: Menubar muß neu gezeichnet ' werden, wenn das Systemmenü geändert ' wird) ' 04.01.2005 (BugFix: Bei mehrmaligem Aufruf der ' Funktion wird kein falscher Menüpunkt ' mehr entfernt) ' 06.01.2005 (BugFix: Schließen wird nicht mehr ' deaktiviert, außerdem kann nun ' festgelegt werden, ob Resize noch ' möglich ist) ' 09.01.2005 (BugFix durch Udo Schmidt: Funktioniert ' nun auch unter Windows 98) ' Anmerkungen : Artikel Q137033 in der Microsoft Knowledge Base ' (http://support.microsoft.com/?kbid=137033) diente ' als Grundlage für die Entwicklung dieses Codes. ' Der Code im besagten Artikel hat jedoch den ' Nachteil, daß das Systemmenü unangetastet bleibt ' und so die Funktionalität dem Anwender weiterhin ' zur Verfügung steht. Es ist jetzt nur noch möglich, ' den Dialog per Code zu maxi- oder minimieren. ' Die Konstanten für die Menüpunkte "Minimieren" und ' "Maximieren" sind von mir auf einem deutschen ' XP-System ermittelt worden. Sollten die Werte der ' Konstanten in anderen Windows-Versionen (auch ' anderen Sprachen) davon abweichen, bitte ich um eine ' Information diesbezüglich, damit der Code ' dahingehend angepaßt werden kann. ' ******************************************************************** ' ******************************************************************** ' Einstellungen Option Explicit ' ******************************************************************** ' lokale (private) Konstanten Private Const GWL_STYLE As Long = (-16) Private Const MF_FIRST As Long = 0& ' MenuFlagEnum Private Const MIIM_FIRST As Long = 0& ' MenuItemInfoEnum Private Const MFS_FIRST As Long = 0& ' MenuFlagStyleEnum Private Const MFT_FIRST As Long = 0& ' MenuFlagTypeEnum Private Const SMI_FIRST As Long = &HF000& ' SysMenuItemIDEnum Private Const WS_FIRST As Long = 0& ' WindowStyleEnum ' ******************************************************************** ' lokale (private) Auflistungen Private Enum MenuFlagEnum MF_INSERT = (MF_FIRST + &H0&) MF_CHANGE = (MF_FIRST + &H80&) MF_APPEND = (MF_FIRST + &H100&) MF_DELETE = (MF_FIRST + &H200&) MF_REMOVE = (MF_FIRST + &H1000&) MF_BYCOMMAND = (MF_FIRST + &H0&) MF_BYPOSITION = (MF_FIRST + &H400&) MF_SEPARATOR = (MF_FIRST + &H800&) MF_ENABLED = (MF_FIRST + &H0&) MF_GRAYED = (MF_FIRST + &H1&) MF_DISABLED = (MF_FIRST + &H2&) MF_UNCHECKED = (MF_FIRST + &H0&) MF_CHECKED = (MF_FIRST + &H8&) MF_USECHECKBITMAPS = (MF_FIRST + &H200&) MF_STRING = (MF_FIRST + &H0&) MF_BITMAP = (MF_FIRST + &H4&) MF_OWNERDRAW = (MF_FIRST + &H100&) MF_POPUP = (MF_FIRST + &H10&) MF_MENUBARBREAK = (MF_FIRST + &H20&) MF_MENUBREAK = (MF_FIRST + &H40&) MF_UNHILITE = (MF_FIRST + &H0&) MF_HILITE = (MF_FIRST + &H80&) MF_DEFAULT = (MF_FIRST + &H1000&) MF_SYSMENU = (MF_FIRST + &H2000&) MF_HELP = (MF_FIRST + &H4000&) MF_RIGHTJUSITFY = (MF_FIRST + &H4000&) MF_MOUSESELECT = (MF_FIRST + &H8000&) MF_END = (MF_FIRST + &H80&) End Enum Private Enum MenuItemInfoMaskEnum MIIM_STATE = (MIIM_FIRST + &H1&) MIIM_ID = (MIIM_FIRST + &H2&) MIIM_SUBMENU = (MIIM_FIRST + &H4&) MIIM_CHECKMARKS = (MIIM_FIRST + &H8&) MIIM_TYPE = (MIIM_FIRST + &H10&) MIIM_DATA = (MIIM_FIRST + &H20&) MIIM_STRING = (MIIM_FIRST + &H40&) MIIM_BITMAP = (MIIM_FIRST + &H80&) MIIM_FTYPE = (MIIM_FIRST + &H100&) End Enum Private Enum MenuFlagStyleEnum MFS_GRAYED = (MFS_FIRST + &H3&) MFS_DISABLED = MenuFlagStyleEnum.MFS_GRAYED MFS_CHECKED = MenuFlagEnum.MF_CHECKED MFS_HILITE = MenuFlagEnum.MF_HILITE MFS_ENABLED = MenuFlagEnum.MF_ENABLED MFS_UNCHECKED = MenuFlagEnum.MF_UNCHECKED MFS_UNHILITE = MenuFlagEnum.MF_UNHILITE MFS_DEFAULT = MenuFlagEnum.MF_DEFAULT MFS_MASK = (MFS_FIRST + &H108B&) MFS_HOTTRACKDRAWN = (MFS_FIRST + &H10000000) MFS_CACHEDBMP = (MFS_FIRST + &H20000000) MFS_BOTTOMGAPDROP = (MFS_FIRST + &H40000000) MGS_TOPGAPDROP = (MFS_FIRST + &H80000000) MFS_GAPDROP = MFS_BOTTOMGAPDROP Or MGS_TOPGAPDROP End Enum Private Enum MenuFlagTypeEnum MFT_STRING = MenuFlagEnum.MF_STRING MFT_BITMAP = MenuFlagEnum.MF_BITMAP MFT_MENUBARBREAK = MenuFlagEnum.MF_MENUBARBREAK MFT_MENUBREAK = MenuFlagEnum.MF_MENUBREAK MFT_OWNERDRAW = MenuFlagEnum.MF_OWNERDRAW MFT_RADIOCHECK = (MFT_FIRST + &H200&) MFT_SEPARATOR = MenuFlagEnum.MF_SEPARATOR MFT_RIGHTORDER = (MFT_FIRST + &H2000&) MFT_RIGHTJUSTIFY = MenuFlagEnum.MF_RIGHTJUSITFY End Enum Private Enum SysMenuItemIDEnum SMI_RESTORE = (SMI_FIRST + &H120&) SMI_MOVE = (SMI_FIRST + &H10&) SMI_RESIZE = (SMI_FIRST + &H0&) SMI_MINIMIZE = (SMI_FIRST + &H20&) SMI_MAXIMIZE = (SMI_FIRST + &H30&) SMI_CLOSE = (SMI_FIRST + &H60&) End Enum Private Enum WindowStyleEnum WS_MAXIMIZEBOX = (WS_FIRST + &H10000) WS_MINIMIZEBOX = (WS_FIRST + &H20000) WS_THICKFRAME = (WS_FIRST + &H40000) End Enum ' ******************************************************************** ' lokale (private) Datentypen Private Type MenuItemInfoType cbSize As Long fMask As MenuItemInfoMaskEnum fType As MenuFlagTypeEnum fState As MenuFlagStyleEnum wID As Long hSubMenu As Long hbmpChecked As Long hbmpUnchecked As Long dwItemData As Long dwTypeData As String cch As Long End Type ' ******************************************************************** ' lokale (private) API-Funktionen Private Declare Function DrawMenuBar Lib "user32.dll" ( _ ByVal hMenu As Long) As Long Private Declare Function EnableMenuItem Lib "user32.dll" ( _ ByVal hMenu As Long, _ ByVal wIDEnableItem As Long, _ ByVal wEnable As Long) As Long Private Declare Function GetMenuItemCount Lib "user32.dll" ( _ ByVal hWnd As Long) As Long Private Declare Function GetMenuItemInfo Lib "user32.dll" _ Alias "GetMenuItemInfoA" ( _ ByVal hMenu As Long, _ ByVal uItem As Long, _ ByVal fByPosition As Long, _ ByRef lpMenuItemInfo As MenuItemInfoType) As Long Private Declare Function GetSystemMenu Lib "user32.dll" ( _ ByVal hWnd As Long, _ ByVal bRevert As Long) As Long Private Declare Function GetWindowLong Lib "user32" _ Alias "GetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal wIndx As Long) As Long Private Declare Function RemoveMenu Lib "user32.dll" ( _ ByVal hMenu As Long, _ ByVal nPosition As Long, _ ByVal wFlags As Long) As Long Private Declare Function SetWindowLong Lib "user32.dll" _ Alias "SetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long ' ******************************************************************** ' globale (öffentliche) Methoden Public Sub SetMinMaxButtons(ByVal hWnd As Long, _ ByVal CanMinimize As Boolean, _ ByVal CanMaximize As Boolean, _ Optional ByVal BlockResize As Boolean = True) Const ErrPart1 As String = "Folgender Fehlercode wurde gemeldet: " Const ErrPart2 As String = vbNewLine & "Die Bedeutung dieses " & _ "Fehlercodes ist in der MSDN " & _ "Library nachzulesen." Dim WindowStyle As Long Dim hMenu As Long Dim Result As Long Dim lngMinimize As Long Dim lngMaximize As Long Dim lngResize As Long Dim lngMenuItems As Long Dim i As Long Dim MenuItemInfo As MenuItemInfoType ' Positionen der Menüpunkte "Maximize" und "Minimize" festlegen lngMaximize = 0 lngMinimize = 0 lngResize = 0 ' Aktuelle Eigenschaften des Fensters auslesen WindowStyle = GetWindowLong(hWnd, GWL_STYLE) ' Fehler ins Debug-Fenster schreiben If (WindowStyle = 0) Then Debug.Print ErrPart1 & CStr(Err.LastDllError) & ErrPart2 Else ' Systemmenü referenzieren hMenu = GetSystemMenu(hWnd, 0) If (hMenu <> 0) Then ' Anzahl Einträge im Menü ermitteln lngMenuItems = GetMenuItemCount(hMenu) ' Alle MenuItems durchlaufen (null-basiert!) For i = 0 To lngMenuItems - 1 ' Struktur für den Aufruf vorbereiten With MenuItemInfo .cbSize = Len(MenuItemInfo) .fMask = MenuItemInfoMaskEnum.MIIM_ID .fState = MenuFlagStyleEnum.MFS_DEFAULT End With ' MenuItemInfo auslesen Result = GetMenuItemInfo(hMenu, i, 1, MenuItemInfo) If (Result <> 0) Then ' Minimieren und Maximieren heraussuchen Select Case MenuItemInfo.wID Case SysMenuItemIDEnum.SMI_MAXIMIZE lngMaximize = i Case SysMenuItemIDEnum.SMI_MINIMIZE lngMinimize = i Case SysMenuItemIDEnum.SMI_RESIZE lngResize = i End Select End If Next i End If If (Not (CanMaximize)) And (lngMaximize <> 0) Then ' Maximize-Button entfernen WindowStyle = WindowStyle And Not (WS_MAXIMIZEBOX) ' "Maximize" aus dem Systemmenü entfernen If (hMenu <> 0) Then Result = RemoveMenu(hMenu, lngMaximize, MF_BYPOSITION) Result = EnableMenuItem(hMenu, lngMaximize, _ MF_BYPOSITION Or MF_DISABLED) If (Result = &HFFFFFFFF) Then Debug.Print ErrPart1 & CStr(Err.LastDllError) & _ ErrPart2 End If End If End If If (Not (CanMinimize)) And (lngMinimize <> 0) Then ' Minimize-Button entfernen WindowStyle = WindowStyle And Not (WS_MINIMIZEBOX) ' "Minimize" aus dem Systemmenü entfernen If (hMenu <> 0) Then Result = RemoveMenu(hMenu, lngMinimize, MF_BYPOSITION) Result = EnableMenuItem(hMenu, lngMinimize, _ MF_BYPOSITION Or MF_DISABLED) If (Result = &HFFFFFFFF) Then Debug.Print ErrPart1 & CStr(Err.LastDllError) & _ ErrPart2 End If End If End If ' Resize setzen If (Not (CanMinimize And CanMaximize)) And (BlockResize) And _ (lngResize <> 0) Then WindowStyle = WindowStyle And Not (WS_THICKFRAME) ' "Resize" aus dem Systemmenü entfernen If (hMenu <> 0) Then Result = RemoveMenu(hMenu, lngResize, MF_BYPOSITION) Result = EnableMenuItem(hMenu, lngResize, _ MF_BYPOSITION Or MF_DISABLED) If (Result = &HFFFFFFFF) Then Debug.Print ErrPart1 & CStr(Err.LastDllError) & _ ErrPart2 End If End If End If ' Eigenschaften neu setzen WindowStyle = SetWindowLong(hWnd, GWL_STYLE, WindowStyle) If (WindowStyle = 0) Then Debug.Print ErrPart1 & CStr(Err.LastDllError) & ErrPart2 End If ' Systemmenü neu zeichnen lassen If (hMenu <> 0) Then Call DrawMenuBar(hWnd) End If End If End Sub '--- Ende Modul "mod_ButtonState" alias mod_Buttonstate.bas --- '-------------- Ende Projektdatei Projekt1.vbp --------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
VB5 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
VB6 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
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 2 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 hedgehog am 16.03.2006 um 09:56
Hallo,
ich habe den Bedarf, das "X" auszublenden oder zu disablen. Die Minimize- und Maximize-Buttons können in meiner Anwednung erhalten bleiben. Dieser Tipp kann das nicht (noch nicht). Möglich? Wenn ja, wie?
Kommentar von Henning Klein am 20.09.2005 um 15:13
Der Tip ist ja ganz nett, aber so aufwendig.
Schlieslich kann mit mit Tip 213 (Fensterstile zur Laufzeit ändern) auch jeder MDI-Parent-Form die Min/Max-Buttons entziehen.
Von den anderen Möglichkeiten zur Fenstergestaltung des Tips 213 mal ganz abgesehen.
Henning