Results 1 to 32 of 32

Thread: Ugly icons...[RESOLVED]

  1. #1

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840

    Ugly icons...[RESOLVED]

    Hi.

    Have any of you ever tried to extract an icon from a DLL, and show it in a picturebox on WinXP?

    The alphablended part of the icon is converted to a solid black.

    I found some code on PSC but for some strange reason it only works on icons extracted with SHGetFileInfo API and not the ExtractIconEx API. And of course, I need to use ExtractIconEx because I need to pass an index to the icon I want.

    Does anyone know how to restore the alphablend regardless of the API?

    Or does anyone know how to specify which icon to extract using SHGetFileInfo?
    Last edited by pax; Feb 27th, 2004 at 12:32 PM.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  2. #2
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    I used "SHGetFileInfo" API to extract an icon from files and yes it gives the same result as you said above . Didn't work much on that but I'm a little happy (for now ) with it . If you need the code , tell me to paste it here . It's a C# class though .

  3. #3

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi.

    So you get the solid black as well?

    You said you use SHGetFileInfo?
    Do you have a way of specifying the index?
    I mean, how can I extract icon no. 123 from shell32.dll using SHGetFileInfo?

    Until now I have only been able to extract that using ExtractIconEx.

    I only use SHGetFileInfo to get the associated icon.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  4. #4
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Originally posted by pax
    Hi.

    So you get the solid black as well?

    You said you use SHGetFileInfo?
    Do you have a way of specifying the index?
    I mean, how can I extract icon no. 123 from shell32.dll using SHGetFileInfo?

    Until now I have only been able to extract that using ExtractIconEx.

    I only use SHGetFileInfo to get the associated icon.
    Yes , I get that black nasty color around the edges . But I think this because I converted the icon to bitmap .




    I mean, how can I extract icon no. 123 from shell32.dll using SHGetFileInfo?
    What do you mean by icon number ? and what index is that ?

  5. #5

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi.

    The Shell32.dll file is an icon resource containing some 200 icons.

    Index 3 is a closed folder
    Index 4 is an open folder
    Index 34 is the desktop icon
    etc.
    etc.

    With the ExtractIconEx function you can specify which icon you want to extract. Whereas, as far as I know, the SHGetFileInfo only returns the associated icon.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  6. #6
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    I didn't know this about Shell32.dll .

    and I've just tried "SHGetFileInfo" API with the above file and returned the associated icon which is not what you want .

    Hold on, I think I've tried something like this in one of my previous proj . I look it up .

  7. #7
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Sorry , it took me a while to convert this code to .NET (from one of my VB6 progys ) .

    ExtractAssociatedIcon API is the one that returns icon with index .

    VB Code:
    1. <DllImport("shell32.dll", EntryPoint:="ExtractAssociatedIcon")> _
    2.     Private Shared Function ExtractAssociatedIcon(ByVal hInst As System.IntPtr, <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As String, ByRef lpiIcon As Integer) As System.IntPtr
    3.  
    4.     End Function
    5.     Dim ico As Icon
    6.     Private Sub GetIconInfo()
    7.         Dim iconPath As String = "C:\windows\system32\shell32.dll"
    8.         Dim hInst As IntPtr = Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly().GetModules()(0))
    9.         Dim iIcon As Int32
    10.         Dim hIcon As IntPtr
    11.         '6 is the index you need to change only .
    12.         hIcon = ExtractAssociatedIcon(hInst, iconPath, 6)
    13.         ico = Icon.FromHandle(hIcon)
    14.     End Sub
    15.  
    16.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    17.         GetIconInfo()
    18.     End Sub
    19.  
    20.     Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    21.         e.Graphics.DrawIcon(ico, 0, 0)
    22.     End Sub


  8. #8

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Wow, thanks.

    I only have Win2000 here, so I will try when I get home on WinXP, to see if my AlphaFix function will work on these icons.

    If it does I will post the alphafix solution.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  9. #9
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Originally posted by pax
    Wow, thanks.

    I only have Win2000 here, so I will try when I get home on WinXP, to see if my AlphaFix function will work on these icons.

    If it does I will post the alphafix solution.
    I'm on XP machine . I tested and posted a sample . It seems to work solid .
    Attached Images Attached Images  

  10. #10

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi Pirate.

    True, but what if you convert it to a bitmap? will it still stay aplhablended?

    That is way I previously searched for, and found, some code to fix the alphablend.

    But anyways, I'll implement your code into my app on my XP machine, and I will soon enough find out wether I need to fix them or not, and if so, if my fix will work.

    It's strange that the fix works on icons extracted with SHGetFileInfo and not ExtractIconEx

    Thank's again for all your help.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  11. #11
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Originally posted by pax
    Hi Pirate.

    True, but what if you convert it to a bitmap? will it still stay aplhablended?

    That is way I previously searched for, and found, some code to fix the alphablend.

    But anyways, I'll implement your code into my app on my XP machine, and I will soon enough find out wether I need to fix them or not, and if so, if my fix will work.

    It's strange that the fix works on icons extracted with SHGetFileInfo and not ExtractIconEx

    Thank's again for all your help.
    Umm , I'm not sure but let's be optimistic and say it stay alphablended .

    What fix is that you're talking about ? Don't mess much with those API again .

  12. #12

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi.

    the fix is just some code some guy at PSC wrote. Basically he creates a new bitmap object based on the iconinfo, and uses bitmap data to transfer it to another new bitmap object with 32bpp format, which restores the alphablend.

    I'll post the code for the fix when I have tested your code against it.

    But I have no idea what went wrong anyways. I extracted an icon using SHGetFileInfo and passed it to my fix function and it worked perfectly.
    Then I extracted another icon using ExtracIconEx and ran that through my fix function and it returned a blank bitmap.

    My guess is that there is some difference in the iconinfo returned by those two API's (Perhaps ExtractIconEx hasn't been updated to support alphablends?)

    The purpose of my app is to extracticons from any file and save them as bitmaps. And I don't want to save a bitmap with that ugly black edge.

    So I'm really anxious to get home and test your code...

    I'll post the result later.

    Thank's
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  13. #13
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Since you're entrapped in these APIs , do you know if there's a way to return number of icons inside a file . ??

  14. #14

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi Pirate.

    Calling the ExtractIconEx with index -1 and no pointers will return the number of icons.

    VB Code:
    1. <DllImport("shell32.dll", EntryPoint:="ExtractIconEx", CharSet:=CharSet.Auto)> _
    2.     Private Shared Function ExtractIconEx(ByVal Filename As String, ByVal IconIndex As Integer, ByRef hLargeIcon As IntPtr, ByRef hSmallIcon As IntPtr, ByVal Count As Integer) As Integer
    3.     End Function
    4.  
    5.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    6.         Dim systempath As String = Environment.GetFolderPath(Environment.SpecialFolder.System)
    7.         Dim filename As String = IO.Path.Combine(systempath, "shell32.dll")
    8.         MessageBox.Show("Shell32.DLL contains " & ExtractIconEx(filename, -1, Nothing, Nothing, 1) & " icons")
    9.  
    10.     End Sub
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  15. #15

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi Pirate.

    I have a question about the code you posted.

    It seems to only return 32x32 icons. What if I want the 16x16 icon?
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  16. #16
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Then simply , do this :

    VB Code:
    1. e.Graphics.DrawIcon(ico, New Rectangle(0, 0, 16, 16))
    Or
    use the ugly SHGetFileInfo method .

    btw , thanks for index -1 hook up . It worked

  17. #17

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi Pirate.

    I finally got some of it to work. I'm sorry to say that I didn't use your code.

    It turns out that it had been working all the time, except on the icons I had tried. Now I coincidently choose another index and it worked. So it works on some icons and not on others.

    Now, ain't that some weird S**t?

    Now I don't know what to do with the other icons. Perhaps they don't have an alphachannel?

    Here's my code. Maybe you can figure it out?

    VB Code:
    1. Imports System.Runtime.InteropServices
    2. Imports System.Drawing.Imaging
    3.  
    4. Public Class IconExtraction
    5.  
    6. #Region "API"
    7.     <DllImport("shell32.dll", EntryPoint:="ExtractIconEx", CharSet:=CharSet.Auto)> _
    8.     Private Shared Function ExtractIconEx(ByVal Filename As String, ByVal IconIndex As Integer, ByRef hIconLarge As IntPtr, ByRef hIconSmall As IntPtr, ByVal IconCount As Integer) As IntPtr
    9.     End Function
    10.  
    11.     <DllImport("shell32.dll", EntryPoint:="SHGetFileInfo", CharSet:=CharSet.Auto)> _
    12.     Private Shared Function SHGetFileInfo(ByVal FileName As String, ByVal FileAttributes As Integer, ByRef Buffer As SHFileInfo, ByVal FileInfo As Integer, ByVal Flags As Integer) As IntPtr
    13.     End Function
    14.  
    15.     <DllImport("user32", EntryPoint:="GetIconInfo", CharSet:=CharSet.Auto)> _
    16.     Private Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As IntPtr
    17.     End Function
    18.  
    19.     <DllImport("Gdi32", EntryPoint:="CreateDC", CharSet:=CharSet.Auto)> _
    20.     Private Shared Function CreateDC(ByVal Driver As String, ByVal DeviceName As String, ByVal Output As String, ByVal Mode As IntPtr) As IntPtr
    21.     End Function
    22.  
    23.     <DllImport("Gdi32", EntryPoint:="GetDeviceCaps", CharSet:=CharSet.Auto)> _
    24.     Private Shared Function GetDeviceCaps(ByVal hDC As IntPtr, ByVal Index As Integer) As Integer
    25.     End Function
    26.  
    27.     <DllImport("Gdi32", EntryPoint:="DeleteDC", CharSet:=CharSet.Auto)> _
    28.     Private Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
    29.     End Function
    30.  
    31.     <DllImport("user32", EntryPoint:="DestroyIcon", CharSet:=CharSet.Auto)> _
    32.     Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As IntPtr
    33.     End Function
    34. #End Region
    35.  
    36. #Region "Structures"
    37.     Private Structure SHFileInfo
    38.         Public hIcon As IntPtr
    39.         Public iIcon As Integer
    40.         Public dwAttributes As Integer
    41.         Public szDisplayName As String
    42.         Public szTypeName As String
    43.     End Structure
    44.     Private Structure ICONINFO
    45.         Dim fIcon As Boolean
    46.         Dim xHotspot As Integer
    47.         Dim yHotspot As Integer
    48.         Dim hbmMask As IntPtr
    49.         Dim hbmColor As IntPtr
    50.     End Structure
    51.  
    52. #End Region
    53.  
    54. #Region "Constants"
    55.     Private Const SHGFI_ICON = &H100
    56.     Private Const SHGFI_SMALLICON = &H1   ' Small icon
    57.     Private Const SHGFI_LARGEICON = &H0   ' Large icon
    58.     Private Const SHGFI_USEFILEATTRIBUTES = &H10
    59.  
    60.     Private Const BITSPIXEL As Integer = 12
    61.     Private Const PLANES As Integer = 14
    62. #End Region
    63.  
    64. #Region "Private Functions"
    65.     'Used by the alphafix
    66.     Private Shared Function GetColorDepth() As Integer
    67.         Dim screenDC As IntPtr = CreateDC("DISPLAY", Nothing, Nothing, IntPtr.Zero)
    68.         Dim bitDepth As Integer = GetDeviceCaps(screenDC, BITSPIXEL)
    69.         bitDepth *= GetDeviceCaps(screenDC, PLANES)
    70.         DeleteDC(screenDC)
    71.         Return bitDepth
    72.     End Function
    73.     Private Shared Function FixAlphaBitmap(ByVal bmSource As Bitmap) As Bitmap
    74.  
    75.         'WARNING! This function will fail if the passed bitmap is not of
    76.         'the correct Pixelformat.
    77.         Dim bmData As Imaging.BitmapData
    78.         Dim bmBounds As New Rectangle(0, 0, bmSource.Width, bmSource.Height)
    79.  
    80.         'create a new bitmap with an ARGB format and point it to the same memory
    81.         'location as the original bitmap.
    82.         bmData = bmSource.LockBits(bmBounds, ImageLockMode.ReadOnly, bmSource.PixelFormat)
    83.         Dim dstBitmap As New Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0)
    84.         bmSource.UnlockBits(bmData)
    85.  
    86.         bmData = Nothing
    87.  
    88.         Return dstBitmap
    89.  
    90.     End Function
    91. #End Region
    92.  
    93.     Public Shared Function GetIconCount(ByVal FileName As String) As Integer
    94.         Dim hCount As IntPtr
    95.  
    96.         hCount = ExtractIconEx(FileName, -1, Nothing, Nothing, 1)
    97.  
    98.         Return hCount.ToInt32
    99.     End Function
    100.  
    101.     Public Shared Function ExtractLargeIcon(ByVal FileName As String, ByVal Index As Integer) As Icon
    102.         Dim hIcon As IntPtr
    103.  
    104.         ExtractIconEx(FileName, Index, hIcon, Nothing, 1)
    105.  
    106.         Return Icon.FromHandle(hIcon)
    107.     End Function
    108.     Public Shared Function ExtractSmallIcon(ByVal FileName As String, ByVal Index As Integer) As Icon
    109.         Dim hIcon As IntPtr
    110.  
    111.         ExtractIconEx(FileName, Index, Nothing, hIcon, 1)
    112.  
    113.         Return Icon.FromHandle(hIcon)
    114.     End Function
    115.  
    116.     Public Shared Function ExtractLargeAssociatedIcon(ByVal FileName As String) As Icon
    117.         Dim sh As New SHFileInfo()
    118.  
    119.         SHGetFileInfo(FileName, 0, sh, Marshal.SizeOf(sh), SHGFI_ICON Or SHGFI_LARGEICON Or SHGFI_USEFILEATTRIBUTES)
    120.  
    121.         GC.Collect()
    122.  
    123.         Return Icon.FromHandle(sh.hIcon)
    124.     End Function
    125.     Public Shared Function ExtractSmallAssociatedIcon(ByVal FileName As String) As Icon
    126.         Dim sh As New SHFileInfo()
    127.  
    128.         SHGetFileInfo(FileName, 0, sh, Marshal.SizeOf(sh), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_USEFILEATTRIBUTES)
    129.  
    130.         GC.Collect()
    131.  
    132.         Return Icon.FromHandle(sh.hIcon)
    133.  
    134.     End Function
    135.  
    136.     Public Shared Function ConvertToBitmap(ByVal hIcon As IntPtr) As Bitmap
    137.         Dim B As Bitmap
    138.         Dim hBitmap As IntPtr
    139.         Dim bmp As Bitmap
    140.         Dim ii As New ICONINFO()
    141.  
    142.         GetIconInfo(hIcon, ii)
    143.         hBitmap = ii.hbmColor
    144.         bmp = Bitmap.FromHbitmap(hBitmap)
    145.         If Environment.OSVersion.Version.Major >= 5 AndAlso _
    146.          Environment.OSVersion.Version.Minor >= 1 AndAlso _
    147.          GetColorDepth() = 32 Then
    148.             B = FixAlphaBitmap(bmp).Clone
    149.         Else
    150.             B = Bitmap.FromHicon(hIcon)
    151.         End If
    152.         DestroyIcon(hBitmap)
    153.         DestroyIcon(hIcon)
    154.  
    155.         GC.Collect()
    156.  
    157.         hBitmap = Nothing
    158.         bmp = Nothing
    159.         ii = Nothing
    160.  
    161.         Return B
    162.  
    163.     End Function
    164. End Class
    Last edited by pax; Feb 27th, 2004 at 11:20 AM.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  18. #18
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    I doesn't matter for me if you got it working using my code or someone's else . What's important is that I'd probably see this thread marked as [Resolved] . It's nice to share your code with others btw .


  19. #19

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Hi Pirate.

    It turns out it was wrong what I just posted, so while you were posting I was editing
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  20. #20

    Thread Starter
    Fanatic Member pax's Avatar
    Join Date
    Mar 2001
    Location
    Denmark
    Posts
    840
    Finally...

    It was because they had no alphachannel, so all ARGB values of the returned bitmap had an alphavalue of 0.

    So I solved it by lopping through all pixels in the fixed bitmap and if I found and alphachannel <> 0 then I knew the bitmap was ok.
    If I didn't find any I knew the bitmap was blank, returned nothing causing an exception in the calling procedure, which I could catch, so I could return the a bitmap converted using icon.fromhandle.

    Phew, that was hard to describe I hope it made sence.

    Here's the new code:
    VB Code:
    1. Imports System.Runtime.InteropServices
    2. Imports System.Drawing.Imaging
    3.  
    4. Public Class IconExtraction
    5.  
    6. #Region "API"
    7.     <DllImport("shell32.dll", EntryPoint:="ExtractIconEx", CharSet:=CharSet.Auto)> _
    8.     Private Shared Function ExtractIconEx(ByVal Filename As String, ByVal IconIndex As Integer, ByRef hIconLarge As IntPtr, ByRef hIconSmall As IntPtr, ByVal IconCount As Integer) As IntPtr
    9.     End Function
    10.  
    11.     <DllImport("shell32.dll", EntryPoint:="SHGetFileInfo", CharSet:=CharSet.Auto)> _
    12.     Private Shared Function SHGetFileInfo(ByVal FileName As String, ByVal FileAttributes As Integer, ByRef Buffer As SHFileInfo, ByVal FileInfo As Integer, ByVal Flags As Integer) As IntPtr
    13.     End Function
    14.  
    15.     <DllImport("user32", EntryPoint:="GetIconInfo", CharSet:=CharSet.Auto)> _
    16.     Private Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As IntPtr
    17.     End Function
    18.  
    19.     <DllImport("Gdi32", EntryPoint:="CreateDC", CharSet:=CharSet.Auto)> _
    20.     Private Shared Function CreateDC(ByVal Driver As String, ByVal DeviceName As String, ByVal Output As String, ByVal Mode As IntPtr) As IntPtr
    21.     End Function
    22.  
    23.     <DllImport("Gdi32", EntryPoint:="GetDeviceCaps", CharSet:=CharSet.Auto)> _
    24.     Private Shared Function GetDeviceCaps(ByVal hDC As IntPtr, ByVal Index As Integer) As Integer
    25.     End Function
    26.  
    27.     <DllImport("Gdi32", EntryPoint:="DeleteDC", CharSet:=CharSet.Auto)> _
    28.     Private Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
    29.     End Function
    30.  
    31.     <DllImport("user32", EntryPoint:="DestroyIcon", CharSet:=CharSet.Auto)> _
    32.     Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As IntPtr
    33.     End Function
    34. #End Region
    35.  
    36. #Region "Structures"
    37.     Private Structure SHFileInfo
    38.         Public hIcon As IntPtr
    39.         Public iIcon As Integer
    40.         Public dwAttributes As Integer
    41.         Public szDisplayName As String
    42.         Public szTypeName As String
    43.     End Structure
    44.     Private Structure ICONINFO
    45.         Dim fIcon As Boolean
    46.         Dim xHotspot As Integer
    47.         Dim yHotspot As Integer
    48.         Dim hbmMask As IntPtr
    49.         Dim hbmColor As IntPtr
    50.     End Structure
    51.  
    52. #End Region
    53.  
    54. #Region "Constants"
    55.     Private Const SHGFI_ICON = &H100
    56.     Private Const SHGFI_SMALLICON = &H1   ' Small icon
    57.     Private Const SHGFI_LARGEICON = &H0   ' Large icon
    58.     Private Const SHGFI_USEFILEATTRIBUTES = &H10
    59.  
    60.     Private Const BITSPIXEL As Integer = 12
    61.     Private Const PLANES As Integer = 14
    62. #End Region
    63.  
    64. #Region "Private Functions"
    65.     'Used by the alphafix
    66.     Private Shared Function GetColorDepth() As Integer
    67.         Dim screenDC As IntPtr = CreateDC("DISPLAY", Nothing, Nothing, IntPtr.Zero)
    68.         Dim bitDepth As Integer = GetDeviceCaps(screenDC, BITSPIXEL)
    69.         bitDepth *= GetDeviceCaps(screenDC, PLANES)
    70.         DeleteDC(screenDC)
    71.         Return bitDepth
    72.     End Function
    73.     Private Shared Function FixAlphaBitmap(ByVal bmSource As Bitmap) As Bitmap
    74.         Dim X, Y As Integer
    75.         Dim C As Color
    76.         Dim bAlphaFound As Boolean
    77.  
    78.         'WARNING! This function will fail if the passed bitmap is not of
    79.         'the correct Pixelformat.
    80.         Dim bmData As Imaging.BitmapData
    81.         Dim bmBounds As New Rectangle(0, 0, bmSource.Width, bmSource.Height)
    82.  
    83.         'create a new bitmap with an ARGB format and point it to the same memory
    84.         'location as the original bitmap.
    85.         bmData = bmSource.LockBits(bmBounds, ImageLockMode.ReadOnly, bmSource.PixelFormat)
    86.         Dim dstBitmap As New Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0)
    87.         bmSource.UnlockBits(bmData)
    88.  
    89.         bmData = Nothing
    90.  
    91.         For Y = 0 To dstBitmap.Height - 1
    92.             For X = 0 To dstBitmap.Width - 1
    93.                 C = dstBitmap.GetPixel(X, Y)
    94.                 If C.A <> 0 Then
    95.                     bAlphaFound = True
    96.                     Exit For
    97.                 End If
    98.             Next
    99.             If bAlphaFound = True Then Exit For
    100.         Next
    101.         If Not bAlphaFound Then dstBitmap = Nothing
    102.  
    103.         Return dstBitmap
    104.  
    105.     End Function
    106. #End Region
    107.  
    108.     Public Shared Function GetIconCount(ByVal FileName As String) As Integer
    109.         Dim hCount As IntPtr
    110.  
    111.         hCount = ExtractIconEx(FileName, -1, Nothing, Nothing, 1)
    112.  
    113.         Return hCount.ToInt32
    114.     End Function
    115.  
    116.     Public Shared Function ExtractLargeIcon(ByVal FileName As String, ByVal Index As Integer) As Icon
    117.         Dim hIcon As IntPtr
    118.  
    119.         ExtractIconEx(FileName, Index, hIcon, Nothing, 1)
    120.  
    121.         Return Icon.FromHandle(hIcon)
    122.     End Function
    123.     Public Shared Function ExtractSmallIcon(ByVal FileName As String, ByVal Index As Integer) As Icon
    124.         Dim hIcon As IntPtr
    125.  
    126.         ExtractIconEx(FileName, Index, Nothing, hIcon, 1)
    127.  
    128.         Return Icon.FromHandle(hIcon)
    129.     End Function
    130.  
    131.     Public Shared Function ExtractLargeAssociatedIcon(ByVal FileName As String) As Icon
    132.         Dim sh As New SHFileInfo()
    133.  
    134.         SHGetFileInfo(FileName, 0, sh, Marshal.SizeOf(sh), SHGFI_ICON Or SHGFI_LARGEICON Or SHGFI_USEFILEATTRIBUTES)
    135.  
    136.         GC.Collect()
    137.  
    138.         Return Icon.FromHandle(sh.hIcon)
    139.     End Function
    140.     Public Shared Function ExtractSmallAssociatedIcon(ByVal FileName As String) As Icon
    141.         Dim sh As New SHFileInfo()
    142.  
    143.         SHGetFileInfo(FileName, 0, sh, Marshal.SizeOf(sh), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_USEFILEATTRIBUTES)
    144.  
    145.         GC.Collect()
    146.  
    147.         Return Icon.FromHandle(sh.hIcon)
    148.  
    149.     End Function
    150.  
    151.     Public Shared Function ConvertToBitmap(ByVal hIcon As IntPtr) As Bitmap
    152.         Dim B As Bitmap
    153.         Dim hBitmap As IntPtr
    154.         Dim bmp As Bitmap
    155.         Dim ii As New ICONINFO()
    156.  
    157.         GetIconInfo(hIcon, ii)
    158.         hBitmap = ii.hbmColor
    159.         bmp = Bitmap.FromHbitmap(hBitmap)
    160.         If Environment.OSVersion.Version.Major >= 5 AndAlso _
    161.          Environment.OSVersion.Version.Minor >= 1 AndAlso _
    162.          GetColorDepth() = 32 Then
    163.             Try
    164.                 B = FixAlphaBitmap(bmp).Clone
    165.             Catch
    166.                 If B Is Nothing Then B = Bitmap.FromHicon(hIcon)
    167.             End Try
    168.         Else
    169.                 B = Bitmap.FromHicon(hIcon)
    170.         End If
    171.         DestroyIcon(hBitmap)
    172.         DestroyIcon(hIcon)
    173.  
    174.         GC.Collect()
    175.  
    176.         hBitmap = Nothing
    177.         bmp = Nothing
    178.         ii = Nothing
    179.  
    180.         Return B
    181.  
    182.     End Function
    183. End Class

    So it seems I've been going about this all wrong from the get go.
    But all's well that ends well.

    Thank's again Pirate, and sorry if I wasted your time.
    At least, I hope you can use this in the future.
    I wish I could think of something witty to put in my sig...

    ...Currently using VS2013...

  21. #21
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    You're welcome smart boy . I didn't test the code yet but it seems priceless for troubled guys here .

  22. #22
    Addicted Member Latin4567's Avatar
    Join Date
    Jan 2005
    Posts
    202

    Re: Ugly icons...[RESOLVED]

    Quote Originally Posted by Pirate
    Umm , I'm not sure but let's be optimistic and say it stay alphablended .

    What fix is that you're talking about ? Don't mess much with those API again .
    bitmaps CANT be alpha-blended... the operating system uses magic pink to use transparency with bitmaps though...

    you guys need to use png...

  23. #23
    Member
    Join Date
    Jun 2005
    Posts
    55

    Re: Ugly icons...[RESOLVED]

    I am looking for this code too, but the error says:
    Assembly is not declared.

    Do I need to import something?
    VB.NET 2003 Professional Edition

    VB
    C#
    C++
    J#

  24. #24
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    Where does it say this error ? can you show some code ?
    Yes , you should import System.Runtime.Interoper.. namespace .

    Quote Originally Posted by tmasboa
    I am looking for this code too, but the error says:
    Assembly is not declared.

    Do I need to import something?

  25. #25
    Member
    Join Date
    Jun 2005
    Posts
    55

    Re: Ugly icons...[RESOLVED]

    Here's my code:
    VB Code:
    1. Imports System.runtime.InteropServices
    2. Imports System.Drawing
    3.  
    4. Public Class Form1
    5.     Inherits System.Windows.Forms.Form
    6.  
    7.  
    8.  
    9.     <DllImport("shell32.dll", EntryPoint:="ExtractAssociatedIcon")> _
    10.         Private Shared Function ExtractAssociatedIcon(ByVal hInst As System.IntPtr, <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As String, ByRef lpiIcon As Integer) As System.IntPtr
    11.  
    12.     End Function
    13.     Dim ico As Icon
    14.     Private Sub GetIconInfo()
    15.         Dim iconPath As String = "C:\windows\system32\shell32.dll"
    16.         Dim hInst As IntPtr = Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly().GetModules()(0))
    17.         Dim iIcon As Int32
    18.         Dim hIcon As IntPtr
    19.         '6 is the index you need to change only .
    20.         hIcon = ExtractAssociatedIcon(hInst, iconPath, 6)
    21.         ico = Icon.FromHandle(hIcon)
    22.     End Sub
    23.  
    24.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    25.         GetIconInfo()
    26.     End Sub
    27.  
    28.     Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    29.         e.Graphics.DrawIcon(ico, 0, 0)
    30.     End Sub
    31.  
    32.  
    33.  
    34. End Class
    I took out the Windows form designer... region because it seemed to be irrelevent

    edit: It gives me error before I run it:
    Name 'Assembly' is not declared.

    Thanks
    VB.NET 2003 Professional Edition

    VB
    C#
    C++
    J#

  26. #26
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083

    Re: Ugly icons...[RESOLVED]

    oh ok , it might be the assembly namesapce not imported . try this

    Imports System.Reflection.Assembly (at the very top of your class declaration)

  27. #27
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083
    i don't think that will fix it , it's complaining about this assembly var , try this :


    Dim hInst As IntPtr = Marshal.GetHINSTANCE(Me.GetType.Assembly.GetExecutingAssembly().GetModules()(0))

  28. #28
    Member
    Join Date
    Jun 2005
    Posts
    55

    Re: Ugly icons...[RESOLVED]

    hmm... still doesn't work
    But i tried:
    Imports System.Reflection
    and it worked!
    thanks
    VB.NET 2003 Professional Edition

    VB
    C#
    C++
    J#

  29. #29
    Sleep mode
    Join Date
    Aug 2002
    Location
    RUH
    Posts
    8,083

    Re: Ugly icons...[RESOLVED]

    i hope pax doesn't get mad about hijacking his thread like that

  30. #30
    Member
    Join Date
    Jun 2005
    Posts
    55

    Re: Ugly icons...[RESOLVED]

    oh well
    VB.NET 2003 Professional Edition

    VB
    C#
    C++
    J#

  31. #31
    New Member
    Join Date
    Dec 2007
    Posts
    2

    Re: Ugly icons...[RESOLVED]

    Hello Pax

    I've found two minor bugs in your code.

    Lines 160/161:

    Old:
    vb Code:
    1. If Environment.OSVersion.Version.Major >= 5 AndAlso _
    2.         Environment.OSVersion.Version.Minor >= 1 AndAlso _
    3.         GetColorDepth() = 32 Then
    4.     'do something
    5. End If

    New:
    vb Code:
    1. Static myVersionBreak As New Version(5, 1, 0, 0)
    2. If (Environment.OSVersion.Version >= myVersionBreak) AndAlso _
    3.         (GetColorDepth() = 32) Then
    4.     'do something
    5. End If

    Reason:
    If there comes an OS Version 6.0, 7.0, 8.0 etc. your code is gonna fail as the minor version is not greater than 1. Remark: Luckily the version object overrides the compare operators what allows us to compare two version objects directly.


    Lines 44.5 and 36.5:
    The following line is missing:
    vb Code:
    1. <StructLayout(LayoutKind.Sequential)> _

    Reason:
    Interopability structures should be labeled with this attribute to prevent the compiler from rearranging the field order for memory optimization reasons.

    Thank you for the code and bye

    Chris

  32. #32
    New Member
    Join Date
    Dec 2007
    Posts
    2

    Re: Ugly icons...[RESOLVED]

    (Sorry, posted it twice accidentally. Please delete this one...)
    Last edited by CHHA; Dec 14th, 2007 at 09:10 AM. Reason: Duplicate

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