Alternative Taskleiste mit VB programmieren

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

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von Peter329.

    Alternative Taskleiste mit VB programmieren

    Hi,

    meine Windows Taskleiste enthält sehr viele Icons, zur Zeit rund zwei Dutzend.

    Deshalb würde ich gerne eine alternative Taskleiste programmieren. Dieses Programm soll ein Fenster öffnen, das (ähnlich wie die Taskleiste) eine Liste von Icons präsentiert. Durch Klick auf ein Icon soll die dazugehörige Anwendung gestartet werden. Danach wird die alternative Taskleiste wieder minimiert. Und auf diese Weise kann ich die Windows Taskleiste entlasten.

    Natürlich muss die alternative Taskleiste dynamisch aufgebaut werden. D.h. die Icons dürfen nicht fest einprogrammiert sein, sondern müssen dynamisch geladen werden, etwa indem ich alle Programme aus einer bestimmten load library in die alternative Taskleiste aufnehme.

    Wie macht man das am besten ?

    Die erste Frage lautet: wie erhalte ich denn das Icon, das einem Programm zugeordnet ist ?

    Und die zweite Frage ist: Was für ein Control ist zweckmäßig. Eine Datagridview mit einer Zeile und einer variablen Anzahl von Spalten (eine Spalte pro Icon) ? Klingt mir nicht so ganz prickelnd ...

    Ich hoffe, ihr habt ein paar schlaue Ideen !

    LG
    Peter

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Peter329“ ()

    Peter329 schrieb:

    das Icon
    bekommst Du so:

    VB.NET-Quellcode

    1. Using dlg As New OpenFileDialog ' Exe auswählen
    2. dlg.Filter = "EXE Files|*.exe|All files|*.*"
    3. If dlg.ShowDialog <> Windows.Forms.DialogResult.OK Then
    4. Return
    5. End If
    6. Using fs = New IO.FileStream("c:\Temp\___Icon.ico", IO.FileMode.Create)
    7. Dim ico As Icon = Icon.ExtractAssociatedIcon(dlg.FileName)
    8. ico.Save(fs) ' das Icon der Exe speichern
    9. End Using
    10. End Using
    Du kannst die Pfade der zu startenden Exen per D&D auf Deine GUI ziehen und sie in einer Datei anhängen.
    Mach Dir ein Controm (teste ListBox), die die Icons und die Namen der Programme anzeigt und per Doppelklick startet.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Erst mal herzlichen Dank für eure Antworten.

    Ich habe jetzt mal versucht, die Lösung von RFG aufzugreifen, das Icon aus eine .exe Datei zu extrahieren.

    Die Syntax klappt zwar. Aber leider ist das Ergebnis nicht so ganz zufriedenstellend. Das generierte Icon hat nicht die richtige Farbe und außerdem fehlt der Hintergrund im oberen Teil.

    Im Anhang sieht man das generierte Icon und rechts daneben das Icon aus dem Link ...

    Was hab ich falsch gemacht?

    LG
    Peter
    Bilder
    • ExtractIcon.jpg

      21,04 kB, 238×139, 687 mal angesehen

    Peter329 schrieb:

    falsch gemacht
    hast Du nix.
    Teste das ganze mal mit bekannten Icons: Excel, Word, Visual Studio.
    Einige Exen übermalen ihre Icons in der Taskbar, vielleicht hast Du so eine erwischt.
    en Verweis-Pfeil malt das System da rein.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    ok, das sieht so aus, als ob dieser Effekt nur bei diesem einen Icon auftritt ... in allen anderen Fällen, die ich bisher getestet habe, klappt es.

    Trotzdem würde ich jetzt gern nun auch den Ansatz von @Fakiz aufgreifen und eine List View ausprobieren ...

    Wenn ich das richtig verstehe, muss ich mit der ListView.Columns.Add Methode Spalten definieren, also etwa eine für das Icon und eine für den Text:

    VB.NET-Quellcode

    1. 'Define columns
    2. With ListView1.Columns
    3. .Add("Icon")
    4. .Add("Text")
    5. End With


    Bis dahin ist ja alles noch ganz easy.

    Aber nun muss ich die Spalten mit Inhalt füllen. Das macht wohl die Methode "Listview.items.add" ...

    Einen Text String kann ich leicht einstellen, und so die zweite Spalte mit dem Namen der .exe befüllen. Aber wie kriege ich jetzt das Icon der .exe in die erste Spalte der ListView?

    Oder hab ich das was ganz grundlegendes falsch verstanden?

    LG
    Peter
    Du kannst an stelle das Icon zu speichern auch eine ImageList verwenden in die du das Icon lädst.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private imgList As ImageList
    2. Private Sub Form1_Load(sender As Object, e As EventArgs)
    3. imgList = New ImageList()
    4. imgList.ColorDepth = ColorDepth.Depth32Bit
    5. imgList.ImageSize = New System.Drawing.Size(32, 32)
    6. listView1.View = View.SmallIcon
    7. listView1.SmallImageList = imgList
    8. End Sub
    9. Private Sub button1_Click(sender As Object, e As EventArgs)
    10. Using ofd As New OpenFileDialog()
    11. ofd.Filter = "Executable|*.exe"
    12. If ofd.ShowDialog() = DialogResult.OK Then
    13. imgList.Images.Add(Icon.ExtractAssociatedIcon(ofd.FileName))
    14. Dim item As New ListViewItem()
    15. item.Text = ""
    16. item.SubItems.Add(ofd.FileName)
    17. listView1.Items.Add(item).ImageIndex = item.Index
    18. End If
    19. End Using
    20. End Sub

    Jau ... der Ansatz ist doch jetzt supi !

    Das Display sieht jetzt schon ganz manierlich aus ... und alle Icons werden fehlerfrei dargestellt !

    Allerding ist der Abstand der Icons in der Horizontalen noch zu weit. Wie kann man das denn steuern ? Ich habe mal versucht "Tile" zu setzen aber das ändert nix.

    LG
    Peter

    Peter329 schrieb:

    Abstand der Icon
    Poste mal nen Screenshot und mal rein, wie es sein soll.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Voilá ... Ich hab mal spaßeshalber die Windows/System32 aufbereitet ... :)

    Der Abstand der Icons ist zu groß ...

    Außerdem, müsste man irgendwie erkennen können, welches Icon gerade fokussiert wird ... man weiß nie, ob das Icon schon den Focus erhalten halt, oder ob der Mouse Cursor sich noch außerhalb befindet.

    Schlaue Ideen ?

    LG
    Peter
    Bilder
    • Alternate Task Bar .jpg

      72,77 kB, 1.721×79, 193 mal angesehen

    Peter329 schrieb:

    erkennen können
    Was hast Du da für ein Control in Verwendung?
    Mach Dir ggf. ein UserControl, das kannst Du dann gestalten wie Du willst und die einzelnen Instanzen packst Du in ein FlowlayoutPanel.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ganz einfach über die Ansicht Tile und einer angepassten Größe.

    VB.NET-Quellcode

    1. listView1.View = View.Tile
    2. listView1.TileSize = New Size(40, 40)
    3. listView1.LargeImageList = imgList


    PS: Beim 1. Bild ist das 1. Item selektiert.
    Bilder
    • tileSize.png

      19,88 kB, 303×136, 160 mal angesehen
    • tileSize.png

      22,09 kB, 301×132, 179 mal angesehen
    Na, das Control ist die ListViewBox ...

    Mhh ... gut, ein eigenes Control basteln ist natürlich so eine Sache ... denn die Icon Darstellung funktioniert eben der Property:

    VB.NET-Quellcode

    1. ListView1.View = View.SmallIcon


    Wenn man das selbst zusammen baut, dann bin ich ja wieder da wo ich am Anfang stand, wie ich die Icon in die Control kriege ! Und das ist ja nun offensichtlich nicht ganz so trivial ...

    Die Frage ist, ob es irgendwo eine Eigenschaft gibt, mit der man die Zellengröße steuern kann ... denn bis auf ein paar Kleinigkeiten sieht meine Alternate Task Bar nämlich schon ganz manierlich aus ...

    [edit]

    Den Beitrag von Fakiz hab ich erst nach dem Senden gesehen.

    @Fakiz

    Suuuuuuupiiiiii ! Damit kann man den Abstand der Icons hervorragend einstellen ! Ich bin begeistert.

    Wenn ich jetzt noch wüsste, wie man das Icon irgendwie kenntlich machen kann, das den Fokus hat, dann wäre ich restlos glücklich ! Bei mir ändert sich nämlich nichts an der Helligkeit, wenn der Cursor über einem der angezeigten Icons schwebt. Das Icon "erblasst" erst, wenn ich das Icon ausgewählt, also angeklickt habe.

    Naiv wie ich nun mal bin, hab ich das MouseHover Event ausprobiert:

    VB.NET-Quellcode

    1. Private Sub ListView1_MouseHover(sender As Object, e As System.EventArgs) Handles ListView1.MouseHover
    2. Dim i As Integer = ListView1.SelectedIndices(0)
    3. Label1.Text = i.ToString
    4. End Sub


    Aber das liefert Exceptions, weil kein Item ausgewählt ist ... Auch ist mir nicht so ganz klar, wann das MouseHover Event feuert ... Irgendwie kriege ich das nicht gebacken !



    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Peter329“ ()

    Peter329 schrieb:

    kein Item ausgewählt
    Klar, es ist ja auch keins ausgewählt.
    Du musst Dir das Control unter dem Mauszeiger holen, gugst Du hier.
    Achtung, das ist VB6-Code, Du musst alle Deklarationen auf .NET umstellen. Gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Die ListView verfügt über die Eigenschaft HideSelection diese Eigenschaft ist im Normalfall auf true. Es werden also Items die selektiert sind nach dem verlust des Fokus nicht mehr als selektiert makiert. Ich hoffe du meinst das.

    *Edit*
    ich hab dich falsch verstanden...
    Bei mir ändert sich nämlich nichts an der Helligkeit, wenn der Cursor über einem der angezeigten Icons schwebt


    Hierfür stellt die ListView die Eigenschaft HoverSelection zur verfügung.

    VB.NET-Quellcode

    1. ListView1.HoverSelection = True


    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Fakiz“ ()

    Danke erst mal an euch beide, dass ihr so viel Geduld mit mir habt.

    @RFG

    Bist du dir sicher, dass dein Code Beispiel in die richtige Richtung geht? Da wird alle 10 Millisekunden ein Timer gestartet ... und der guckt dann nach, ob der Mousezeiger über einem Control schwebt, um dann den Text dieser Control anzuzeigen.

    Ich meine, das hilft mir nicht weiter. Denn in meinem Beispiel hab ich doch nur eine EINZIGE Control, nämlich die ListView. Denn ich will doch folgendes erreichen:

    Wenn der Mouse Cursor innerhalb der ListView Control über einem Icon schwebt, dann soll dieses Icon irgendwie kenntlich gemacht werden.

    @Fakiz

    Aus gleichen Grund meine ich, hilft mir auch die Sache mit der HideSelection nicht weiter.

    Was möchte ich?

    Wenn meine Alternative Action Bar angezeigt wird und ich mit dem Cursor darüber fahre, dann soll jeweils das Icon, welches gerade den Focus hat irgendwie gekennzeichnet werden ... also etwa indem ein Rahmen um die Zelle gezeichnet wird. Sobald der Cursor das Icon verlässt, soll auch die Kennzeichnung wieder verschwinden ...

    Diese Technik verwendet etwa der Windows Explorer in der "Medium Icon View" oder der "Large Icon View"

    Ich hoffe, ich habe mein Anliegen verständlich machen können.

    Geht sowas mit der List View Control ?

    Peter329 schrieb:

    ein Timer gestartet
    Das kannst Du doch durch Dein Hover ersetzen.
    Ich hab die Timer-Methode mal in .NET umgeschrieben:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True)> _
    4. Public Shared Function GetCursorPos(ByRef lpPoint As System.Drawing.Point) As <MarshalAs(UnmanagedType.Bool)> Boolean
    5. End Function
    6. <DllImport("user32.dll")> _
    7. Private Shared Function WindowFromPoint(ByVal p As Point) As IntPtr
    8. End Function
    9. <DllImport("user32.dll", EntryPoint:="GetWindowText")>
    10. Public Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    11. End Function
    12. Private Const WM_GETTEXT = &HD
    13. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    14. Timer1.Enabled = Not Timer1.Enabled
    15. End Sub
    16. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    17. Dim oPoint As Point
    18. Dim hWnd As IntPtr
    19. Dim lLength As Integer
    20. Dim sWindowText As New System.Text.StringBuilder(256)
    21. ' Mausposition ermitteln
    22. If GetCursorPos(oPoint) Then
    23. ' Fensterhandle des Controls, auf dem sich
    24. ' der Mauszeiger befindet
    25. hWnd = WindowFromPoint(oPoint)
    26. ' Fenstertext des Controls ermitteln
    27. lLength = GetWindowText(hWnd, sWindowText, sWindowText.Capacity)
    28. ' Handle anzeigen
    29. Label1.Text = hWnd.ToString
    30. ' Mausposition anzeigen
    31. Label2.Text = "x " & oPoint.X & " y " & oPoint.Y
    32. ' Fenstertext anzeigen
    33. Label3.Text = sWindowText.ToString
    34. End If
    35. End Sub
    36. End Class

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    .HoverSelection = True

    Das ist die fabelhafte Eigenschaft nach der ich gesucht hatte ! DANKE ! :)

    Wow, ihr beiden, das war eine schwierige Geburt ... aber jetzt bin ich RESTLOS begeistert!

    Meine alternative Task Leiste funktioniert prima ... gerade mal 65 Zeilen Code ... und ich kann endlich meine Windows Task Bar wieder frei räumen!

    Ihr habt meinen Tag gerettet ! Danke nochmal an alle Ratgeber !

    LG
    Peter