Sign in to follow this  
Followers 0
zwierzak

Problem extracting folder's icon

3 posts in this topic

#1 ·  Posted (edited)

Hello. I am writing some kind of a toolbar and i am not able to properly extract and set the folder's icon. The icon is set, but it's usually the wrong one. Can any1 look at this code and tell me what i do wrong? The problem starts here: "Case $GUI_EVENT_DROPPED"

And I would also like to get rid of this pop up window that appears while getting the icon index, but i am not really into MDSN, I don't know how to use it properly. Can I also get your advice on this matter? :)

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Resources\ikona.ico
#AutoIt3Wrapper_Outfile=Flawless Toolbar v1.exe
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****


#include <GUIConstantsEx.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <GuiRichEdit.au3>
#include <File.au3>
#include <Array.au3>
#include <WinAPIShellEx.au3>
#include <APIShellExConstants.au3>
#include <WinAPIDlg.au3>


Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode", 3)

HotKeySet("^2", "_show_hide_console")
HotKeySet("^1", "_hide_show_toolbar")
HotKeySet("^!{NUMPADADD}", "_volume_up")
HotKeySet("^!{NUMPADSUB}", "_volume_down")
HotKeySet("^!{NUMPADDIV}", "_volume_mute")


;Dane ikonek
Global $exeDir, $n = 0, $Start

;Dane okien
Global $stateTool = True ;state of toolbar hidden / shown
Global $stateConsole = False ;state of the consol: hidden/shown
Global $stateOptions = False
Global $tX = @DesktopWidth / 4
Global $tY = 0
Global $i = 2, $j = 6 ;this is used to calulate width and height of the console
Global $tWidth = @DesktopWidth / $i, $tHeight = @DesktopHeight / $j + 10
Global $cHeight = @DesktopHeight / 2

;hiding speed
Global $hide_speed = 10;

;Effect glass
Global $Struct = DllStructCreate("int cxLeftWidth;int cxRightWidth;int cyTopHeight;int cyBottomHeight;")
Global $sStruct = DllStructCreate("dword;int;ptr;int")

If Not IniRead(@ScriptDir & "\data_shortcuts.ini", "number", "n", "") Then
    IniWrite(@ScriptDir & "\data_shortcuts.ini", "number", "n", $n)
Else
    $n = IniRead(@ScriptDir & "\data_shortcuts.ini", "number", "n", "")
EndIf

$cmd = Run(@ComSpec, "", @SW_HIDE, $STDERR_CHILD + $STDIN_CHILD + $STDOUT_CHILD)

;TOOLBAR
$Toolbar = GUICreate("Flawless Toolbar by Zwierzak", $tWidth, $tHeight, $tX, $tY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_ACCEPTFILES, $WS_EX_TOOLWINDOW))
$LV = GUICtrlCreateListView("", -1, -1, $tWidth + 30, $tHeight + 5, BitOR($LVS_SINGLESEL, $LVS_ICON, $LVS_EX_REGIONAL)) ;liczby dodawane aby ukryc "biale linie"
_GUICtrlListView_SetIconSpacing($LV, 80, 80)
_GUICtrlListView_SetView($LV, 1) ;sets icon size
GUICtrlSetState($LV, $GUI_DROPACCEPTED)
;invisible button responsible for creating a hotkey to an active window
$buttonDelete = GUICtrlCreateButton("Delete", 0, -50)
$buttonExit = GUICtrlCreateButton("Exit", 50, -50)
Local $AccelKeys[2][2] = [["{DEL}", $buttonDelete],["{ESC}", $buttonExit]]
GUISetAccelerators($AccelKeys, $Toolbar)

;CONSOLE
$hConsole = GUICreate("Flawless Console by Zwierzak", @DesktopWidth, $cHeight, 0, -$cHeight, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW));zostanie stworzona ukryta
$consoleList = _GUICtrlRichEdit_Create($hConsole, "", 0, 0, @DesktopWidth, $cHeight - 30, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
_GUICtrlRichEdit_SetReadOnly($consoleList)
$consoleInput = GUICtrlCreateInput("", 0, $cHeight - 30, @DesktopWidth - 50, 30)
GUICtrlSetFont($consoleInput, 12)
$Enter = GUICtrlCreateButton("Enter", @DesktopWidth - 50, $cHeight - 30, 50, 30)
GUICtrlSetState($Enter, $GUI_DEFBUTTON)

;OPTIONS
$Options = GUICreate("Opcje", 400, 500, 192, 124)
$Apply = GUICtrlCreateButton("Zapisz", 0, 470, 100, 30)
$Cancel = GUICtrlCreateButton("Anuluj", 300, 470, 100, 30)
$tabs = GUICtrlCreateTab(0, 0, 400, 470)
$page1 = GUICtrlCreateTabItem("Ogolne")
$Checkbox1 = GUICtrlCreateCheckbox("Uruchom przy starcie systemu", 8, 32, 161, 17)
GUICtrlCreateTabItem("")

;TRAY
$tr_options = TrayCreateItem("Opcje")
$tr_hotkeys = TrayCreateItem("Klawisze skrótów")
$tr_opis = TrayCreateItem("O programie")
$tr_exit = TrayCreateItem("Exit")


If @OSVersion = "WIN_VISTA" Or @OSVersion = "WIN_7" Then
    _Vista_EnableBlurBehind($Toolbar)
    _Vista_EnableBlurBehind($hConsole)
    GUICtrlSetBkColor($LV, 0x000000)
    GUICtrlSetColor($LV, 0xFFFFFF)
    GUICtrlSetBkColor($consoleInput, 0x000000)
    GUICtrlSetColor($consoleInput, 0xFFFFFF)
    GUICtrlSetBkColor($Enter, 0x000000)
    GUICtrlSetColor($Enter, 0xFFFFFF)
    _GUICtrlRichEdit_SetBkColor($consoleList, 0x000000)
    _GUICtrlRichEdit_SetCharColor($consoleList, 0xFFFFFF)
EndIf

_load_icons()
_load_settings()

GUISetOnEvent($GUI_EVENT_DROPPED, "GuiEvent", $Toolbar)
GUISetOnEvent($GUI_EVENT_CLOSE, "GuiEvent", $Toolbar)
GUISetOnEvent($GUI_EVENT_CLOSE, "_show_options", $Options)
GUICtrlSetOnEvent($buttonDelete, "GuiEvent")
GUICtrlSetOnEvent($buttonExit, "GuiEvent")
GUICtrlSetOnEvent($Enter, "GuiEvent")
GUICtrlSetOnEvent($Apply, "_save_settings")
GUICtrlSetOnEvent($Cancel, "_show_options")


TrayItemSetOnEvent($tr_exit, "_exit")
TrayItemSetOnEvent($tr_options, "_show_options")
TrayItemSetOnEvent($tr_opis, "_about")
TrayItemSetOnEvent($tr_hotkeys, "_hotkeys")

AdlibRegister("cout", 100)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState(@SW_SHOW, $Toolbar)
GUISetState(@SW_SHOW, $hConsole)
TrayTip("Info", "Klawisze skrótów opisane są w menu tray, znajdują się pod pozycją 'Klawisze skrótów' ", 10000)

While 1
    Sleep(100)
    _Start()
WEnd

Func GuiEvent()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE, $buttonExit
            _exit()
        Case $buttonDelete
            If _delete() = 0 Then ContinueCase
            _GUICtrlListView_DeleteAllItems($LV)
            _load_icons()
        Case $Enter
            Switch GUICtrlRead($consoleInput)
                Case "exit"
                    _add_edit(GUICtrlRead($consoleInput) & @CRLF & "Exiting console...")
                    GUICtrlSetData($consoleInput, "")
                    Sleep(1000)
                    _exit()
                Case "cls"
                    Local $number = _GUICtrlRichEdit_GetLineCount($consoleList) ;return number of lines
                    Local $last_line = _GUICtrlRichEdit_GetTextInLine($consoleList, $number) ;saves the last line
                    _GUICtrlRichEdit_SetText($consoleList, "")
                    _add_edit($last_line)
                Case Else
                    StdinWrite($cmd, GUICtrlRead($consoleInput) & @CRLF)
            EndSwitch
            GUICtrlSetData($consoleInput, "")
        Case $GUI_EVENT_DROPPED

            Local $szDrive, $szDir, $szFname, $szExt, $name
            $exeDir = @GUI_DragFile ;file directory
            _PathSplit($exeDir, $szDrive, $szDir, $szFname, $szExt)
            If $szExt = "" Then ;folder
                ;update
                $name = StringSplit($exeDir, "\")
                    If $name[$name[0]] <> "" Then
                        $name = $name[$name[0]]
                    Else
                        $name = $name[$name[0]-1]
                    EndIf

                    ; Select icon
                Local $aIcon = _WinAPI_PickIconDlg()
                If @error Then Exit

                ; Set icon to selected folder
                Local $tSHFCS = DllStructCreate($tagSHFOLDERCUSTOMSETTINGS & ';wchar szIconFile[' & (StringLen($aIcon[0]) + 1) & ']')
                DllStructSetData($tSHFCS, 'Size', DllStructGetPtr($tSHFCS, 'szIconFile') - DllStructGetPtr($tSHFCS))
                DllStructSetData($tSHFCS, 'Mask', $FCSM_ICONFILE)
                DllStructSetData($tSHFCS, 'IconFile', DllStructGetPtr($tSHFCS, 'szIconFile'))
                DllStructSetData($tSHFCS, 'SizeIF', 260)
                DllStructSetData($tSHFCS, 'IconIndex', -1)
                DllStructSetData($tSHFCS, 'szIconFile', -1)



                _WinAPI_ShellGetSetFolderCustomSettings($exeDir, $FCS_READ, $tSHFCS)

                    MsgBox(0,"", "exe:" & $exeDir & @CRLF & DllStructGetData($tSHFCS, "IconFile") & @CRLF & DllStructGetData($tSHFCS, "SizeIF") & @CRLF & DllStructGetData($tSHFCS, "IconIndex") & @CRLF & DllStructGetData($tSHFCS, "szIconFile"))
                    GUICtrlCreateListViewItem($name, $LV)
                    GUICtrlSetImage(-1, "SHELL32.dll", DllStructGetData($tSHFCS, "IconIndex"), 1)


                _save($exeDir)
            ElseIf $szExt = ".exe" Then ;aplikacja
                Update($exeDir)
                _save($exeDir)
            ElseIf $szExt = ".lnk" Then ;skrot
                Local $dir = FileGetShortcut($exeDir)
                Update($dir[0])
                _save($dir[0])
            EndIf
    EndSwitch
EndFunc   ;==>GuiEvent

Func cout()
    $line = StdoutRead($cmd)
    $error = StderrRead($cmd)

    If $error <> "" Then _add_edit(@CRLF & $error)
    If $line <> "" Then _add_edit($line)
EndFunc   ;==>cout

Func _add_edit($text)
    _GUICtrlRichEdit_SetFont($consoleList, 10, "Lucida Console")
    _GUICtrlRichEdit_AppendText($consoleList, Console_CP852_to_UNICODE($text))
    GUICtrlSetState($consoleInput, $GUI_FOCUS)
EndFunc   ;==>_add_edit

Func _save_settings()
    If GUICtrlRead($Checkbox1) = 1 Then
        FileCreateShortcut(@ScriptDir & "\" & @ScriptName, @StartupDir & "\" & @ScriptName, @ScriptDir)
        IniWrite(@ScriptDir & "\settings.ini", "autostart", "value", "1")
    Else
        FileDelete(@StartupDir & "\" & @ScriptName & ".lnk")
        IniWrite(@ScriptDir & "\settings.ini", "autostart", "value", "4")
    EndIf

    _show_options()
EndFunc   ;==>_save_settings

Func _load_settings()
    GUICtrlSetState($Checkbox1, IniRead(@ScriptDir & "\settings.ini", "autostart", "value", ""))
EndFunc   ;==>_load_settings

Func _save($data)
    ;data - directory to a fle
    Local $szDrive, $szDir, $szFname, $szExt
    $n = IniRead(@ScriptDir & "\data_shortcuts.ini", "number", "n", "")

    _PathSplit($data, $szDrive, $szDir, $szFname, $szExt)
    Local $wd = $szDrive & $szDir

    $n += 1
    IniWrite(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $n, $data);zapisuje sciezke
    IniWrite(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $n & "_wd", $wd) ;zapisuje working dir

    IniWrite(@ScriptDir & "\data_shortcuts.ini", "number", "n", $n)
EndFunc   ;==>_save

Func _load_icons()
    $n = IniRead(@ScriptDir & "\data_shortcuts.ini", "number", "n", "")
    For $i = 1 To $n Step +1
        Update(IniRead(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $i, ""))
    Next
EndFunc   ;==>_load_icons

Func Update($directory)
    $IHM = _WinAPI_ExtractIconEx($directory, -1, 0, 0, 0)
    Local $filename = FileGetVersion($directory, "ProductName")

    If $filename = "" Then
        Local $string = StringSplit($directory, "\");string[0]=ilosc elementow, string[string[o]]=ostatni element="name.exe"
        Local $name = StringSplit($string[$string[0]], ".");name[1]=nazwa, name[2]="exe"
        $filename = $name[1]
    EndIf
    GUICtrlCreateListViewItem($filename, $LV)
    GUICtrlSetImage(-1, $directory, -1, 1)
EndFunc   ;==>Update

Func _delete()
    $n_index = _GUICtrlListView_GetSelectionMark($LV)

    If $n_index = -1 Then Return 0;if nothing is selected, return 0

    $n_index += 1
    $n = IniRead(@ScriptDir & "\data_shortcuts.ini", "number", "n", "")

    IniDelete(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $n_index)
    IniDelete(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $n_index & "_wd")
    For $i = $n_index + 1 To $n Step +1
        IniWrite(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $i - 1, IniRead(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $i, ""))
        IniWrite(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $i - 1 & "_wd", IniRead(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $i & "_wd", ""))
    Next
    IniDelete(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $n)
    IniDelete(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $n & "_wd")

    IniWrite(@ScriptDir & "\data_shortcuts.ini", "number", "n", $n - 1);aktualizuje n

    ;nie chcialo mi sie sprawdzac kiedy tworzy sie zerowy wpis, wiec po prostu zawsze go usuwam xD
    IniDelete(@ScriptDir & "\data_shortcuts.ini", "shortcuts", "0")
    IniDelete(@ScriptDir & "\data_shortcuts.ini", "shortcuts", "0_wd")

    Return 1
EndFunc   ;==>_delete

Func _Start()
    If $Start Then
        $Start = 0
        Local $index = _GUICtrlListView_GetSelectionMark($LV)
        Local $path = IniRead(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $index + 1, "") ;czyta sciezke
        Local $wd = IniRead(@ScriptDir & "\data_shortcuts.ini", "shortcuts", $index + 1 & "_wd", "");czyta working dir

        ShellExecute($path, "", $wd)
    EndIf
EndFunc   ;==>_Start

Func _exit()
    AdlibUnRegister("cout")
    AdlibUnRegister("_hide_show_toolbar")
    Exit
EndFunc   ;==>_exit

Func _show_options()
    If $stateOptions = False Then
        GUISetState(@SW_SHOW, $Options)
        $stateOptions = True
    Else
        GUISetState(@SW_HIDE, $Options)
        $stateOptions = False
    EndIf
EndFunc   ;==>_show_options

Func _hide_show_toolbar()
    $winpos = WinGetPos(WinGetTitle($Toolbar))

    If $stateTool = True Then ;toolbar jest widoczny
        While $winpos[1] + $winpos[3] > 0
            $winpos = WinGetPos(WinGetTitle($Toolbar))
            WinMove(WinGetTitle($Toolbar), "", $tX, $winpos[1] - 10)
            Sleep($hide_speed)
        WEnd
        $stateTool = False
    Else ;toolbar jest niewidoczny
        While $winpos[1] < 0
            $winpos = WinGetPos(WinGetTitle($Toolbar))
            WinMove(WinGetTitle($Toolbar), "", $tX, $winpos[1] + 10)
            Sleep($hide_speed)
        WEnd
        WinMove(WinGetTitle($Toolbar), "", $tX, $tY);umieszcza okno gdzie bylo przy tworzeniu
        WinActivate(WinGetTitle($Toolbar))
        $stateTool = True
    EndIf
EndFunc   ;==>_hide_show_toolbar

Func _show_hide_console()
    If $stateConsole = False Then ;konsola jest ukryta
        Do
            $winpos = WinGetPos(WinGetTitle($hConsole))
            WinMove(WinGetTitle($hConsole), "", 0, $winpos[1] + 30)
            Sleep($hide_speed)
        Until $winpos[1] > 0
        WinMove(WinGetTitle($hConsole), "", 0, 0)
        $stateConsole = True
        WinActivate(WinGetTitle($hConsole))
    Else;kosnola jest widoczna
        Do
            $winpos = WinGetPos(WinGetTitle($hConsole))
            WinMove(WinGetTitle($hConsole), "", 0, $winpos[1] - 30)
            Sleep($hide_speed)
        Until $winpos[1] < -$cHeight
        $stateConsole = False
    EndIf
EndFunc   ;==>_show_hide_console

Func _volume_mute()
    Send("{Volume_mute}")
EndFunc   ;==>_volume_mute

Func _volume_up()
    Send("{Volume_up}")
EndFunc   ;==>_volume_up

Func _volume_down()
    Send("{Volume_down}")
EndFunc   ;==>_volume_down

Func _about()
    MsgBox(64, "Flawless Toolbar", "Flawless Toolbar Beta by zwierzak(autoit.xaa.pl)")
EndFunc   ;==>_about

Func _hotkeys()
    MsgBox(64, "Flawless Toolbar", "Aby pokazać / ukryć toolbara wciśnij ctrl+1" & @CRLF & "Aby pokazać / ukryć konsolę wciśnij ctrl+2" & @CRLF & "Aby skasować ikonkę z listy zaznacz ją i wciśnij 'delete'" & @CRLF & @CRLF & "Korzystając z klawiatury numerycznej..." & @CRLF & "Aby zwiekszyc głośność dźwięku wciśnij 'ctrl alt +'" & @CRLF & "Aby zmniejszyc głośność dźwięku wciśnij 'ctrl alt -'" & @CRLF & "Aby wyłączyć/włączyć dźwięk wciśnij 'ctrl alt /'")
EndFunc   ;==>_hotkeys

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($exeDir, 4) <> ".icl" Then
                        $Start = 1;click approved
                        $LHT = ($LVHT[0] + 1)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _Vista_EnableBlurBehind($hWnd, $bColor = 0x000000)
    Const $DWM_BB_ENABLE = 0x00000001

    DllStructSetData($sStruct, 1, $DWM_BB_ENABLE)
    DllStructSetData($sStruct, 2, "1")
    DllStructSetData($sStruct, 4, "1")

    GUISetBkColor($bColor, $hWnd)
    $Ret = DllCall("dwmapi.dll", "int", "DwmEnableBlurBehindWindow", "hwnd", $hWnd, "ptr", DllStructGetPtr($sStruct))
    If @error Then
        Return 0
    Else
        Return $Ret
    EndIf
EndFunc   ;==>_Vista_EnableBlurBehind

Func Console_CP852_to_UNICODE($sText = "")
    ; Tablica zamienników Strony kodowej CMD (CP/OEM 852) na standard Unicode (UTF-8)
    Dim $CODEPAGE[20][2]
    $CODEPAGE[1][0] = "0x88"
    $CODEPAGE[1][1] = "ł"
    $CODEPAGE[2][0] = "0x9D"
    $CODEPAGE[2][1] = "Ł"
    $CODEPAGE[3][0] = "0x86"
    $CODEPAGE[3][1] = "ć"
    $CODEPAGE[4][0] = "0x8F"
    $CODEPAGE[4][1] = "Ć"
    $CODEPAGE[5][0] = "0x97"
    $CODEPAGE[5][1] = "Ś"
    $CODEPAGE[6][0] = "0x98"
    $CODEPAGE[6][1] = "ś"
    $CODEPAGE[7][0] = "0xE0"
    $CODEPAGE[7][1] = "Ó"
    $CODEPAGE[8][0] = "0xA2"
    $CODEPAGE[8][1] = "ó"
    $CODEPAGE[9][0] = "0xA5"
    $CODEPAGE[9][1] = "ą"
    $CODEPAGE[10][0] = "0xA4"
    $CODEPAGE[10][1] = "Ą"
    $CODEPAGE[11][0] = "0xA8"
    $CODEPAGE[11][1] = "Ę"
    $CODEPAGE[12][0] = "0xA9"
    $CODEPAGE[12][1] = "ę"
    $CODEPAGE[13][0] = "0xAB"
    $CODEPAGE[13][1] = "ź"
    $CODEPAGE[14][0] = "0x8D"
    $CODEPAGE[14][1] = "Ź"
    $CODEPAGE[15][0] = "0xBD"
    $CODEPAGE[15][1] = "Ż"
    $CODEPAGE[16][0] = "0xBE"
    $CODEPAGE[16][1] = "ż"
    $CODEPAGE[17][0] = "0xE3"
    $CODEPAGE[17][1] = "Ń"
    $CODEPAGE[18][0] = "0xE4"
    $CODEPAGE[18][1] = "ń"
    $CODEPAGE[19][0] = "0xF5"
    $CODEPAGE[19][1] = "$"

    $sRet = ""
    For $iIter = 1 To StringLen($sText) Step 1
        $itmp = StringMid($sText, $iIter, 1)
        For $iRep = 1 To 19 Step 1
            If Asc($itmp) = $CODEPAGE[$iRep][0] Then $itmp = $CODEPAGE[$iRep][1]
        Next
        $sRet &= $itmp
    Next
    Return $sRet
EndFunc   ;==>Console_CP852_to_UNICODE

;Autor: zwierzak(autoit.xaa.pl)
Edited by zwierzak

Share this post


Link to post
Share on other sites



zwierzak, As far as I understand the problem is as follows: When you drop a folder on the toolbar you get a wrong icon in the toolbar. You want the same icon in the toolbar as the icon in Windows Explorer.

You can get the proper icon in this way:

  • Call _WinAPI_CoInitialize
  • Create a system image list
  • Use _WinAPI_ShellGetFileInfo to get the icon
  • Call _WinAPI_ShellGetFileInfo with the PIDL as parameter
According to the 3.3.10.2 help file _WinAPI_ShellGetFileInfo supports a PIDL as parameter instead of the path. But it does not. If $sPath is a PIDL then 'wstr' in the DllCall must be replaced by 'ptr'.

Copied from WinAPIShellEx.au3:

Func _WinAPI_ShellGetFileInfo($sPath, $iFlags, $iAttributes, ByRef $tSHFILEINFO)
  Local $Ret = DllCall('shell32.dll', 'dword_ptr', 'SHGetFileInfoW', 'wstr', $sPath, 'dword', $iAttributes, _
    'struct*', $tSHFILEINFO, 'uint', DllStructGetSize($tSHFILEINFO), 'uint', $iFlags)
  If @error Then Return SetError(@error, @extended, 0)

  Return $Ret[0]
EndFunc   ;==>_WinAPI_ShellGetFileInfo

You have to use the proper implementation of SHGetFileInfo.

Here is an example with a ListView. Drop files or folders (one at a time) on the listview to show icons.

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <WinAPICom.au3>
#include <WinAPIShellEx.au3>

Opt( "MustDeclareVars", 1 )

MainFunc()

Func MainFunc()

  _WinAPI_CoInitialize()

  ; Create GUI
  Local $hGui = GUICreate( "Drop files or folders (one at a time) on the listview to show icons", 550, 300, 300, 200, _
    -1, BitOR( $WS_EX_ACCEPTFILES, $WS_EX_TOPMOST ) )

  ; System image list
  Local $hImlLarge = GetSystemImageList( True )

  ; Create ListView
  Local $idLV = GUICtrlCreateListView( "", 0, 0, 550, 300 )
  GUICtrlSetStyle( $idLV, BitOR( $GUI_SS_DEFAULT_LISTVIEW, $LVS_ICON ) )
  GUICtrlSetState( $idLV, $GUI_DROPACCEPTED )
  Local $hLV = ControlGetHandle( $hGui, "", $idLV )
  _GUICtrlListView_SetExtendedListViewStyle( $hLV, $LVS_EX_DOUBLEBUFFER )
  _GUICtrlListView_SetImageList( $hLV, $hImlLarge, 0 )

  ; Show GUI
  GUISetState( @SW_SHOW )

  While 1

    Switch GUIGetMsg()

      Case $GUI_EVENT_DROPPED
        Local $fil = @GUI_DragFile
        Local $iImage = GetIconIndex( $fil )
        Local $sText = StringRight( $fil, StringLen( $fil ) - StringInStr( $fil, "\", 0, -1 ) )
        _GUICtrlListView_AddItem( $hLV, $sText, $iImage )

      Case $GUI_EVENT_CLOSE
        ExitLoop

    EndSwitch
    
  WEnd

  _WinAPI_CoUninitialize()
  GUIDelete( $hGui )
  Exit

EndFunc

Func GetSystemImageList( $bLargeIcons = False )
  Local $tSHFILEINFO = DllStructCreate( $tagSHFILEINFO )
  Local $dwFlags = BitOR( $SHGFI_USEFILEATTRIBUTES, $SHGFI_SYSICONINDEX )
  If Not $bLargeIcons Then $dwFlags = BitOR( $dwFlags, $SHGFI_SMALLICON )
  Local $hIml = _WinAPI_ShellGetFileInfo( ".txt", $dwFlags, $FILE_ATTRIBUTE_NORMAL, $tSHFILEINFO )
  If @error Then Return SetError( @error, 0, 0 )
  Return $hIml
EndFunc

Func GetIconIndex( $sFileName )
  Local $pPIDL = _WinAPI_ShellILCreateFromPath( $sFileName )
  Local $tSHFILEINFO = DllStructCreate( $tagSHFILEINFO )
  Local $iFlags = BitOr( $SHGFI_PIDL, $SHGFI_SYSICONINDEX )
  ShellGetFileInfo( $pPIDL, $iFlags, 0, $tSHFILEINFO )
  Local $iIcon = DllStructGetData( $tSHFILEINFO, "iIcon" )
  _WinAPI_CoTaskMemFree( $pPIDL )
  Return $iIcon
EndFunc

Func ShellGetFileInfo($pPIDL, $iFlags, $iAttributes, ByRef $tSHFILEINFO)
  Local $aRet = DllCall('shell32.dll', 'dword_ptr', 'SHGetFileInfoW', 'ptr', $pPIDL, 'dword', $iAttributes, 'struct*', $tSHFILEINFO, 'uint', DllStructGetSize($tSHFILEINFO), 'uint', $iFlags)
  If @error Then Return SetError(@error, @extended, 0)
  Return $aRet[0]
EndFunc

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thank you very much! It really works, now I will be able to use your example in my code:))

BTW. Is there any good tutorial on using those DLL calls, and API functions? It has always caused problems to me :<

Edited by zwierzak

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