Results 1 to 7 of 7

Thread: how can I get the system icon associated with folders?

  1. #1

    Thread Starter
    l33t! MrPolite's Avatar
    Join Date
    Sep 2001
    Posts
    4,428

    how can I get the system icon associated with folders?

    I use SHGetFileInfo to get the icons associted with different file types, but how can I get the system icon for a folder?
    rate my posts if they help ya!
    Extract thumbnail without reading the whole image file: (C# - VB)
    Apply texture to bitmaps: (C# - VB)
    Extended console library: (VB)
    Save JPEG with a certain quality (image compression): (C# - VB )
    VB.NET to C# conversion tips!!

  2. #2
    Frenzied Member <ABX's Avatar
    Join Date
    Jul 2002
    Location
    Canada eh...
    Posts
    1,622

    Re: how can I get the system icon associated with folders?

    This quite a pain in the ass because of the alpha layer but it is do able:

    VB Code:
    1. Option Strict On
    2. Option Explicit On
    3.  
    4. Imports System.Runtime.InteropServices
    5.  
    6. Imports System.Drawing.Imaging
    7.  
    8. Public Class FileIconExtractor
    9.  
    10. #Region " API "
    11.  
    12.     <DllImport("shell32.dll", EntryPoint:="SHGetFileInfo")> _
    13.     Private Shared Function SHGetFileInfo(ByVal Path As String, ByVal FileAttributes As Integer, ByRef FileInfo As SHFILEINFO, ByVal FileInfoLength As Integer, ByVal Flags As SHGFI) As Integer
    14.  
    15.     End Function
    16.  
    17.     <Flags()> Private Enum SHGFI
    18.         SmallIcon = &H1
    19.         LargeIcon = &H0
    20.         Icon = &H100
    21.         DisplayName = &H200
    22.         Typename = &H400
    23.         SysIconIndex = &H4000
    24.         UseFileAttributes = &H10
    25.     End Enum
    26.  
    27.     <StructLayout(LayoutKind.Sequential)> _
    28.     Private Structure SHFILEINFO
    29.         Public hIcon As IntPtr
    30.         Public iIcon As Integer
    31.         Public dwAttributes As Integer
    32.         <MarshalAs(UnmanagedType.LPStr, SizeConst:=260)> Public szDisplayName As String
    33.         <MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String
    34.  
    35.     End Structure
    36. #End Region
    37.  
    38.     Public Shared Function ExtractFileIcon(ByVal Extension As String, Optional ByVal Large As Boolean = True) As Bitmap
    39.         Dim FileInfo As New SHFILEINFO
    40.  
    41.         Dim Flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
    42.         If Not Large Then Flags = Flags Or SHGFI.SmallIcon
    43.  
    44.         SHGetFileInfo(Extension, 256, FileInfo, Marshal.SizeOf(FileInfo), Flags)
    45.  
    46.         Dim Icon As Bitmap = AlphaHelper.ConvertToBitmap(FileInfo.hIcon)
    47.  
    48.         Return Icon
    49.     End Function
    50.  
    51. End Class
    52.  
    53. ''' <summary>
    54. ''' Thanks goes to pax on vbforums for this code...
    55. ''' [url]http://www.vbforums.com/member.php?u=15972[/url]
    56. ''' </summary>
    57. Friend Class AlphaHelper
    58.  
    59. #Region " API "
    60.     <DllImport("user32", EntryPoint:="GetIconInfo", CharSet:=CharSet.Auto)> _
    61.     Private Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As IntPtr
    62.     End Function
    63.  
    64.     <DllImport("Gdi32", EntryPoint:="CreateDC", CharSet:=CharSet.Auto)> _
    65.     Private Shared Function CreateDC(ByVal Driver As String, ByVal DeviceName As String, ByVal Output As String, ByVal Mode As IntPtr) As IntPtr
    66.     End Function
    67.  
    68.     <DllImport("Gdi32", EntryPoint:="GetDeviceCaps", CharSet:=CharSet.Auto)> _
    69.     Private Shared Function GetDeviceCaps(ByVal hDC As IntPtr, ByVal Index As Integer) As Integer
    70.     End Function
    71.  
    72.     <DllImport("Gdi32", EntryPoint:="DeleteDC", CharSet:=CharSet.Auto)> _
    73.     Private Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
    74.     End Function
    75.  
    76.     <DllImport("user32", EntryPoint:="DestroyIcon", CharSet:=CharSet.Auto)> _
    77.     Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As IntPtr
    78.     End Function
    79.  
    80. #End Region
    81.  
    82. #Region " API Structures and Constants "
    83.  
    84.     Private Structure ICONINFO
    85.         Dim fIcon As Boolean
    86.         Dim xHotspot As Integer
    87.         Dim yHotspot As Integer
    88.         Dim hbmMask As IntPtr
    89.         Dim hbmColor As IntPtr
    90.     End Structure
    91.  
    92.     Private Const BITSPIXEL As Integer = 12
    93.     Private Const PLANES As Integer = 14
    94.  
    95. #End Region
    96.  
    97.     Private Shared Function GetColorDepth() As Integer
    98.         Dim screenDC As IntPtr = CreateDC("DISPLAY", Nothing, Nothing, IntPtr.Zero)
    99.         Dim bitDepth As Integer = GetDeviceCaps(screenDC, BITSPIXEL)
    100.         bitDepth *= GetDeviceCaps(screenDC, PLANES)
    101.         DeleteDC(screenDC)
    102.         Return bitDepth
    103.     End Function
    104.  
    105.  
    106.     Public Shared Function FixAlphaBitmap(ByVal bmSource As Bitmap) As Bitmap
    107.         Dim X, Y As Integer
    108.         Dim C As Color
    109.         Dim bAlphaFound As Boolean
    110.  
    111.         'WARNING! This function will fail if the passed bitmap is not of
    112.         'the correct Pixelformat.
    113.         Dim bmData As Imaging.BitmapData
    114.         Dim bmBounds As New Rectangle(0, 0, bmSource.Width, bmSource.Height)
    115.  
    116.         'create a new bitmap with an ARGB format and point it to the same memory
    117.         'location as the original bitmap.
    118.         bmData = bmSource.LockBits(bmBounds, ImageLockMode.ReadOnly, bmSource.PixelFormat)
    119.         Dim dstBitmap As New Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0)
    120.         bmSource.UnlockBits(bmData)
    121.  
    122.         bmData = Nothing
    123.  
    124.         For Y = 0 To dstBitmap.Height - 1
    125.             For X = 0 To dstBitmap.Width - 1
    126.                 C = dstBitmap.GetPixel(X, Y)
    127.                 If C.A <> 0 Then
    128.                     bAlphaFound = True
    129.                     Exit For
    130.                 End If
    131.             Next
    132.             If bAlphaFound = True Then Exit For
    133.         Next
    134.         If Not bAlphaFound Then dstBitmap = Nothing
    135.  
    136.         Return dstBitmap
    137.  
    138.     End Function
    139.  
    140.     Public Shared Function ConvertToBitmap(ByVal hIcon As IntPtr) As Bitmap
    141.         Dim B As Bitmap
    142.         Dim hBitmap As IntPtr
    143.         Dim bmp As Bitmap
    144.         Dim ii As New ICONINFO
    145.  
    146.         GetIconInfo(hIcon, ii)
    147.         hBitmap = ii.hbmColor
    148.         bmp = Bitmap.FromHbitmap(hBitmap)
    149.         If Environment.OSVersion.Version.Major >= 5 AndAlso _
    150.          Environment.OSVersion.Version.Minor >= 1 AndAlso _
    151.          GetColorDepth() = 32 Then
    152.             Try
    153.                 B = CType(FixAlphaBitmap(bmp).Clone, Bitmap)
    154.             Catch
    155.                 If B Is Nothing Then B = Bitmap.FromHicon(hIcon)
    156.             End Try
    157.         Else
    158.             B = Bitmap.FromHicon(hIcon)
    159.         End If
    160.         DestroyIcon(hBitmap)
    161.         DestroyIcon(hIcon)
    162.  
    163.         GC.Collect()
    164.  
    165.         hBitmap = Nothing
    166.         bmp = Nothing
    167.         ii = Nothing
    168.  
    169.         Return B
    170.  
    171.     End Function
    172.  
    173. End Class
    Tips:
    • Google is your friend! Search before posting!
    • Name your thread appropriately... "I Need Help" doesn't cut it!
    • Always post your code!!!! We can't read your mind!!! (well, at least most of us!)
    • Allways Include the Name and Line of the Exception (if one is occuring!)
    • If it is relevant state the version of Visual Studio/.Net Framwork you are using (2002/2003/2005)


    If you think I was helpful, rate my post
    IRC Contact: Rizon/xous ChakraNET/xous Freenode/xous

  3. #3

    Thread Starter
    l33t! MrPolite's Avatar
    Join Date
    Sep 2001
    Posts
    4,428

    Re: how can I get the system icon associated with folders?

    hey thanks for the post you SORTA misread my post maybe?
    I want to get the default folder icon, not a file's icon. I tried using SHGetFileInfo... I dont have an actual folder path
    (using the SHGFI_USEFILEATTRIBUTES I can get file_type icons without having a valid path, but it isnt working for folders)

    and p.s. that code is slightly messed up Pix or whoever who wrote that is using GetPixel which is massively slow. This code, which is "surprisingly" similar to the code above is a bit cleaner (and faster, because it uses Marshal to read memory) http://dotnetrix.co.uk/misc.html
    rate my posts if they help ya!
    Extract thumbnail without reading the whole image file: (C# - VB)
    Apply texture to bitmaps: (C# - VB)
    Extended console library: (VB)
    Save JPEG with a certain quality (image compression): (C# - VB )
    VB.NET to C# conversion tips!!

  4. #4
    Frenzied Member <ABX's Avatar
    Join Date
    Jul 2002
    Location
    Canada eh...
    Posts
    1,622

    Re: how can I get the system icon associated with folders?

    Rather simple fix :P

    VB Code:
    1. Option Strict On
    2. Option Explicit On
    3.  
    4. Imports System.Runtime.InteropServices
    5.  
    6. Imports System.Drawing.Imaging
    7.  
    8. Public Class FileIconExtractor
    9.  
    10. #Region " API "
    11.  
    12.     <DllImport("shell32.dll", EntryPoint:="SHGetFileInfo")> _
    13.     Private Shared Function SHGetFileInfo(ByVal Path As String, ByVal FileAttributes As Integer, ByRef FileInfo As SHFILEINFO, ByVal FileInfoLength As Integer, ByVal Flags As SHGFI) As Integer
    14.  
    15.     End Function
    16.  
    17.     <Flags()> Private Enum SHGFI
    18.         SmallIcon = &H1
    19.         LargeIcon = &H0
    20.         OpenIcon = &H2
    21.         Icon = &H100
    22.         DisplayName = &H200
    23.         Typename = &H400
    24.         SysIconIndex = &H4000
    25.         UseFileAttributes = &H10
    26.     End Enum
    27.  
    28.     <StructLayout(LayoutKind.Sequential)> _
    29.     Private Structure SHFILEINFO
    30.         Public hIcon As IntPtr
    31.         Public iIcon As Integer
    32.         Public dwAttributes As Integer
    33.         <MarshalAs(UnmanagedType.LPStr, SizeConst:=260)> Public szDisplayName As String
    34.         <MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String
    35.  
    36.     End Structure
    37.  
    38.     Private Const File_Attributes_Directory As Integer = &H10
    39. #End Region
    40.  
    41.     Public Shared Function ExtractFileIcon(ByVal Extension As String, Optional ByVal Large As Boolean = True) As Bitmap
    42.         Dim FileInfo As New SHFILEINFO
    43.  
    44.         Dim Flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
    45.         If Not Large Then Flags = Flags Or SHGFI.SmallIcon
    46.  
    47.         SHGetFileInfo(Extension, 256, FileInfo, Marshal.SizeOf(FileInfo), Flags)
    48.  
    49.         Dim FileIcon As Icon = Icon.FromHandle(FileInfo.hIcon)
    50.  
    51.         Return AlphaHelper.IconToAlphaBitmap(FileIcon)
    52.     End Function
    53.  
    54.  
    55.     Public Shared Function ExtractFolderIcon(ByVal Folder As String, Optional ByVal Open As Boolean = True, Optional ByVal Large As Boolean = True) As Bitmap
    56.         Dim FileInfo As New SHFILEINFO
    57.  
    58.         Dim Flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
    59.  
    60.         If Open Then Flags = Flags Or SHGFI.OpenIcon
    61.  
    62.         If Not Large Then Flags = Flags Or SHGFI.SmallIcon
    63.  
    64.         SHGetFileInfo(Folder, [b]File_Attributes_Directory[/b], FileInfo, Marshal.SizeOf(FileInfo), Flags)
    65.  
    66.         Dim FileIcon As Icon = Icon.FromHandle(FileInfo.hIcon)
    67.  
    68.         Return AlphaHelper.IconToAlphaBitmap(FileIcon)
    69.     End Function
    70.  
    71.  
    72. End Class
    73.  
    74. Friend Class AlphaHelper
    75.  
    76. #Region " IconInfo"
    77.  
    78.     <DllImport("gdi32.dll", SetLastError:=True)> _
    79.     Private Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
    80.     End Function
    81.  
    82.     <DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
    83.     Private Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
    84.     End Function
    85.  
    86.     Private Structure ICONINFO
    87.         Dim fIcon As Boolean
    88.         Dim xHotspot As Integer
    89.         Dim yHotspot As Integer
    90.         Dim hbmMask As IntPtr
    91.         Dim hbmColor As IntPtr
    92.     End Structure
    93.  
    94. #End Region
    95.  
    96.     Public Shared Function IconToAlphaBitmap(ByVal ico As Icon) As Bitmap
    97.  
    98.         Dim ii As New ICONINFO
    99.  
    100.         GetIconInfo(ico.Handle, ii)
    101.  
    102.         Dim bmp As Bitmap = Bitmap.FromHbitmap(ii.hbmColor)
    103.         DeleteObject(ii.hbmColor)
    104.         DeleteObject(ii.hbmMask)
    105.  
    106.         If Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32 Then
    107.             Return ico.ToBitmap
    108.         End If
    109.  
    110.         Dim bmData As Imaging.BitmapData
    111.         Dim bmBounds As New Rectangle(0, 0, bmp.Width, bmp.Height)
    112.  
    113.         bmData = bmp.LockBits(bmBounds, _
    114.                     ImageLockMode.ReadOnly, _
    115.                     bmp.PixelFormat)
    116.  
    117.         Dim dstBitmap As New Bitmap(bmData.Width, _
    118.                     bmData.Height, _
    119.                     bmData.Stride, _
    120.                     PixelFormat.Format32bppArgb, _
    121.                     bmData.Scan0)
    122.  
    123.         Dim x, y As Integer
    124.         Dim IsAlphaBitmap As Boolean = False
    125.  
    126.         For y = 0 To bmData.Height - 1
    127.             For x = 0 To bmData.Width - 1
    128.                 Dim PixelColor As Color
    129.                 PixelColor = Color.FromArgb(Marshal.ReadInt32(bmData.Scan0, (bmData.Stride * y) + (4 * x)))
    130.                 If PixelColor.A > 0 And PixelColor.A < 255 Then
    131.                     IsAlphaBitmap = True
    132.                     Exit For
    133.                 End If
    134.             Next
    135.             If IsAlphaBitmap Then Exit For
    136.         Next
    137.  
    138.         bmp.UnlockBits(bmData)
    139.  
    140.         If IsAlphaBitmap Then
    141.             Return New Bitmap(dstBitmap)
    142.         Else
    143.             Return New Bitmap(ico.ToBitmap)
    144.         End If
    145.  
    146.     End Function
    147.  
    148. End Class

    Note if you just want a general folder just pass "".

    but for special folders such as the root of a drive, the icons are special.

    lol: I misread your post 3 times (and got different things each time)
    You should just need to edit the bold code in your implementation.
    Last edited by <ABX; Jun 5th, 2005 at 02:35 AM.
    Tips:
    • Google is your friend! Search before posting!
    • Name your thread appropriately... "I Need Help" doesn't cut it!
    • Always post your code!!!! We can't read your mind!!! (well, at least most of us!)
    • Allways Include the Name and Line of the Exception (if one is occuring!)
    • If it is relevant state the version of Visual Studio/.Net Framwork you are using (2002/2003/2005)


    If you think I was helpful, rate my post
    IRC Contact: Rizon/xous ChakraNET/xous Freenode/xous

  5. #5

    Thread Starter
    l33t! MrPolite's Avatar
    Join Date
    Sep 2001
    Posts
    4,428

    Re: how can I get the system icon associated with folders?

    oh ha! didnt notice the File_Attributes_Directory attribute! thanks!
    p.s. it's puzzling me why when I assign the icon to an imageList and then use it in a listview, the alpha channels work fine. But if I wanna draw it manually they get messed up (and hence the fix above)


    hmm another Q: is it possible to get that same icon at 48x48?
    rate my posts if they help ya!
    Extract thumbnail without reading the whole image file: (C# - VB)
    Apply texture to bitmaps: (C# - VB)
    Extended console library: (VB)
    Save JPEG with a certain quality (image compression): (C# - VB )
    VB.NET to C# conversion tips!!

  6. #6
    Frenzied Member <ABX's Avatar
    Join Date
    Jul 2002
    Location
    Canada eh...
    Posts
    1,622

    Re: how can I get the system icon associated with folders?

    From looking here: http://msdn.microsoft.com/library/de...einfo.asp]MSDN documentation

    And here:
    http://msdn.microsoft.com/library/de...abouticons.asp

    It seems that it may return a 48x48 icon depending the shell settings.

    You could "cheat" by setting "HKEY_CURRENT_USER\Control Panel, Desktop\WindowMetrics\Shell Icon Size" to the size you want then changing it back after the call but this might cause problems for other applications.

    You could also try using SHGFI_ICONLOCATION (see the first link) to find out where the icon is stored, and then using ExtractIcon(Ex) to get the 48x48, how you would figure out which 48x48 is the one you want is beyond me.
    Tips:
    • Google is your friend! Search before posting!
    • Name your thread appropriately... "I Need Help" doesn't cut it!
    • Always post your code!!!! We can't read your mind!!! (well, at least most of us!)
    • Allways Include the Name and Line of the Exception (if one is occuring!)
    • If it is relevant state the version of Visual Studio/.Net Framwork you are using (2002/2003/2005)


    If you think I was helpful, rate my post
    IRC Contact: Rizon/xous ChakraNET/xous Freenode/xous

  7. #7

    Thread Starter
    l33t! MrPolite's Avatar
    Join Date
    Sep 2001
    Posts
    4,428

    Re: how can I get the system icon associated with folders?

    wow cool thanks
    I'm hoping the longhorn api would be better since I've heard they're cleaning it up

    I think I should stick with manually inserting the 48x48 icon... too messy with apis
    rate my posts if they help ya!
    Extract thumbnail without reading the whole image file: (C# - VB)
    Apply texture to bitmaps: (C# - VB)
    Extended console library: (VB)
    Save JPEG with a certain quality (image compression): (C# - VB )
    VB.NET to C# conversion tips!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width