Standard-App Symbole (WinWord.exe etc.) fehlerhaft gezeichnet?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Dideldum.

    Standard-App Symbole (WinWord.exe etc.) fehlerhaft gezeichnet?

    Hi Ihr,

    ich habe Probleme mit der Darstellung verschiedener Anwendungs-Symbole in meinem Programm.
    Bei Dark-Theme werden einige Symbole nicht richtig angezeigt, da dann bestimmte Farben durchsichtig sind und an diesen Stellen der dunkle Hintergrund sichtbar ist.
    Bei hellem Theme fällt das Problem nicht auf.

    Davon betroffen sind alle möglichen Anwendungs-Symbolen von denen im Office-Paket über Notepad++ bis hin zu allen möglichen Anwendungssymbolen.

    Diese Symbole lese ich mit solchem Code aus den Anwendungen ein:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub LoadSnippingToolFromSettingsAndAssignToButtons(anwendung As String)
    2. If IO.File.Exists(anwendung) = True Then
    3. Dim base64Icon As String = My.Settings.SnippingTool_Image
    4. If Not String.IsNullOrEmpty(base64Icon) Then
    5. Dim iconBitmap As Bitmap = IconHelper.Base64StringToBitmap(base64Icon)
    6. mnu_MainForm_Extras_SnippingTool.Image = iconBitmap
    7. mnu_MainForm_Extras_SnippingTool.Text = CapitalizeFirstLetter(IO.Path.GetFileNameWithoutExtension(anwendung))
    8. sym_Mainform_SnippingTool.Image = iconBitmap
    9. sym_Mainform_SnippingTool.Text = CapitalizeFirstLetter(IO.Path.GetFileNameWithoutExtension(anwendung))
    10. mnu_MainForm_Extras_SnippingTool.Visible = True
    11. sym_Mainform_SnippingTool.Visible = True
    12. End If
    13. Else
    14. mnu_MainForm_Extras_SnippingTool.Visible = False
    15. sym_Mainform_SnippingTool.Visible = False
    16. End If
    17. End Sub
    18. Private Sub SaveSnippingToolImageToSettings(anwendung As String)
    19. Dim iconBitmap As Bitmap = IconHelper.ExtractIcon(anwendung)
    20. Dim base64Icon As String = IconHelper.BitmapToBase64String(iconBitmap)
    21. My.Settings.SnippingTool_Image = base64Icon
    22. End Sub
    23. Public Class IconHelper
    24. ' Methode zum Extrahieren des Symbols einer EXE-Datei
    25. Public Shared Function ExtractIcon(filePath As String) As Bitmap
    26. Dim icon As Icon = Icon.ExtractAssociatedIcon(filePath)
    27. Return icon.ToBitmap()
    28. End Function
    29. ' Methode zum Konvertieren eines Bitmaps in einen Base64-String
    30. Public Shared Function BitmapToBase64String(bitmap As Bitmap) As String
    31. Using ms As New MemoryStream()
    32. bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
    33. Return Convert.ToBase64String(ms.ToArray())
    34. End Using
    35. End Function
    36. ' Methode zum Konvertieren eines Base64-Strings in ein Bitmap
    37. Public Shared Function Base64StringToBitmap(base64String As String) As Bitmap
    38. Dim imageBytes As Byte() = Convert.FromBase64String(base64String)
    39. Using ms As New MemoryStream(imageBytes)
    40. Return New Bitmap(ms)
    41. End Using
    42. End Function
    43. End Class



    Ich habe schon die verschiedensten Einstellungen für die Symbol-Eigenschaft "ImageTransparentColor" getestet von dem Default-Wert "Magenta" über ""Schwarz" bis zu Web-Transparent.
    Aber immer sehen die Symbole bei dunklem Hintergrund besch...eiden aus.

    Kann ich hier was einstellen, um den dummen Effekt zu unterbinden?

    Beste Grüsse
    Bilder
    • 2024-06-07 20-32-45.jpg

      34,55 kB, 1.278×192, 231 mal angesehen
    • 2024-06-07 20-33-54.jpg

      33,67 kB, 1.275×183, 241 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Dideldum“ ()

    Hab jetzt selbst erstmal versucht ein Icon zu pinseln. Da ist nix transparent, was nicht auch bei der anwendungseigenen Darstellung transparent ist.

    VB.NET-Quellcode

    1. Private bild As Bitmap
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    3. bild = IconHelper.ExtractIcon(path)
    4. End Sub
    5. Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
    6. e.Graphics.DrawImage(bild, New Point(50, 50))
    7. End Sub

    Hi @Haudruferzappeltnoch

    danke Dir für Deine Hilfe. :)

    Ich meine Menustrip mit Menuitems und als Symbolleiste einen Toolstrip mit Toolstrip-Buttons.
    Hast Du auch bei Deinen Tests den Hintergrund der Symbolleiste schwarz eingestellt?
    Bei himmelblauem Hintergrund der Symbolleiste sehe ich kein Problem - nur, wenn diese schwarz ist.
    Wenn ich den Mauszeiger über ein solches Symbol bewege, wird der eigentliche Symbolhintergrund hellblau, aber auch Teile des Symbols selbst.
    Hi @Haudruferzappeltnoch

    Gracias :)
    kann ich erst morgen machen - mein Gute-Nacht-Backup läuft gerade. ^^
    Ich melde mich morgen, mit einem Ergebnis. ;)



    Hi @Haudruferzappeltnoch

    ja, Du hast recht, das Problem tritt generell auf, nicht nur bei Dark-Theme.

    Also, wenn ich das Anwendungssymbol direkt auf die Symbolleiste pinseln lasse:

    VB.NET-Quellcode

    1. Private Sub sym_MainForm_Paint(sender As Object, e As PaintEventArgs) Handles sym_MainForm.Paint
    2. Dim bild As Bitmap = IconHelper.ExtractIcon("C:\Program Files\Microsoft Office\Office16\WINWORD.EXE")
    3. e.Graphics.DrawImage(bild, New Point(0, 0))
    4. End Sub

    Ist alles OK mit dem Alpha-Kanal.

    Nur, wenn ich die Anwendungssymbole im Menustrip einem Menuitem oder in einem Toolstrip einem Toolstrip-Button zuweisen lasse, spinnt die Darstellung des Symbols.

    Wobei es keinen Unterschied macht, ob ich dem Menustrip und dem Toolstrip als BackgroundImage ein Hintergrundbild oder als BackColor eine feste Farbe oder die Farbe Color.transparent zuweise.
    Das Problem besteht in allen Konstellationen.



    Ich habe jetzt versucht, im IconHelper den Alpha-Kanal sauber zu verarbeiten:

    VB.NET-Quellcode

    1. Public Class IconHelper
    2. ' Methode zum Extrahieren des Symbols einer EXE-Datei mit Alpha-Transparenz
    3. Public Shared Function ExtractIcon(filePath As String) As Bitmap
    4. Dim icon As Icon = Icon.ExtractAssociatedIcon(filePath)
    5. If icon IsNot Nothing Then
    6. Using tempBitmap As New Bitmap(icon.Width, icon.Height, PixelFormat.Format32bppArgb)
    7. Using g As Graphics = Graphics.FromImage(tempBitmap)
    8. g.Clear(Color.Transparent)
    9. g.DrawIcon(icon, New Rectangle(Point.Empty, tempBitmap.Size))
    10. End Using
    11. Return New Bitmap(tempBitmap)
    12. End Using
    13. End If
    14. Return Nothing
    15. End Function
    16. end class


    Und lade jetzt die Symbole nicht aus den in My.settings zwischengespeicherten String-Variablen, sondern direkt beim Aufbau der ToolStripButtons und der ToolStripMenuItems;
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub OftBenötigteAppSymboleAnzeigen()
    2. Dim toolStripButtons As ToolStripItem() = {sym_Mainform_OftBenötigteApps1, sym_Mainform_OftBenötigteApps2,
    3. sym_Mainform_OftBenötigteApps3, sym_Mainform_OftBenötigteApps4, sym_Mainform_OftBenötigteApps5,
    4. sym_Mainform_OftBenötigteApps6, sym_Mainform_OftBenötigteApps7, sym_Mainform_OftBenötigteApps8,
    5. sym_Mainform_OftBenötigteApps9, sym_Mainform_OftBenötigteApps10}
    6. Dim toolstripMenuItems As ToolStripMenuItem() = {mnu_Mainform_Extras_OftBenötigteApps1, mnu_Mainform_Extras_OftBenötigteApps2,
    7. mnu_Mainform_Extras_OftBenötigteApps3, mnu_Mainform_Extras_OftBenötigteApps4, mnu_Mainform_Extras_OftBenötigteApps5,
    8. mnu_Mainform_Extras_OftBenötigteApps6, mnu_Mainform_Extras_OftBenötigteApps7, mnu_Mainform_Extras_OftBenötigteApps8,
    9. mnu_Mainform_Extras_OftBenötigteApps9, mnu_Mainform_Extras_OftBenötigteApps10}
    10. Dim paths As New List(Of String) From {LoadOftBenötigteAppsPathFromSettings(0), LoadOftBenötigteAppsPathFromSettings(1),
    11. LoadOftBenötigteAppsPathFromSettings(2), LoadOftBenötigteAppsPathFromSettings(3), LoadOftBenötigteAppsPathFromSettings(4),
    12. LoadOftBenötigteAppsPathFromSettings(5), LoadOftBenötigteAppsPathFromSettings(6), LoadOftBenötigteAppsPathFromSettings(7),
    13. LoadOftBenötigteAppsPathFromSettings(8), LoadOftBenötigteAppsPathFromSettings(9)
    14. }
    15. For i As Integer = 0 To paths.Count - 1
    16. Dim path As String = paths(i)
    17. If path IsNot String.Empty AndAlso IO.File.Exists(path) = True Then
    18. Dim icon As Bitmap = IconHelper.ExtractIcon(path)
    19. If icon IsNot Nothing Then
    20. Dim toolStripMenuItem As ToolStripMenuItem = TryCast(toolstripMenuItems(i), ToolStripMenuItem)
    21. If toolStripMenuItem IsNot Nothing Then
    22. toolStripMenuItem.Image = icon
    23. toolStripMenuItem.ImageTransparentColor = Color.FromArgb(255, 255, 255, 255)
    24. toolStripMenuItem.Text = CapitalizeFirstLetter(IO.Path.GetFileNameWithoutExtension(path))
    25. toolStripMenuItem.Visible = True
    26. End If
    27. Dim toolStripButton As ToolStripButton = TryCast(toolStripButtons(i), ToolStripButton)
    28. If toolStripButton IsNot Nothing Then
    29. toolStripButton.Image = icon
    30. toolStripButton.ImageTransparentColor = Color.FromArgb(255, 255, 255, 255)
    31. toolStripButton.ToolTipText = CapitalizeFirstLetter(IO.Path.GetFileNameWithoutExtension(path))
    32. toolStripButton.Visible = True
    33. End If
    34. Else
    35. Dim toolStripMenuItem As ToolStripMenuItem = TryCast(toolstripMenuItems(i), ToolStripMenuItem)
    36. If toolStripMenuItem IsNot Nothing Then
    37. toolStripMenuItem.Visible = False
    38. End If
    39. Dim toolStripButton As ToolStripButton = TryCast(toolStripButtons(i), ToolStripButton)
    40. If toolStripButton IsNot Nothing Then
    41. toolStripButton.Visible = False
    42. End If
    43. End If
    44. Else
    45. Dim toolStripMenuItem As ToolStripMenuItem = TryCast(toolstripMenuItems(i), ToolStripMenuItem)
    46. If toolStripMenuItem IsNot Nothing Then
    47. toolStripMenuItem.Visible = False
    48. End If
    49. Dim toolStripButton As ToolStripButton = TryCast(toolStripButtons(i), ToolStripButton)
    50. If toolStripButton IsNot Nothing Then
    51. toolStripButton.Visible = False
    52. End If
    53. End If
    54. Next
    55. End Sub


    Leider ohne Erfolg.
    Setze ich die Eigenschaften ImageTransparentColor = Color.FromArgb(255, 254, 254, 254) z.B. auf Color.FromArgb(0, 0, 0, 0) oder Color.FromArgb(255, 0, 0, 0), wird in beiden Fällen das Schwarz, das ich in einem Symbol drin habe aber transparent. Wobei es m.E. aber nur in dem zweiten Fall transparent sein dürfte.
    Und die fehlerhaft angezeigten Symbole scheren sich gar nicht um die ARGB-Settings.

    Ich verstehe nicht, woran das liegen kann. ;(

    Beiträge zusammengefügt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Dideldum schrieb:

    lade jetzt die Symbole nicht aus den in My.settings zwischengespeicherten String-Variablen, sondern direkt beim Aufbau der ToolStripButtons und der ToolStripMenuItems
    Das ja schonmal sinnvoll, dass man die Konvertierungen ausschließen kann.

    Dass es funktioniert, wenn du selbst zeichnest ist merkwürdig. Bei mir geht es auch bei einer Image-Zuweisung, also wenn das Control selbst malt.
    Auch bei einem ToolStripMenuItem nun probiert, da kommt bei mir keine Transparenz rein. Auch mit der ursprünglichen ExtractIcon-Methode.
    Ich krieg bei mir das Problem nicht nachgestellt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Hi @Haudruferzappeltnoch,

    besten Merci für Deine Hilfe. :)

    Was ich bislang festgestellt habe, der sichtbare Falschfarben-Effekt tritt nur wirklich sichtbar auf, wenn ich die ToolstripMenuItem.backColor und die Toolstripbutton.backColor auf eine sehr dunkle Farbe wie color.schwarz und die Symbole auf ca. 30x30Px resize.
    Und es betrifft nur rel. wenige Anwendungssymbole.
    Die meisten werden korrekt gezeichnet.
    Als ob in manchen Anwendungssymbolen die Alpha-Masken nicht wirklich stimmen.



    Hi @Haudruferzappeltnoch

    Geschafft: :)

    VB.NET-Quellcode

    1. toolStripButton.ImageTransparentColor = Color.FromArgb(0, 13, 14, 15)
    2. toolStripButton.BackColor = Color.FromArgb(0, 255, 255, 255)


    ist die Lösung.
    Eine (hoffentlich) unmögliche ARGB-Farbe als undurchsichtig in die ImageTransparentColor und zusätzlich eine undurchsichtige ARGB "Weiss" als Backcolor ergibt Bild siehe Anlage.
    Ohne die gesetzte BackColor habe ich die Farbfehler und ohne die ImageTransparentColor, welche hoffentlich in keinem Symbol verwendet wird, ebenfalls.

    Allerdings verstehe ich nicht, warum es so klappt. :/

    Beiträge zusammengefügt. ~Thunderbolt
    Bilder
    • 2024-06-08 21-32-26.jpg

      44,26 kB, 1.392×225, 228 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()