Gruppen von Menü-Items, die sich wie OptionButtons gegenseitig
auslösen, können Sie in Visual Basic nicht auf direktem Wege
erhalten. Sie können zwar eine Gruppe von Menü-Items selbst
verwalten und entsprechend die Checked-Eigenschaft bei einem Item
aus einer solchen Gruppe setzen und bei den übrigen (bzw. beim
zuvor gesetzten) löschen. Doch ähnlich der unterschiedlichen
Darstellung von CheckBoxen und OptionButtons wird auch in einem
Menü eine Option durch einen Punkt (besser gesagt, durch einen
ausgefüllten kleinen Kreis) dargestellt, und nicht von einem
Häkchen.
Das API bietet jedoch die Möglichkeit, Menü-Items als
Optionsgruppe zu interpretieren und das Setzen der gewählten
Option, das Freigeben der zuvor gesetzten Option und die Darstellung
des Punktes in einem einzigen Aufruf zu erledigen - mit der Funktion
CheckMenuRadioItem.
Ehe Sie diese Funktion aufrufen können, müssen Sie mittels der
API-Funktionen GetMenu und GetSubMenu das Handle des übergeordneten
Menüs ermitteln, das Sie im ersten Parameter an CheckMenuRadioItem
übergeben.
Zunächst ermitteln Sie mit GetMenu
das Hauptmenü des betreffenden Forms. GetSubMenu
liefert Ihnen dann das Handle des Menüpunktes, unter dem sich das
Optionsmenü befinden soll. Hier geben Sie als Index einfach die
abgezählte Position im Hauptmenü an, wobei der erste Menüpunkt
die Positionsnummer 0 hat.
Ihre Definition der Optionsgruppe geben Sie bei jedem Aufruf in
den Parametern First und Last der Funktion CheckMenuRadioItem erneut
an. Auch hier beginnt die Zählung innerhalb des Menüs bei 0.
Falls Sie innerhalb des Menüs (oder auch schon in der
übergeordneten) Menüleiste im Laufe der Anwendung Menüpunkte ein-
oder ausblenden (Eigenschaft Visible eines Menüpunkts), müssen Sie
dies bei allen Zählungen berücksichtigen. In Visual Basic über
die Eigenschaft Visible unsichtbar gesetzte Menüpunkte existieren
nämlich nicht für das Menüsystem aus der Sicht des APIs.
Die ganze Aufruferei samt Ermittlung der Handles können Sie in
eine Hilfsprozedur packen und damit etwas komfortabler gestalten.
Sie übergeben der Hilfsprozedur CheckRadioMenuItem im ersten
Parameter das Form, in dem das Menü erscheint, und im zweiten
Parameter die Position im Hauptmenü. Im dritten, optionalen
Parameter geben Sie den Index des Items an, das als aktive Option
Ihrer Optionsgruppe markiert sein soll.
Dieser Index ist relativ in Bezug auf das Untermenü, in dem die
Optionsgruppe enthalten ist, aber absolut innerhalb Ihrer
Optionsgruppe. Sie geben hier also beispielsweise 1 an,
wenn das erste Item Ihrer Optionsgruppe markiert werden soll, auch
wenn etwa die Optionsgruppe erst beim fünften Item des Untermenüs
beginnen sollte. Lassen Sie den Parameter weg (er ist ja optional),
wird das erste Item der Optionsgruppe als Voreinstellung gewählt.
Übergeben Sie als Index den Wert 0, wird keines der
Items markiert.
Die Optionsgruppe selbst definieren Sie mit den beiden folgenden,
ebenfalls optionalen Parametern. In FromItem geben Sie die Position
des Items an, mit dem die Optionsgruppe beginnen soll, und in ToItem
geben Sie die Position des letzten Items Ihrer Optionsgruppe an.
Lassen Sie FromItem weg, wird das erste Item des Untermenüs als
Beginn der Optionsgruppe betrachtet. Lassen Sie ToItem weg, wird das
letzte Item des Untermenüs über die API-Funktion GetMenuItemCount
ermittelt und als Ende der Optionsgruppe betrachtet. lassen Sie
beide weg, bildet das ganze Untermenü Ihre Optionsgruppe.
Um die Positions-Zählerei zu vereinfachen, können Sie sowohl
bei der Angabe des Untermenüs als auch bei der Definition der
Optionsgruppe die tatsächliche Position angeben - die Zählung
beginnt bei natürlicherweise jeweils bei 1. Dies
entspricht der Voreinstellung (OptionBase1) des letzten optionalen
Parameters (OptionBase) der Funktion CheckRadioMenuItem. Geben Sie
hier ausdrücklich OptionBase0 an, wenn die Zählung API-like mit
0 beginnen soll.
Nun müssen Sie nur noch selbst über eine (am besten Form-weit
gültige) Variable nachhalten, welche Option gewählt ist. Das API
bietet hier keine Unterstützung - es ist allein Ihre Sache.
Private Const MF_BYPOSITION = &H400&
Private Declare Function CheckMenuRadioItem Lib "user32" _
(ByVal hMenu As Long, ByVal First As Long, ByVal Last As Long, _
ByVal Check As Long, ByVal Flags As Long) As Long
Private Declare Function GetMenu Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" _
(ByVal hMenu As Long) As Long
Private Declare Function GetSubMenu Lib "user32" _
(ByVal hMenu As Long, ByVal nPos As Long) As Long
Public Enum OptionBaseConstants
OptionBase0
OptionBase1
End Enum
Public Sub CheckRadioMenuItem(Form As Form, ByVal Menu As Integer, _
Optional ByVal CheckItem As Integer = 1, _
Optional ByVal FromItem As Integer = -1, _
Optional ByVal ToItem As Integer = -1, _
Optional ByVal OptionBase As OptionBaseConstants = OptionBase1)
Dim nMenu As Long
Dim nSubMenu As Long
Dim nFromItem As Integer
Dim nToItem As Integer
Dim nCheckItem As Integer
nMenu = GetMenu(Form.hwnd)
nSubMenu = GetSubMenu(nMenu, Menu - OptionBase)
If FromItem > -1 Then
nFromItem = FromItem - OptionBase
End If
If ToItem = -1 Then
nToItem = GetMenuItemCount(nSubMenu)
Else
nToItem = ToItem - OptionBase
End If
If CheckItem = 0 Then
nCheckItem = -1
Else
nCheckItem = nFromItem + CheckItem - 1
End If
CheckMenuRadioItem nSubMenu, nFromItem, nToItem, _
nCheckItem, MF_BYPOSITION
End Sub
|