Sign in to follow this  
Followers 0
ProgAndy

ICL Icon Extract !

18 posts in this topic

#1 ·  Posted (edited)

Finally, I've done the Task, and I proudly present the Read_ICLFormat UDF. With this UDF it's possible to extract the incons from a icl-Library, which is sometimes used to store Icons. The threeo functions, you can call are:

CODE

;===============================================================================

;

; Function Name: _ICL_ExtractIcon

; Description:: Extracts an Icon Group Resource from an ICL-File

; Parameter(s): $ICLFile : File to extract Icon from

; $Icon_Group : Icon Group Resource to extract

; positive: 0 based group index

; negative: Icon Index starting with -1

; string : name of resource

; $ICOFile : Icon File to create

; Requirement(s): _WinAPI.au3

; Return Value(s): Success: 1, Error: 0, @error > 0

; Author(s): Prog@ndy

;

;===============================================================================

;

;===============================================================================

;

; Function Name: _ICL_ExtractMultipleIcons

; Description:: Extracts an Icon Group Resource from an ICL-File

; Parameter(s): $ICLFile : File to extract Icon from

; $Icon_Group : 1-Dimensional Array of Icon Group Resources to extract

; positive: 0 based group index

; negative: Icon Index starting with -1

; string : name of resource

; $ICOFile : Icon File to create

; Requirement(s): _WinAPI.au3

; Return Value(s): Success: 1, Error: 0, @error > 0

; Author(s): Prog@ndy

;

;===============================================================================

;

;===============================================================================

;

; Function Name: _ICL_ListIcons

; Description:: Lists all Icons of an ICL-File

; Parameter(s): $ICLFile : File to list Icons

; Requirement(s): _WinAPI.au3

; Return Value(s): Success: Array with all possible IDS to get, Error: 0, @error > 0

; [0] -> the 0-based Index

; [1] -> the negative index, starting with -1

; [0] -> if available, the name of the resource

; Author(s): Prog@ndy

;

;===============================================================================

;

As an example, the one from smashly, but this time ONLY .icl Extraction smile.gif ( the original one can be found here: http://www.autoitscript.com/forum/index.ph...=74565&st=0 )

;Supported dropfiles: cpl, dll, exe, icl, ocx
;ICL is view only, no extraction!!!

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include "Read_ICLFormat.au3"

Opt("GUIOnEventMode", 1)

Global $sIn = @SystemDir & "\shell32.dll"
Global $hGui, $LV, $Extract, $LHT, $IHM

$hGui = GUICreate("", 500, 400, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_ACCEPTFILES))
GUISetOnEvent($GUI_EVENT_DROPPED, "GuiEvent", $hGui)
GUISetOnEvent($GUI_EVENT_CLOSE, "GuiEvent", $hGui)
$LV = GUICtrlCreateListView("", 5, 5, 490, 390, $LVS_ICON)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetTip(-1, "Drop a supported file here to view it's icons." & @LF & "Double Click an icon to extract.")
_GUICtrlListView_SetView($LV, 1)
Update()
GUISetState(@SW_SHOW, $hGui)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    Sleep(100)
    ChkExtract()
WEnd

Func GuiEvent()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_DROPPED
            If StringRegExp(@GUI_DragFile, "(?i)\.(cpl|dll|exe|icl|ocx)", 0) Then
                _GUICtrlListView_DeleteAllItems($LV)
                $sIn = @GUI_DragFile
                Update()
            EndIf
    EndSwitch
EndFunc   ;==>GuiEvent

Func ChkExtract()
    If $Extract Then
        $Extract = 0
        Local $FOD = FileSaveDialog("Save extracted icon as..", "", "Icon file (*.ico)", 18, DefName(), $hGui)
        If Not @error And $FOD <> "" Then
            WinSetTitle($hGui, "", "Extracting...")
            _ICL_ExtractIcon($sIn, $LHT, $FOD)
            If @error Then
                WinSetTitle($hGui, "", "Error extracting icon - Error Code: " & @error)
            Else
                WinSetTitle($hGui, "", "Done - Icons found in " & StringMid($sIn, StringInStr($sIn, "\", 0, -1) + 1) & ": " & $IHM)
            EndIf
        EndIf
    EndIf
EndFunc   ;==>ChkExtract

Func Update()
    $IHM = _WinAPI_ExtractIconEx($sIn, -1, 0, 0, 0)
    WinSetTitle($hGui, "", "Icons found in " & StringMid($sIn, StringInStr($sIn, "\", 0, -1) + 1) & ": " & $IHM)
    For $i = 1 To $IHM
        GUICtrlCreateListViewItem("-" & $i, $LV)
        GUICtrlSetImage(-1, $sIn, -$i, 1)
    Next
EndFunc   ;==>Update

Func DefName()
    Local $FN = StringFormat("%0" & StringLen($IHM) & "d", $LHT+1)
    Return $FN & "_" & StringTrimRight(StringMid($sIn, StringInStr($sIn, "\", 0, -1) + 1), 3) & "ico"
EndFunc   ;==>DefName

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndLV, $tInfo
    $hWndLV = GUICtrlGetHandle($LV)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndLV
            Switch $iCode
                Case $NM_DBLCLK
                    Local $LVHT = _GUICtrlListView_HitTest($hWndLV)
                    If $LVHT[0] <> -1 And StringRight($sIn, 4) = ".icl" Then
                        $Extract = 1
                        $LHT = ($LVHT[0])
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Changelog:

2008/08/12

  • Added: _ICL_ListIcons
  • Fixed: If a wrong value for Icon type is read, it's now defaulted to 1
  • Fixed: The resource names were handled incorrectly (hope, now it's correct)
//Edit: Forgot to update attachment ...

Previous downloads: 27

Read_ICLFormat.au3

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites



Rockin' work ProgAndy, congrats bud and Thank You :o

Damn, After looking at your code I would have never worked out the ICL structure anytime before at least the year 2020. :P

That should keep DJBaselord happy for the time being ..lol

Did you try and extract any icons from the library.icl that came in the IconLib demo using your code?

Well I'm off to give your code a good thrashing :P

Cheers

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hi again

Well I must say I'm impressed. :P

I've been tinkering with your code and it works great in most cases of what I tried.

Minor problem: :P

I did find a discrepancy with extracting from the library.icl found in the IconLib demo found at code project.

When I extract any icon from the library.icl using your code I get the correct size of byte data, but the 3rd byte that identifies the icon as an icon or cursor for some reason is set as 0E instead of 01.

eg:

Start of header comes back as 0x00000E when it should be 0x000001

The good news:

I also tried your code on a standard 16bit exe and it extracts the icon correctly.

(16bit exe I tested your code on was twunk_16.exe found in the windows directory)

Which means I can add 16 bit module support into my Iconator app .. w00t :o

Side notes:

In the example GUI you posted:

In the WM_NOTIFY() function change from:

$LHT = ($LVHT[0] + 1)

To

$LHT = $LVHT[0]

And in the DefName() function change from:

Local $FN = StringFormat("%0" & StringLen($IHM) & "d", $LHT)

To

Local $FN = StringFormat("%0" & StringLen($IHM) & "d", $LHT +1)

Cheers Edited by smashly

Share this post


Link to post
Share on other sites

OK, I fixed all. the wrong header is in the library.icl, I think. Even ExtractIconEx doesn't show an icon :P

Changelog:

2008/08/12

* Added: _ICL_ListIcons

* Fixed: If a wrong value for Icon type is read, it's now defaulted to 1


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

Hi again,

Thank you for the update, but I still get 0x00000E when extracting any single icon from library.icl from the IconLib demo.

As a nasty workaround I forced the value of "1" .

eg:

Func _ICL_SaveIconGroup($FileHandle, $ICOPath, $Icon_Group, $aICONS, $aICON_GROUPS, $rscAlignShift)
    Local $rscShifted = BitShift(1, -1 * $rscAlignShift)
    Local $ReadBytes
    Local $ICOHandle = _WinAPI_CreateFile($ICOPath, 1, 4)

    Local $realOffset = $aICON_GROUPS[$Icon_Group][0] * $rscShifted

    _ICL_WinAPI_SetFilePointer($FileHandle, $realOffset, 0)
    $header = DllStructCreate($tagGRPICONDIR)
    _WinAPI_ReadFile($FileHandle, DllStructGetPtr($header), DllStructGetSize($header), $ReadBytes)
    
    DllStructSetData($header, "idType", "1") ;<-- workaround
    .............

Cheers

Share this post


Link to post
Share on other sites

Well, it IS fixed :P but I forgot to uplaod it :P


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

the extract func returning 0 always :/

lets say i got my icon this way

DllCall("shell32","long","ExtractAssociatedIcon","int",0,"str",$filename,"int*",$iconnumber)

how can i save it and still be valid ...

tried to understand your code but got lost with the group save one

would be nice if the example worked

thanks for posting :D

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

ExtractAssociatedIcon doesn't work with ICL-libraries.

This example and library only work with ICL-libraries, not 32bit-DLL and 32bit-exe (only 16bit)

For normal Icon extracting, look at the ResHacker project by trancexx.

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

A little off-topic since it's not related to scripts but I've used IcoFX to do this in the past. It's free and there's a portable version.

WBD

Share this post


Link to post
Share on other sites

I noticed an internal function in the UDF called _ICL_SaveIconGroup

Are you thinking of writing a function that can create .icl files ProgAndy?


Das Häschen benutzt Radar

Share this post


Link to post
Share on other sites

No. i think, ICL-files are out-dated, DLLs are better, since they are 32bit and not old 16bit (Vista doesn't support 16bit anymore)


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

hi progandy,

i just read that .icl is nothing more but a renamed 16 bit resource dll.

if this info is correct (there is hardly any info about this format on the net), wouldn't it be possible to extract icons from .icl by simply using the known winapi (extracticon, loadimage) functions ? edit: well, you still could not save it to harddisk, that's what your udf does, but could it be displayed in this way ?

btw: i am desperately seeking a way to save multiple icons to an. icl file. could i use your _ICL_SaveIconGroup to do so, theoretically ?

grüße j.

Edited by jennico

Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

Share this post


Link to post
Share on other sites

Not directly. you would have to read the documentation for 16-bit fileformat and then creae the file. it is just the other way round .

Information on the format can be found on the links in my UDF and by understanding my funcs ^_^ (It has been long ago ehen i wrote this, i can't explain the script anymore)


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

understand your udf ? man, yet i have spent lots of hours in doing so ! ^_^ i'll go on trying, but i fear i need an extra brain from ebay.

j. ;)


Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

I think, the image here is the most important part ^_^http://www.codeguru.com/csharp/.net/net_ge....php/c12787__2/

(The incomplete headers are in my Script, if you need them)

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

ja, apparently CastorTiu and his iconlib is the only source for this theme in the net it.

meanwhile i found transexx' reshacker project and it seems that this does 80% of my way to create .icl files.

thank you for providing very useful links.

j.


Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

nice :D

butt... can you extract an icon from *.exe with this?

and if you can, how do you do that?

Edited by ludocus

Share this post


Link to post
Share on other sites

No. This UDfs can't extract 32-bit exe-files. They are only designed to extract 16bit ICL and exe files.

Here is some code to do that: _ExtractIconToFile (i think it is from smashly, but he deleted it in his own post.)

Also there is the ResHacker Project wich can extract them.


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0