Extracting image out of exe with Xojo

Hi everyone,

Do you know how I can programmatically extract and image (jpg, png, giff) out of en exe file?

Like I drag an exe file on my application and then those icons within the exe file are extracted for use in my own application.

Thank you very much in advance.

I use the MBS plugins.
Example:
put a ListBox and a Canvas into a window
add a FileType with special/any to your project

in the ListBox Open event place this.
me.AcceptFileDrop(FileTypes1.All)

In ListBox DropObject Event place this
if obj.FolderItemAvailable then
Canvas1.Backdrop = obj.FolderItem.IconMBS(32,32)
me.text = obj.FolderItem.ShellPath
end if

Run your project and drag a application to the ListBox
You can see the application icon in the canvas1 and the shellpath in the ListBox

Under Windows, you can use the ExtractIconEx and DrawIconEx to copy icons into a Xojo Picture object. This method accepts a Win32 PE (exe/dll/scr/etc.) file, the index of the icon to extract, and the width/height in pixels to request:

Function ExtractIcon(Resource as FolderItem, Index As Integer, pixSize As Integer = 32) As Picture
  #If TargetWin32 Then
    Declare Function ExtractIconExW Lib "Shell32" (Resource As WString, Index As Integer, largeIco As Ptr, smallIco As Ptr, Icons As Integer) As Integer
    Declare Function DrawIconEx Lib "User32" (hDC As Integer, xLeft As Integer, yTop As Integer, hIcon As Integer, cxWidth As Integer, cyWidth As Integer, istepIfAniCur As Integer, hbrFlickerFreeDraw As Integer, diFlags As Integer) As Boolean
    Declare Function DestroyIcon Lib "User32" (hIcon As Integer) As Integer
    Dim theIcon As Picture = New Picture(pixsize, pixsize, 32)
    theIcon.Transparent = 1
    
    Dim largeIco As New MemoryBlock(4)
    Try
      Call ExtractIconExW(resource.AbsolutePath, Index, largeIco, Nil, 1)
      Call DrawIconEx(theIcon.Graphics.Handle(Graphics.HandleTypeHDC), 0, 0, largeIco.Int32Value(0), pixsize, pixsize, 0, 0, &h3)
    Catch
      Call DestroyIcon(largeIco.Int32Value(0))
      Return Nil
    End Try
    Call DestroyIcon(largeIco.Int32Value(0))
    Return theIcon
  #endif
  
Exception
  Return Nil
  
End Function
1 Like

Hello Horst and Andrew,

Thank you very much for your replies and your solutions.

I looked up the MBS solution but according to the Monkeybread software, this is a Macintosh solution only. Because I am only using Windows, for the moment this solution will not work for me.

So I used the solution given by Andrew. It does exactly what I want.

Can you tell me how I can get the maximum amount of icons the executable contains? I like my application to extract all the icons from the executable and let the user decide which icon is used.

Thank you again for your time spend on my request, which is very much appreciated.

Have a very nice day.

Greetings,

Chris

Pass -1 as the index to get the number of icons returned.

dim numIcons as integer

numIcons = ExtractIconEx(resource.AbsolutePath, -1, Nil, Nil, 0)

Hello Tim,

Thank you very much for your fast reply and your help.

I tried your solution to get the maximum number of icons present in the executable but get the following error :

“Item does not exist”.

This is the method :

[code]Dim numIcons As Integer

#If TargetWin32 Then
numIcons = ExtractIconEx(Resource.AbsolutePath, -1, Nil, Nil, 0)
Declare Function ExtractIconExW Lib “Shell32” (Resource As WString, Index As Integer, largeIco As Ptr, smallIco As Ptr, Icons As Integer) As Integer
Declare Function DrawIconEx Lib “User32” (hDC As Integer, xLeft As Integer, yTop As Integer, hIcon As Integer, cxWidth As Integer, cyWidth As Integer, istepIfAniCur As Integer, hbrFlickerFreeDraw As Integer, diFlags As Integer) As Boolean
Declare Function DestroyIcon Lib “User32” (hIcon As Integer) As Integer
Dim theIcon As Picture = New Picture(pixsize, pixsize, 32)
theIcon.Transparent = 1

Dim largeIco As New MemoryBlock(4)
Try
  Call ExtractIconExW(resource.AbsolutePath, Index, largeIco, Nil, 1)
  Call DrawIconEx(theIcon.Graphics.Handle(Graphics.HandleTypeHDC), 0, 0, largeIco.Int32Value(0), pixsize, pixsize, 0, 0, &h3)
Catch
  Call DestroyIcon(largeIco.Int32Value(0))
  Return Nil
End Try
Call DestroyIcon(largeIco.Int32Value(0))
Return theIcon

#endif

Exception
Return Nil[/code]

Can you tell me what is wrong because I fail to see.

Thank you again very much for your support.

Friendly greetings,

Chris

#If TargetWin32 Then numIcons = ExtractIconEx(Resource.AbsolutePath, -1, Nil, Nil, 0) Declare Function ExtractIconExW Lib "Shell32" (Resource As WString, Index As Integer, largeIco As Ptr, smallIco As Ptr, Icons As Integer) As Integer [...]

You can’t use ExtractIconEx until after the line on which it’s declared. Also, note that ExtractIconEx is actually declared as ExtractIconExW (note the ending “W”.) (more info about “W”)

  Dim numIcons As Integer
  #If TargetWin32 Then
    Declare Function ExtractIconExW Lib "Shell32" (Resource As WString, Index As Integer, largeIco As Ptr, smallIco As Ptr, Icons As Integer) As Integer
    numIcons = ExtractIconExW(Resource.AbsolutePath, -1, Nil, Nil, 0)  

Hello Andrew,

Thank you very much for your kind and friendly support.

Exactly what I needed, works perfect! Indeed I placed the ExtractIconEx at the wrong position and also did not add the “W”.

Horst, Andrew and Tim, thank you very much for your replies and help, which is very much appreciated.

Wish you all a very nice day.

Friendly greetings,

Chris