Buenas, extraigo el icono de una extensión y lo aplico a un ListView pero se ve mal.
Creo que obtengo el icono multipágina y asigna al listview el icono de mayor tamaño, entonces al reducirlo se ve mal. creo que eso es lo que pasa. ¿Cómo puedo usar el icono que yo quiera?
código de ejemplo
Dim imageListSmall As New ImageList()
Dim iconForFile As Icon
ListView1.View = View.Details
iconForFile = System.Drawing.Icon.ExtractAssociatedIcon("C:\Windows\System32\notepad.exe")
imageListSmall.Images.Add(iconForFile)
ListView1.SmallImageList = imageListSmall
Dim ColumnHeadr As New ColumnHeader
ListView1.Columns.Add(ColumnHeadr)
ListView1.Items.Add("Notepad.exe", 0)
gracias
vale ya está:
Dim imageListSmall As New ImageList()
Dim iconForFile As Icon
ListView1.View = View.Details
iconForFile = System.Drawing.Icon.ExtractAssociatedIcon("C:\Windows\System32\notepad.exe")
'Fix a smaller version with interpolation
Dim bm As New Bitmap(iconForFile.ToBitmap)
Dim thumb As New Bitmap(16, 16)
Dim g As Graphics = Graphics.FromImage(thumb)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(bm, New Rectangle(0, 0, 16, 16), New Rectangle(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel)
g.Dispose()
bm.Dispose()
imageListSmall.Images.Add("1", thumb)
ListView1.SmallImageList = imageListSmall
Dim ColumnHeadr As New ColumnHeader
ListView1.Columns.Add(ColumnHeadr)
ListView1.Items.Add("notepad.exe", "1")
No lo doy por resuelto por si hay otra manera más sencilla...
Encontré otra forma usando API.
Con este código puedes escoger el icono si es multipágina.
", ShellIcon.GetIcon(("C:\windows\system32\notepad.exe", 0)
", ShellIcon.GetIcon(("C:\windows\system32\notepad.exe", 1)
", ShellIcon.GetIcon(("C:\windows\system32\notepad.exe", 2)
Imports System.Runtime.InteropServices
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListView1.View = View.Details
Dim imgList As New ImageList
imgList.Images.Add("1", ShellIcon.GetIcon("C:\windows\system32\notepad.exe", 1))
ListView1.SmallImageList = imgList
Dim ColumnHeadr As New ColumnHeader
ListView1.Columns.Add(ColumnHeadr)
ListView1.Items.Add("notepad.exe", "1")
End Sub
End Class
Public NotInheritable Class ShellIcon
Private Sub New()
End Sub
<StructLayout(LayoutKind.Sequential)> _
Public Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As IntPtr
Public dwAttributes As UInteger
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
Public szDisplayName As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
Public szTypeName As String
End Structure
Private Class Win32
Public Const SHGFI_ICON As UInteger = &H100
Public Const SHGFI_LARGEICON As UInteger = &H0
' 'Large icon
Public Const SHGFI_SMALLICON As UInteger = &H1
' 'Small icon
<DllImport("shell32.dll")> _
Public Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbSizeFileInfo As UInteger, uFlags As UInteger) As IntPtr
End Function
<DllImport("User32.dll")> _
Public Shared Function DestroyIcon(hIcon As IntPtr) As Integer
End Function
End Class
Shared Sub New()
End Sub
Public Shared Function GetSmallIcon(fileName As String) As Icon
Return GetIcon(fileName, Win32.SHGFI_SMALLICON)
End Function
Public Shared Function GetLargeIcon(fileName As String) As Icon
Return GetIcon(fileName, Win32.SHGFI_LARGEICON)
End Function
Public Shared Function GetIcon(fileName As String, flags As UInteger) As Icon
Dim shinfo As New SHFILEINFO()
Dim hImgSmall As IntPtr = Win32.SHGetFileInfo(fileName, 0, shinfo, CUInt(Marshal.SizeOf(shinfo)), Win32.SHGFI_ICON Or flags)
Dim icon As Icon = DirectCast(System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone(), Icon)
Win32.DestroyIcon(shinfo.hIcon)
Return icon
End Function
End Class
FUENTE:
http://www.pinvoke.net/default.aspx/shell32/SHGetFileInfo.html (http://www.pinvoke.net/default.aspx/shell32/SHGetFileInfo.html)
Dim imageListSmall As New ImageList()
Dim iconForFile As Icon
ListView1.View = View.Details
iconForFile = System.Drawing.Icon.ExtractAssociatedIcon("C:\Windows\System32\notepad.exe")
imageListSmall.Images.Add(iconForFile)
ListView1.SmallImageList = imageListSmall
ListView1.SmallImageList.ColorDepth = ColorDepth.Depth32Bit
Dim ColumnHeadr As New ColumnHeader
ListView1.Columns.Add(ColumnHeadr)
ListView1.Items.Add("Notepad.exe", 0)
Hola.
Es bien sabido que la metodología más común por excelencia, me refiero a System.Drawing.Icon.ExtractAssociatedIcon(), es una mierd@ pinchá en un palo, no se puede describir de otra forma.
En mi API gratuita ElektroKit, tienes la implementación de dos alternativas que puedes copiar en tu proyecto, ofrecen mejores resultados, son las funciones Win32 SHDefExtractIcon y ExtractIconEx, quizás podrías necesitarlas para el futuro.
Dentro de mi API también, existe una función que sirve como wrapper de la función SHDefExtractIcon, está en la class Elektro.Imaging.Tools.ImageUtil, la función se llama ExtractIconFromFile y precisamente extrae iconos al tamaño deseado. Quizás te sirva, el código es este:
(http://i.imgur.com/5DaahXt.png)
(http://i.imgur.com/LCTo3Jk.png) (https://github.com/ElektroStudios/ElektroKit/blob/12f1ff734193945286b00b3abf605a1b89fea648/Solution/Elektro.Imaging/Tools/ImageUtil.vb)
( Click en la imagen para ir al código fuente )
Ejemplo de uso:
Dim iconFile As Icon = ImageUtil.ExtractIconFromFile("C:\Windows\System32\notepad.exe", iconIndex:=0, iconSize:=16)
Saludos!