locked
Get the shortcut icon without the arrow (overlay) RRS feed

  • Question

  • I use the code below to get shortcut icon, but how to remove the small arrow (overlay)? like the page

    https://stackoverflow.com/questions/43545998/shgetfileinfo-for-lnk-file-without-lnk-overlay-arrow

    My code is below:


        <DllImport("shell32.dll", CharSet:=CharSet.Auto)>
        Private Shared Function SHGetFileInfo _
          (ByVal pszPath As String,
           ByVal dwFileAttributes As Integer,
           ByRef psfi As SHFILEINFO,
           ByVal cbFileInfo As Integer,
           ByVal uFlags As Integer) As IntPtr
        End Function
        Public Enum IconSize
            SmallIcon = 1
            LargeIcon = 0
        End Enum

        Private Structure SHFILEINFO
            Public hIcon As IntPtr ' : icon
            Public iIcon As Integer ' : icondex
            Public dwAttributes As Integer ' : SFGAO_ flags
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
        End Structure

        <Flags()> Private Enum SHGFI
            SmallIcon = &H1
            LargeIcon = &H0
            Icon = &H100
            DisplayName = &H200
            Typename = &H400
            SysIconIndex = &H4000
            UseFileAttributes = &H10
            SHGFI_LINKOVERLAY = &H8000
            FILE_ATTRIBUTE_NORMAL = &H80
        End Enum


        Public Function GetDefaultIcon(ByVal Path As String, ByVal IconSize As IconSize, LinkOverlay As Boolean) As Icon
            Dim ico As Icon = Nothing
            If Path <> "" Then
                Try
                    Dim shfiFolderInfo As New SHFILEINFO
                    Dim flags As UInteger = SHGFI.Icon
                    If IconSize = IconSize.LargeIcon Then
                        flags = flags + SHGFI.LargeIcon
                    Else
                        flags = flags + SHGFI.SmallIcon
                    End If
                    If LinkOverlay = True Then
                        flags = flags + SHGFI.SHGFI_LINKOVERLAY
                    End If

                    SHGetFileInfo(Path, SHGFI.FILE_ATTRIBUTE_NORMAL, shfiFolderInfo, Marshal.SizeOf(shfiFolderInfo), flags)

                    ico = Icon.FromHandle(shfiFolderInfo.hIcon)
                Catch ex As Exception
                End Try
            End If
            Return ico
        End Function


    • Edited by gaxjyxq Tuesday, June 6, 2017 8:00 AM
    Tuesday, June 6, 2017 7:48 AM

Answers

  • The test I did :

    Dim fi As New SHFILEINFO
    Dim hImageList As IntPtr = SHGetFileInfo("C:\Users\Christian\Desktop\AdvOR.exe - Raccourci.lnk", 0, fi, Marshal.SizeOf(fi), SHGFI_SYSICONINDEX)
    Dim hIcon = ImageList_GetIcon(hImageList, fi.iIcon, ILD_TRANSPARENT)
    Dim ico As Icon = Icon.FromHandle(hIcon)
    Dim g As Graphics = Graphics.FromHwnd(New IntPtr(0))
    g.DrawIcon(ico, 50, 50)
    
    ' Declarations
    
    Public Const ILD_NORMAL As Integer = &H0
    Public Const ILD_TRANSPARENT As Integer = &H1
    Public Const ILD_MASK As Integer = &H10
    Public Const ILD_IMAGE As Integer = &H20
    
    <DllImport("Comctl32")>
    Public Shared Function ImageList_GetIcon(himl As IntPtr, i As Integer, flags As UInteger) As IntPtr
    End Function
    
    Public Const SHGFI_DISPLAYNAME As Integer = &H200
    Public Const SHGFI_SYSICONINDEX As Integer = &H4000
    
    Public Structure SHFILEINFO
        Public hIcon As IntPtr
        Public iIcon As Integer
        Public dwAttributes As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
    End Structure
    
    <DllImport("shell32", CharSet:=CharSet.Auto)>
    Public Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbFileInfo As UInteger, uFlags As UInteger) As IntPtr
    End Function


    • Edited by Castorix31 Tuesday, June 6, 2017 10:35 AM
    • Marked as answer by gaxjyxq Tuesday, June 6, 2017 11:51 AM
    Tuesday, June 6, 2017 10:34 AM
  • I have sloved this problem, used the code below

      <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Structure SHFILEINFO
            Public hIcon As IntPtr
            Public iIcon As Integer
            Public dwAttributes As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
        End Structure

    • Marked as answer by gaxjyxq Wednesday, June 7, 2017 3:35 AM
    Wednesday, June 7, 2017 3:35 AM

All replies

  • SHGFI_SYSICONINDEX gives the icon without the arrow

    (tested on a desktop .lnk on Windows 10)

    Tuesday, June 6, 2017 8:30 AM
  • My code will not work yet!

     Public Function GetDefaultIcon(ByVal Path As String, ByVal IconSize As IconSize, LinkOverlay As Boolean) As Icon
            Dim ico As Icon = Nothing
            If Path <> "" Then
                Try
                    Dim shfiFolderInfo As New SHFILEINFO
                    Dim flags As UInteger = SHGFI.ICON
                    If IconSize = IconSize.LargeIcon Then
                        flags = flags + SHGFI.LARGEICON
                    Else
                        flags = flags + SHGFI.SMALLICON
                    End If

                    If LinkOverlay = False Then
                        flags = flags + SHGFI.SYSICONINDEX

                    End If

                    SHGetFileInfo(Path, SHGFI.FILE_ATTRIBUTE_NORMAL, shfiFolderInfo, Marshal.SizeOf(shfiFolderInfo), flags)

                    ico = Icon.FromHandle(shfiFolderInfo.hIcon)
                Catch ex As Exception
                End Try
            End If
            Return ico
        End Function

    Tuesday, June 6, 2017 9:37 AM
  • Can i view your code? thank you.
    Tuesday, June 6, 2017 9:38 AM
  • The test I did :

    Dim fi As New SHFILEINFO
    Dim hImageList As IntPtr = SHGetFileInfo("C:\Users\Christian\Desktop\AdvOR.exe - Raccourci.lnk", 0, fi, Marshal.SizeOf(fi), SHGFI_SYSICONINDEX)
    Dim hIcon = ImageList_GetIcon(hImageList, fi.iIcon, ILD_TRANSPARENT)
    Dim ico As Icon = Icon.FromHandle(hIcon)
    Dim g As Graphics = Graphics.FromHwnd(New IntPtr(0))
    g.DrawIcon(ico, 50, 50)
    
    ' Declarations
    
    Public Const ILD_NORMAL As Integer = &H0
    Public Const ILD_TRANSPARENT As Integer = &H1
    Public Const ILD_MASK As Integer = &H10
    Public Const ILD_IMAGE As Integer = &H20
    
    <DllImport("Comctl32")>
    Public Shared Function ImageList_GetIcon(himl As IntPtr, i As Integer, flags As UInteger) As IntPtr
    End Function
    
    Public Const SHGFI_DISPLAYNAME As Integer = &H200
    Public Const SHGFI_SYSICONINDEX As Integer = &H4000
    
    Public Structure SHFILEINFO
        Public hIcon As IntPtr
        Public iIcon As Integer
        Public dwAttributes As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
    End Structure
    
    <DllImport("shell32", CharSet:=CharSet.Auto)>
    Public Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbFileInfo As UInteger, uFlags As UInteger) As IntPtr
    End Function


    • Edited by Castorix31 Tuesday, June 6, 2017 10:35 AM
    • Marked as answer by gaxjyxq Tuesday, June 6, 2017 11:51 AM
    Tuesday, June 6, 2017 10:34 AM
  • Another problem, i will get the display name of file and folder, there is the C# code below

    https://stackoverflow.com/questions/5145394/how-to-get-the-actual-localized-folder-names

    My code is below, but it only get the first letter for the English name, get the garbage characters for the non-English name.

     <Flags()> Private Enum SHGFI

            ICON = &H100            'Get icon
            DISPLAYNAME = &H200     'Get display name
            TYPENAME = &H400        'Get type name
            ATTRIBUTES = &H800     'Get attributes
            ICONLOCATION = &H1000     'Get icon location
            EXETYPE = &H2000     'Return exe type
            SYSICONINDEX = &H4000     'Get system icon index
            LINKOVERLAY = &H8000     'put a link overlay On icon
            SELECTED = &H10000     'show icon In selected state
            ATTR_SPECIFIED = &H20000     'Get only specified attributes
            LARGEICON = &H0     'Get large icon
            SMALLICON = &H1     'Get small icon
            OPENICON = &H2     'Get open icon
            SHELLICONSIZE = &H4      'Get shell size icon
            PIDL = &H8     'pszPath Is a pidl
            USEFILEATTRIBUTES = &H10     'use passed dwFileAttribute
            ADDOVERLAYS = &H20     'apply the appropriate overlays
            OVERLAYINDEX = &H40     'Get the index Of the overlay

            FILE_ATTRIBUTE_DIRECTORY = &H10
            FILE_ATTRIBUTE_NORMAL = &H80

        End Enum

        Public Structure SHFILEINFO
            Public hIcon As IntPtr
            Public iIcon As Integer
            Public dwAttributes As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
        End Structure

        <DllImport("shell32", CharSet:=CharSet.Auto)>
        Public Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbFileInfo As UInteger, uFlags As UInteger) As IntPtr
        End Function

        Public Function GetDisplayName(ByVal Path As String) As String
            Dim fi As New SHFILEINFO

            SHGetFileInfo(Path, 0, fi, CType(Marshal.SizeOf(fi), UInteger), SHGFI.DISPLAYNAME)
            Return fi.szDisplayName
        End Function

    Wednesday, June 7, 2017 3:04 AM
  • I have sloved this problem, used the code below

      <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Structure SHFILEINFO
            Public hIcon As IntPtr
            Public iIcon As Integer
            Public dwAttributes As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String
        End Structure

    • Marked as answer by gaxjyxq Wednesday, June 7, 2017 3:35 AM
    Wednesday, June 7, 2017 3:35 AM