Sign in to follow this  
Followers 0
picea892

Extract custom folder image

4 posts in this topic

Hi everyone. Thanks in advance for any help people can provide. I have found the traditional ways I have used to extract icons from Exe's to place in a listview did not work for a custom folder icon. This includes the _GUIImageList_AddIcon method.

Below is a script fragment which serves my purpose but not in a streamlined fashion. The script was posted by

I save the icon as a bmp and use _GUIImageList_AddBitmap to put the picture into my listview.

Can someone help me modify this so I can use _GUIImageList_Add and skip the step of saving it as an .bmp prior to adding to an imagelist?

Does anyone know of a different method to do this?

Picea892

;tempfile is the save folder and file name
;$sections[$i][1] is from an ini file and is the folder path name to extract image
ExtractIcons($sections[$i][1],$tempfile)
_GUIImageList_AddBitmap($hImage, $tempfile) ;imagelist to be used to populate a listview


Func ExtractIcons($file,$tempfile)
    $Ret = DllCall("shell32","long","ExtractAssociatedIcon","int",0,"str",$file,"int*",(-1*-1)-1)
    $hIcon = $Ret[0]
    _GDIPlus_Startup()
    $Bitmap = DllCall($ghGDIPDll,"int","GdipCreateBitmapFromHICON", "ptr",$hIcon, "int*",0)
    $Bitmap = $Bitmap[2]
    $w = _GDIPlus_ImageGetWidth($Bitmap)
    $h = _GDIPlus_ImageGetHeight($Bitmap)
    ;transparent code by smashly / Malkey - modified by UEZ
    $hImage = _GDIPlus_BitmapCloneArea($Bitmap, 0, 0, $w, $h, $GDIP_PXF32ARGB)
    $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $w, $h, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)

    $iStride = DllStructGetData($tBitmapData, "stride")
    $iScan0 = DllStructGetData($tBitmapData, "Scan0")
    $tPixel = DllStructCreate("int", $iScan0 + (0 * $iStride) + (0 * 4))

    $iFirstPixel = DllStructGetData($tPixel, 1)
    $iTransPixel = BitAND($iFirstPixel, 0x00FFFFFF)

    $iFirstPixel = StringRegExpReplace(Hex($iFirstPixel, 8), "(.{2})(.{2})(.{2})(.{2})", "\4\3\2\1")
    $iTransPixel = StringTrimRight($iFirstPixel, 2) & "00"
    $v_BufferA = DllStructCreate("byte[" & $h * $w * 4 & "]", $iScan0) ; Create DLL structure for all pixels
    $AllPixels = DllStructGetData($v_BufferA, 1)
    $sREResult1 = StringRegExpReplace(StringTrimLeft($AllPixels, 2), "(.{8})", "\1 ")
    $sPix = "0x" & StringStripWS(StringRegExpReplace($sREResult1, "(" & $iFirstPixel & ")", $iTransPixel), 8)
    $AllPixels = DllStructSetData($v_BufferA, 1, $sPix)

    _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)
    if not FileExists(@ScriptDir & "\folderpics") then DirCreate(@ScriptDir & "\folderpics")
    _GDIPlus_ImageSaveToFileEx($hImage, $tempfile, _GDIPlus_EncodersGetCLSID("BMP"))

    _GDIPlus_ImageDispose($hImage)

    _GDIPlus_Shutdown()
    _WinAPI_DestroyIcon($hIcon)
    ;
    return 1
EndFunc

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

#Include <Constants.au3>
#Include <WinAPIEx.au3>

Global Const $STM_SETIMAGE = 0x0172

GUICreate('', 128, 128)
GUICtrlCreateIcon('', 0, 48, 48, 32, 32)
$hWnd = GUICtrlGetHandle(-1)
$tInfo = DllStructCreate($tagSHFILEINFO)
_WinAPI_ShellGetFileInfo(@FavoritesDir, BitOR($SHGFI_ICON, $SHGFI_LARGEICON), 0, $tInfo)
$hIcon = DllStructGetData($tInfo, 'hIcon')
_WinAPI_DestroyIcon(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_ICON, $hIcon))
GUISetState()

Do
Until GUIGetMsg() = -3

And use the _GUIImageList_ReplaceIcon() function to add HICON.

Edited by Yashied

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks Yashied.

You never cease to amaze me with your udfs. Icons, Winapiex, colourpicker.

I now have all three in my script!

My slightly tweaked code...for all those who follow.

AddIcon($hImage, $sections[$i][1])
Func AddIcon($hWnd, $sFile)
;Global Const $STM_SETIMAGE = 0x0172
$tInfo = DllStructCreate($tagSHFILEINFO)
_WinAPI_ShellGetFileInfo($sFile, BitOR($SHGFI_ICON, $SHGFI_LARGEICON), 0, $tInfo)
$hIcon = DllStructGetData($tInfo, 'hIcon')
_WinAPI_Destroyicon(_GUIImageList_ReplaceIcon($hWnd, -1, $hIcon))
EndFunc
Edited by picea892

Share this post


Link to post
Share on other sites

Func _GUIImageList_AddAssociatedIcon($hWnd, $sPath, $fSmall = 0)
    
    Local $Index, $Flags = $SHGFI_ICON, $tInfo = DllStructCreate($tagSHFILEINFO)

    If Not _WinAPI_PathIsDirectory($sPath) Then
        $Flags = BitOR($Flags, $SHGFI_USEFILEATTRIBUTES)
    EndIf
    If $fSmall Then
        $Flags = BitOR($Flags, $SHGFI_SMALLICON)
    EndIf
    _WinAPI_ShellGetFileInfo($sPath, $Flags, 0, $tInfo)
    If @error Then
        Return SetError(1, 0, -1)
    EndIf
    $hIcon = DllStructGetData($tInfo, 'hIcon')
    $Index = _GUIImageList_ReplaceIcon($hWnd, -1, $hIcon)
    _WinAPI_DestroyIcon($hIcon)
    Return $Index
EndFunc   ;==>_GUIImageList_AddAssociatedIcon

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