|
-
Jun 4th, 2005, 11:23 PM
#1
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!!
-
Jun 5th, 2005, 01:04 AM
#2
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:
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Public Class FileIconExtractor
#Region " API "
<DllImport("shell32.dll", EntryPoint:="SHGetFileInfo")> _
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
End Function
<Flags()> Private Enum SHGFI
SmallIcon = &H1
LargeIcon = &H0
Icon = &H100
DisplayName = &H200
Typename = &H400
SysIconIndex = &H4000
UseFileAttributes = &H10
End Enum
<StructLayout(LayoutKind.Sequential)> _
Private Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As Integer
<MarshalAs(UnmanagedType.LPStr, SizeConst:=260)> Public szDisplayName As String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String
End Structure
#End Region
Public Shared Function ExtractFileIcon(ByVal Extension As String, Optional ByVal Large As Boolean = True) As Bitmap
Dim FileInfo As New SHFILEINFO
Dim Flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
If Not Large Then Flags = Flags Or SHGFI.SmallIcon
SHGetFileInfo(Extension, 256, FileInfo, Marshal.SizeOf(FileInfo), Flags)
Dim Icon As Bitmap = AlphaHelper.ConvertToBitmap(FileInfo.hIcon)
Return Icon
End Function
End Class
''' <summary>
''' Thanks goes to pax on vbforums for this code...
''' [url]http://www.vbforums.com/member.php?u=15972[/url]
''' </summary>
Friend Class AlphaHelper
#Region " API "
<DllImport("user32", EntryPoint:="GetIconInfo", CharSet:=CharSet.Auto)> _
Private Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As IntPtr
End Function
<DllImport("Gdi32", EntryPoint:="CreateDC", CharSet:=CharSet.Auto)> _
Private Shared Function CreateDC(ByVal Driver As String, ByVal DeviceName As String, ByVal Output As String, ByVal Mode As IntPtr) As IntPtr
End Function
<DllImport("Gdi32", EntryPoint:="GetDeviceCaps", CharSet:=CharSet.Auto)> _
Private Shared Function GetDeviceCaps(ByVal hDC As IntPtr, ByVal Index As Integer) As Integer
End Function
<DllImport("Gdi32", EntryPoint:="DeleteDC", CharSet:=CharSet.Auto)> _
Private Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
End Function
<DllImport("user32", EntryPoint:="DestroyIcon", CharSet:=CharSet.Auto)> _
Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As IntPtr
End Function
#End Region
#Region " API Structures and Constants "
Private Structure ICONINFO
Dim fIcon As Boolean
Dim xHotspot As Integer
Dim yHotspot As Integer
Dim hbmMask As IntPtr
Dim hbmColor As IntPtr
End Structure
Private Const BITSPIXEL As Integer = 12
Private Const PLANES As Integer = 14
#End Region
Private Shared Function GetColorDepth() As Integer
Dim screenDC As IntPtr = CreateDC("DISPLAY", Nothing, Nothing, IntPtr.Zero)
Dim bitDepth As Integer = GetDeviceCaps(screenDC, BITSPIXEL)
bitDepth *= GetDeviceCaps(screenDC, PLANES)
DeleteDC(screenDC)
Return bitDepth
End Function
Public Shared Function FixAlphaBitmap(ByVal bmSource As Bitmap) As Bitmap
Dim X, Y As Integer
Dim C As Color
Dim bAlphaFound As Boolean
'WARNING! This function will fail if the passed bitmap is not of
'the correct Pixelformat.
Dim bmData As Imaging.BitmapData
Dim bmBounds As New Rectangle(0, 0, bmSource.Width, bmSource.Height)
'create a new bitmap with an ARGB format and point it to the same memory
'location as the original bitmap.
bmData = bmSource.LockBits(bmBounds, ImageLockMode.ReadOnly, bmSource.PixelFormat)
Dim dstBitmap As New Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0)
bmSource.UnlockBits(bmData)
bmData = Nothing
For Y = 0 To dstBitmap.Height - 1
For X = 0 To dstBitmap.Width - 1
C = dstBitmap.GetPixel(X, Y)
If C.A <> 0 Then
bAlphaFound = True
Exit For
End If
Next
If bAlphaFound = True Then Exit For
Next
If Not bAlphaFound Then dstBitmap = Nothing
Return dstBitmap
End Function
Public Shared Function ConvertToBitmap(ByVal hIcon As IntPtr) As Bitmap
Dim B As Bitmap
Dim hBitmap As IntPtr
Dim bmp As Bitmap
Dim ii As New ICONINFO
GetIconInfo(hIcon, ii)
hBitmap = ii.hbmColor
bmp = Bitmap.FromHbitmap(hBitmap)
If Environment.OSVersion.Version.Major >= 5 AndAlso _
Environment.OSVersion.Version.Minor >= 1 AndAlso _
GetColorDepth() = 32 Then
Try
B = CType(FixAlphaBitmap(bmp).Clone, Bitmap)
Catch
If B Is Nothing Then B = Bitmap.FromHicon(hIcon)
End Try
Else
B = Bitmap.FromHicon(hIcon)
End If
DestroyIcon(hBitmap)
DestroyIcon(hIcon)
GC.Collect()
hBitmap = Nothing
bmp = Nothing
ii = Nothing
Return B
End Function
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
-
Jun 5th, 2005, 02:05 AM
#3
-
Jun 5th, 2005, 02:32 AM
#4
Re: how can I get the system icon associated with folders?
Rather simple fix :P
VB Code:
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Public Class FileIconExtractor
#Region " API "
<DllImport("shell32.dll", EntryPoint:="SHGetFileInfo")> _
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
End Function
<Flags()> Private Enum SHGFI
SmallIcon = &H1
LargeIcon = &H0
OpenIcon = &H2
Icon = &H100
DisplayName = &H200
Typename = &H400
SysIconIndex = &H4000
UseFileAttributes = &H10
End Enum
<StructLayout(LayoutKind.Sequential)> _
Private Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As Integer
<MarshalAs(UnmanagedType.LPStr, SizeConst:=260)> Public szDisplayName As String
<MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String
End Structure
Private Const File_Attributes_Directory As Integer = &H10
#End Region
Public Shared Function ExtractFileIcon(ByVal Extension As String, Optional ByVal Large As Boolean = True) As Bitmap
Dim FileInfo As New SHFILEINFO
Dim Flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
If Not Large Then Flags = Flags Or SHGFI.SmallIcon
SHGetFileInfo(Extension, 256, FileInfo, Marshal.SizeOf(FileInfo), Flags)
Dim FileIcon As Icon = Icon.FromHandle(FileInfo.hIcon)
Return AlphaHelper.IconToAlphaBitmap(FileIcon)
End Function
Public Shared Function ExtractFolderIcon(ByVal Folder As String, Optional ByVal Open As Boolean = True, Optional ByVal Large As Boolean = True) As Bitmap
Dim FileInfo As New SHFILEINFO
Dim Flags As SHGFI = SHGFI.Icon Or SHGFI.UseFileAttributes
If Open Then Flags = Flags Or SHGFI.OpenIcon
If Not Large Then Flags = Flags Or SHGFI.SmallIcon
SHGetFileInfo(Folder, [b]File_Attributes_Directory[/b], FileInfo, Marshal.SizeOf(FileInfo), Flags)
Dim FileIcon As Icon = Icon.FromHandle(FileInfo.hIcon)
Return AlphaHelper.IconToAlphaBitmap(FileIcon)
End Function
End Class
Friend Class AlphaHelper
#Region " IconInfo"
<DllImport("gdi32.dll", SetLastError:=True)> _
Private Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.Cdecl)> _
Private Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
End Function
Private Structure ICONINFO
Dim fIcon As Boolean
Dim xHotspot As Integer
Dim yHotspot As Integer
Dim hbmMask As IntPtr
Dim hbmColor As IntPtr
End Structure
#End Region
Public Shared Function IconToAlphaBitmap(ByVal ico As Icon) As Bitmap
Dim ii As New ICONINFO
GetIconInfo(ico.Handle, ii)
Dim bmp As Bitmap = Bitmap.FromHbitmap(ii.hbmColor)
DeleteObject(ii.hbmColor)
DeleteObject(ii.hbmMask)
If Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32 Then
Return ico.ToBitmap
End If
Dim bmData As Imaging.BitmapData
Dim bmBounds As New Rectangle(0, 0, bmp.Width, bmp.Height)
bmData = bmp.LockBits(bmBounds, _
ImageLockMode.ReadOnly, _
bmp.PixelFormat)
Dim dstBitmap As New Bitmap(bmData.Width, _
bmData.Height, _
bmData.Stride, _
PixelFormat.Format32bppArgb, _
bmData.Scan0)
Dim x, y As Integer
Dim IsAlphaBitmap As Boolean = False
For y = 0 To bmData.Height - 1
For x = 0 To bmData.Width - 1
Dim PixelColor As Color
PixelColor = Color.FromArgb(Marshal.ReadInt32(bmData.Scan0, (bmData.Stride * y) + (4 * x)))
If PixelColor.A > 0 And PixelColor.A < 255 Then
IsAlphaBitmap = True
Exit For
End If
Next
If IsAlphaBitmap Then Exit For
Next
bmp.UnlockBits(bmData)
If IsAlphaBitmap Then
Return New Bitmap(dstBitmap)
Else
Return New Bitmap(ico.ToBitmap)
End If
End Function
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
-
Jun 5th, 2005, 02:12 PM
#5
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!!
-
Jun 9th, 2005, 12:44 AM
#6
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
-
Jun 9th, 2005, 12:46 AM
#7
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|