Verzeichnisse und Dateien in ListView mit Icons via SHGetFileInfo Lib "shell32.dll"

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von SystemUnknow.

    Verzeichnisse und Dateien in ListView mit Icons via SHGetFileInfo Lib "shell32.dll"

    Hallo Leute,

    nun bin ich an einem Punkt, wo es nicht mehr weitergeht - darum bitte ich Euch um Hilfe.

    Das Problem-Programm ist eigentlich sehr simpel.
    Es ist ein ListView, das mit Verzeichnissen und Dateien ab einem Startverzeichnis gefüllt wird.
    Dabei werden auch noch die kleinen Icons, passend zur Datei bereitgestellt (via SHGetFileInfo und "shell32.dll") und im ListView angezeigt.
    So oder ähnlich findet man es oft im Web..

    Meine Testumgebung ist Windows7 64Bit, administrativer Account.

    1. Beim Programmstart wird das Startverzeichnis "C:\Windows\System32" übergeben - StartButton drücken - alles ok - alle verzeichnisse und Dateien werden angezeigt und die Icons kommen auch komplett.
    2. Nochmal "Start" drücken - gleiches Startverzeichnis -> eine Fehlermeldung kommt und die Dateiliste ist nicht komplett.
    3. Nochmal "Start" drücken - Programm friert ohne Fehlermeldung komplett ein und lässt sich nur noch im Taskmanager abschiessen.

    Irgendwie kommt kein Icon-Index und damit keine Zuordnung eines Icons zur ImageList.

    Aber nach vielen vielen Stunden sehe ich den Wald vor lauter Bäumen nicht mehr.
    Bitte helft mir ein wenig - ok?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Runtime.InteropServices
    4. Public Class frmMain
    5. Private Structure SHFILEINFO
    6. Public hIcon As IntPtr
    7. Public iIcon As Integer
    8. Public dwAttributes As Integer
    9. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
    10. Public szDisplayName As String
    11. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
    12. Public szTypeName As String
    13. End Structure
    14. Private Declare Auto Function SHGetFileInfo Lib "shell32.dll" _
    15. (ByVal pszPath As String, ByVal dwFileAttributes As Integer, _
    16. ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, _
    17. ByVal uFlags As Integer) As IntPtr
    18. Private Const SHGFI_ICON = &H100
    19. Private Const SHGFI_SMALLICON = &H1
    20. Private Const SHGFI_LARGEICON = &H0
    21. Friend nIndex As Long = 0
    22. Dim hImgSmall As IntPtr
    23. Dim shinfo As SHFILEINFO
    24. '// Form Load
    25. Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    26. '// ListView einstellen
    27. With ListView1
    28. .SmallImageList = ImageList1
    29. .View = View.Details
    30. .Columns.Add("Name", 200, HorizontalAlignment.Left)
    31. .Columns.Add("Erw.", 60, HorizontalAlignment.Left)
    32. .Columns.Add("Erstellt", 120, HorizontalAlignment.Left)
    33. End With
    34. shinfo.szDisplayName = New String(Chr(0), 260)
    35. shinfo.szTypeName = New String(Chr(0), 80)
    36. End Sub
    37. '// Button Start
    38. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    39. ListFiles(TextBox1.Text)
    40. End Sub
    41. '// ListView mit Diretorys und Files füllen
    42. Private Sub ListFiles(ByVal sStartDir As String)
    43. shinfo = New SHFILEINFO()
    44. Dim hImgSmall As IntPtr = Nothing
    45. Dim SubItemIndex As Integer
    46. '// ListView leeren, ImageListe leeren
    47. ListView1.Items.Clear()
    48. ImageList1.Images.Clear()
    49. '// Eieruhr
    50. Me.Cursor = Cursors.WaitCursor
    51. ListView1.BeginUpdate()
    52. '// Verzeichnisse
    53. Try
    54. For Each fDirs As String In IO.Directory.GetDirectories(sStartDir)
    55. hImgSmall = SHGetFileInfo(fDirs.ToString, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    56. ImageList1.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))
    57. ListView1.Items.Add(System.IO.Path.GetFileName(fDirs), SubItemIndex)
    58. ListView1.Items(SubItemIndex).SubItems.Add("<DIR>")
    59. ListView1.Items(SubItemIndex).SubItems.Add(IO.File.GetCreationTime(fDirs).ToString("dd.MM.yyyy hh:mm"))
    60. SubItemIndex += 1
    61. Next
    62. Catch ex As Exception
    63. MsgBox(ex.ToString)
    64. End Try
    65. '// Files
    66. Try
    67. For Each file As String In IO.Directory.GetFiles(sStartDir)
    68. hImgSmall = SHGetFileInfo(file.ToString, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    69. ImageList1.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))
    70. ListView1.Items.Add(System.IO.Path.GetFileName(file), SubItemIndex)
    71. ListView1.Items(SubItemIndex).SubItems.Add(IO.Path.GetExtension(file))
    72. ListView1.Items(SubItemIndex).SubItems.Add(IO.File.GetCreationTime(file).ToString("dd.MM.yyyy hh:mm"))
    73. SubItemIndex += 1
    74. Next
    75. Catch ex As Exception
    76. MsgBox(ex.ToString)
    77. End Try
    78. ListView1.EndUpdate()
    79. Me.Cursor = Cursors.Default
    80. End Sub
    81. End Class


    Achso: die Problemfälle sind "C:\Windows\Sytem32" und "C:\Windows\Fonts" (hier knallt es gleich!)

    Anbei die Screenshots, das Programm und das Projekt.

    LG,
    Bruno
    Bilder
    • IconTest_GUI.png

      45,6 kB, 447×636, 350 mal angesehen
    • IconTest_Ex.png

      26,11 kB, 489×229, 261 mal angesehen
    Dateien

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

    Hallo nochmal,

    ich komme gerade von einem Kumpel, der auf seinem PC Vista hat.
    Dort der selbe Effekt (falls es wichtig sein sollte).
    Allerdings gibt es dort keinerlei Probleme mit dem C:\Windows\Fonts Verzeichnis - alles komisch.

    LG und auf Hilfe wartend,
    Bruno
    habe code etwas besser angeschaut.....entferne komplett "hImgSmall".





    MSDN:
    hIconHICONA handle to the icon that represents the file. You are responsible for destroying this handle with DestroyIcon when you no longer need it.


    es währe nicht schlecht wenn speicher auch frei gibst wenn die icons nicht mehr verwendet werden:
    msdn.microsoft.com/en-us/library/ms648063%28v=VS.85%29.aspx

    API kannst gleich in Button_Click aufrufen !

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

    entferne komplett "hImgSmall".
    Sorry - das verstehe ich leider nicht.
    Wenn ich die beiden Zeilen mit "hImgSmall" entferne, kann ja die "SHGetFileInfo" Function der shell32.dll nicht mehr aufgerufen werden - ergo -> keine Icons.
    Meinst Du das vielleicht anders?

    LG,
    Bruno
    Funktion wird aufgerufen !
    hImgSmall verwendest du nie irgends auser:

    VB.NET-Quellcode

    1. hImgSmall = SHGetFileInfo (......)

    wenn dich das so stürtzig macht, dann schreib vor Funktionname "Call"(braucht man nicht unbedingt).

    Sicher ist mir klar, das diese Funktion 2x aufgerufen wird.
    Einmal holt sie sie Icons (besser gesagt die Handles) für die Verzeichnisse und einmal für die Files.

    Mir ist nur unklar, warum Du vorschlägst, das ich sie entfernen soll...

    LG,
    Bruno
    funz nicht ?
    Die Variable brauchst du nicht....habe schon geschrieben warum... !

    Ahh - jetzt ist der Groschen gefallen und ich weiß wie Du es meinst 8-) ..
    Ich rufe jetzt die Funktionen direkt auf - hat sich aber nichts geändert - wüsste auch nicht warum.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Runtime.InteropServices
    4. Public Class frmMain
    5. Private Structure SHFILEINFO
    6. Public hIcon As IntPtr
    7. Public iIcon As Integer
    8. Public dwAttributes As Integer
    9. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
    10. Public szDisplayName As String
    11. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
    12. Public szTypeName As String
    13. End Structure
    14. Private Declare Auto Function SHGetFileInfo Lib "shell32.dll" _
    15. (ByVal pszPath As String, ByVal dwFileAttributes As Integer, _
    16. ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, _
    17. ByVal uFlags As Integer) As IntPtr
    18. Private Const SHGFI_ICON = &H100
    19. Private Const SHGFI_SMALLICON = &H1
    20. Private Const SHGFI_LARGEICON = &H0
    21. Friend nIndex As Long = 0
    22. Dim shinfo As SHFILEINFO
    23. '// Form Load
    24. Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    25. '// ListView einstellen
    26. With ListView1
    27. .SmallImageList = ImageList1
    28. .View = View.Details
    29. .Columns.Add("Name", 200, HorizontalAlignment.Left)
    30. .Columns.Add("Erw.", 60, HorizontalAlignment.Left)
    31. .Columns.Add("Erstellt", 120, HorizontalAlignment.Left)
    32. End With
    33. shinfo.szDisplayName = New String(Chr(0), 260)
    34. shinfo.szTypeName = New String(Chr(0), 80)
    35. End Sub
    36. '// Button Start
    37. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    38. ListFiles(TextBox1.Text)
    39. End Sub
    40. '// ListView mit Diretorys und Files füllen
    41. Private Sub ListFiles(ByVal sStartDir As String)
    42. shinfo = New SHFILEINFO()
    43. Dim SubItemIndex As Integer
    44. '// ListView leeren, ImageListe leeren
    45. ListView1.Items.Clear()
    46. ImageList1.Images.Clear()
    47. '// Eieruhr
    48. Me.Cursor = Cursors.WaitCursor
    49. ListView1.BeginUpdate()
    50. '// Verzeichnisse
    51. Try
    52. For Each fDirs As String In IO.Directory.GetDirectories(sStartDir)
    53. SHGetFileInfo(fDirs.ToString, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    54. ImageList1.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))
    55. ListView1.Items.Add(System.IO.Path.GetFileName(fDirs), SubItemIndex)
    56. ListView1.Items(SubItemIndex).SubItems.Add("<DIR>")
    57. ListView1.Items(SubItemIndex).SubItems.Add(IO.File.GetCreationTime(fDirs).ToString("dd.MM.yyyy hh:mm"))
    58. SubItemIndex += 1
    59. Next
    60. Catch ex As Exception
    61. MsgBox(ex.ToString)
    62. End Try
    63. '// Files
    64. Try
    65. For Each file As String In IO.Directory.GetFiles(sStartDir)
    66. SHGetFileInfo(file.ToString, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    67. ImageList1.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))
    68. ListView1.Items.Add(System.IO.Path.GetFileName(file), SubItemIndex)
    69. ListView1.Items(SubItemIndex).SubItems.Add(IO.Path.GetExtension(file))
    70. ListView1.Items(SubItemIndex).SubItems.Add(IO.File.GetCreationTime(file).ToString("dd.MM.yyyy hh:mm"))
    71. SubItemIndex += 1
    72. Next
    73. Catch ex As Exception
    74. MsgBox(ex.ToString)
    75. End Try
    76. ListView1.EndUpdate()
    77. Me.Cursor = Cursors.Default
    78. End Sub
    79. End Class



    LG,
    Bruno

    WOW!

    Du bist mein "Tagesheld" :P !

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Runtime.InteropServices
    4. Public Class frmMain
    5. Private Structure SHFILEINFO
    6. Public hIcon As IntPtr
    7. Public iIcon As Integer
    8. Public dwAttributes As Integer
    9. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
    10. Public szDisplayName As String
    11. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
    12. Public szTypeName As String
    13. End Structure
    14. Private Declare Auto Function SHGetFileInfo Lib "shell32.dll" _
    15. (ByVal pszPath As String, ByVal dwFileAttributes As Integer, _
    16. ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, _
    17. ByVal uFlags As Integer) As IntPtr
    18. Private Declare Auto Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long
    19. Private Const SHGFI_ICON = &H100
    20. Private Const SHGFI_SMALLICON = &H1
    21. Private Const SHGFI_LARGEICON = &H0
    22. Friend nIndex As Long = 0
    23. Dim shinfo As SHFILEINFO
    24. '// Form Load
    25. Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    26. '// ListView einstellen
    27. With ListView1
    28. .SmallImageList = ImageList1
    29. .View = View.Details
    30. .Columns.Add("Name", 200, HorizontalAlignment.Left)
    31. .Columns.Add("Erw.", 60, HorizontalAlignment.Left)
    32. .Columns.Add("Erstellt", 120, HorizontalAlignment.Left)
    33. End With
    34. shinfo.szDisplayName = New String(Chr(0), 260)
    35. shinfo.szTypeName = New String(Chr(0), 80)
    36. End Sub
    37. '// Button Start
    38. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    39. ListFiles(TextBox1.Text)
    40. End Sub
    41. '// ListView mit Diretorys und Files füllen
    42. Private Sub ListFiles(ByVal sStartDir As String)
    43. shinfo = New SHFILEINFO()
    44. Dim SubItemIndex As Integer
    45. '// ListView leeren, ImageListe leeren
    46. ListView1.Items.Clear()
    47. ImageList1.Images.Clear()
    48. '// Eieruhr
    49. Me.Cursor = Cursors.WaitCursor
    50. ListView1.BeginUpdate()
    51. '// Verzeichnisse
    52. Try
    53. For Each fDirs As String In IO.Directory.GetDirectories(sStartDir)
    54. SHGetFileInfo(fDirs.ToString, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    55. ImageList1.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))
    56. DestroyIcon(shinfo.hIcon)
    57. ListView1.Items.Add(System.IO.Path.GetFileName(fDirs), SubItemIndex)
    58. ListView1.Items(SubItemIndex).SubItems.Add("<DIR>")
    59. ListView1.Items(SubItemIndex).SubItems.Add(IO.File.GetCreationTime(fDirs).ToString("dd.MM.yyyy hh:mm"))
    60. SubItemIndex += 1
    61. Next
    62. Catch ex As Exception
    63. MsgBox(ex.ToString)
    64. End Try
    65. '// Files
    66. Try
    67. For Each file As String In IO.Directory.GetFiles(sStartDir)
    68. SHGetFileInfo(file.ToString, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    69. ImageList1.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))
    70. DestroyIcon(shinfo.hIcon)
    71. ListView1.Items.Add(System.IO.Path.GetFileName(file), SubItemIndex)
    72. ListView1.Items(SubItemIndex).SubItems.Add(IO.Path.GetExtension(file))
    73. ListView1.Items(SubItemIndex).SubItems.Add(IO.File.GetCreationTime(file).ToString("dd.MM.yyyy hh:mm"))
    74. SubItemIndex += 1
    75. Next
    76. Catch ex As Exception
    77. MsgBox(ex.ToString)
    78. End Try
    79. ListView1.EndUpdate()
    80. Me.Cursor = Cursors.Default
    81. End Sub
    82. End Class



    Die Funktion..

    VB.NET-Quellcode

    1. Private Declare Auto Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long


    ..und das zerstören der Icons nach dem Einfügen in die Imagelist..

    VB.NET-Quellcode

    1. DestroyIcon(shinfo.hIcon)


    ..hats doch Tatsache gebracht.

    Vielen lieben Dank dafür!

    LG,
    Bruno