Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: okik en 1 Noviembre 2016, 18:09 pm



Título: Listview con iconos de archivo
Publicado por: okik en 1 Noviembre 2016, 18:09 pm
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
Código
  1.        Dim imageListSmall As New ImageList()
  2.        Dim iconForFile As Icon
  3.        ListView1.View = View.Details
  4.        iconForFile = System.Drawing.Icon.ExtractAssociatedIcon("C:\Windows\System32\notepad.exe")
  5.  
  6.        imageListSmall.Images.Add(iconForFile)
  7.        ListView1.SmallImageList = imageListSmall
  8.  
  9.        Dim ColumnHeadr As New ColumnHeader
  10.        ListView1.Columns.Add(ColumnHeadr)
  11.        ListView1.Items.Add("Notepad.exe", 0)
  12.  

gracias



vale ya está:

Código
  1.        Dim imageListSmall As New ImageList()
  2.        Dim iconForFile As Icon
  3.        ListView1.View = View.Details
  4.        iconForFile = System.Drawing.Icon.ExtractAssociatedIcon("C:\Windows\System32\notepad.exe")
  5.  
  6.        'Fix a smaller version with interpolation
  7.        Dim bm As New Bitmap(iconForFile.ToBitmap)
  8.        Dim thumb As New Bitmap(16, 16)
  9.        Dim g As Graphics = Graphics.FromImage(thumb)
  10.        g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
  11.        g.DrawImage(bm, New Rectangle(0, 0, 16, 16), New Rectangle(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel)
  12.        g.Dispose()
  13.        bm.Dispose()
  14.  
  15.        imageListSmall.Images.Add("1", thumb)
  16.        ListView1.SmallImageList = imageListSmall
  17.  
  18.        Dim ColumnHeadr As New ColumnHeader
  19.        ListView1.Columns.Add(ColumnHeadr)
  20.        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.
Código:
", ShellIcon.GetIcon(("C:\windows\system32\notepad.exe", 0)
Código:
", ShellIcon.GetIcon(("C:\windows\system32\notepad.exe", 1)
Código:
", ShellIcon.GetIcon(("C:\windows\system32\notepad.exe", 2)

Código
  1. Imports System.Runtime.InteropServices
  2.  
  3. Public Class Form1
  4.  
  5.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  6.  
  7.        ListView1.View = View.Details
  8.        Dim imgList As New ImageList
  9.        imgList.Images.Add("1", ShellIcon.GetIcon("C:\windows\system32\notepad.exe", 1))
  10.        ListView1.SmallImageList = imgList
  11.  
  12.        Dim ColumnHeadr As New ColumnHeader
  13.        ListView1.Columns.Add(ColumnHeadr)
  14.        ListView1.Items.Add("notepad.exe", "1")
  15.  
  16.  
  17.    End Sub
  18. End Class
  19.  
  20.  
  21.  
  22. Public NotInheritable Class ShellIcon
  23.    Private Sub New()
  24.    End Sub
  25.    <StructLayout(LayoutKind.Sequential)> _
  26.    Public Structure SHFILEINFO
  27.        Public hIcon As IntPtr
  28.        Public iIcon As IntPtr
  29.        Public dwAttributes As UInteger
  30.        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
  31.        Public szDisplayName As String
  32.        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
  33.        Public szTypeName As String
  34.    End Structure
  35.  
  36.    Private Class Win32
  37.        Public Const SHGFI_ICON As UInteger = &H100
  38.        Public Const SHGFI_LARGEICON As UInteger = &H0
  39.        ' 'Large icon
  40.        Public Const SHGFI_SMALLICON As UInteger = &H1
  41.        ' 'Small icon
  42.        <DllImport("shell32.dll")> _
  43.        Public Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, cbSizeFileInfo As UInteger, uFlags As UInteger) As IntPtr
  44.        End Function
  45.  
  46.        <DllImport("User32.dll")> _
  47.        Public Shared Function DestroyIcon(hIcon As IntPtr) As Integer
  48.        End Function
  49.  
  50.    End Class
  51.  
  52.  
  53.    Shared Sub New()
  54.    End Sub
  55.  
  56.    Public Shared Function GetSmallIcon(fileName As String) As Icon
  57.        Return GetIcon(fileName, Win32.SHGFI_SMALLICON)
  58.    End Function
  59.  
  60.    Public Shared Function GetLargeIcon(fileName As String) As Icon
  61.        Return GetIcon(fileName, Win32.SHGFI_LARGEICON)
  62.    End Function
  63.  
  64.    Public Shared Function GetIcon(fileName As String, flags As UInteger) As Icon
  65.        Dim shinfo As New SHFILEINFO()
  66.        Dim hImgSmall As IntPtr = Win32.SHGetFileInfo(fileName, 0, shinfo, CUInt(Marshal.SizeOf(shinfo)), Win32.SHGFI_ICON Or flags)
  67.  
  68.        Dim icon As Icon = DirectCast(System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone(), Icon)
  69.        Win32.DestroyIcon(shinfo.hIcon)
  70.        Return icon
  71.    End Function
  72. End Class

FUENTE:
http://www.pinvoke.net/default.aspx/shell32/SHGetFileInfo.html (http://www.pinvoke.net/default.aspx/shell32/SHGetFileInfo.html)


Título: Re: Listview con iconos de archivo
Publicado por: Slava_TZD en 1 Noviembre 2016, 22:11 pm
Código
  1. Dim imageListSmall As New ImageList()
  2.        Dim iconForFile As Icon
  3.        ListView1.View = View.Details
  4.        iconForFile = System.Drawing.Icon.ExtractAssociatedIcon("C:\Windows\System32\notepad.exe")
  5.        imageListSmall.Images.Add(iconForFile)
  6.        ListView1.SmallImageList = imageListSmall
  7.  
  8.        ListView1.SmallImageList.ColorDepth = ColorDepth.Depth32Bit
  9.  
  10.        Dim ColumnHeadr As New ColumnHeader
  11.        ListView1.Columns.Add(ColumnHeadr)
  12.        ListView1.Items.Add("Notepad.exe", 0)


Título: Re: Listview con iconos de archivo
Publicado por: Eleкtro en 1 Diciembre 2016, 16:15 pm
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:
Código
  1. Dim iconFile As Icon = ImageUtil.ExtractIconFromFile("C:\Windows\System32\notepad.exe", iconIndex:=0, iconSize:=16)

Saludos!