7 Replies - 7997 Views - Last Post: 29 December 2012 - 10:22 PM Rate Topic: -----

#1 rusoaica  Icon User is offline

  • D.I.C Head

Reputation: 34
  • View blog
  • Posts: 201
  • Joined: 10-March 12

Get external applications icons

Posted 28 December 2012 - 03:22 AM

hello, i am developing a custom taskbar similar to Windows Taskbar. So far, i got the running applications and added a control for each of them to my taskbar. Now, i want to get the icons of those applications running in Windows Taskbar. So far, i've tried it this way, with no luck:

 <DllImportAttribute("user32.dll", EntryPoint:="SendMessageW")> _
    Public Shared Function SendMessage(<InAttribute()> ByVal hWnd As System.IntPtr, ByVal Msg As UInteger, ByVal wParam As UInteger, ByVal lParam As Integer) As IntPtr
    End Function
    Public Const WM_GETICON As UInteger = &H7F

    Public Shared Function GetWindowIcon(ByVal WindowHandle As IntPtr) As Icon
        Dim IconHandle As IntPtr = SendMessage(WindowHandle, WM_GETICON, 0, 0)
        If Not IconHandle = IntPtr.Zero Then
            Return Icon.FromHandle(IconHandle)
        Else
            Return Nothing
        End If
    End Function
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For Each processname As Process In Process.GetProcesses
            If processname.MainWindowTitle = "Untitled - Notepad" Then
                Dim x As Icon = GetWindowIcon(processname.Handle)
                'PictureBox1.Image = GetWindowIcon(processname.Handle).ToBitmap
                Me.Icon = x
            End If
        Next
    End Sub


- which does nothing, and like this:

   <StructLayout(LayoutKind.Sequential)> _
    Private 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

    <DllImport("shell32.dll")> _
    Private Shared Function SHGetFileInfo(ByRef path As String, ByRef fileAttributes As UInteger, _
ByRef fileInfo As SHFILEINFO, ByRef sizeInfo As UInteger, ByRef flags As UInteger) As IntPtr
    End Function

    Public Function GetApplicationIcon(ByRef fileName As String, ByRef sizeType As String) As Icon
        Dim iconHandle As IntPtr
        Dim fileInfo As New SHFILEINFO()

        Try
            Select Case sizeType.ToLower()
                Case "small"
                    iconHandle = SHGetFileInfo(fileName, 0, fileInfo, CInt(Marshal.SizeOf(fileInfo)), 256 Or 1)
                    Exit Select
                Case "large"
                    iconHandle = SHGetFileInfo(fileName, 0, fileInfo, CInt(Marshal.SizeOf(fileInfo)), 256 Or 0)
                    Exit Select
                Case Else
                    iconHandle = SHGetFileInfo(fileName, 0, fileInfo, CInt(Marshal.SizeOf(fileInfo)), 256 Or 1)
                    Exit Select
            End Select

            Return System.Drawing.Icon.FromHandle(fileInfo.hIcon)
        Catch ex As Exception
            Console.WriteLine(ex.ToString)
            Return Nothing
        End Try
    End Function
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Me.Icon = GetApplicationIcon("Notepad.exe", "small")
    End Sub


which throws an error of kind: "object reference not set to an instance of an object. What am i doing wrong and what is the right way to get the icon of an external program an display it as a bitmap in a picturebox?

Is This A Good Question/Topic? 0
  • +

Replies To: Get external applications icons

#2 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 765
  • Joined: 19-October 11

Re: Get external applications icons

Posted 28 December 2012 - 05:00 AM

Replace your line 17 with Me.Icon = Icon.ExtractAssociatedIcon(procInfo.MainModule.FileName), get rid of lines 18 and 19, and put code I gave in Try...Catch block so you'll capture any exceptions.

Edit: I'm talking about your code in first block.

This post has been edited by lucky3: 28 December 2012 - 05:01 AM

Was This Post Helpful? 2
  • +
  • -

#3 rusoaica  Icon User is offline

  • D.I.C Head

Reputation: 34
  • View blog
  • Posts: 201
  • Joined: 10-March 12

Re: Get external applications icons

Posted 28 December 2012 - 05:07 AM

that worked, thank you very much!
Was This Post Helpful? 0
  • +
  • -

#4 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 765
  • Joined: 19-October 11

Re: Get external applications icons

Posted 28 December 2012 - 05:29 AM

You're welcome. Just to add, if anyone is going to use this on 64 bit OS system, you could catch

Quote

A 32 bit processes cannot access modules of a 64 bit process


To avoid that
  • go to project's properties (right-click on project in solution explorer, and properties (usually at the bottom) OR go to Project in the upper menu, and click properties (usually at or near the bottom))
  • select Compile tab
  • scroll down to Advanced Compile Options
  • set Target CPU to AnyCPU (or x64 but it will only work on 64 bit OS then)


Attached Image

So your code would look something like:
        For Each procInfo In Process.GetProcesses
            If procInfo.MainWindowTitle.Contains("Adobe Photoshop") Then
                Try
                    Me.Icon = Icon.ExtractAssociatedIcon(procInfo.MainModule.FileName)
                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try
            End If
        Next



and your compile settings:

Attached Image
Was This Post Helpful? 2
  • +
  • -

#5 rusoaica  Icon User is offline

  • D.I.C Head

Reputation: 34
  • View blog
  • Posts: 201
  • Joined: 10-March 12

Re: Get external applications icons

Posted 29 December 2012 - 11:42 AM

i now have another problem.. for certain reasons, i ended up creating my taskbar this way:

Private Structure ExternalApp
        Dim hWnd As Integer
        Dim MainWindowText As String
    End Structure

Dim myWindows(-1) As ExternalApp

 For intloop = 0 To myWindows.GetUpperBound(0)
                If (myWindows(intloop).MainWindowText.ToLower() <> "terminalstartup") Then
                    Dim myButton As New LCARSTerminalControls.Controls.PillControl
                    Dim myCloseButton As New LCARSTerminalControls.Controls.PillControl
                    Dim TaskbarIcon As New PictureBox
                    myCloseButton.Size = New Point(20, 25)
                    myCloseButton.ButtonText = "X"
                    myCloseButton.ButtonTextAlign = ContentAlignment.MiddleCenter
                    myCloseButton.Color = LCARSTerminalControls.LCARSTerminalColors.Red
                    myCloseButton.Left = (((myAppsPanel.Controls.Count - 1) \ 2) * 134) + 31
                    myCloseButton.Top = 0
                    myCloseButton.Data = myWindows(intloop).hWnd
                    myCloseButton.Beeping = beeping
                    myCloseButton.Tag = (intloop + 6).ToString
                    myAppsPanel.Controls.Add(myCloseButton)
                    AddHandler myCloseButton.Click, AddressOf CloseButton_Click
                    myButton.ButtonStyle = LCARSTerminalControls.Controls.PillControl.LCARSTerminalControlStyle.RoundedSquare
                    myButton.ButtonText = myWindows(intloop).MainWindowText
                    myButton.Size = New Point(100, 25)
                    myButton.Left = (((myAppsPanel.Controls.Count - 1) \ 2) * 134) + 56
                    myButton.Top = 0
                    myButton.Beeping = False
                    myButton.Data = myWindows(intloop).hWnd
                    myButton.Beeping = beeping
                    myButton.ButtonTextAlign = ContentAlignment.TopLeft
                    If getWindowState(myWindows(intloop).hWnd) = WindowStates.MINIMIZED Then
                        myButton.Lit = False
                    Else
                        myButton.Lit = True
                    End If
                    myButton.Tag = (intloop + 6).ToString
                    myAppsPanel.Controls.Add(myButton)
                    AddHandler myButton.Click, AddressOf AppsButton_Click
                    TaskbarIcon.Image = Icon.ExtractAssociatedIcon(myWindows(intloop).hWnd).ToBitmap
                    TaskbarIcon.Left = (((myAppsPanel.Controls.Count - 1) \ 2) * 134) + 56
                    myAppsPanel.Controls.Add(TaskbarIcon)
                End If
            Next



So, everything works as expected, myCloseButton and MyButton are some custom controls i made inheriting the stadard button control. My question is now: how to add the code for external images icons inside that loop, if the loop does not contain the filenames, but instead it contains the handle of those windows? Is there any variatin of Icon.ExtractAssociatedIcon that accepts as argument the window handle of an application? Or is there any way to obtain the filename of the window giving only its handle?
Was This Post Helpful? 0
  • +
  • -

#6 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 765
  • Joined: 19-October 11

Re: Get external applications icons

Posted 29 December 2012 - 02:34 PM

If you have process handle, you can get its mainmodule.filename:

                    Dim myHandle As IntPtr 'this is here just to illustrate the handle, and how to use it later, to get icon with it. How you get your handle is your business

                    For Each proc In Process.GetProcesses
                        If proc.MainWindowHandle = myHandle Then
                            Me.Icon = Icon.ExtractAssociatedIcon(proc.MainModule.FileName)
                        End If
                    Next


Was This Post Helpful? 1
  • +
  • -

#7 rusoaica  Icon User is offline

  • D.I.C Head

Reputation: 34
  • View blog
  • Posts: 201
  • Joined: 10-March 12

Re: Get external applications icons

Posted 29 December 2012 - 03:41 PM

yeh, i knew about that, but is there any way to get the filename from the window handle?
Was This Post Helpful? 0
  • +
  • -

#8 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 765
  • Joined: 19-October 11

Re: Get external applications icons

Posted 29 December 2012 - 10:22 PM

There's no way to get something like filename from IntPtr structure. But you can use it (as showed in example above) to find what is of your interest. I suggest you to read first 2 sentences of Remarks section on that link.

This post has been edited by lucky3: 29 December 2012 - 10:24 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1