Home All Groups Group Topic Archive Search About

Convert windows SHFILEINFO to DotNet

Author
28 Jun 2005 12:56 AM
**Developer**
Need this:

typedef struct _SHFILEINFO {
    HICON hIcon;
    int iIcon;
    DWORD dwAttributes;
    TCHAR szDisplayName[MAX_PATH];
    TCHAR szTypeName[80];
} SHFILEINFO

This is what I tried:
Public Structure SHFILEINFO

Public hIcon As IntPtr

Public iIcon As Integer

Public dwAttributes As Integer

<MarshalAs(UnmanagedType.LPStr, SizeConst:=Kernel.MAX_PATH)> Public
szDisplayName As String

<MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String

End Structure



Kernel.MAX_PATH equals 260

But it doesn't appear to work. Does it look OK to you or do you know how to
fix it.

Thanks

Author
28 Jun 2005 1:28 AM
Jim Hughes
Show quote Hide quote
" **Developer**" <REMOVEdevelo***@a-znet.com> wrote in message
news:u%23PkCx3eFHA.3808@TK2MSFTNGP14.phx.gbl...
> Need this:
>
> typedef struct _SHFILEINFO {
>    HICON hIcon;
>    int iIcon;
>    DWORD dwAttributes;
>    TCHAR szDisplayName[MAX_PATH];
>    TCHAR szTypeName[80];
> } SHFILEINFO
>
> This is what I tried:
> Public Structure SHFILEINFO
>
> Public hIcon As IntPtr
>
> Public iIcon As Integer
>
> Public dwAttributes As Integer
>
> <MarshalAs(UnmanagedType.LPStr, SizeConst:=Kernel.MAX_PATH)> Public
> szDisplayName As String
>
> <MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As
> String
>
> End Structure
>

Google is your friend!
http://www.google.com/search?biw=951&hl=en&q=SHFILEINFO+vb.net&btnG=Google+Search

From
http://www.codeguru.com/vb/gen/vb_misc/icons/article.php/c5597/

The difference is in the UnmangedType for szDisplayName

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
Author
28 Jun 2005 11:13 AM
**Developer**
Show quote Hide quote
"Jim Hughes" <NOSPAMJ3033@Hotmail.com> wrote in message
news:%23eAy3C4eFHA.1404@TK2MSFTNGP09.phx.gbl...
>" **Developer**" <REMOVEdevelo***@a-znet.com> wrote in message
>news:u%23PkCx3eFHA.3808@TK2MSFTNGP14.phx.gbl...
snip
>
> The difference is in the UnmangedType for szDisplayName
>
> 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
>
Jim

I did see this in the help but was (and am still) confused about the ByVal
in ByValStr. This struc is used to obtain strings so I'd expect ByRef

As you have it can the API call return strings?

Do I need to somehow define some place to put the string or does this
actually set aside memory for the returned string?

I did try this and it didn't fix my problem but that's most likely because I
have an additional problem in the code.

Thanks
Author
28 Jun 2005 1:29 AM
Ken Tucker [MVP]
Hi,

        Here is a quick example.   Add a listview control to the form and
name it lv.  Add an imagelist to form name it imlIcon.

Private Function getLocalIcons(ByVal szFolderPath As String)

Dim dirInfo As New System.IO.DirectoryInfo(szFolderPath)

Dim di As System.IO.DirectoryInfo

Dim fi As System.IO.FileInfo

Dim lvitem As ListViewItem

Dim hIcon As Icon

Dim cIcon As New clsGetIcon

Dim htIcons As New Hashtable

Dim intIndex As Integer

imlIcon.Images.Clear()

lv.Items.Clear()

lv.SmallImageList = imlIcon

For Each di In dirInfo.GetDirectories()

lvitem = lv.Items.Add(di.Name)

hIcon = cIcon.getIcon(di.FullName)

If htIcons.ContainsKey(hIcon) Then

intIndex = htIcons(hIcon)

Else

imlIcon.Images.Add(hIcon.ToBitmap)

intIndex = imlIcon.Images.Count - 1

End If

lvitem.ImageIndex = intIndex

Next

For Each fi In dirInfo.GetFiles()

lvitem = lv.Items.Add(fi.Name)

hIcon = cIcon.getIcon(fi.FullName)

If htIcons.ContainsKey(hIcon) Then

intIndex = htIcons(hIcon)

Else

imlIcon.Images.Add(hIcon.ToBitmap)

intIndex = imlIcon.Images.Count - 1

End If

lvitem.ImageIndex = intIndex

Next

End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

lv.SuspendLayout()

getLocalIcons("C:\")

lv.ResumeLayout()

End Sub



The helper class.

Imports System.Runtime.InteropServices

Public Class clsGetIcon

Public Structure SHFILEINFO

Dim hIcon As IntPtr

Dim iIcon As Integer

Dim dwAttributes As Integer

<VBFixedString(260),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst:=260)> Public szDisplayName As String

'String that contains the name of the file as it appears in the Microsoft®
Windows® Shell, or the path and file name of the file that contains the icon
representing the file.

<VBFixedString(80),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst:=80)> Public szTypeName As String

End Structure


Private Declare Auto Function SHGetFileInfo Lib "shell32" (ByVal pszPath As
String, _

ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, _

ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As Integer

Private Const SHGFI_ICON As Integer = &H100

Private Const SHGFI_SMALLICON As Integer = &H1 'Small icon

Private Const SHGFI_TYPENAME As Integer = &H400 ' get type name



Public Function getIcon(ByVal szFilename As String) As Icon

Try

Dim aSHFileInfo As New SHFILEINFO

Dim cbFileInfo As Integer = _

Marshal.SizeOf(aSHFileInfo)

Dim uflags As Integer = SHGFI_ICON Or SHGFI_SMALLICON

SHGetFileInfo(szFilename, 0, aSHFileInfo, cbFileInfo, uflags)

Dim myIcon As Icon

myIcon = Icon.FromHandle(aSHFileInfo.hIcon)

aSHFileInfo.szTypeName = Space(255)

SHGetFileInfo(szFilename, 0, aSHFileInfo, cbFileInfo, SHGFI_TYPENAME)

Trace.WriteLine(aSHFileInfo.szTypeName)

Return myIcon

Catch ex As Exception

Debug.WriteLine(ex.ToString)

Return Nothing

End Try

End Function

End Class



Ken

---------------------------

" **Developer**" <REMOVEdevelo***@a-znet.com> wrote in message
news:u%23PkCx3eFHA.3808@TK2MSFTNGP14.phx.gbl...
Need this:

typedef struct _SHFILEINFO {
    HICON hIcon;
    int iIcon;
    DWORD dwAttributes;
    TCHAR szDisplayName[MAX_PATH];
    TCHAR szTypeName[80];
} SHFILEINFO

This is what I tried:
Public Structure SHFILEINFO

Public hIcon As IntPtr

Public iIcon As Integer

Public dwAttributes As Integer

<MarshalAs(UnmanagedType.LPStr, SizeConst:=Kernel.MAX_PATH)> Public
szDisplayName As String

<MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As String

End Structure



Kernel.MAX_PATH equals 260

But it doesn't appear to work. Does it look OK to you or do you know how to
fix it.

Thanks
Author
28 Jun 2005 11:17 AM
**Developer**
Is something missing for the following.

> myIcon = Icon.FromHandle(aSHFileInfo.hIcon)

I tried your structure in my code and that did not fix my problem so I'd
like to get your example running exactly as you have it.

Thanks
Author
28 Jun 2005 11:23 AM
**Developer**
For that statement I get

Reference to a non-shared member requires an object reference.

Thanks

Show quoteHide quote
" **Developer**" <REMOVEdevelo***@a-znet.com> wrote in message
news:eu6OxM9eFHA.2888@TK2MSFTNGP15.phx.gbl...
> Is something missing for the following.
>
>> myIcon = Icon.FromHandle(aSHFileInfo.hIcon)
>
> I tried your structure in my code and that did not fix my problem so I'd
> like to get your example running exactly as you have it.
>
> Thanks
>
Author
28 Jun 2005 2:34 PM
**Developer**
FYI

I simply changed Icon to MyIcon

Show quoteHide quote
" **Developer**" <REMOVEdevelo***@a-znet.com> wrote in message
news:eDJqVP9eFHA.256@TK2MSFTNGP14.phx.gbl...
> For that statement I get
>
> Reference to a non-shared member requires an object reference.
>
> Thanks
>
> " **Developer**" <REMOVEdevelo***@a-znet.com> wrote in message
> news:eu6OxM9eFHA.2888@TK2MSFTNGP15.phx.gbl...
>> Is something missing for the following.
>>
>>> myIcon = Icon.FromHandle(aSHFileInfo.hIcon)
>>
>> I tried your structure in my code and that did not fix my problem so I'd
>> like to get your example running exactly as you have it.
>>
>> Thanks
>>
>
>
Author
28 Jun 2005 2:49 PM
**Developer**
>
> I simply changed Icon to MyIcon
>

but aSHFileInfo.szTypeName always returns spaces

so I tried the struct suggested by Amin and Herfried but I still get only
spaces



Show quoteHide quote
>>> Is something missing for the following.
>>>
>>>> myIcon = Icon.FromHandle(aSHFileInfo.hIcon)
>>>
Author
28 Jun 2005 6:00 AM
Herfried K. Wagner [MVP]
Show quote Hide quote
" **Developer**" <REMOVEdevelo***@a-znet.com> schrieb:
> typedef struct _SHFILEINFO {
>    HICON hIcon;
>    int iIcon;
>    DWORD dwAttributes;
>    TCHAR szDisplayName[MAX_PATH];
>    TCHAR szTypeName[80];
> } SHFILEINFO
>[...]
> <MarshalAs(UnmanagedType.LPStr, SizeConst:=Kernel.MAX_PATH)> Public
> szDisplayName As String
>
> <MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As
> String
>
> End Structure

The strings must be stored as 'ByValTStr's, which means that they are stored
inside the structure.

<URL:http://groups.google.to/groups?selm=u%23IVf5baFHA.1040%40TK2MSFTNGP10.phx.gbl>

--
M S   Herfried K. Wagner
M V P  <URL:http://dotnet.mvps.org/>
V B   <URL:http://classicvb.org/petition/>
Author
28 Jun 2005 11:31 AM
**Developer**
Show quote Hide quote
"Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message
news:uy4X3a6eFHA.1040@TK2MSFTNGP10.phx.gbl...
>" **Developer**" <REMOVEdevelo***@a-znet.com> schrieb:
>> typedef struct _SHFILEINFO {
>>    HICON hIcon;
>>    int iIcon;
>>    DWORD dwAttributes;
>>    TCHAR szDisplayName[MAX_PATH];
>>    TCHAR szTypeName[80];
>> } SHFILEINFO
>>[...]
>> <MarshalAs(UnmanagedType.LPStr, SizeConst:=Kernel.MAX_PATH)> Public
>> szDisplayName As String
>>
>> <MarshalAs(UnmanagedType.LPStr, SizeConst:=80)> Public szTypeName As
>> String
>>
>> End Structure
>
> The strings must be stored as 'ByValTStr's, which means that they are
> stored inside the structure.


With ByValStr is memory allocated for the API call and the result put into
the string without me doing anything else?


Why is it called ByVal since I expect a returned string. Why doesn't
ByRefTStr make more sense?

Thanks for the input


Show quoteHide quote
Author
28 Jun 2005 2:53 PM
Herfried K. Wagner [MVP]
" **Developer**" <REMOVEdevelo***@a-znet.com> schrieb:
> Why is it called ByVal since I expect a returned string. Why doesn't
> ByRefTStr make more sense?

In this particular case the buffer for the string (value) is stored inline
in the structure, and not just a pointer to a string (reference) is stored
inside the structure.

--
M S   Herfried K. Wagner
M V P  <URL:http://dotnet.mvps.org/>
V B   <URL:http://classicvb.org/petition/>
Author
28 Jun 2005 3:04 PM
**Developer**
Thanks again

Show quoteHide quote
"Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message
news:%23DjTgE$eFHA.3032@TK2MSFTNGP10.phx.gbl...
>" **Developer**" <REMOVEdevelo***@a-znet.com> schrieb:
>> Why is it called ByVal since I expect a returned string. Why doesn't
>> ByRefTStr make more sense?
>
> In this particular case the buffer for the string (value) is stored inline
> in the structure, and not just a pointer to a string (reference) is stored
> inside the structure.
>
> --
> M S   Herfried K. Wagner
> M V P  <URL:http://dotnet.mvps.org/>
> V B   <URL:http://classicvb.org/petition/>