XTab's Blog

Ged Mead's Blog at vbCity

vbCity Blogs moved to:
http://cs.vbcity.com/blogs
  Home :: Syndication  :: Login

OctNovember 2009Dec
SMTWTFS
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Archives

Topics

Ramblings

VB.NET

  This question comes up every so often in the forums and it's one of those things that you'd think should be easy, but actually isn't. Well, it isn't until you know how - like most things in developer land. The question is usually something along the lines of "How can I grab the icon from an MS Word file?" The application may not necessarily be MS Word, but the that's the general thrust of it.

  The only approach I have successfully used in this kind of scenario is the SHGetFileInfo API*. This API will grab the icon from an application.

  Here's the way I do it: First, Import Runtime.InteropServices into your Windows Form.

Code Copy
Imports System.Runtime.InteropServices

  Next, the API code, which goes at the top of the form, outside of any procedures:

Code Copy
    Private 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

    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
    Dim hImgSmall As IntPtr 'The handle to the system image list.
    Private Const SHGFI_ICON As Long = &H100
    Private Const SHGFI_SMALLICON As Long = &H1

  Note the two Constants at the end there being declared as Long. You'll usually find you have to tweak old API code to fix these kind of lines if you have Option Strict On.

  To demonstrate this API in action, here is how I've structured it:

  • I have added a button (btnSelectFile) to the Form.
  • When this button is clicked, an OpenFileDialog is created to allow the user to select a file.
  • Once a file has been selected, the file name is passed to a function that will dig out the icon for that file type and pass it back.
  • For demo purposes, the Form's default icon will be replaced with this selected one.

  Here is the code in the function that grabs the icon:

Code Copy
Function GetIcon(ByVal filename As String) As Icon
        Dim shinfo As SHFILEINFO
        shinfo = New SHFILEINFO

        'Get the small icon.
        hImgSmall = SHGetFileInfo(filename, 0, shinfo, _
          Marshal.SizeOf(shinfo), _
          SHGFI_ICON Or SHGFI_SMALLICON)

        Return System.Drawing.Icon.FromHandle(shinfo.hIcon)

End Function

  And here is that function being called from a Button Click, the icon then being shown as the Form's icon:

Code Copy
  Private Sub btnSelectFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectFile.Click
        Dim ofd As New OpenFileDialog

        If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then Me.Icon = GetIcon(ofd.FileName)


End Sub

  That's pretty much all there is to it, if you are happy to plonk the icon on the form like that. But in most cases you'll probably want something a bit more reusable. One easy way to store the grabbed icon is to put it in an ImageList.

  Assuming that you are only going to deal with one icon at a time, you can do something like this:

Code Copy
Dim myIcons As New ImageList
myIcons.Images.Add(System.Drawing.Icon.FromHandle(shinfo.hIcon))

  Now that you have that icon safely stored in the ImageList, you can access the ImageList in the usual way if you want to place the icon image elsewhere. And of course you can change the above code slightly to allow for more than one icon to be added to the ImageList and used as required.

  Finally, if you need to switch the icon into Bitmap format you can use the handy ToBitmap method:

Code Copy
Dim bmp As Bitmap = System.Drawing.Icon.FromHandle(shinfo.hIcon).ToBitmap

  It is possible then to save the Bitmap by using the Bitmap's Save method. However, I have found this to be a bit hit-and-miss, with it sometimes throwing a generic GDI+ error when I tried to recall it for use by means of the Image.FromFile method.

  I hope that if you need to grab an image from an application that you find this article useful.

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

  * There is the much more hopeful sounding ExtractIcon API which I have used to extract the icon of a currently running VB application, but haven't managed to port the logic over to the kind of file selection scenario described here.

posted on Thursday, November 27, 2008 6:00 PM

Feedback

# re: How To Get the Icon from an Application 5/21/2009 3:00 AM jesus
nothing


Post Feedback

Title:
Name:
Url:
Comments: 
Protected by Clearscreen.SharpHIPEnter the code you see: