Extract icons from exe,dll and draw directly on vfp form

Published on by Yousfi Benameur

                  
 
this code use APIs to extract icons handles (hIcon) from any exe or dll file.
then can draw directtly the graphic representation of each icon on the form surface without saving to ico or images.
in principe the drawing is not persistent but if calling the ydraw method at:
-resizing the form or moving it that makes the drawing persistent.

API used here:
     ExtractAssociatedIcon
     ExtractIconEx
	 DrawIcon
	 GetWindowDC
	 ReleaseDC
     DestroyIcon
Note: Can resize the form to have better view
Important:this code is tested on VFP9Sp2 and windwos10 pro.

Click on code to select [then copy] -click outside to deselect


*1*  draw extracted icons directly on form surface

Publi yform
yform=Newobject("yIcons")
yform.Show
Read Events
Retu
*
Define Class yIcons As Form
    Height = 403
    Width = 868
    ShowWindow = 2
    AutoCenter = .T.
    Caption = "All VFP9.exe icons"
    Name = "Form1"

    Add Object command1 As CommandButton With ;
        Top = 360, ;
        Left = 425, ;
        Height = 37, ;
        Width = 98, ;
        FontBold = .T., ;
        FontSize = 12, ;
        Anchor = 768, ;
        Caption = "Draw icons", ;
        MousePointer = 15, ;
        SpecialEffect = 2, ;
        ForeColor = Rgb(255,0,0), ;
        BackColor = Rgb(128,255,0), ;
        Name = "Command1"

    Add Object combo1 As ComboBox With ;
        FontBold = .T., ;
        FontSize = 11, ;
        Anchor = 768, ;
        Height = 37, ;
        Left = 235, ;
        Top = 360, ;
        Width = 180, ;
        Name = "Combo1"

    Add Object label1 As Label With ;
        AutoSize = .T., ;
        FontSize = 24, ;
        Anchor = 768, ;
        BackStyle = 0, ;
        Caption = "?", ;
        Height = 39, ;
        Left = 543, ;
        MousePointer = 15, ;
        Top = 359, ;
        Width = 20, ;
        ForeColor = Rgb(0,255,0), ;
        Name = "Label1"

    Procedure ydraw
        Local m.x,m.y
        m.x=10
        m.y=40
        Local hwindow,hDC
        hwindow=Thisform.HWnd
        hDC = GetWindowDC(hwindow)
        Thisform.Cls  && clear drawings surface form

        Sele ycurs
        Scan
            DrawIcon(hDC,m.x, m.y,xhandle )
            If m.x>Thisform.Width-40
                m.x=10
                m.y=m.y+40
            Else
                m.x=m.x+40
                m.y=m.y
            Endi
            =DestroyIcon(xhandle)  &&important to draw clean icon
        Endscan
        ReleaseDC(hwindow, hDC)
    Endproc

    Procedure Load
        Declare Long ExtractAssociatedIcon In shell32.Dll Long, String, Long @
        Declare Integer  DestroyIcon In  user32.Dll Integer hIcon
        Declare Long ExtractIconEx In shell32 String @, Long, Long @, Long @, Long
        Declare SHORT DrawIcon In user32;
            INTEGER hDC,;
            INTEGER X,;
            INTEGER Y,;
            INTEGER hIcon
        Declare Integer ReleaseDC In user32;
            INTEGER hWindow, Integer hdc
        Declare Integer GetWindowDC In user32 Integer hWindow

        Create Cursor ycurs (xhandle i)

    Endproc

    Procedure Moved
        Thisform.command1.Click
    Endproc

    Procedure Resize
        Thisform.command1.Click
    Endproc

    Procedure Destroy
        Clea Dlls
        Clea Events
    Endproc

    Procedure command1.Click
        Local m.lcfile As String
        With Thisform.combo1
            Do Case
                Case .Value=1
                    m.lcfile=Home(1)+"vfp9.exe"
                Case .Value=2
                    m.lcfile=Addbs(Getenv("windir"))+"system32\shell32.dll"
                Case .Value=3
                    m.lcfile=Addbs(Getenv("windir"))+"explorer.exe"
                Case .Value=4
                    m.lcfile=Addbs(Getenv("windir"))+"system32\MSPAINT.exe"

            Endcase
        Endwith


        Local numIcons As Integer
        numIcons = ExtractIconEx(m.lcfile , -1,  0, 0, 0)
        If numIcons = 0
            Messagebox( "No icons found in the file -- abording.")
            Return .F.  && cancel
        Else
            Thisform.Caption=Trans(numIcons)+" Icons found in "+lcfile
        Endi

        Sele ycurs
        Try
            Zap
        Catch
        Endtry

        For i=1 To numIcons
            lpIcon=i-1
            Insert Into ycurs Values(ExtractAssociatedIcon(0, lcfile, @lpIcon))
        Endfor
        Thisform.Cls
        Thisform.ydraw()
        Retu
    Endproc

    Procedure combo1.Init
        With This
            .AddItem("vfp9.exe")
            .AddItem("Shell32.dll")
            .AddItem("explorer")
            .AddItem("MSPaint")
            .ListIndex=1
            .Value=1
            .Style=2
        Endwith
        *exe or dlls must exist on disc.
    Endproc

    Procedure label1.Click
        Local m.myvar
        TEXT to m.myvar noshow
this code use APIs to extract icons handles (hIcon) from any exe or dll file
then can draw directtly the graphic representation of each icon on the form surface.
in principethe drawing is not persistent but if calling the ydraw method at
-resizing the form or moving it that makes the drawing persistent.

API used here:
     ExtractAssociatedIcon
	 ExtractIconEx
	 DrawIcon
	 GetWindowDC
	 ReleaseDC
Note: Can resize the form to have better view
        ENDTEXT
        Messagebox(m.myvar,0+32+4096,"Summary help")

    Endproc

Enddefine
*
*-- EndDefine: yIcons


Extract icons from exe,dll and draw directly on vfp form
To be informed of the latest articles, subscribe:
Comment on this post