• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

scorch

Icons dos ficheiros

32 mensagens neste tópico

Boas,

Eu estou a desenvolver uma aplicação tipo Windows Explorer e gostava de saber como fazer para aparecerem os ícones que o computador usa na ListView. Por exemplo, se é um atalho mostra a seta e o ícone do programa/ficheiro. E também ao clicar duas vezes abrir o programa predefinido para abrir esse tipo de ficheiros.

Cumps,

Scorch ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu segui este exemplo.

Na função AddImages ele dá erro. Melhor, diz apenas:

vshost.exe deixou de funcionar.

O Windows está a procurar uma solução para o problema.

Não me diz mais nada. Não sei qual é o erro. Se eu não chamar a função, ele funciona bem. (não mostra os icones)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

provavelmente tem a ver com a path onde estas a correr isto...quilo fica com um nome bue comprido........

Renomeia a pasta onde ele é extraido..aqui ta a funcionar bem

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O programa que vem como exemplo funciona bem. Ao implementar é que dá mal.

Tenho este código:

Imports System.Runtime.InteropServices

Private Structure SHFILEINFO
        Public hIcon As IntPtr            ' : icon
        Public iIcon As Integer           ' : icondex
        Public dwAttributes As Integer    ' : SFGAO_ flags
         _
        Public szDisplayName As String
         _
        Public szTypeName As String
    End Structure

    Private Declare Auto Function SHGetFileInfo Lib "shell32.dll" _
            (ByVal pszPath As String, _
             ByVal dwFileAttributes As Integer, _
             ByRef psfi As SHFILEINFO, _
             ByVal cbFileInfo As Integer, _
             ByVal uFlags As Integer) As IntPtr

    Private Const SHGFI_ICON = &H100
    Private Const SHGFI_SMALLICON = &H1
    Private Const SHGFI_LARGEICON = &H0    ' Large icon
    Private Const MAX_PATH = 260

    Private Sub AddImages(ByVal strFileName As String)

        Dim shInfo As SHFILEINFO
        shInfo = New SHFILEINFO()
        shInfo.szDisplayName = New String(vbNullChar, MAX_PATH)
        shInfo.szTypeName = New String(vbNullChar, 80)
        Dim hIcon As IntPtr
        hIcon = SHGetFileInfo(strFileName, 0, shInfo, Marshal.SizeOf(shInfo), SHGFI_ICON Or SHGFI_SMALLICON)
        Dim MyIcon As Drawing.Bitmap
        MyIcon = Drawing.Icon.FromHandle(shInfo.hIcon).ToBitmap
        ListViewLargeImageList.Images.Add(strFileName.ToString(), MyIcon)

AddImages(foundFile)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

onde dá erro exactamente? linha?

já agora, penso que não precisas desse código todo, podias utilizar 

System.Drawing.Icon.ExtractAssociatedIcon(filename)

associado a uma Imagelist, no entanto é apenas uma ideia  ;)

cumps,

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não dá erro em nenhuma linha. Só acontece que se eu chamar a função AddImages(), ele, ao fazer debug, dá-me aquela MessageBox.

vshost.exe deixou de funcionar.

O Windows está a procurar uma solução para o problema.

Vou tentar com o que disseste.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Provavelmente, apesar de ele não me dizer que dá erro, se eu comentar essa linha, ele funciona direito mas sem os icones. Se eu chamar a tal função, ele não me diz que erro aconteceu nem em que linho, apenas aquela MessageBox.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Agora tenho um problema:

Consigo importa-lo para a ImageList, mas não consigo saber o nome ou como é que ele me referencia o icon importado para o poder chamar.

ListViewLargeImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
'lvItem.ImageKey = System.Drawing.Icon.ExtractAssociatedIcon(foundFile)

Fazendo isto, dá erro:

Value of type 'System.Drawing.Icon' cannot be converted to 'String'.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

boas, deixo-te aqui um bocado de código para estudares:P

        With Me.FolderBrowserDialog1
            .RootFolder = Environment.SpecialFolder.MyComputer
            .ShowDialog()
        End With
        If Me.FolderBrowserDialog1.SelectedPath <> Nothing Then
            For Each file As String In My.Computer.FileSystem.GetFiles(Me.FolderBrowserDialog1.SelectedPath)
                Me.ImageList1.Images.Add(My.Computer.FileSystem.GetName(file), System.Drawing.Icon.ExtractAssociatedIcon(file).ToBitmap)
            Next
            Me.lblMaxImg.Text = Me.ImageList1.Images.Count
            Me.PictureBox1.Image = Me.ImageList1.Images(0)
            Me.lblNomeImg.Text = Me.ImageList1.Images.Keys(0).ToString
            Me.lblImgAct.Text = 0
        End If

isso basicamente percorre todos os ficheiros na pasta que seleccionares e depois adiciona o nome do ficheiro como key e a imagem. recomendo que na imagelist uses Depth32bit para poderes ver os icons correctamente, isto é com as devidas transparencias, isto se não estiveres já a usar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Dim passar_icons As Integer = ListViewLargeImageList.Images.Count
For Each foundFile As String In My.Computer.FileSystem.GetFiles(path)
                lvItem = ListView.Items.Add(My.Computer.FileSystem.GetFileInfo(foundFile).Name)
                
                ListViewLargeImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
                ListViewSmallImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
                lvItem.ImageKey = ListViewLargeImageList.Images.Keys(passar_icons).ToString
                
                lvItem.SubItems.AddRange(New String() {My.Computer.FileSystem.GetFileInfo(foundFile).Extension, "Column3"})
                
                passar_files = passar_files + 1
                
                tssl_ficheiros.Text = passar_files & " Ficheiros e " & passar_dirs & " Pastas = " & passar_dirs + passar_files
                passar_icons = passar_icons + 1
                Application.DoEvents()
            Next

Não, ele não mostra ícones.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tu estás a adicionar as imagens sem definires a key string e depois estas a tentar obter a key de uma imagem.

Tu tens

 
ListViewLargeImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
ListViewSmallImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile))

quando devias ter

 
ListViewLargeImageList.Images.Add("TextFileLarge", System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
ListViewSmallImageList.Images.Add("TextFileSmall", System.Drawing.Icon.ExtractAssociatedIcon(foundFile))

óbvio que as keys que coloquei são meros exemplos, tens que colocar o ideal para ti.

EDIT:

uma coisa que me esqueci de referir foi como obter uma imagem através da key. Não sei se já sabias ou não mas fica aqui o código :P

Me.PictureBox1.Image = Me.ImageList1.Images.Item("key")

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Agora mostra ícones. Só que só são um ficheiro branco que, pela qualidade, parece do Win 2000. :down:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Dá para mostrar um print? Já agora como tens as propriedades das ImageList? Image Size e Image Bit Depth?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E os outros tipos de ficheiros, também aparecem com má qualidade?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Aparecem todos com esse ícone e com essa qualidade. :down:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hum.... estranho. Experimenta fazer debug e vê o valor do imagelist.count se for maior que 1 e as imagens forem diferentes, então deves ter algum problema com o teu código (acho eu, também pode ser de outra coisa qualquer).

Quanto a qualidade experimenta usar 32; 32 em vez de 50; 50 a qualidade deve melhor. Acho que o tamanho normal dos icons e de 32 para baixo, pelo menos os do SO.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A máxima qualidade que ele permite é 32. Já para não falar que a qualidade e o tamanho não são o problema, pois eu antes fazia os ficheiros, consoante a extensão, mostrarem algumas imagens e essas dava na perfeição.

O meu código é este:

For Each foundFile As String In My.Computer.FileSystem.GetFiles(path)
                lvItem = ListView.Items.Add(My.Computer.FileSystem.GetFileInfo(foundFile).Name)
ListViewLargeImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile).ToString, System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
                ListViewSmallImageList.Images.Add(System.Drawing.Icon.ExtractAssociatedIcon(foundFile).ToString, System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
                lvItem.ImageKey = ListViewLargeImageList.Images.Keys(passar_icons).ToString
                lvItem.SubItems.AddRange(New String() {My.Computer.FileSystem.GetFileInfo(foundFile).Extension, "Column3"})
                passar_files = passar_files + 1
                tssl_ficheiros.Text = passar_files & " Ficheiros e " & passar_dirs & " Pastas = " & passar_dirs + passar_files
                passar_icons = passar_icons + 1
                Application.DoEvents()
            Next

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Continuas a ter aí uma coisa mal.

Isto

System.Drawing.Icon.ExtractAssociatedIcon(foundFile).ToString

vai-te retornar sempre "(Ícone)".

Tu queres usar o que como key? Nome do ficheiro?

My.Computer.FileSystem.GetFileInfo(foundFile).Name

ou a extensão do ficheiro?

My.Computer.FileSystem.GetFileInfo(foundFile).Extension

Apenas uma ideia, podias pensar em implementar um sistema deste género: utilizavas como key a extensão do ficheiro, e depois à medida que ias percorrendo os ficheiros, verificavas na ImageList se já tinhas essa extensão lá. Se já tivesses utilizavas essa imagem,

senão adicionavas. Assim evitavas teres imagens repetidas na ImageList.

EDIT:

eu quando me referi aos 32;32 não era no depth mas sim no tamanho.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Dá-me este erro que eu não percebo:

Conversion from string ".0" to type 'Integer' is not valid.

ListViewLargeImageList.Images.Add(My.Computer.FileSystem.GetFileInfo(foundFile).Extension, System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
                ListViewSmallImageList.Images.Add(My.Computer.FileSystem.GetFileInfo(foundFile).Extension, System.Drawing.Icon.ExtractAssociatedIcon(foundFile))
                'Aqui dá o erro.
                lvItem.ImageKey = ListViewLargeImageList.Images.Keys(My.Computer.FileSystem.GetFileInfo(foundFile).Extension)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens que usar o outro código que te dei.

Me.PictureBox1.Image = Me.ImageList1.Images.Item(My.Computer.FileSystem.GetFileInfo(foundFile).Extension)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora