Menu Owner Draw

  • VB.NET

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von Lost-Ha[n]f-PHP.

    Menu Owner Draw

    Hallo Leute,

    ich habe ein bisschen Source gesucht, mit dem ich meine Items selber zeichnen kann. So habeich dort jetzt auch Icons und Bilder. Die Hintergrundfarbe konnte ich aendern. Jetzt will ich nur noch 2 Sachen haben.

    1: wenn ich ueber einem Item bin, soll es nicht in std-Blau gezeichnet werden sondern in einer benutzerdefinierten Farbe.
    2:Die Shortcuts sollen buendig an der rechten Seite angezeigt werden.

    Koennt ihr mir helfen? Ich schicke euch mal kurz den ganzen code:

    <pre>
    Private Sub AddHandlerForAllMenuItems(ByVal mitems As Menu.MenuItemCollection)
    Dim mi As MenuItem
    For Each mi In mitems
    AddHandler mi.Click, AddressOf MenuItems_Click
    AddHandler mi.MeasureItem, AddressOf MenuItems_MeasureItem
    AddHandler mi.DrawItem, AddressOf MenuItems_DrawItem
    mi.OwnerDraw = True
    ' Prozedur rekursiv aufrufen
    AddHandlerForAllMenuItems(mi.MenuItems)
    Next
    End Sub

    Private Sub MenuItems_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim mi As MenuItem = CType(sender, MenuItem)
    If mi Is mnuBeenden Then Close()
    End Sub

    ' Sammelprozedur zur Ermittlung des Platzbedarfs für alle Menüeinträge
    Private Sub MenuItems_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs)
    Dim mi As MenuItem = CType(sender, MenuItem)
    Dim fnt As Font = SystemInformation.MenuFont
    Dim sf As New StringFormat
    sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show
    If mi.Text = "-" Then
    e.ItemHeight = 10
    Else
    e.ItemHeight = SystemInformation.MenuHeight
    End If
    e.ItemWidth = CInt(e.Graphics.MeasureString(mi.Text + GetShortcutText(mi), fnt, 0, sf).Width + 10)
    If mi.Parent Is mmMain Then
    e.ItemWidth -= 10
    Else
    e.ItemWidth += SystemInformation.MenuButtonSize.Width
    End If
    End Sub

    ' Sammelprozedur zum Zeichnen aller Menüeinträge
    Private Sub MenuItems_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)
    Dim mi As MenuItem = CType(sender, MenuItem)
    Dim fnt As Font = SystemInformation.MenuFont
    Dim brText, brBack, brIcon As Brush
    Dim sf As New StringFormat
    Dim rfAll, rfText, rfIcon As RectangleF
    Dim gr As Graphics = e.Graphics

    ' Ausgaberechteck für Text und Icons
    rfAll = RectangleF.op_Implicit(e.Bounds)
    rfText = rfAll
    rfIcon = rfAll
    If mi.Parent Is mmMain Then
    rfText.X += 4
    rfText.Width -= 2
    Else
    rfText.X += SystemInformation.MenuButtonSize.Width + 4
    rfText.Width -= SystemInformation.MenuButtonSize.Width + 4
    rfIcon.Width = SystemInformation.MenuButtonSize.Width
    End If


    ' Hintergrund zeichnen
    If e.BackColor.Equals(SystemColors.Window) Then
    ' normale Darstellung, per Default weiß
    If mi.Parent Is mmMain Then
    brBack = New SolidBrush(SystemColors.Control)
    Else
    brBack = New SolidBrush(Color.FromArgb(255, 255, 255))
    End If
    brIcon = New SolidBrush(SystemColors.Control)
    Else
    ' inverse Darstellung
    brBack = New SolidBrush(e.BackColor)
    brIcon = brBack
    End If
    e.Graphics.FillRectangle(brBack, rfAll)

    ' Hintergrund für die Iconspalte zeichnen
    If Not (mi.Parent Is mmMain) Then
    gr.FillRectangle(brIcon, rfIcon)
    End If

    ' Rahmen zeichnen
    If (e.State And DrawItemState.HotLight) = DrawItemState.HotLight Then
    Dim rect As Rectangle
    rect = e.Bounds
    rect.Inflate(-1, -1)
    gr.DrawRectangle(Pens.Gray, rect)
    End If

    ' Text-/Linienausgabe
    If mi.Text = "-" Then
    gr.DrawLine(Pens.Gray, rfText.X + 2, rfText.Y + 4, rfText.Right - 2, rfText.Y + 4)
    Else
    ' Textfarbe je nach Enabled-Zustand
    If mi.Enabled Then
    brText = New SolidBrush(e.ForeColor)
    Else
    brText = New SolidBrush(Color.DarkGray)
    End If
    sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show
    e.Graphics.DrawString(mi.Text + GetShortcutText(mi), _
    fnt, brText, rfText, sf)
    End If

    ' Checkbox / Icon darstellen
    If mi.Checked Then
    Dim x0, y0 As Single
    Dim pn As Pen
    x0 = rfAll.X + 5
    y0 = rfAll.Y + 5
    gr.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
    If mi.RadioCheck Then
    gr.FillEllipse(brText, x0, y0, 8, 8)
    Else
    pn = New Pen(brText, 2)
    gr.DrawLine(pn, x0, y0 + 4, x0 + 4, y0 + 8)
    gr.DrawLine(pn, x0 + 4, y0 + 8, x0 + 12, y0)
    End If
    Else
    Dim pt As New Point(CInt(rfAll.X + 2), CInt(rfAll.Y + 2))
    If mi Is mnuDatensicherung Then
    gr.DrawImageUnscaled(imglstMenu.Images(0), pt)
    ElseIf mi Is mnuDrucken Then
    gr.DrawImageUnscaled(imglstMenu.Images(1), pt)
    End If
    End If

    ' aufräumen
    If Not IsNothing(brBack) Then brBack.Dispose()
    If Not IsNothing(brText) Then brText.Dispose()
    If Not IsNothing(brIcon) Then brIcon.Dispose()
    If Not IsNothing(sf) Then sf.Dispose()
    End Sub

    ' Tastenkürzel zum Menüeintrag in Textform ermitteln
    Private Function GetShortcutText(ByVal mi As MenuItem) As String
    Dim s As String
    Dim Lenge As Integer = 30
    Dim i As Integer

    If mi.Shortcut <> Shortcut.None Then
    s = " (" + mi.Shortcut.ToString("g", Globalization.CultureInfo.CurrentCulture()) + ")"
    End If
    Return s
    End Function
    </pre>

    Aufgerufen wird alles im Form_Load mit: AddHandlerForAllMenuItems(mmMain.MenuItems)

    'mmMain ist das MainMenu!!!

    Bitte helft mir!

    DANKE
    Habe jetzt die OverFarbe hinbekommen.

    Jetzt habe ich ein neues Problem:
    Wenn ich jetzt ueber das menu gehe, bleibt immer ein Rahmen am den Raendern.
    (Das hat nichs mit der Farbe zu tun sondern mit dem Rentakle gezeichne). Wie bekomme ich die Rahmen wieder weg???