Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0139: Bitmaps vor MenüItem setzen

 von 

Beschreibung 

Windows erlaubt es bei bekanntem Menühandle, eine kleine Grafik vor jeden Eintrag zu setzen. Es ist ein leichtes dies auch mit VB über die entsprechenden APIs zu machen. Das tolle daran ist, daß es egal ist um welches Menü es sich handelt, also auch im Systemmenü anwendbar.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

AppendMenuA (AppendMenu), GetMenu, GetSubMenu, GetSystemMenu, SetMenuItemBitmaps

Download:

Download des Beispielprojektes [5,09 KB]

'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 Project1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Bildfeld-Steuerelement "Picture8"
' Steuerelement: Bildfeld-Steuerelement "Picture7"
' Steuerelement: Bildfeld-Steuerelement "Picture6"
' Steuerelement: Bildfeld-Steuerelement "Picture5"
' Steuerelement: Bildfeld-Steuerelement "Picture4"
' Steuerelement: Bildfeld-Steuerelement "Picture3"
' Steuerelement: Bildfeld-Steuerelement "Picture2"
' Steuerelement: Bildfeld-Steuerelement "Picture1"
' Steuerelement: Beschriftungsfeld "Label1"
' Steuerelement: Menü "mnuMenü"
' Steuerelement: Menü "a" auf mnuMenü
' Steuerelement: Menü "b" auf mnuMenü
' Steuerelement: Menü "c" auf mnuMenü
' Steuerelement: Menü "d" auf mnuMenü
' Steuerelement: Menü "mnuExtras"
' Steuerelement: Menü "e" auf mnuExtras
' Steuerelement: Menü "f" auf mnuExtras
' Steuerelement: Menü "g" auf mnuExtras
' Steuerelement: Menü "h" auf mnuExtras

Option Explicit

Private Declare Function GetMenu Lib "user32" (ByVal _
        hwnd As Long) As Long
        
Private Declare Function GetSubMenu Lib "user32" (ByVal _
        hMenu As Long, ByVal nPos As Long) As Long

Private Declare Function SetMenuItemBitmaps Lib "user32" _
        (ByVal hMenu As Long, ByVal nPosition As Long, _
        ByVal wFlags As Long, ByVal hBitmapUnchecked As _
        Long, ByVal hBitmapChecked As Long) As Long

Private Declare Function GetSystemMenu Lib "user32" (ByVal _
        hwnd As Long, ByVal bRevert As Long) As Long
        
Private Declare Function AppendMenu Lib "user32" Alias _
        "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As _
        Long, ByVal wIDNewItem As Long, ByVal lpNewItem As _
        String) As Long

Const MF_STRING = &H0&
Const MF_SEPARATOR = &H800&
Const MF_BYPOSITION = &H400&
Const MF_BYCOMMAND = &H0&

Private Sub Form_Load()
  Dim h1&, h2&
    h1 = GetMenu(Me.hwnd)
    h2 = GetSubMenu(h1, 0)
    Call SetMenuItemBitmaps(h2, 0, MF_BYPOSITION, _
                            Picture1.Picture, Picture1.Picture)
    Call SetMenuItemBitmaps(h2, 1, MF_BYPOSITION, _
                            Picture2.Picture, Picture2.Picture)
    Call SetMenuItemBitmaps(h2, 2, MF_BYPOSITION, _
                            Picture3.Picture, Picture3.Picture)
    Call SetMenuItemBitmaps(h2, 3, MF_BYPOSITION, _
                            Picture4.Picture, Picture4.Picture)
    
    h2 = GetSubMenu(h1, 1)
    Call SetMenuItemBitmaps(h2, 0, MF_BYPOSITION, _
                            Picture5.Picture, Picture5.Picture)
    Call SetMenuItemBitmaps(h2, 1, MF_BYPOSITION, _
                            Picture6.Picture, Picture6.Picture)
    Call SetMenuItemBitmaps(h2, 2, MF_BYPOSITION, _
                            Picture7.Picture, Picture7.Picture)
    Call SetMenuItemBitmaps(h2, 3, MF_BYPOSITION, _
                            Picture8.Picture, Picture8.Picture)
    
    h1 = GetSystemMenu(hwnd, False)
    Call AppendMenu(h1, MF_SEPARATOR, 0, "")
    Call AppendMenu(h1, MF_STRING, &H200, "B&efehl 1")
    Call AppendMenu(h1, MF_STRING, &H201, "Be&fehl 2")
    Call AppendMenu(h1, MF_STRING, &H202, "Bef&ehl 3")
    Call AppendMenu(h1, MF_STRING, &H203, "Befe&hl 4")
    
    Call SetMenuItemBitmaps(h1, &H200, MF_BYCOMMAND, _
                            Picture1.Picture, Picture1.Picture)
    Call SetMenuItemBitmaps(h1, &H201, MF_BYCOMMAND, _
                            Picture2.Picture, Picture2.Picture)
    Call SetMenuItemBitmaps(h1, &H202, MF_BYCOMMAND, _
                            Picture3.Picture, Picture3.Picture)
    Call SetMenuItemBitmaps(h1, &H203, MF_BYCOMMAND, _
                            Picture4.Picture, Picture4.Picture)

End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Project1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

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 25 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 Klaus am 03.11.2008 um 14:28

Hallo,

Gibt es keine Antwort auf die Frage von:
Michael Laege am 09.09.2001 um 19:50 ???

Kommentar von Traxus am 24.07.2007 um 16:10

Bilder für die Untermenüs: BEISPIEL
1.Fürs erste Menüpunkt (im obigen Beispiel „a“) ein Untermenü erstellen
2.diesen Code für „Form_Load“ ersetzen

Private Sub Form_Load()
Dim h1&, h2&, h3&
h1 = GetMenu(Me.hwnd)
h2 = GetSubMenu(h1, 0)
h3 = GetSubMenu(h2, 0)
Call SetMenuItemBitmaps(h2, 0, MF_BYPOSITION, _
Picture3.Picture, Picture3.Picture)
Call SetMenuItemBitmaps(h3, 0, MF_BYPOSITION, _
Picture2.Picture, Picture2.Picture)
End Sub

Dann müsste es klappen

Kommentar von Fabian Camps am 20.12.2005 um 08:47

Alles zu schwirig

Kommentar von Jörg Döring am 28.08.2005 um 02:07

Welche Größe haben diese Bitmaps max und welche Farbtiefe ?

Kommentar von password am 06.11.2004 um 19:12

@Sammy: Das Systemmenü ist das, welches erscheint, wenn du auf den Icon links oben in der Fenster-Leiste oder unten auf den entsprechenden Eintrag in der Taskleiste (hier rechts-) klickst. Im allgemeinen Erscheinen hier die Von Windows verwalteten Optionen Schließen, maximieren, minimieren etc...

Ich denke, viele Leute interessiert, wie man auch beim Highlight normale (nicht invertierte) und hervorgehobene Bilder bekommt. Mich auch. Allerdings finde ich, solltet ihr das Geheimnis rausrücken: Derjenige, der den ApiViewer 2004 (ein super Tool) programmiert hat, weiss es ja anscheinend...

Kommentar von Schü am 02.07.2004 um 11:21

Hallo!

Diser Tipp funktioniert gut! Ich habe die Bilder in eine ImageList gapackt und über ImageList1.Listitems(i).Picture angesprochen. Das geht einfacher.

Allerdings habe ich ein Popupmenü , das natürlich mit Visible=False unsichtbar ist. Dort klappt das setzen des Bildes nicht, da bei jedem Aus/Einblenden des entsprechenden Menüs die Bitmaps wieder verschwinden!!

Wie bekomme ich diese in ein PopupMenü??

Kommentar von Sammy am 04.06.2004 um 20:09

Der Autor hat Geschrieben:

"...also auch im Systemmenü anwendbar."

Frage: Was ist ein Systemmenü=

Kommentar von AMH am 02.04.2004 um 14:18

Hinweis zu Tipp 139: Die AddressOf-Funktion darf laut Doku nur in Globalmodulen, nicht in Form-Modulen verwendet werden.

Kommentar von Jürgen Simon am 04.02.2004 um 12:50

Ansich funktioniert es so, aber:
Die Größe des Icons sollte nicht fest auf 13 * 13 Pixel eingestellt sein sonder mit:
1.

Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Const SM_CXMENUCHECK = 71&
Const SM_CYMENUCHECK = 71&
abgefragt werden.
2. Bei selbst gezeichneten Bildern muss AutoRedraw=True gesetzt werden und vor der Zuweisung mit SetMenuItemBitmap mit
Picture.Picture=Picture.Image

die ImageEigenschaft an die PictureEigenschaft zugewiesen werden. Dann sollte alles funktionieren.
Größere Bilder als mit GetSystemMetrics (normalerweise 13*13) ermittelt sind nicht drin.

Kommentar von DNS13 am 13.10.2003 um 15:51

also *.ico geht bei mir nicht :(

kann man auch größere Bilder wie 16 x 16 machen?

Kommentar von Jonathan Haas am 03.10.2003 um 11:49

Also bei mir gehts auch in MDI-Forms.

Kommentar von Sebbi-Webbi am 02.07.2003 um 04:26

Ich weiß nicht wie ihr euch anstellt - *.ico-Files oder Untermenüs läuft bei mir!
Aber wahrscheinlich stell ich mich auch nicht besser an denn bei Menüs von MDIForms und MDIChilds krieg ichs dann auch nicht mehr gebacken!Weiß jemand Rat oder ne andere Methode mit der es möglich ist?
MfG
Sebbi-Webbi

Kommentar von Timm Linder am 25.02.2003 um 15:47

Professionelle Programme wie VB oder Office gehen das Problem anders an. Diese Programme verwenden nicht die "standardmäßigen" Menüs, die mit Windows "mitgeliefert" werden, sondern Zusatz-Steuerelemente, die solche Bitmaps unterstützen. Des Weiteren unterstützen diese Controls auch andere nützliche Funktionen, z.B. kann man bei Word die Menüs selbst "auseinanderbauen", d.h. man kann die Einträge verschieben usw..

Kommentar von Dominik Dunst am 20.06.2002 um 18:47

Wei bekomme ich ein Icon in ein Untermenü??
bitte antworten

Kommentar von -=[V-F]=-Neuroquila am 25.03.2002 um 14:07

wie schon hier viele verzweifelt sind, bin ich erst recht...vorallem wenn solche beispiele nicht richtig auskommentiert sind und sehr schwer zu verstehen sind...irgendwie soll man sich doch den code merken können, oder?naja auf jeden fall hier mein problem:ich verwende ebenfalls bitmaps(16x16)naja auf jeden fall nachdem ich den code ausgeführt habe, wurde das menü des inetexplorers mit diesen bitmaps gefüllt; nach beendigung wieder auf den urzustand gesetzt. ich weiss ja nicht was hier falsch läuft und ob es damit zusammenhängt, das ich mit vb 5 arbeite aber nach so vielen leudem mit probs würde ich mir mal gedanken machen ob nun der code nicht stimmt.
ich schau jetzt erst mal woanders :P
vielleicht finde ich dort besser auskommentierte tips *g*
trotzdem mfg DaGiNsI alias -=[V-F]=-Neuroquila

Kommentar von Roman Studer am 19.02.2002 um 16:28

Wenn ich Untermenus habe, wie kriege ich dort ein Icon (Bitmap) hinein?

Kommentar von David E. am 07.01.2002 um 00:51

Hab den Tip jetzt mal ausprobiert, und ich war entäuscht. Weder mein Gehalt hatte sich erhöht, noch fand ich meinen Chef im Mülleimer vor. Das mit dem Tag rückgangig machen habe ich mich nicht getraut. Vielleicht schaut ihr mal nach was da nicht stimmt.
Mfg
David E.

Kommentar von Michael Zimmermann am 13.09.2001 um 09:56

Warum funktioniert das bei mir nicht?
Wenn ich die Beispielanwendung laufen lasse, klappts.
Ersetz ich die Bilder aber durch eigene klappts nicht.
Hab *.ico(32x32) und *.bmp (32x32 und 13x13)versucht.

Kommentar von Michael Laege am 09.09.2001 um 19:50

Das klappt ja schon ganz gut.
Wie kann ich aber verhindern, dass die Bitmap invertiert dargestellt wird, wenn der Eintrag markiert ist?
Ich denke dabei an solche Menüeinträge von professionelleren Programmen wie z.B. Visual Basic. Dabei werden die Grafiken nämlich nicht invertiert, sondern hervorgehoben.

Kommentar von Steffen Bracke am 15.08.2001 um 22:29

Hier ist nochmal Steffen.
Aufgrund das einige Programmierer Schwierigkeiten mit Bildern im Menü haben, hab ich mal schnell eine Beispielanwendung aus bereits verwendeten Anwendungen zusammengestellt, die ich gern zur Verfügung stellen möchte, da ich von vbarchiv mir ebenfalls einige Sachen hab herunterladen können.
Vielen Dank und kontaktieren sie mich mal.
Bis bald und Gruß Steffen.

Kommentar von Steffen Bracke am 15.08.2001 um 21:13

Ich hab mal in einer Computerzeitschrift über dieses Thema gelesen (Verfasser Ralf Nebelo)und mich darüber hergemacht. Leider ist es auch mir nicht gelungen, weiße Bildanteile im Menübefehl auch weiß darzustellen. Aber es ist wichtig die Bitmap richtig zupositionieren und die Bitmap muss das richtige Format haben. Geduld, es geht...

Kommentar von Ellen am 09.03.2001 um 20:25

Schöner Tip... hat mich jetzt Stunden gekostet und ich krieg's nicht auf die Reihe...
Wie kann ich dem "TagesMenü" und "Extra" ein Bitmap voranstellen?
Bin bei SetMenuItemInfo gelandet, aber egal ob ich dem TagesMenü oder Extra ein Bitmap verpassen will, immer wird das Tagesmenü durch die dösige Windows-Fahne ersetzt.
Gibt's Hilfe????

Kommentar von Thomas Hoffmann am 28.02.2001 um 11:12

Wenn die Bitmaps noch immer nicht angezeigt werden kann es daran liegen, daß die Position des Menüeintrags nicht richtig ist. Mit GetMenuItem(hwnd as Long, nPos as Long) as Long lässt sich das umgehen. (Bsp.: SetMenuItemBitmap(h2, GetMenuItem(h2,1), MF_BYPOSITION, Picture1, Picture2), dabei wird aus dem Menü der zweite Eintrag mit einem Bild versehen). Die Bilder müssen Bitmaps sein und man muß beachten, daß alles was Weiß beim Bitmap ist transparent wird. Bitmaps werden auch nur dann vor den Menüeintrag gesetzt, wenn der Eintrag kein Untermenü enthält.

Kommentar von Götz Reinecke am 14.10.2000 um 18:59

Hallo Mathias,
mhm, eigentlich sollten es auch Bitmaps sein und keine Icons. Letztere haben ein ganz anderes Format.
Grüße
Götz

Kommentar von Matthias Bartelt am 14.10.2000 um 15:51

Ich bin am Verzweifeln: Wenn ich ein Icon des Beispiel-Projektes durch mein eigenes ersetze, wird es nicht angezeigt. Mein Icon ist auch 13*13 Pixel groß. Ich habe alles versucht (Auch die Farbanzahl herunterstellen). Ich mache meine Icons mit Microangelo. Warum gehen meine eigenen Icons nicht ?