Jump to content
Sign in to follow this  
picea892

Extract custom folder image

Recommended Posts

picea892

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
Yashied

#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
picea892

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
Yashied

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.