diff --git a/.gitignore b/.gitignore index d5da268..a4863f2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ temp/ Au3ChangelogUpdater.exe package.json +lib/desktop.ini diff --git a/lib/DropSourceObject.au3 b/lib/DropSourceObject.au3 new file mode 100644 index 0000000..b0ef5d8 --- /dev/null +++ b/lib/DropSourceObject.au3 @@ -0,0 +1,123 @@ +#include-once +#include "InternalObject.au3" +#include "IUnknown.au3" + +Global $__g_iDropSourceCount + +Global $__g_hMthd_QueryContinueDrag, $__g_hMthd_GiveFeedback +Global $__g_hMthd_DragEnterTarget, $__g_hMthd_DragLeaveTarget + +Global $tagSourceObjIntData = "hwnd hTarget;" + + +Func CreateDropSource() + $__g_iDropSourceCount += 1 + + Local $iObjectId = PrepareInternalObject(3) + Local $tObject = $__g_aObjects[$iObjectId][1] + Local $tSupportedIIDs = $__g_aObjects[$iObjectId][2] + + If Not $__g_hMthd_QueryContinueDrag Then + $__g_hMthd_QueryContinueDrag = DllCallbackRegister("__Mthd_QueryContinueDrag", "long", "ptr;bool;dword") + $__g_hMthd_GiveFeedback = DllCallbackRegister("__Mthd_GiveFeedback", "long", "ptr;dword") + $__g_hMthd_DragEnterTarget = DllCallbackRegister("__Mthd_DragEnterTarget", "long", "ptr;hwnd") + $__g_hMthd_DragLeaveTarget = DllCallbackRegister("__Mthd_DragLeaveTarget", "long", "ptr") + EndIf + + Local $tIDropSrcVTab = DllStructCreate("ptr pFunc[5]") + $tIDropSrcVTab.pFunc(1) = DllCallbackGetPtr($__g_hMthd_QueryInterfaceThunk) + $tIDropSrcVTab.pFunc(2) = DllCallbackGetPtr($__g_hMthd_AddRefThunk) + $tIDropSrcVTab.pFunc(3) = DllCallbackGetPtr($__g_hMthd_ReleaseThunk) + $tIDropSrcVTab.pFunc(4) = DllCallbackGetPtr($__g_hMthd_QueryContinueDrag) + $tIDropSrcVTab.pFunc(5) = DllCallbackGetPtr($__g_hMthd_GiveFeedback) + + Local $tIDropSrcNotifyVTab = DllStructCreate("ptr pFunc[5]") + $tIDropSrcNotifyVTab.pFunc(1) = DllCallbackGetPtr($__g_hMthd_QueryInterfaceThunk) + $tIDropSrcNotifyVTab.pFunc(2) = DllCallbackGetPtr($__g_hMthd_AddRefThunk) + $tIDropSrcNotifyVTab.pFunc(3) = DllCallbackGetPtr($__g_hMthd_ReleaseThunk) + $tIDropSrcNotifyVTab.pFunc(4) = DllCallbackGetPtr($__g_hMthd_DragEnterTarget) + $tIDropSrcNotifyVTab.pFunc(5) = DllCallbackGetPtr($__g_hMthd_DragLeaveTarget) + + Local $tInternalData = DllStructCreate($tagSourceObjIntData) + + $tObject.pVTab(2) = DllStructGetPtr($tIDropSrcVTab) + $tObject.pVTab(3) = DllStructGetPtr($tIDropSrcNotifyVTab) + $tObject.pData = DllStructGetPtr($tInternalData) + _WinAPI_GUIDFromStringEx($sIID_IDropSource, DllStructGetPtr($tSupportedIIDs, 2)) + _WinAPI_GUIDFromStringEx($sIID_IDropSourceNotify, DllStructGetPtr($tSupportedIIDs, 3)) + + $__g_aObjects[$iObjectId][4] = $tIDropSrcVTab + $__g_aObjects[$iObjectId][5] = $tIDropSrcNotifyVTab + $__g_aObjects[$iObjectId][6] = $tInternalData + +;~ ConsoleWrite("IUnknown Location: " & DllStructGetPtr($tObject, "pVTab") & @CRLF) +;~ ConsoleWrite("IDropSource Location: " & DllStructGetPtr($tObject, "pVTab") + $PTR_LEN & @CRLF) +;~ ConsoleWrite("IDropNotify Location: " & DllStructGetPtr($tObject, "pVTab") + 2*$PTR_LEN & @CRLF) + + $__g_aObjects[$iObjectId][0] = DllStructGetPtr($tObject, "pVTab") + $PTR_LEN + Return $__g_aObjects[$iObjectId][0] +EndFunc ;==>CreateDropSource + +Func DestroyDropSource($pObject) + If (Not $pObject) Or (Not IsPtr($pObject)) Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) + + DestroyInternalObject($pObject) + If Not @error Then + $__g_iDropSourceCount -= 1 + If Not $__g_iDropSourceCount Then + DllCallbackFree($__g_hMthd_QueryContinueDrag) + DllCallbackFree($__g_hMthd_GiveFeedback) + DllCallbackFree($__g_hMthd_DragEnterTarget) + DllCallbackFree($__g_hMthd_DragLeaveTarget) + + $__g_hMthd_QueryContinueDrag = 0 + $__g_hMthd_GiveFeedback = 0 + $__g_hMthd_DragEnterTarget = 0 + $__g_hMthd_DragLeaveTarget = 0 + EndIf + EndIf +EndFunc ;==>DestroyDropSource + + +Func __Mthd_QueryContinueDrag($pThis, $bEscapePressed, $iKeyState) + #forceref $pThis, $bEscapePressed, $iKeyState + + Local $iReturn = $S_OK + If $bEscapePressed Then + $iReturn = $DRAGDROP_S_CANCEL + Else + If Not BitAND($iKeyState, BitOR($MK_LBUTTON, $MK_RBUTTON)) Then $iReturn = $DRAGDROP_S_DROP + EndIf + + Return $iReturn +EndFunc ;==>__Mthd_QueryContinueDrag + + +Func __Mthd_GiveFeedback($pThis, $iEffect) + #forceref $pThis, $iEffect + +;~ Local Const $iDataOffset = $PTR_LEN * 3 + 4 +;~ Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $iDataOffset)), 1) +;~ Local $tData = DllStructCreate($tagSourceObjIntData, $pData) + + Return $DRAGDROP_S_USEDEFAULTCURSORS +EndFunc ;==>__Mthd_GiveFeedback + +Func __Mthd_DragEnterTarget($pThis, $hTarget) + Local Const $iDataOffset = $PTR_LEN * 2 + 4 + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $iDataOffset)), 1) + Local $tData = DllStructCreate($tagSourceObjIntData, $pData) + DllStructSetData($tData, "hTarget", $hTarget) + + Return $S_OK +EndFunc ;==>__Mthd_DragEnterTarget + +Func __Mthd_DragLeaveTarget($pThis) + #forceref $pThis + Local Const $iDataOffset = $PTR_LEN * 2 + 4 + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $iDataOffset)), 1) + Local $tData = DllStructCreate($tagSourceObjIntData, $pData) + DllStructSetData($tData, "hTarget", 0) + + Return $S_OK +EndFunc ;==>__Mthd_DragLeaveTarget diff --git a/lib/DropTargetObject.au3 b/lib/DropTargetObject.au3 new file mode 100644 index 0000000..1b5b672 --- /dev/null +++ b/lib/DropTargetObject.au3 @@ -0,0 +1,513 @@ +#include-once +#include +#include +#include "InternalObject.au3" +#include "IUnknown.au3" +#include +#include +#include +#include +#include + +#include +#include "TreeListExplorer.au3" +#include "IFileOperation.au3" +#include "SharedFunctions.au3" + +Global $__g_iDropTargetCount +Global $__g_hMthd_DragEnter, $__g_hMthd_DragOver, $__g_hMthd_DragLeave, $__g_hMthd_Drop +Global $tagTargetObjIntData = "hwnd hTarget;bool bAcceptDrop;ptr pDataObject;ptr pIDropTgtHelper" +Global Const $__g_iTargetObjDataOffset = $PTR_LEN * 2 + 4 + +Global $hTreeOrig +Global $iPreviousHot, $sDropTV, $iFinalEffect +Global $sSourceDrive, $sSourcePath, $bIsSameDrive, $bIsSameFolder + +Func CreateDropTarget($hTarget = 0) + $__g_iDropTargetCount += 1 + + Local $iObjectId = PrepareInternalObject(2) + Local $tObject = $__g_aObjects[$iObjectId][1] + Local $tSupportedIIDs = $__g_aObjects[$iObjectId][2] + + If Not $__g_hMthd_DragEnter Then + $__g_hMthd_DragEnter = DllCallbackRegister("__Mthd_DragEnter", "long", "ptr;ptr;dword;uint64;ptr") + $__g_hMthd_DragOver = DllCallbackRegister("__Mthd_DragOver", "long", "ptr;dword;uint64;ptr") + $__g_hMthd_DragLeave = DllCallbackRegister("__Mthd_DragLeave", "long", "ptr") + $__g_hMthd_Drop = DllCallbackRegister("__Mthd_Drop", "long", "ptr;ptr;dword;uint64;ptr") + EndIf + + Local $tIDropTgtVTab = DllStructCreate("ptr pFunc[7]") + $tIDropTgtVTab.pFunc(1) = DllCallbackGetPtr($__g_hMthd_QueryInterfaceThunk) + $tIDropTgtVTab.pFunc(2) = DllCallbackGetPtr($__g_hMthd_AddRefThunk) + $tIDropTgtVTab.pFunc(3) = DllCallbackGetPtr($__g_hMthd_ReleaseThunk) + $tIDropTgtVTab.pFunc(4) = DllCallbackGetPtr($__g_hMthd_DragEnter) + $tIDropTgtVTab.pFunc(5) = DllCallbackGetPtr($__g_hMthd_DragOver) + $tIDropTgtVTab.pFunc(6) = DllCallbackGetPtr($__g_hMthd_DragLeave) + $tIDropTgtVTab.pFunc(7) = DllCallbackGetPtr($__g_hMthd_Drop) + + Local $tInternalData = DllStructCreate($tagTargetObjIntData) + $tInternalData.hTarget = $hTarget + + $tObject.pVTab(2) = DllStructGetPtr($tIDropTgtVTab) + $tObject.pData = DllStructGetPtr($tInternalData) + _WinAPI_GUIDFromStringEx($sIID_IDropTarget, DllStructGetPtr($tSupportedIIDs, 2)) + + $__g_aObjects[$iObjectId][4] = $tIDropTgtVTab + $__g_aObjects[$iObjectId][5] = $tInternalData + + Local $oDropTgtHelper = ObjCreateInterface($sCLSID_DragDropHelper, $sIID_IDropTargetHelper, $tagIDropTargetHelper) + + Local $pIDropTgtHelper + $oDropTgtHelper.QueryInterface($sIID_IDropTargetHelper, $pIDropTgtHelper) + $tInternalData.pIDropTgtHelper = $pIDropTgtHelper + +;~ ConsoleWrite("IUnknown Location: " & DllStructGetPtr($tObject, "pVTab") & @CRLF) +;~ ConsoleWrite("IDropTarget Location: " & DllStructGetPtr($tObject, "pVTab") + $PTR_LEN & @CRLF) + + $__g_aObjects[$iObjectId][0] = DllStructGetPtr($tObject, "pVTab") + $PTR_LEN + Return $__g_aObjects[$iObjectId][0] +EndFunc ;==>CreateDropTarget + +Func DestroyDropTarget($pObject) + If (Not $pObject) Or (Not IsPtr($pObject)) Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) + + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pObject + $__g_iTargetObjDataOffset)), 1) + Local $tData = DllStructCreate($tagTargetObjIntData, $pData) + _Release($tData.pIDropTgtHelper) + + DestroyInternalObject($pObject) + If Not @error Then + $__g_iDropTargetCount -= 1 + If Not $__g_iDropTargetCount Then + DllCallbackFree($__g_hMthd_DragEnter) + DllCallbackFree($__g_hMthd_DragOver) + DllCallbackFree($__g_hMthd_DragLeave) + DllCallbackFree($__g_hMthd_Drop) + + $__g_hMthd_DragEnter = 0 + $__g_hMthd_DragOver = 0 + $__g_hMthd_DragLeave = 0 + $__g_hMthd_Drop = 0 + EndIf + EndIf +EndFunc ;==>DestroyDropTarget + +Func __Mthd_DragEnter($pThis, $pDataObject, $iKeyState, $iPoint, $piEffect) + + #forceref $pThis, $pDataObject, $iKeyState, $iPoint, $piEffect + + Local $sDirText = "" + + Local $tPoint = DllStructCreate($tagPoint) + $tPoint.X = _WinAPI_LoDWord($iPoint) + $tPoint.Y = _WinAPI_HiDWord($iPoint) + + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $__g_iTargetObjDataOffset)), 1) + Local $tData = DllStructCreate($tagTargetObjIntData, $pData) + $tData.bAcceptDrop = False + $tData.pDataObject = $pDataObject + + Local $oDataObject = ObjCreateInterface($pDataObject, $sIID_IDataObject, $tagIDataObject) + ;Addref to counteract the automatic release() when $oDataObject falls out of scope. + $oDataObject.AddRef() + + ;Accept only if dataobject contains a HDrop. + Local $pIEnumFmtEtc + $oDataObject.EnumFormatEtc($DATADIR_GET, $pIEnumFmtEtc) + Local $oIEnumFmtEtc = ObjCreateInterface($pIEnumFmtEtc, $sIID_IEnumFORMATETC, $tagIEnumFORMATETC) + Local $tFormatEtc = DllStructCreate($tagFORMATETC) + Local $pFmtEtc = DllStructGetPtr($tFormatEtc), $iFetched + $oIEnumFmtEtc.Reset() + While $oIEnumFmtEtc.Next(1, $pFmtEtc, $iFetched) = $S_OK +;~ ConsoleWrite(Hex($tFormatEtc.cfFormat) & " " & _ClipBoard_GetFormatName($tFormatEtc.cfFormat) & @CRLF) + If $tFormatEtc.cfFormat = $CF_HDROP Then + $tData.bAcceptDrop = True + ExitLoop + EndIf + WEnd + + ; test getting filename to compare + Local $tFormatEtc = DllStructCreate($tagFORMATETC) + $tFormatEtc.cfFormat = $CF_HDROP + $tFormatEtc.iIndex = -1 + $tFormatEtc.tymed = $TYMED_HGLOBAL + + Local $oDataObject = ObjCreateInterface($pDataObject, $sIID_IDataObject, $tagIDataObject) + Local $tStgMedium = DllStructCreate($tagSTGMEDIUM) + $oDataObject.AddRef() + $oDataObject.GetData($tFormatEtc, $tStgMedium) + + Local $asFilenames = _WinAPI_DragQueryFileEx($tStgMedium.handle) + Local $sPathName = $asFilenames[1] + If StringInStr(FileGetAttrib($sPathName), "D") Then + $sPathName = $sPathName & "\" + EndIf + Local $aPath = _PathSplit_mod($sPathName) + $sSourceDrive = $aPath[$PATH_DRIVE] + $sSourcePath = $aPath[$PATH_DRIVE] & $aPath[$PATH_DIRECTORY] + ; test + + Switch _WinAPI_GetClassName_mod($tData.hTarget) + Case $WC_LISTVIEW + ; + Case $WC_TREEVIEW + $hTreeOrig = _GUICtrlTreeView_GetSelection($tData.hTarget) + Case Else + $tData.bAcceptDrop = False + EndSwitch + + __DoDropResponse($tData, $iKeyState, $tPoint, $piEffect, $sDirText) + + Local $oIDropTgtHelper = ObjCreateInterface($tData.pIDropTgtHelper, $sIID_IDropTargetHelper, $tagIDropTargetHelper) + $oIDropTgtHelper.AddRef() + + $oIDropTgtHelper.DragEnter($tData.hTarget, $pDataObject, $tPoint, $piEffect) + + Return $S_OK +EndFunc ;==>__Mthd_DragEnter + +Func __Mthd_DragOver($pThis, $iKeyState, $iPoint, $piEffect) + + #forceref $pThis, $iKeyState, $iPoint, $piEffect + + Local $sDirText = "" + Local $bIsFolder + Local $sDestDrive, $sDestPath + + Local $tPoint = DllStructCreate($tagPoint) + $tPoint.X = _WinAPI_LoDWord($iPoint) + $tPoint.Y = _WinAPI_HiDWord($iPoint) + + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $__g_iTargetObjDataOffset)), 1) + Local $tData = DllStructCreate($tagTargetObjIntData, $pData) + + _WinAPI_ScreenToClient_mod($tData.hTarget, $tPoint) + + Switch _WinAPI_GetClassName_mod($tData.hTarget) + Case $WC_LISTVIEW + Local $aListItem = _GUICtrlListView_HitTest($tData.hTarget, $tPoint.X, $tPoint.Y) + Local $sItemText = _GUICtrlListView_GetItemText($tData.hTarget, $aListItem[0]) + Local $sFullPath = __TreeListExplorer_GetPath(1) & $sItemText + If Not $sItemText Then + ; get the currently selected path + $sDirPath = __TreeListExplorer_GetPath(1) + ; obtain folder name only for drag tooltip + Local $aPath = _StringBetween($sDirPath, "\", "\") + $sDirText = $aPath[UBound($aPath) - 1] + ; get full path for comparison + $sDestPath = $sDirPath + ElseIf StringInStr(FileGetAttrib($sFullPath), "D") Then + $sDirText = $sItemText + $bIsFolder = True + ; get full path for comparison + $sDestPath = $sFullPath & "\" + Else + ; get the currently selected path + $sDirPath = __TreeListExplorer_GetPath(1) + ; obtain folder name only for drag tooltip + Local $aPath = _StringBetween($sDirPath, "\", "\") + $sDirText = $aPath[UBound($aPath) - 1] + ; get full path for comparison + $sDestPath = $sDirPath + EndIf + + ; clear previously DROPHILITED listview item + _GUICtrlListView_SetItemState($tData.hTarget, $iPreviousHot, 0, $LVIS_DROPHILITED) + + If $aListItem[0] >= 0 Then + $iPreviousHot = $aListItem[0] + ; bring focus to listview to show hot item (needed for listview to listview drag) + _WinAPI_SetFocus($tData.hTarget) + If $bIsFolder Then + _GUICtrlListView_SetItemState($tData.hTarget, $aListItem[0], $LVIS_DROPHILITED, $LVIS_DROPHILITED) + EndIf + Else + ; clear previously DROPHILITED listview item + _GUICtrlListView_SetItemState($tData.hTarget, $iPreviousHot, 0, $LVIS_DROPHILITED) + EndIf + Case $WC_TREEVIEW + Local $hTreeItem = _GUICtrlTreeView_HitTestItem($tData.hTarget, $tPoint.X, $tPoint.Y) + $sDirText = _GUICtrlTreeView_GetText($tData.hTarget, $hTreeItem) + If $hTreeItem <> 0 Then + ; bring focus to treeview to properly show DROPHILITE + _WinAPI_SetFocus($tData.hTarget) + _GUICtrlTreeView_SelectItem($tData.hTarget, $hTreeItem) + _GUICtrlTreeView_SetState($tData.hTarget, $hTreeOrig, $TVIS_SELECTED, True) + ; get full path for comparison + $sDestPath = TreeItemToPath($tData.hTarget, $hTreeItem) + $sDropTV = $sDestPath + EndIf + Case Else + $sDirText = "" + EndSwitch + + ; compare source and target to determine if they are on the same drive + If StringInStr($sDestPath, $sSourceDrive) Then + $bIsSameDrive = True + Else + $bIsSameDrive = False + EndIf + + ; compare source and target to determine if they are the same + If $sDestPath = $sSourcePath Then + $bIsSameFolder = True + Else + $bIsSameFolder = False + EndIf + + __DoDropResponse($tData, $iKeyState, $tPoint, $piEffect, $sDirText, $bIsSameDrive, $bIsSameFolder) + + Local $tEffect = DllStructCreate("dword iEffect", $piEffect) + $iFinalEffect = $tEffect.iEffect + + Local $oIDropTgtHelper = ObjCreateInterface($tData.pIDropTgtHelper, $sIID_IDropTargetHelper, $tagIDropTargetHelper) + $oIDropTgtHelper.AddRef() + $oIDropTgtHelper.DragOver($tPoint, $piEffect) + + Return $S_OK +EndFunc ;==>__Mthd_DragOver + +Func __Mthd_DragLeave($pThis) + #forceref $pThis + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $__g_iTargetObjDataOffset)), 1) + Local $tData = DllStructCreate($tagTargetObjIntData, $pData) + + __SetDropDescription($tData.pDataObject, $DROPIMAGE_INVALID) + + Local $oIDropTgtHelper = ObjCreateInterface($tData.pIDropTgtHelper, $sIID_IDropTargetHelper, $tagIDropTargetHelper) + $oIDropTgtHelper.AddRef() + $oIDropTgtHelper.DragLeave() + + Switch _WinAPI_GetClassName_mod($tData.hTarget) + Case $WC_LISTVIEW + ; clear previously DROPHILITED listview item + _GUICtrlListView_SetItemState($tData.hTarget, $iPreviousHot, 0, $LVIS_DROPHILITED) + Case $WC_TREEVIEW + ; restore original treeview selection if cursor leaves treeview + _GUICtrlTreeView_SelectItem($tData.hTarget, $hTreeOrig) + EndSwitch + + $tData.bAcceptDrop = False + $tData.pDataObject = 0 + + Return $S_OK +EndFunc ;==>__Mthd_DragLeave + +Func __Mthd_Drop($pThis, $pDataObject, $iKeyState, $iPoint, $piEffect) + #forceref $pThis, $iKeyState, $iPoint, $piEffect + + Local $sDirText = "" + Local $bIsFolder, $iFlags, $sAction + + Local $tPoint = DllStructCreate($tagPoint) + $tPoint.X = _WinAPI_LoDWord($iPoint) + $tPoint.Y = _WinAPI_HiDWord($iPoint) + + Local $pData = DllStructGetData(DllStructCreate("ptr", Ptr($pThis + $__g_iTargetObjDataOffset)), 1) + Local $tData = DllStructCreate($tagTargetObjIntData, $pData) + + _WinAPI_ScreenToClient_mod($tData.hTarget, $tPoint) + + __DoDropResponse($tData, $iKeyState, $tPoint, $piEffect, $sDirText) + + Local $oIDropTgtHelper = ObjCreateInterface($tData.pIDropTgtHelper, $sIID_IDropTargetHelper, $tagIDropTargetHelper) + $oIDropTgtHelper.AddRef() + $oIDropTgtHelper.Drop($pDataObject, $tPoint, $piEffect) + + Local $tEffect = DllStructCreate("dword iEffect", $piEffect) + If $tEffect.iEffect <> $DROPEFFECT_NONE Then + + Local $tFormatEtc = DllStructCreate($tagFORMATETC) + $tFormatEtc.cfFormat = $CF_HDROP + $tFormatEtc.iIndex = -1 + $tFormatEtc.tymed = $TYMED_HGLOBAL + + Local $oDataObject = ObjCreateInterface($pDataObject, $sIID_IDataObject, $tagIDataObject) + Local $tStgMedium = DllStructCreate($tagSTGMEDIUM) + $oDataObject.AddRef() + $oDataObject.GetData($tFormatEtc, $tStgMedium) + + Local $asFilenames = _WinAPI_DragQueryFileEx($tStgMedium.handle) + + Switch _WinAPI_GetClassName_mod($tData.hTarget) + Case $WC_LISTVIEW + ; clear previously DROPHILITED listview item + _GUICtrlListView_SetItemState($tData.hTarget, $iPreviousHot, 0, $LVIS_DROPHILITED) + + Local $aListItem = _GUICtrlListView_HitTest($tData.hTarget, $tPoint.X, $tPoint.Y) + Local $sItemText = _GUICtrlListView_GetItemText($tData.hTarget, $aListItem[0]) + Local $sFullPath = __TreeListExplorer_GetPath(1) & $sItemText + If StringInStr(FileGetAttrib($sFullPath), "D") Then + $sDirText = $sItemText + $sFullPath = $sFullPath + $bIsFolder = True + Else + ; get the currently selected path + $sDirPath = __TreeListExplorer_GetPath(1) + $sFullPath = $sDirPath + ; obtain folder name only for drag tooltip + Local $aPath = _StringBetween($sDirPath, "\", "\") + $sDirText = $aPath[UBound($aPath) - 1] + EndIf + ; handle case when cursor is over ListView but not on item; current directory becomes drop dir + If $sDirText = "" Then + ; get the currently selected path + $sDirPath = __TreeListExplorer_GetPath(1) + $sFullPath = $sDirPath + ; obtain folder name only for drag tooltip + Local $aPath = _StringBetween($sDirPath, "\", "\") + $sDirText = $aPath[UBound($aPath) - 1] + EndIf + + ; determine if IFileOperation needs to copy or move files + Switch $iFinalEffect + Case $DROPEFFECT_COPY + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + $sAction = "CopyItems" + _IFileOperationFile($pDataObject, $sFullPath, $sAction, $iFlags) + __TreeListExplorer_Reload(1) + Case $DROPEFFECT_MOVE + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + $sAction = "MoveItems" + _IFileOperationFile($pDataObject, $sFullPath, $sAction, $iFlags) + ; send response back to source to indicate that file move has been handled + $tEffect.iEffect = $DROPEFFECT_NONE + __SetPerformedDropEffect($pDataObject, $DROPEFFECT_NONE) + __TreeListExplorer_Reload(1) + EndSwitch + + Case $WC_TREEVIEW + ; restore original treeview selection + _GUICtrlTreeView_SelectItem($tData.hTarget, $hTreeOrig) + + ; full treeview drop path is most recently DROPHILITED item + Local $sFullPath =$sDropTV + + ; determine if IFileOperation needs to copy or move files + Switch $iFinalEffect + Case $DROPEFFECT_COPY + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + $sAction = "CopyItems" + _IFileOperationFile($pDataObject, $sFullPath, $sAction, $iFlags) + __TreeListExplorer_Reload(1) + Case $DROPEFFECT_MOVE + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + $sAction = "MoveItems" + _IFileOperationFile($pDataObject, $sFullPath, $sAction, $iFlags) + ; send response back to source to indicate that file move has been handled + $tEffect.iEffect = $DROPEFFECT_NONE + __SetPerformedDropEffect($pDataObject, $DROPEFFECT_NONE) + __TreeListExplorer_Reload(1) + EndSwitch + + EndSwitch + EndIf + + $tData.bAcceptDrop = False + $tData.pDataObject = 0 + + Return $S_OK +EndFunc ;==>__Mthd_Drop + +Func __SetDropDescription($pDataObject, $iType, $sMessage = "", $sInsert = "") + Local $tFormatEtc = DllStructCreate($tagFORMATETC) + $tFormatEtc.cfFormat = _ClipBoard_RegisterFormat($CFSTR_DROPDESCRIPTION) + $tFormatEtc.ptd = 0 + $tFormatEtc.aspect = $DVASPECT_CONTENT + $tFormatEtc.index = -1 + $tFormatEtc.tymed = $TYMED_HGLOBAL + + Local $tDropDesc = DllStructCreate($tagDROPDESCRIPTION) + Local $hGblMem = _MemGlobalAlloc(DllStructGetSize($tDropDesc), $GPTR) + Local $pDropDesc = _MemGlobalLock($hGblMem) + $tDropDesc = DllStructCreate($tagDROPDESCRIPTION, $pDropDesc) + $tDropDesc.iType = $iType + $tDropDesc.sMessage = $sMessage + $tDropDesc.sInsert = $sInsert + _MemGlobalUnlock($hGblMem) + + Local $tStgMedium = DllStructCreate($tagSTGMEDIUM) + $tStgMedium.tymed = $TYMED_HGLOBAL + $tStgMedium.handle = $hGblMem + $tStgMedium.pUnkForRelease = 0 + + Local $oDataObj = ObjCreateInterface($pDataObject, $sIID_IDataObject, $tagIDataObject) + $oDataObj.AddRef() + $oDataObj.SetData($tFormatEtc, $tStgMedium, 1) +EndFunc ;==>__SetDropDescription + +Func __DoDropResponse($tData, $iKeyState, $tPoint, $piEffect, $sDirText, $bIsSameDrive = False, $bIsSameFolder = False) + + #forceref $tData, $iKeyState, $tPoint, $piEffect + + Local $iRetEffect = $DROPEFFECT_NONE, $iReqOp + Local $tEffect = DllStructCreate("dword iEffect", $piEffect) + + ;See what the user is asking for based on key modifiers. + If $tData.bAcceptDrop Then + Switch BitAND($iKeyState, BitOR($MK_CONTROL, $MK_ALT, $MK_SHIFT)) + Case BitOr($MK_CONTROL, $MK_ALT), 0 + $iReqOp = $DROPEFFECT_MOVE + Case $MK_CONTROL + $iReqOp = $DROPEFFECT_COPY + Case BitOR($MK_CONTROL, $MK_SHIFT), $MK_ALT + $iReqOp = $DROPEFFECT_LINK + EndSwitch + + ;If move is legally an option + If BitAND($tEffect.iEffect, $DROPEFFECT_MOVE) Then + If $iReqOp = $DROPEFFECT_MOVE And $bIsSameDrive Then $iRetEffect = $DROPEFFECT_MOVE + EndIf + ;If copy is legally an option + If BitAND($tEffect.iEffect, $DROPEFFECT_COPY) Then + If $iReqOp = $DROPEFFECT_COPY Or $iRetEffect = $DROPEFFECT_NONE Then $iRetEffect = $DROPEFFECT_COPY + EndIf + ;If link is legally an option + If BitAND($tEffect.iEffect, $DROPEFFECT_LINK) Then + If $iReqOp = $DROPEFFECT_LINK Or $iRetEffect = $DROPEFFECT_NONE Then $iRetEffect = $DROPEFFECT_LINK + EndIf + If $bIsSameFolder Then $iRetEffect = $DROPEFFECT_NONE + EndIf + $tEffect.iEffect = $iRetEffect + + Switch $tEffect.iEffect + Case $DROPEFFECT_NONE + __SetDropDescription($tData.pDataObject, $DROPIMAGE_NOIMAGE, "", "") + + Case $DROPEFFECT_LINK + __SetDropDescription($tData.pDataObject, $DROPIMAGE_LINK, "Link to %1", $sDirText) + + Case $DROPEFFECT_COPY + __SetDropDescription($tData.pDataObject, $DROPIMAGE_COPY, "Copy to %1", $sDirText) + + Case $DROPEFFECT_MOVE + __SetDropDescription($tData.pDataObject, $DROPIMAGE_MOVE, "Move to %1", $sDirText) + EndSwitch + + Return +EndFunc ;==>__DoDropResponse + +Func __SetPerformedDropEffect($pDataObject, $iDropEffect) + Local $tFormatEtc = DllStructCreate($tagFORMATETC) + $tFormatEtc.cfFormat = _ClipBoard_RegisterFormat($CFSTR_PERFORMEDDROPEFFECT) + $tFormatEtc.ptd = 0 + $tFormatEtc.aspect = $DVASPECT_CONTENT + $tFormatEtc.index = -1 + $tFormatEtc.tymed = $TYMED_HGLOBAL + + Local $hGblMem = _MemGlobalAlloc(4, $GPTR) + Local $pDropEffect = _MemGlobalLock($hGblMem) + Local $tDropEffect = DllStructCreate("dword iEffect", $pDropEffect) + $tDropEffect.iEffect = $iDropEffect + _MemGlobalUnlock($hGblMem) + + Local $tStgMedium = DllStructCreate($tagSTGMEDIUM) + $tStgMedium.tymed = $TYMED_HGLOBAL + $tStgMedium.handle = $hGblMem + $tStgMedium.pUnkForRelease = 0 + + Local $oDataObj = ObjCreateInterface($pDataObject, $sIID_IDataObject, $tagIDataObject) + $oDataObj.AddRef() + $oDataObj.SetData($tFormatEtc, $tStgMedium, 1) +EndFunc ;==>__SetPerformedDropEffect diff --git a/lib/GUIFrame_WBD_Mod.au3 b/lib/GUIFrame_WBD_Mod.au3 index efe78a0..f0c1f55 100644 --- a/lib/GUIFrame_WBD_Mod.au3 +++ b/lib/GUIFrame_WBD_Mod.au3 @@ -107,7 +107,6 @@ Func _GUIFrame_Create($hWnd, $iSepOrient = 0, $iSepPos = 0, $iSepSize = 5, $iX = Local $iSeperator_Pos, $hSeparator, $hFirstFrame, $hSecondFrame, $nSepPercent Local $iFrame_Style = BitOR(0x40000000, 0x10000000) ; $WS_CHILD, WS_VISIBLE Local $iFrame_Ext_Style = 0x02000000 ; WS_EX_COMPOSITED - ;Local $iFrame_Ext_Style = 0 ; Set separator size Local $iSeparatorSize = 9 diff --git a/lib/IFileOperation.au3 b/lib/IFileOperation.au3 new file mode 100644 index 0000000..fea2170 --- /dev/null +++ b/lib/IFileOperation.au3 @@ -0,0 +1,142 @@ +#include-once + +#include + +; originally from Danyfirex + +Global Const $FOFX_ADDUNDORECORD = 0x20000000 +Global Const $FOFX_NOSKIPJUNCTIONS = 0x00010000 +Global Const $FOFX_PREFERHARDLINK = 0x00020000 +Global Const $FOFX_SHOWELEVATIONPROMPT = 0x00040000 +Global Const $FOFX_EARLYFAILURE = 0x00100000 +Global Const $FOFX_PRESERVEFILEEXTENSIONS = 0x00200000 +Global Const $FOFX_KEEPNEWERFILE = 0x00400000 +Global Const $FOFX_NOCOPYHOOKS = 0x00800000 +Global Const $FOFX_NOMINIMIZEBOX = 0x01000000 +Global Const $FOFX_MOVEACLSACROSSVOLUMES = 0x02000000 +Global Const $FOFX_DONTDISPLAYSOURCEPATH = 0x04000000 +Global Const $FOFX_DONTDISPLAYDESTPATH = 0x08000000 +Global Const $FOFX_RECYCLEONDELETE = 0x00080000 +Global Const $FOFX_REQUIREELEVATION = 0x10000000 +Global Const $FOFX_COPYASDOWNLOAD = 0x40000000 +Global Const $FOFX_DONTDISPLAYLOCATIONS = 0x80000000 + + +Global Const $IID_IShellItem = "{43826d1e-e718-42ee-bc55-a1e261c37bfe}" +Global Const $dtag_IShellItem = _ + "BindToHandler hresult(ptr;clsid;clsid;ptr*);" & _ + "GetParent hresult(ptr*);" & _ + "GetDisplayName hresult(int;ptr*);" & _ + "GetAttributes hresult(int;int*);" & _ + "Compare hresult(ptr;int;int*);" + +Global Const $IID_IShellItemArray = "{b63ea76d-1f85-456f-a19c-48159efa858b}" +Global Const $dtagIShellItemArray = "BindToHandler hresult();GetPropertyStore hresult();" & _ + "GetPropertyDescriptionList hresult();GetAttributes hresult();GetCount hresult(dword*);" & _ + "GetItemAt hresult();EnumItems hresult();" + +Global Const $BHID_EnumItems = "{94F60519-2850-4924-AA5A-D15E84868039}" +Global Const $IID_IEnumShellItems = "{70629033-e363-4a28-a567-0db78006e6d7}" +Global Const $dtagIEnumShellItems = "Next hresult(ulong;ptr*;ulong*);Skip hresult();Reset hresult();Clone hresult();" + + +Global Const $CLSID_IFileOperation = "{3AD05575-8857-4850-9277-11B85BDB8E09}" +Global Const $IID_IFileOperation = "{947AAB5F-0A5C-4C13-B4D6-4BF7836FC9F8}" +Global Const $dtagIFileOperation = "Advise hresult(ptr;dword*);" & _ + "Unadvise hresult(dword);" & _ + "SetOperationFlags hresult(dword);" & _ + "SetProgressMessage hresult(wstr);" & _ + "SetProgressDialog hresult(ptr);" & _ + "SetProperties hresult(ptr);" & _ + "SetOwnerWindow hresult(hwnd);" & _ + "ApplyPropertiesToItem hresult(ptr);" & _ + "ApplyPropertiesToItems hresult(ptr);" & _ + "RenameItem hresult(ptr;wstr;ptr);" & _ + "RenameItems hresult(ptr;wstr);" & _ + "MoveItem hresult(ptr;ptr;wstr;ptr);" & _ + "MoveItems hresult(ptr;ptr);" & _ + "CopyItem hresult(ptr;ptr;wstr;ptr);" & _ + "CopyItems hresult(ptr;ptr);" & _ + "DeleteItem hresult(ptr;ptr);" & _ + "DeleteItems hresult(ptr);" & _ + "NewItem hresult(ptr;dword;wstr;wstr;ptr);" & _ + "PerformOperations hresult();" & _ + "GetAnyOperationsAborted hresult(ptr*);" + +; Local $iFlags = BitOR($FOF_NOERRORUI, $FOFX_KEEPNEWERFILE, $FOFX_NOCOPYHOOKS, $FOF_NOCONFIRMATION) +; FOFX_ADDUNDORECORD (preferred) +; FOFX_RECYCLEONDELETE +; FOFX_NOCOPYHOOKS + +;Local $sAction = "CopyItems" +;Local $sAction = "MoveItems" + +;_IFileOperationFile($pDataObj, $sPathTo, $sAction, $iFlags) + +Func _IFileOperationDelete($pDataObj, $iFlags = 0) + + Local $tIIDIShellItem = CLSIDFromString($IID_IShellItem) + Local $tIIDIShellItemArray = CLSIDFromString($IID_IShellItemArray) + + + Local $oIFileOperation = ObjCreateInterface($CLSID_IFileOperation, $IID_IFileOperation, $dtagIFileOperation) + If Not IsObj($oIFileOperation) Then Return SetError(2, 0, False) + + $oIFileOperation.SetOperationFlags($iFlags) + + $oIFileOperation.DeleteItems($pDataObj) + + Return $oIFileOperation.PerformOperations() = 0 + +EndFunc ;==>_IFileOperationDelete + +Func _IFileOperationFile($pDataObj, $sPathTo, $sAction, $iFlags = 0) + + If Not FileExists($sPathTo) Then + DirCreate($sPathTo) + EndIf + + + Local $tIIDIShellItem = CLSIDFromString($IID_IShellItem) + Local $tIIDIShellItemArray = CLSIDFromString($IID_IShellItemArray) + + + Local $oIFileOperation = ObjCreateInterface($CLSID_IFileOperation, $IID_IFileOperation, $dtagIFileOperation) + If Not IsObj($oIFileOperation) Then Return SetError(2, 0, False) + + Local $pIShellItemTo = 0 + + _SHCreateItemFromParsingName($sPathTo, 0, DllStructGetPtr($tIIDIShellItem), $pIShellItemTo) + + + If Not $pIShellItemTo Then Return SetError(3, 0, False) + + $oIFileOperation.SetOperationFlags($iFlags) + + Switch $sAction + Case "CopyItems" + $oIFileOperation.CopyItems($pDataObj, $pIShellItemTo) + Case "MoveItems" + $oIFileOperation.MoveItems($pDataObj, $pIShellItemTo) + EndSwitch + + Return $oIFileOperation.PerformOperations() = 0 + +EndFunc ;==>_IFileOperationFile + + +Func _SHCreateItemFromParsingName($szPath, $pbc, $riid, ByRef $pv) + Local $aRes = DllCall("shell32.dll", "long", "SHCreateItemFromParsingName", "wstr", $szPath, "ptr", $pbc, "ptr", $riid, "ptr*", 0) + If @error Then Return SetError(1, 0, @error) + $pv = $aRes[4] + Return $aRes[0] +EndFunc ;==>_SHCreateItemFromParsingName + + +Func CLSIDFromString($sString) + Local $tCLSID = DllStructCreate("dword;word;word;byte[8]") + Local $aRet = DllCall("Ole32.dll", "long", "CLSIDFromString", "wstr", $sString, "ptr", DllStructGetPtr($tCLSID)) + If @error Then Return SetError(1, 0, @error) + If $aRet[0] <> 0 Then Return SetError(2, $aRet[0], 0) + Return $tCLSID +EndFunc ;==>CLSIDFromString diff --git a/lib/IUnknown.au3 b/lib/IUnknown.au3 new file mode 100644 index 0000000..98cb066 --- /dev/null +++ b/lib/IUnknown.au3 @@ -0,0 +1,31 @@ +#include-once +#include "ProjectConstants.au3" +#include + +;This allows us to call the IUnknown methods directly from an object pointer. +;(You could also use ObjCreateInterface to create an object type from the ptr). + +Func _QueryInterface($pThis, $sIID) + If (Not $pThis) Or (Not IsPtr($pThis)) Then Return SetError($ERROR_INVALID_PARAMETER) + Local $pVTab = DllStructGetData(DllStructCreate("ptr", $pThis), 1) + Local $pFunc = DllStructGetData(DllStructCreate("ptr", $pVTab), 1) + Local $tIID = _WinAPI_GUIDFromString($sIID) + Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "struct*", $tIID, "ptr*", 0) + Return SetError($aCall[0], 0, $aCall[3]) +EndFunc ;==>_QueryInterface + +Func _AddRef($pThis) + If (Not $pThis) Or (Not IsPtr($pThis)) Then Return SetError($ERROR_INVALID_PARAMETER) + Local $pVTab = DllStructGetData(DllStructCreate("ptr", $pThis), 1) + Local $pFunc = DllStructGetData(DllStructCreate("ptr", $pVTab + $PTR_LEN), 1) + Local $aCall = DllCallAddress("uint", $pFunc, "ptr", $pThis) + Return $aCall[0] +EndFunc ;==>_AddRef + +Func _Release($pThis) + If (Not $pThis) Or (Not IsPtr($pThis)) Then Return SetError($ERROR_INVALID_PARAMETER) + Local $pVTab = DllStructGetData(DllStructCreate("ptr", $pThis), 1) + Local $pFunc = DllStructGetData(DllStructCreate("ptr", $pVTab + 2 * $PTR_LEN), 1) + Local $aCall = DllCallAddress("uint", $pFunc, "ptr", $pThis) + Return $aCall[0] +EndFunc ;==>_Release diff --git a/lib/InternalObject.au3 b/lib/InternalObject.au3 new file mode 100644 index 0000000..3e454ae --- /dev/null +++ b/lib/InternalObject.au3 @@ -0,0 +1,156 @@ +#include-once +#include "ProjectConstants.au3" +#include "IUnknown.au3" + +Global $__g_aObjects[1][20] +Global $__g_hMthd_QueryInterface, $__g_hMthd_AddRef, $__g_hMthd_Release +Global $__g_hMthd_QueryInterfaceThunk, $__g_hMthd_AddRefThunk, $__g_hMthd_ReleaseThunk + +Func PrepareInternalObject($iImplIfaces) + If Not $__g_hMthd_QueryInterface Then + $__g_hMthd_QueryInterface = DllCallbackRegister("__Mthd_QueryInterface", "long", "ptr;ptr;ptr") + $__g_hMthd_AddRef = DllCallbackRegister("__Mthd_AddRef", "long", "ptr") + $__g_hMthd_Release = DllCallbackRegister("__Mthd_Release", "long", "ptr") + $__g_hMthd_QueryInterfaceThunk = DllCallbackRegister("__Mthd_QueryInterfaceThunk", "long", "ptr;ptr;ptr") + $__g_hMthd_AddRefThunk = DllCallbackRegister("__Mthd_AddRefThunk", "long", "ptr") + $__g_hMthd_ReleaseThunk = DllCallbackRegister("__Mthd_ReleaseThunk", "long", "ptr") + EndIf + + Local $iObjectId = UBound($__g_aObjects) + ReDim $__g_aObjects[$iObjectId + 1][UBound($__g_aObjects, 2)] + $__g_aObjects[0][0] += 1 + + Local $tIUnknownVTab = DllStructCreate("ptr pFunc[3]") + $tIUnknownVTab.pFunc(1) = DllCallbackGetPtr($__g_hMthd_QueryInterface) + $tIUnknownVTab.pFunc(2) = DllCallbackGetPtr($__g_hMthd_AddRef) + $tIUnknownVTab.pFunc(3) = DllCallbackGetPtr($__g_hMthd_Release) + + Local $tagSupportedIIDs + For $i = 1 To $iImplIfaces + $tagSupportedIIDs &= "byte[16];" + Next + Local $tSupportedIIDs = DllStructCreate($tagSupportedIIDs) + _WinAPI_GUIDFromStringEx($sIID_IUnknown, DllStructGetPtr($tSupportedIIDs, 1)) + + Local $tagObject = StringFormat("align 4;int iImplIfaces;ptr pVTab[%d];int iRefCnt;" & _ + "ptr pSupportedIIDs;ptr pData", $iImplIfaces) + + Local $tObject = DllStructCreate($tagObject) + $tObject.iRefCnt = 1 + $tObject.iImplIfaces = $iImplIfaces + $tObject.pVTab(1) = DllStructGetPtr($tIUnknownVTab) + $tObject.pSupportedIIDs = DllStructGetPtr($tSupportedIIDs) + + Local $pObject = DllStructGetPtr($tObject, "pVTab") + + $__g_aObjects[$iObjectId][0] = $pObject + $__g_aObjects[$iObjectId][1] = $tObject + $__g_aObjects[$iObjectId][2] = $tSupportedIIDs + $__g_aObjects[$iObjectId][3] = $tIUnknownVTab + + Return $iObjectId +EndFunc + +Func DestroyInternalObject($pObject) + If (Not $pObject) Or (Not IsPtr($pObject)) Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) + + For $i = 0 To UBound($__g_aObjects) - 1 + If $__g_aObjects[$i][0] = $pObject Then ExitLoop + Next + If $i = UBound($__g_aObjects) Then Return SetError($ERROR_INVALID_PARAMETER, 0, False) + + For $j = 0 To UBound($__g_aObjects, 2) - 1 + $__g_aObjects[$i][$j] = 0 + Next + $__g_aObjects[0][0] -= 1 + + If Not $__g_aObjects[0][0] Then + DllCallbackFree($__g_hMthd_QueryInterface) + DllCallbackFree($__g_hMthd_AddRef) + DllCallbackFree($__g_hMthd_Release) + DllCallbackFree($__g_hMthd_QueryInterfaceThunk) + DllCallbackFree($__g_hMthd_AddRefThunk) + DllCallbackFree($__g_hMthd_ReleaseThunk) + + $__g_hMthd_QueryInterface = 0 + $__g_hMthd_AddRef = 0 + $__g_hMthd_Release = 0 + $__g_hMthd_QueryInterfaceThunk = 0 + $__g_hMthd_AddRefThunk = 0 + $__g_hMthd_ReleaseThunk = 0 + EndIf +EndFunc ;==>DestroyDropSource + + +#Region Internal IUnknown Methods + +Func __Mthd_QueryInterface($pThis, $pIID, $ppObj) +;~ ConsoleWrite("QI: " & _WinAPI_StringFromGUID($pIID) & @CRLF) + + Local $hResult = $S_OK + + Local $iIIDCnt = DllStructGetData(DllStructCreate("int", Ptr($pThis - 4)), 1) + Local $tThis = DllStructCreate(StringFormat("align 4;ptr pVTab[%d];int iRefCnt;ptr pSupportedIIDs", $iIIDCnt), $pThis) + Local $pTestIID = $tThis.pSupportedIIDs + + If Not $ppObj Then + $hResult = $E_POINTER + Else + For $i = 0 To $iIIDCnt - 1 + If _WinAPI_StringFromGUID($pIID) = _WinAPI_StringFromGUID(Ptr($pTestIID)) Then + DllStructSetData(DllStructCreate("ptr", $ppObj), 1, Ptr($pThis + $i * $PTR_LEN)) +;~ ConsoleWrite("FOUND: " & $pThis + $i * $PTR_LEN & @CRLF) + + __Mthd_AddRef($pThis) + ExitLoop + EndIf + $pTestIID += 16 + Next + If $i = $iIIDCnt Then $hResult = $E_NOINTERFACE + + EndIf + + Return $hResult +EndFunc ;==>__Mthd_QueryInterface + +Func __Mthd_AddRef($pThis) + + Local $iImplIfaces = DllStructGetData(DllStructCreate("int", Ptr($pThis - 4)), 1) + Local $tThis = DllStructCreate(StringFormat("align 4;ptr pVTab[%d];int iRefCnt", $iImplIfaces), $pThis) + $tThis.iRefCnt += 1 + + Return $tThis.iRefCnt +EndFunc ;==>__Mthd_AddRef + +Func __Mthd_Release($pThis) + Local $iImplIfaces = DllStructGetData(DllStructCreate("int", Ptr($pThis - 4)), 1) + Local $tThis = DllStructCreate(StringFormat("align 4;ptr pVTab[%d];int iRefCnt", $iImplIfaces), $pThis) + $tThis.iRefCnt -= 1 + Return $tThis.iRefCnt +EndFunc ;==>__Mthd_Release + +Func __Mthd_QueryInterfaceThunk($pThis, $pIID, $ppObj) + Local $hResult = $S_OK + Local $tIID = DllStructCreate($tagGUID, $pIID) + If _WinAPI_StringFromGUID($tIID) = $sIID_IUnknown Then + DllStructSetData(DllStructCreate("ptr", $ppObj), 1, $pThis) + Else + $pThis = Ptr($pThis - $PTR_LEN) + Local $pVTab = DllStructGetData(DllStructCreate("ptr", $pThis), 1) + Local $pFunc = DllStructGetData(DllStructCreate("ptr", $pVTab), 1) + Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr", $pIID, "ptr", $ppObj) + $hResult = $aCall[0] + EndIf + Return $hResult +EndFunc ;==>__Mthd_QueryInterfaceThunk + +Func __Mthd_AddRefThunk($pThis) + $pThis = Ptr($pThis - $PTR_LEN) + Return _AddRef($pThis) +EndFunc ;==>__Mthd_AddRefThunk + +Func __Mthd_ReleaseThunk($pThis) + $pThis = Ptr($pThis - $PTR_LEN) + Return _Release($pThis) +EndFunc ;==>__Mthd_ReleaseThunk +#EndRegion Internal IUnknown Methods diff --git a/lib/ProjectConstants.au3 b/lib/ProjectConstants.au3 new file mode 100644 index 0000000..79e6fb8 --- /dev/null +++ b/lib/ProjectConstants.au3 @@ -0,0 +1,160 @@ +#include-once + +#include +#include +#include +#include +#include +#include + +Global Const $S_FALSE = 1 +Global Const $PTR_LEN = @AutoItX64 ? 8 : 4 + +Global Const $sCLSID_DragDropHelper = "{4657278A-411B-11D2-839A-00C04FD918D0}" +Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" +Global Const $sIID_IShellFolder = "{000214E6-0000-0000-C000-000000000046}" +Global Const $sIID_IDataObject = "{0000010e-0000-0000-C000-000000000046}" +Global Const $sIID_IDropSource = "{00000121-0000-0000-C000-000000000046}" +Global Const $sIID_IDropSourceNotify = "{0000012B-0000-0000-C000-000000000046}" +Global Const $sIID_IEnumFORMATETC = "{00000103-0000-0000-C000-000000000046}" +Global Const $sIID_IDropTarget = "{00000122-0000-0000-C000-000000000046}" +Global Const $sIID_IDragSourceHelper = "{DE5BF786-477A-11D2-839D-00C04FD918D0}" +Global Const $sIID_IDragSourceHelper2 = "{83E07D0D-0C5F-4163-BF1A-60B274051E40}" +Global Const $sIID_IDropTargetHelper = "{4657278B-411B-11D2-839A-00C04FD918D0}" + +Global Const $CLSCTX_INPROC_SERVER = 0x01 +Global Const $CLSCTX_INPROC_HANDLER = 0x2 +Global Const $CLSCTX_LOCAL_SERVER = 0x4 +Global Const $CLSCTX_REMOTE_SERVER = 0x10 +Global Const $CLSCTX_NO_CODE_DOWNLOAD = 0x400 +Global Const $CLSCTX_NO_CUSTOM_MARSHAL = 0x1000 +Global Const $CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000 +Global Const $CLSCTX_NO_FAILURE_LOG = 0x4000 +Global Const $CLSCTX_DISABLE_AAA = 0x8000 +Global Const $CLSCTX_ENABLE_AAA = 0x10000 +Global Const $CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000 +Global Const $CLSCTX_ACTIVATE_X86_SERVER = 0x40000 +Global Const $CLSCTX_ACTIVATE_32_BIT_SERVER = $CLSCTX_ACTIVATE_X86_SERVER +Global Const $CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000 +Global Const $CLSCTX_ENABLE_CLOAKING = 0x100000 +Global Const $CLSCTX_APPCONTAINER = 0x400000 +Global Const $CLSCTX_ACTIVATE_AAA_AS_IU = 0x800000 +Global Const $CLSCTX_ACTIVATE_ARM32_SERVER = 0x2000000 +Global Const $CLSCTX_ALLOW_LOWER_TRUST_REGISTRATION = 0x4000000 +Global Const $CLSCTX_ALL = BitOR($CLSCTX_INPROC_SERVER, $CLSCTX_INPROC_HANDLER, $CLSCTX_LOCAL_SERVER, $CLSCTX_REMOTE_SERVER) + +Global Const $CFSTR_PERFORMEDDROPEFFECT = "Performed DropEffect" + +Global Const $DRAGDROP_S_DROP = 0x00040100 +Global Const $DRAGDROP_S_CANCEL = 0x00040101 +Global Const $DRAGDROP_S_USEDEFAULTCURSORS = 0x00040102 +Global Const $DRAGDROP_E_NOTREGISTERED = 0x80040100 +Global Const $DRAGDROP_E_ALREADYREGISTERED = 0x80040101 + +Global Const $DROPEFFECT_NONE = 0 +Global Const $DROPEFFECT_COPY = 1 +Global Const $DROPEFFECT_MOVE = 2 +Global Const $DROPEFFECT_LINK = 4 +Global Const $DROPEFFECT_SCROLL = 0x80000000 + +Global Const $MK_LBUTTON = 0x0001 +Global Const $MK_RBUTTON = 0x0002 +Global Const $MK_SHIFT = 0x0004 +Global Const $MK_CONTROL = 0x0008 +Global Const $MK_MBUTTON = 0x0010 +Global Const $MK_ALT = 0x0020 +Global Const $MK_XBUTTON1 = 0x0020 +Global Const $MK_XBUTTON2 = 0x0040 + +Global Const $TYMED_HGLOBAL = 1 +Global Const $TYMED_FILE = 2 +Global Const $TYMED_ISTREAM = 4 +Global Const $TYMED_ISTORAGE = 8 +Global Const $TYMED_GDI = 16 +Global Const $TYMED_MFPICT = 32 +Global Const $TYMED_ENHMF = 64 +Global Const $TYMED_NULL = 0 + +Global Const $DVASPECT_CONTENT = 1 +Global Const $DVASPECT_THUMBNAIL = 2 +Global Const $DVASPECT_ICON = 4 +Global Const $DVASPECT_DOCPRINT = 8 + +Global Const $DV_E_FORMATETC = 0x80040064 +Global Const $DV_E_DVTARGETDEVICE = 0x80040065 +Global Const $DV_E_STGMEDIUM = 0x80040066 +Global Const $DV_E_STATDATA = 0x80040067 +Global Const $DV_E_LINDEX = 0x80040068 +Global Const $DV_E_TYMED = 0x80040069 +Global Const $DV_E_CLIPFORMAT = 0x8004006A +Global Const $DV_E_DVASPECT = 0x8004006B +Global Const $DV_E_DVTARGETDEVICE_SIZE = 0x8004006C +Global Const $DV_E_NOIVIEWOBJECT = 0x8004006D + +Global Const $DATADIR_GET = 1 +Global Const $DATADIR_SET = 2 + +Global Const $CFSTR_DROPDESCRIPTION = "DropDescription" + +Global Const $DROPIMAGE_INVALID = -1 +Global Const $DROPIMAGE_NONE = 0 +Global Const $DROPIMAGE_COPY = 1 +Global Const $DROPIMAGE_MOVE = 2 +Global Const $DROPIMAGE_LINK = 4 +Global Const $DROPIMAGE_LABEL = 6 +Global Const $DROPIMAGE_WARNING = 7 +Global Const $DROPIMAGE_NOIMAGE = 8 + +Global Const $DSH_ALLOWDROPDESCRIPTIONTEXT = 0x0001 + +Global Const $tagFORMATETC = "struct;word cfFormat;ptr ptd;dword aspect;long index;dword tymed;endstruct" +Global Const $tagSTGMEDIUM = "struct;dword tymed;ptr handle;ptr pUnkForRelease;endstruct" +Global Const $tagDROPFILES = "struct;dword pFiles;long pt[2];bool fNC;bool fWide;endstruct" +Global Const $tagSHDRAGIMAGE = "struct;long aiDragImageSize[2];long aiOffset[2];handle hDragImage;dword iColorKey;endstruct" +Global Const $tagDROPDESCRIPTION = "struct;int iType;wchar sMessage[260];wchar sInsert[260];endstruct" +Global Const $tagSHFILEINFOW = "struct;handle hIcon;int iIcon;dword iAttributes;wchar sDisplayName[260];wchar sTypeName[80];endstruct;" + +;~ "ParseDisplayName hresult(hwnd; ptr; wstr; ulong*; ptr*; ulong*);" & _ + +Global Const $tagIShellFolder = _ + "ParseDisplayName hresult(hwnd; ptr; wstr; ulong*; ptr*; ulong*);" & _ + "EnumObjects hresult(hwnd; ulong; ptr*);" & _ + "BindToObject hresult(ptr; ptr*; struct*; ptr*);" & _ + "BindToStorage hresult(ptr; ptr*; struct*; ptr*);" & _ + "CompareIDs hresult(lparam; ptr; ptr);" & _ + "CreateViewObject hresult(hwnd; struct*; ptr*);" & _ + "GetAttributesOf hresult(uint; ptr; ulong*);" & _ + "GetUIObjectOf hresult(hwnd; uint; ptr; struct*; uint*; ptr*);" & _ + "GetDisplayNameOf hresult(ptr; ulong; ptr*);" & _ + "SetNameOf hresult(hwnd; ptr; wstr; ulong; ptr*);" + +Global Const $tagIDataObject = _ + "GetData hresult(struct*; struct*);" & _ + "GetDataHere hresult(struct*; struct*);" & _ + "QueryGetData hresult(struct*);" & _ + "GetCanonicalFormatEtc hresult(struct*; struct*);" & _ + "SetData hresult(struct*; struct*; bool);" & _ + "EnumFormatEtc hresult(dword; ptr*);" & _ + "DAdvise hresult(struct*; dword; ptr*; dword*);" & _ + "DUnadvise hresult(dword);" & _ + "EnumDAdvise hresult(ptr*);" + +Global Const $tagIEnumFORMATETC = _ + "Next hresult(ulong; ptr; ulong*);" & _ + "Skip hresult(ulong);" & _ + "Reset hresult();" & _ + "Clone hresult(ptr*);" + +Global Const $tagIDragSourceHelper = _ + "InitializeFromBitmap hresult(struct*; ptr);" & _ + "InitializeFromWindow hresult(hwnd; ptr; ptr);" + +Global Const $tagIDragSourceHelper2 = $tagIDragSourceHelper & _ + "SetFlags hresult(dword);" + +Global Const $tagIDropTargetHelper = _ + "DragEnter hresult(hwnd; ptr; struct*; dword);" & _ + "DragLeave hresult();" & _ + "DragOver hresult(struct*; dword);" & _ + "Drop hresult(ptr; struct*; dword);" & _ + "Show hresult(bool);" diff --git a/lib/SharedFunctions.au3 b/lib/SharedFunctions.au3 new file mode 100644 index 0000000..0752669 --- /dev/null +++ b/lib/SharedFunctions.au3 @@ -0,0 +1,235 @@ +#include-once + +#include +#include +#include + +Global $hKernel32, $hGdi32, $hUser32, $hShlwapi, $hShell32 + +Func __Timer_QueryPerformanceFrequency_mod() + Local $aCall = DllCall($hKernel32, "bool", "QueryPerformanceFrequency", "int64*", 0) + If @error Then Return SetError(@error, @extended, 0) + Return SetExtended($aCall[0], $aCall[1]) +EndFunc ;==>__Timer_QueryPerformanceFrequency_mod + +Func __Timer_QueryPerformanceCounter_mod() + Local $aCall = DllCall($hKernel32, "bool", "QueryPerformanceCounter", "int64*", 0) + If @error Then Return SetError(@error, @extended, -1) + Return SetExtended($aCall[0], $aCall[1]) +EndFunc ;==>__Timer_QueryPerformanceCounter_mod + +Func _Timer_Diff_mod($iTimeStamp) + Return 1000 * (__Timer_QueryPerformanceCounter_mod() - $iTimeStamp) / __Timer_QueryPerformanceFrequency_mod() +EndFunc ;==>_Timer_Diff_mod + +Func _Timer_Init_mod() + Return __Timer_QueryPerformanceCounter_mod() +EndFunc ;==>_Timer_Init_mod + +Func _WinAPI_ReleaseDC_mod($hWnd, $hDC) + Local $aCall = DllCall($hUser32, "int", "ReleaseDC", "hwnd", $hWnd, "handle", $hDC) + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_ReleaseDC_mod + +Func _WinAPI_GetDCEx_mod($hWnd, $hRgn, $iFlags) + Local $aCall = DllCall($hUser32, 'handle', 'GetDCEx', 'hwnd', $hWnd, 'handle', $hRgn, 'dword', $iFlags) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_GetDCEx_mod + +Func _WinAPI_CreateRectRgn_mod($iLeftRect, $iTopRect, $iRightRect, $iBottomRect) + Local $aCall = DllCall($hGdi32, "handle", "CreateRectRgn", "int", $iLeftRect, "int", $iTopRect, "int", $iRightRect, _ + "int", $iBottomRect) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_CreateRectRgn_mod + +Func _WinAPI_OffsetRect_mod(ByRef $tRECT, $iDX, $iDY) + Local $aCall = DllCall($hUser32, 'bool', 'OffsetRect', 'struct*', $tRECT, 'int', $iDX, 'int', $iDY) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_OffsetRect_mod + +Func _WinAPI_GetWindowRect_mod($hWnd) + Local $tRECT = DllStructCreate($tagRECT) + Local $aCall = DllCall($hUser32, "bool", "GetWindowRect", "hwnd", $hWnd, "struct*", $tRECT) + If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0) + + Return $tRECT +EndFunc ;==>_WinAPI_GetWindowRect_mod + +Func _WinAPI_ShellGetFileInfo_mod($sFilePath, $iFlags, $iAttributes, ByRef $tSHFILEINFO) + Local $aCall = DllCall($hShell32, 'dword_ptr', 'SHGetFileInfoW', 'wstr', $sFilePath, 'dword', $iAttributes, _ + 'struct*', $tSHFILEINFO, 'uint', DllStructGetSize($tSHFILEINFO), 'uint', $iFlags) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_ShellGetFileInfo_mod + +Func _WinAPI_GetClientRect_mod($hWnd) + Local $tRECT = DllStructCreate($tagRECT) + Local $aCall = DllCall($hUser32, "bool", "GetClientRect", "hwnd", $hWnd, "struct*", $tRECT) + If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0) + + Return $tRECT +EndFunc ;==>_WinAPI_GetClientRect_mod + +Func _WinAPI_GetWindowLong_mod($hWnd, $iIndex) + Local $sFuncName = "GetWindowLongW" + If @AutoItX64 Then $sFuncName = "GetWindowLongPtrW" + Local $aCall = DllCall($hUser32, "long_ptr", $sFuncName, "hwnd", $hWnd, "int", $iIndex) + If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_GetWindowLong_mod + +Func _WinAPI_DefWindowProc_mod($hWnd, $iMsg, $wParam, $lParam) + Local $aCall = DllCall($hUser32, "lresult", "DefWindowProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, _ + "lparam", $lParam) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_DefWindowProc_mod + +Func _WinAPI_SetLastError_mod($iErrorCode, Const $_iCallerError = @error, Const $_iCallerExtended = @extended) + DllCall($hKernel32, "none", "SetLastError", "dword", $iErrorCode) + Return SetError($_iCallerError, $_iCallerExtended, Null) +EndFunc ;==>_WinAPI_SetLastError_mod + +Func _WinAPI_SetWindowLong_mod($hWnd, $iIndex, $iValue) + _WinAPI_SetLastError_mod(0) ; as suggested in MSDN + Local $sFuncName = "SetWindowLongW" + If @AutoItX64 Then $sFuncName = "SetWindowLongPtrW" + Local $aCall = DllCall($hUser32, "long_ptr", $sFuncName, "hwnd", $hWnd, "int", $iIndex, "long_ptr", $iValue) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_SetWindowLong_mod + +Func _WinAPI_SetWindowPos_mod($hWnd, $hAfter, $iX, $iY, $iCX, $iCY, $iFlags) + Local $aCall = DllCall($hUser32, "bool", "SetWindowPos", "hwnd", $hWnd, "hwnd", $hAfter, "int", $iX, "int", $iY, _ + "int", $iCX, "int", $iCY, "uint", $iFlags) + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_SetWindowPos_mod + +Func _WinAPI_DrawText_mod($hDC, $sText, ByRef $tRECT, $iFlags) + Local $aCall = DllCall($hUser32, "int", "DrawTextW", "handle", $hDC, "wstr", $sText, "int", -1, "struct*", $tRECT, _ + "uint", $iFlags) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_DrawText_mod + +Func _WinAPI_SetBkColor_mod($hDC, $iColor) + Local $aCall = DllCall($hGdi32, "INT", "SetBkColor", "handle", $hDC, "INT", $iColor) + If @error Then Return SetError(@error, @extended, -1) + + Return $aCall[0] +EndFunc ;==>_WinAPI_SetBkColor_mod + +Func _WinAPI_DeleteObject_mod($hObject) + Local $aCall = DllCall($hGdi32, "bool", "DeleteObject", "handle", $hObject) + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_DeleteObject_mod + +Func _WinAPI_InflateRect_mod(ByRef $tRECT, $iDX, $iDY) + Local $aCall = DllCall($hUser32, 'bool', 'InflateRect', 'struct*', $tRECT, 'int', $iDX, 'int', $iDY) + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_InflateRect_mod + +Func _WinAPI_FillRect_mod($hDC, $tRECT, $hBrush) + Local $aCall + If IsPtr($hBrush) Then + $aCall = DllCall($hUser32, "int", "FillRect", "handle", $hDC, "struct*", $tRECT, "handle", $hBrush) + Else + $aCall = DllCall($hUser32, "int", "FillRect", "handle", $hDC, "struct*", $tRECT, "dword_ptr", $hBrush) + EndIf + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_FillRect_mod + +Func _WinAPI_CreateSolidBrush_mod($iColor) + Local $aCall = DllCall($hGdi32, "handle", "CreateSolidBrush", "INT", $iColor) + If @error Then Return SetError(@error, @extended, 0) + + Return $aCall[0] +EndFunc ;==>_WinAPI_CreateSolidBrush_mod + +Func _WinAPI_GetClassName_mod($hWnd) + If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) + Local $aCall = DllCall($hUser32, "int", "GetClassNameW", "hwnd", $hWnd, "wstr", "", "int", 4096) + If @error Or Not $aCall[0] Then Return SetError(@error, @extended, '') + + Return SetExtended($aCall[0], $aCall[2]) +EndFunc ;==>_WinAPI_GetClassName_mod + +Func _WinAPI_SetTextColor_mod($hDC, $iColor) + Local $aCall = DllCall($hGdi32, "INT", "SetTextColor", "handle", $hDC, "INT", $iColor) + If @error Then Return SetError(@error, @extended, -1) + + Return $aCall[0] +EndFunc ;==>_WinAPI_SetTextColor_mod + +Func _WinAPI_PathIsRoot_mod($sFilePath) + Local $aCall = DllCall($hShlwapi, 'bool', 'PathIsRootW', 'wstr', $sFilePath & "\") + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_PathIsRoot_mod + +Func _WinAPI_ScreenToClient_mod($hWnd, ByRef $tPoint) + Local $aCall = DllCall($hUser32, "bool", "ScreenToClient", "hwnd", $hWnd, "struct*", $tPoint) + If @error Then Return SetError(@error, @extended, False) + + Return $aCall[0] +EndFunc ;==>_WinAPI_ScreenToClient_mod + +Func TreeItemToPath($hTree, $hItem, $bArray = False) + Local $sPath = StringReplace(_GUICtrlTreeView_GetTree($hTree, $hItem), "|", "\") + $sPath = StringTrimLeft($sPath, StringInStr($sPath, "\")) ; remove this pc at the beginning + If StringInStr(FileGetAttrib($sPath), "D") Then $sPath &= "\" ; let folders end with \ + If $bArray Then + Local $aPath = _ArrayFromString($sPath) + _ArrayInsert($aPath, 0, 1) + Return $aPath + EndIf + Return $sPath +EndFunc ;==>TreeItemToPath + +Func _PathSplit_mod($sFilePath) + Local $sDrive = "", $sDir = "", $sFileName = "", $sExtension = "" + Local $aArray = StringRegExp($sFilePath, "^\h*((?:\\\\\?\\)*(\\\\[^\?\/\\]+|[A-Za-z]:)?(.*[\/\\]\h*)?((?:[^\.\/\\]|(?(?=\.[^\/\\]*\.)\.))*)?([^\/\\]*))$", $STR_REGEXPARRAYMATCH) + If @error Then ; This error should never happen. + ReDim $aArray[5] + $aArray[$PATH_ORIGINAL] = $sFilePath + EndIf + $sDrive = $aArray[$PATH_DRIVE] + If StringLeft($aArray[$PATH_DIRECTORY], 1) == "/" Then + $sDir = StringRegExpReplace($aArray[$PATH_DIRECTORY], "\h*[\/\\]+\h*", "\/") + Else + $sDir = StringRegExpReplace($aArray[$PATH_DIRECTORY], "\h*[\/\\]+\h*", "\\") + EndIf + $aArray[$PATH_DIRECTORY] = $sDir + $sFileName = $aArray[$PATH_FILENAME] + $sExtension = $aArray[$PATH_EXTENSION] + + Return $aArray +EndFunc ;==>_PathSplit_mod + +Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") + Local $ret = DllCall($hUser32, "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) + If @error Or Not IsArray($ret) Then Return 0 + Return $ret[0] +EndFunc diff --git a/lib/TreeListExplorer.au3 b/lib/TreeListExplorer.au3 index f54b89e..a6c6401 100644 --- a/lib/TreeListExplorer.au3 +++ b/lib/TreeListExplorer.au3 @@ -1,17 +1,18 @@ #include-once -#include -#include -#include -#include -#include -#include #include #include -#include #include -#include -#Include +#include +#include +#include +#include +#include #include +#Include +#include +#include +#include +#include ; #INDEX# ======================================================================================================================= ; Title .........: TreeListExplorer @@ -20,7 +21,7 @@ ; Description ...: UDF to use a Listview or Treeview as a File/Folder Explorer ; Author(s) .....: Kanashius ; Special Thanks.: WildByDesign for testing this UDF a lot and helping me to make it better -; Version .......: 2.12 +; Version .......: 2.13 ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== @@ -30,10 +31,14 @@ ; __TreeListExplorer_CreateSystem ; __TreeListExplorer_DeleteSystem ; __TreeListExplorer_AddView +; __TreeListExplorer_SetViewIconSize +; __TreeListExplorer_FileGetIconBitmap +; __TreeListExplorer_ComboSetDropDownHeight ; __TreeListExplorer_SetCallback ; __TreeListExplorer_RemoveView ; __TreeListExplorer_OpenPath ; __TreeListExplorer_Reload +; __TreeListExplorer_ReloadView ; __TreeListExplorer_GetPath ; __TreeListExplorer_GetRoot ; __TreeListExplorer_GetSelected @@ -57,6 +62,7 @@ ; __TreeListExplorer__FileGetIconIndex ; __TreeListExplorer__ExpandTreeitem ; __TreeListExplorer__UpdateTreeItemContent +; __TreeListExplorer__TreeViewGetTree ; __TreeListExplorer__GetTreeViewItemDepth ; __TreeListExplorer__UpdateTreeItemExpandable ; __TreeListExplorer__GetDrives @@ -94,9 +100,15 @@ Global $__TreeListExplorer_Callback_ListViewPaths = 32 ; =============================================================================================================================== ; #INTERNAL_USE_ONLY GLOBAL CONSTANTS # ========================================================================================= -Global $__TreeListExplorer__Type_TreeView = 1, $__TreeListExplorer__Type_ListView = 2, $__TreeListExplorer__Type_Input = 3 -Global $__TreeListExplorer__Status_UpdateView = 1, $__TreeListExplorer__Status_ExpandTree = 2 -Global $__TreeListExplorer__Status_LoadTree = 4, $__TreeListExplorer__Status_WaitOpenPath = 8 +Global Const $__TreeListExplorer__Type_TreeView = 1, $__TreeListExplorer__Type_ListView = 2, $__TreeListExplorer__Type_Input = 4 +Global Const $__TreeListExplorer__Type_Combo = 8, $__TreeListExplorer__Type_ComboEx = 16 +Global Const $__TreeListExplorer__Status_UpdateView = 1, $__TreeListExplorer__Status_ExpandTree = 2 +Global Const $__TreeListExplorer__Status_LoadTree = 4, $__TreeListExplorer__Status_WaitOpenPath = 8 +Global Const $__TreeListExplorer__Icon_Folder = "FOLDER", $__TreeListExplorer__Icon_File = "FILE", $__TreeListExplorer__Icon_Disc = "DISC" +Global Const $__TreeListExplorer__Icon_ChangeableInput = "CHANGEABLE", $__TreeListExplorer__Icon_Harddrive = "HARDDRIVE" +Global Const $__TreeListExplorer__Icon_CDROM = "CDROM", $__TreeListExplorer__Icon_Networkdrive = "NETWORKDRIVE" +Global Const $__TreeListExplorer__Icon_Unknown = "UNKNOWN", $__TreeListExplorer__Icon_This_PC = "THISPC" +Global Const $__TreeListExplorer__Icon_Dummy = "DUMMY" ; =============================================================================================================================== ; #INTERNAL_USE_ONLY GLOBAL VARIABLES # ========================================================================================= @@ -106,9 +118,8 @@ Global $__TreeListExplorer__Data[] ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_StartUp ; Description ...: StartUp of the TLE UDF initializing required variables. Must be called before using other UDF functions. -; Syntax ........: __TreeListExplorer_StartUp([$iLang = $__TreeListExplorer_Lang_EN[, $iIconSize = 16]]) +; Syntax ........: __TreeListExplorer_StartUp([$iLang = $__TreeListExplorer_Lang_EN]) ; Parameters ....: $iLang - [optional] an integer to set the language ($__TreeListExplorer_Lang_EN, $__TreeListExplorer_Lang_DE). Default is $__TreeListExplorer_Lang_EN. -; $iIconSize - [optional] the size for icons in the Tree-/ListView. Default is 16. ; Return values .: True on success. ; Author ........: Kanashius ; Modified ......: @@ -118,38 +129,21 @@ Global $__TreeListExplorer__Data[] ; and create the $__TreeListExplorer_Lang_?? variable. ; ; Errors: -; 1 - Parameter not valid (@extended: 1 - $iLang, 2 - $iIconSize) +; 1 - Parameter not valid (@extended: 1 - $iLang) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== -Func __TreeListExplorer_StartUp($iLang = $__TreeListExplorer_Lang_EN, $iIconSize = 16) +Func __TreeListExplorer_StartUp($iLang = $__TreeListExplorer_Lang_EN) Local $arLangData = [["Filename", "Size", "Date created", "This PC"], _ ["Dateiname", "Größe", "Erstelldatum", "Dieser PC"]] If Not IsInt($iLang) Or $iLang<0 Or $iLang>UBound($arLangData)-1 Then Return SetError(1, 1, False) - If Not IsInt($iIconSize) Or $iIconSize<0 Then Return SetError(1, 2, False) $__TreeListExplorer__Data.iDoubleClickTime = 500 Local $arDoubleClickTime = DllCall('user32.dll', 'uint', 'GetDoubleClickTime') If Not @error And UBound($arDoubleClickTime)>0 And IsInt($arDoubleClickTime[0]) Then $__TreeListExplorer__Data.iDoubleClickTime = $arDoubleClickTime[0] - $__TreeListExplorer__Data.iIconSize = $iIconSize _GDIPlus_Startup() - Local $hImageList = _GUIImageList_Create($iIconSize, $iIconSize, 5, 1) - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 3) ; Folder-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 110) ; Folder-Icon checked - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 0) ; File-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 5) ; Disc-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 7) ; Changeableinput-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 8) ; Harddrive-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 11) ; CDROM-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 12) ; Networkdrive-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 53) ; Unknown-Icon - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 15) ; This PC - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 109) ; Dummy element (Crossed O) - _GUIImageList_AddIcon($hImageList, 'shell32.dll', 305) ; Dummy element (Crossed O) - $__TreeListExplorer__Data.iCustomIconsStartIndex = _GUIImageList_GetImageCount($hImageList) - $__TreeListExplorer__Data.hIconList = $hImageList Local $mIcons[] $__TreeListExplorer__Data.mIcons = $mIcons Local $mSystems[] @@ -170,34 +164,6 @@ Func __TreeListExplorer_StartUp($iLang = $__TreeListExplorer_Lang_EN, $iIconSize Return True EndFunc -; #INTERNAL_USE_ONLY# =========================================================================================================== -; Name ..........: __TreeListExplorer_FreeIconCache -; Description ...: Removes all cached icons for all extensions or files -; Syntax ........: __TreeListExplorer_FreeIconCache() -; Parameters ....: -; Return values .: None -; Author ........: Kanashius -; Modified ......: -; Remarks .......: -; Related .......: -; Link ..........: -; Example .......: No -; =============================================================================================================================== -Func __TreeListExplorer_FreeIconCache() - Local $hImageList = $__TreeListExplorer__Data.hIconList, $iCustomIndex = $__TreeListExplorer__Data.iCustomIconsStartIndex - While _GUIImageList_GetImageCount($hImageList)>$iCustomIndex - Local $hIcon = _GUIImageList_GetIcon($hImageList, $iCustomIndex) - _GUIImageList_Remove($hImageList, $iCustomIndex) - _GUIImageList_DestroyIcon($hIcon) - WEnd - Local $mEmpty[] - $__TreeListExplorer__Data["mIcons"] = $mEmpty - Local $arSystemKeys = MapKeys($__TreeListExplorer__Data.mSystems) - For $i=0 To UBound($arSystemKeys)-1 Step 1 - __TreeListExplorer_Reload(__TreeListExplorer__GetHandleFromSystemID($arSystemKeys[$i]), True) - Next -EndFunc - ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_Shutdown ; Description ...: Shutdown of the TLE UDF. Must be called before closing the program. If not called, the program may not exit. @@ -219,11 +185,10 @@ Func __TreeListExplorer_Shutdown() DllCallbackFree($__TreeListExplorer__Data.hProc) _WinAPI_UnhookWindowsHookEx($__TreeListExplorer__Data.hKeyPrevHook) DllCallbackFree($__TreeListExplorer__Data.hKeyProc) - _GUIImageList_Destroy($__TreeListExplorer__Data.hIconList) + __TreeListExplorer_FreeIconCache(Default, False) Local $mMap[] $__TreeListExplorer__Data = $mMap _GDIPlus_Shutdown() - __TreeListExplorer_FreeIconCache() Return True EndFunc @@ -342,25 +307,27 @@ EndFunc ; Description ...: Add a view (TreeView/ListView) to a TLE system. ; Syntax ........: __TreeListExplorer_AddView($hSystem, $hView, [$bShowFolders = Default, [$bShowFiles = Default, [$bNavigation = True, [$bListViewFolderUp = True, [$iLineNumber = @ScriptLineNumber]]]]]) ; Parameters ....: $hSystem - the system handle. -; $hView - the view to add (must be a TreeView or ListView). +; $hView - the view to add (must be a TreeView, ListView, Input or ComboBoxEx). ; $bShowFolders - [optional] a boolean defining, if folders will be shown in the view. Default depends on the view type (see remarks). ; $bShowFiles - [optional] a boolean defining, if files will be shown in the view. Default depends on the view type (see remarks). -; $bNavigation - [optional] boolean. Default is True. If False, the view cannot be used to navigate folders. (ListViews only) -; $bListViewFolderUp - [optional] boolean. Default is True. If False, the view wil not have the ".." folder at the top to go to the parent directory. (ListViews only) -; $bLVDefaultColumns - [optional] boolean. Default is True. If True, the default columns for the listview will be created. (ListViews only) -; $bEnableSorting - [optional] boolean. Default is True. If True, simple sorting is enabled for the ListView, where clicking at the header sorts by that column. (ListViews only) +; $bNavigation - [optional] boolean. Default is True. If False, the view cannot be used to navigate folders. (ListView only) +; $bListViewFolderUp - [optional] boolean. Default is True. If False, the view wil not have the ".." folder at the top to go to the parent directory. (ListView only) +; $bLVDefaultColumns - [optional] boolean. Default is True. If True, the default columns for the listview will be created. (ListView only) +; $bEnableSorting - [optional] boolean. Default is True. If True, simple sorting is enabled for the ListView, where clicking at the header sorts by that column. (ListView/ComboBox) ; $iLineNumber - [optional] an integer value. Default is @ScriptLineNumber. (should not be changed) ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: -; Remarks .......: Default for $bShowFolders is True for TreeViews and ListViews, False for Inputs. +; Remarks .......: Default for $bShowFolders is True (TreeView, ListView, ComboBoxEx) and False (Input). ; -; Default for $bShowFiles is True for ListViews and False for TreeViews and Inputs. +; Default for $bShowFiles is True (ListView, ComboBoxEx) and False (TreeView, Input). ; ; Additional functionality can be accomplished using callbacks (click detection/handle loading/filtering/custom columns/sorting/...). ; See __TreeListExplorer_SetCallback for further information. ; ; $bEnableSorting only allows for simple sorting. To sort by yourself, you can use the $__TreeListExplorer_Callback_ListViewPaths callback (see __TreeListExplorer_SetCallback). +; The ComboBoxEx uses the same sorting method as the ListView, so if it is enabled, it is sorted by name (with folders at the top). +; The $__TreeListExplorer_Callback_ListViewPaths callback can be set for the ComboBoxEx as well. ; ; Errors: ; 1 - $hSystem is not a valid TLE system @@ -387,6 +354,10 @@ Func __TreeListExplorer_AddView($hSystem, $hView, $bShowFolders = Default, $bSho $iType = $__TreeListExplorer__Type_ListView ElseIf StringInStr($sClass, "Edit") And (Not BitAND(_WinAPI_GetWindowLong($hView, $GWL_STYLE), $ES_MULTILINE)) Then ; check if control is input $iType = $__TreeListExplorer__Type_Input + ElseIf StringInStr($sClass, "ComboBoxEx") Then + $iType = $__TreeListExplorer__Type_ComboEx + ElseIf StringInStr($sClass, "ComboBox") Then + $iType = $__TreeListExplorer__Type_Combo Else Return SetError(2, 50, False) ; $hView is not a valid control (wrong control type) EndIf @@ -404,11 +375,11 @@ Func __TreeListExplorer_AddView($hSystem, $hView, $bShowFolders = Default, $bSho Case $__TreeListExplorer__Type_TreeView If $bShowFolders = Default Then $bShowFolders=True If $bShowFiles = Default Then $bShowFiles=False - _GUICtrlTreeView_SetNormalImageList($hView, $__TreeListExplorer__Data.hIconList) + _GUICtrlTreeView_DeleteAll($hView) Case $__TreeListExplorer__Type_ListView If $bShowFolders = Default Then $bShowFolders=True If $bShowFiles = Default Then $bShowFiles=True - _GUICtrlListView_SetImageList($hView, $__TreeListExplorer__Data.hIconList, 1) + _GUICtrlListView_DeleteAllItems($hView) _GUICtrlListView_SetExtendedListViewStyle($hView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES)) Local $iListWidth = _WinAPI_GetWindowWidth($hView) If $bLVDefaultColumns Then @@ -425,6 +396,14 @@ Func __TreeListExplorer_AddView($hSystem, $hView, $bShowFolders = Default, $bSho $bShowFolders=False $bShowFiles=False GUICtrlSetData($hView, "") + Case $__TreeListExplorer__Type_Combo + $bShowFolders=True + $bShowFiles=True + _GUICtrlComboBox_ResetContent($hView) + Case $__TreeListExplorer__Type_ComboEx + $bShowFolders=True + $bShowFiles=True + _GUICtrlComboBoxEx_ResetContent($hView) EndSwitch Local $mView[] $mView.hWnd = $hView @@ -437,13 +416,7 @@ Func __TreeListExplorer_AddView($hSystem, $hView, $bShowFolders = Default, $bSho $mView.sSelected = -1 $mView.iUpdating = 0 $mView.iPathIndex = 0 - $mView.bNavigation = $bNavigation - $mView.bListViewFolderUp = $bListViewFolderUp - Local $mSorting[] - $mSorting.bEnabled = $bEnableSorting - $mSorting.iCol = $mView.iPathIndex - $mSorting.iDir = 0 ; 0 ASC, 1 DESC - $mView.mSorting = $mSorting + $mView.iIconSize = -1 $mView.sCallbackClick = Default $mView.sCallbackDoubleClick = Default $mView.sCallbackLoading = Default @@ -451,12 +424,303 @@ Func __TreeListExplorer_AddView($hSystem, $hView, $bShowFolders = Default, $bSho $mView.sCallbackListViewItemCreated = Default $mView.sCallbackListViewPaths = Default $mView.iLineNumber = $iLineNumber + Local $bAddSortingEntries = False + Switch $iType + Case $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx + $mView.iComboListHeight = 100 + Local $hCombo = $hView + If $iType = $__TreeListExplorer__Type_ComboEx Then $hCombo = _GUICtrlComboBoxEx_GetComboControl($hView) + Local $tInfo + _GUICtrlComboBox_GetComboBoxInfo($hCombo, $tInfo) + $mView.hCombo = DllStructGetData($tInfo, "hCombo") + $mView.hComboEdit = DllStructGetData($tInfo, "hEdit") + If $iType = $__TreeListExplorer__Type_ComboEx Then $mView.hComboEdit = _GUICtrlComboBoxEx_GetEditControl($hView) + $mView.hComboList = DllStructGetData($tInfo, "hList") + $bAddSortingEntries = True + Case $__TreeListExplorer__Type_ListView + $mView.bNavigation = $bNavigation + $mView.bListViewFolderUp = $bListViewFolderUp + $bAddSortingEntries = True + EndSwitch + If $bAddSortingEntries Then + Local $mSorting[] + $mSorting.bEnabled = $bEnableSorting + $mSorting.iCol = $mView.iPathIndex + $mSorting.iDir = 0 ; 0 ASC, 1 DESC + $mView.mSorting = $mSorting + EndIf $__TreeListExplorer__Data["mViews"][$hView] = $mView $__TreeListExplorer__Data["mSystems"][$iSystem]["mViews"][$hView] = 1 - __TreeListExplorer__UpdateView($hView) + __TreeListExplorer_SetViewIconSize($hView) ; includes __TreeListExplorer__UpdateView + If @error Then __TreeListExplorer__UpdateView($hView, True) + Return True +EndFunc + + +; #FUNCTION# ==================================================================================================================== +; Name ..........: __TreeListExplorer_SetViewIconSize +; Description ...: Set the icon size for the Tree-/ListView. +; Syntax ........: __TreeListExplorer_SetViewIconSize($hView[, $iIconSize = 16]) +; Parameters ....: $hView - the view where the callback should be added to (must be a TreeView, ListView or ComboBoxEx). +; $iIconSize - (optional) the desired icon size. Default: 16. +; Return values .: True on success +; Author ........: Kanashius +; Modified ......: +; Remarks .......: Errors: +; 1 - Parameter is invalid (@extended 1 - $hView, 2 - $iIconSize) +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func __TreeListExplorer_SetViewIconSize($hView, $iIconSize = 16) + If Not IsHWnd($hView) Then + $hView = GUICtrlGetHandle($hView) + If @error Then Return SetError(2, @error, False) ; $hView is not a control + EndIf + If Not IsHWnd($hView) Or Not MapExists($__TreeListExplorer__Data.mViews, $hView) Then Return SetError(1, 1, False) + If $__TreeListExplorer__Data.mViews[$hView].iType=$__TreeListExplorer__Type_Input Or $__TreeListExplorer__Data.mViews[$hView].iType=$__TreeListExplorer__Type_Combo Then Return SetError(1, 1, False) ; inputs and normal combo boxes cannot have icons + If Not IsInt($iIconSize) Then Return SetError(1, 2, False) + If $__TreeListExplorer__Data["mViews"][$hView]["iIconSize"]<>$iIconSize Then + Local $iIconSizeBefore = $__TreeListExplorer__Data["mViews"][$hView]["iIconSize"] + $__TreeListExplorer__Data["mViews"][$hView]["iIconSize"] = $iIconSize + If Not MapExists($__TreeListExplorer__Data.mIcons, $iIconSize) Then + Local $mIcon[], $mCache[], $mViews[] + $mIcon["hList"] = _GUIImageList_Create($iIconSize, $iIconSize, 5, 1, 12) + $mCache[$__TreeListExplorer__Icon_File] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 0, True) + $mCache[$__TreeListExplorer__Icon_Folder] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 3, True) + $mCache[$__TreeListExplorer__Icon_Disc] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 5, True) + $mCache[$__TreeListExplorer__Icon_ChangeableInput] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 7, True) + $mCache[$__TreeListExplorer__Icon_Harddrive] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 8, True) + $mCache[$__TreeListExplorer__Icon_CDROM] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 11, True) + $mCache[$__TreeListExplorer__Icon_Networkdrive] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 12, True) + $mCache[$__TreeListExplorer__Icon_Unknown] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 53, True) + $mCache[$__TreeListExplorer__Icon_This_PC] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 15, True) + $mCache[$__TreeListExplorer__Icon_Dummy] = _GUIImageList_AddIcon($mIcon.hList, "shell32.dll", 109, True) + $mIcon["mCache"] = $mCache + $mViews[$hView] = 1 + $mIcon["mViews"] = $mViews + $__TreeListExplorer__Data["mIcons"][$iIconSize] = $mIcon + Else + $__TreeListExplorer__Data["mIcons"][$iIconSize]["mViews"][$hView] = 1 + EndIf + Switch $__TreeListExplorer__Data.mViews[$hView].iType + Case $__TreeListExplorer__Type_TreeView + _GUICtrlTreeView_SetNormalImageList($hView, $__TreeListExplorer__Data.mIcons[$iIconSize].hList) + _GUICtrlTreeView_SetIndent($hView, $iIconSize+4) + Case $__TreeListExplorer__Type_ListView + _GUICtrlListView_SetImageList($hView, $__TreeListExplorer__Data.mIcons[$iIconSize].hList, 0) + _GUICtrlListView_SetImageList($hView, $__TreeListExplorer__Data.mIcons[$iIconSize].hList, 1) + Case $__TreeListExplorer__Type_ComboEx + _GUICtrlComboBoxEx_SetImageList($hView, $__TreeListExplorer__Data.mIcons[$iIconSize].hList) + Case Else + ConsoleWrite("Control does not support an icon size."&@crlf) + EndSwitch + If $iIconSizeBefore<>-1 And MapExists($__TreeListExplorer__Data.mIcons, $iIconSizeBefore) Then ; MapExists crashes with $iIconSizeBefore = -1 for some reason... + MapRemove($__TreeListExplorer__Data.mIcons[$iIconSizeBefore]["mViews"], $hView) + If UBound(MapKeys($__TreeListExplorer__Data.mIcons[$iIconSizeBefore]["mViews"]))<=0 Then __TreeListExplorer_FreeIconCache($iIconSizeBefore, False) + EndIf + __TreeListExplorer_ReloadView($hView, True) + EndIf + Return True +EndFunc + +; #FUNCTION# ==================================================================================================================== +; Name ..........: __TreeListExplorer_FileGetIconBitmap +; Description ...: Get the bitmap of an icon for a file. (May need to be converted to a HBitmap to use in _GUIImageList.) +; Syntax ........: __TreeListExplorer_FileGetIconBitmap($sPath[, $iSize = Default[, $sExt = Default]]) +; Parameters ....: $sPath - the absolute path. +; $iIconSize - (optional) the desired size of the icon. +; Default: If $hView is provided the size for that control is used, 16 otherwise. +; $sExt - (optional) if Default the extension will be parsed from $sPath. (Ignored for folder/drive paths) +; Return values .: The bitmap +; Author ........: Kanashius +; Modified ......: +; Remarks .......: Errors: +; 1 - Invalid parameter (@extended 2 - $iIconSize) +; 2 - Bitmap could not be found/created/... +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func __TreeListExplorer_FileGetIconBitmap($sPath, $iIconSize = Default, $sExt = Default) + If Not ($iIconSize<>Default Or IsInt($iIconSize)) Then Return SetError(1, 2, 0) + Local $sIconPath = -1, $iIconIndex = 0, $bAddForExtension = False + ; check for drives + Local $arRegExpDrive = StringRegExp($sPath, "^([^\/]+?:)\/*$", 1) + If UBound($arRegExpDrive)>0 Then + $sIconPath = "shell32.dll" + $iIconIndex = __TreeListExplorer__GetDriveIconId($arRegExpDrive[0]) + EndIf + ; check for folders (would also match drives) + If __TreeListExplorer__PathIsFolder($sPath) Then + $sIconPath = "shell32.dll" + $iIconIndex = 3 ; Default folder icon + EndIf + If $sIconPath=-1 And $sExt=Default Then + Local $arExt = StringRegExp($sPath, "^.*[^\\](\.[^\\]*?)$", 1) + If Not (@error Or UBound($arExt)<>1) Then $sExt = StringLower($arExt[0]) + EndIf + If $sIconPath=-1 Then + ; Handling for special extensions + Switch $sExt + Case ".exe" + $sIconPath = $sPath + Case ".url" + $sIconPath = IniRead($sPath, "InternetShortcut", "IconFile", -1) + $iIconIndex = IniRead($sPath, "InternetShortcut", "IconIndex", -1) + Case ".lnk" ; todo add the link symbol (arrow) to the icon + Local $arShortcutData = FileGetShortcut($sPath) + If $arShortcutData[4]<>"" Then ; icon file provided + $sIconPath = $arShortcutData[4] + $iIconIndex = $arShortcutData[5] + Else ; otherwise get icon from the linked path + Return __TreeListExplorer_FileGetIconBitmap($arShortcutData[0], $iIconSize) + EndIf + EndSwitch + EndIf + If $sIconPath=-1 Then + Local $sRegData = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt, "ProgID") + If @error Then + $sRegData = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt & "\UserChoice", "ProgID") + If @error Then + $sRegData = RegRead("HKCR\" & $sExt, "") + EndIf + EndIf + If $sRegData<>"" Then $sRegData = RegRead("HKCR\" & $sRegData & "\DefaultIcon", "") + If $sRegData="" Then $sRegData = _WinAPI_AssocQueryString($sExt, $ASSOCSTR_DEFAULTICON) + If StringInStr($sRegData, "@")=1 Then ; Handle urls with @{...} + Local $sIconPath = _WinAPI_LoadIndirectString($sRegData) + If @error Then $sIconPath = -1 + Local $arRes = StringRegExp($sIconPath, "^(.*\\)(.*-)(\d+)(\.\S+)$", 1) + If Not (@error And UBound($arRes)<>4) Then ; check for files with a pixel resolution closer to $iIconSize + Local $arFiles = _FileListToArray($arRes[0], $arRes[1]&"*"&$arRes[3]) + Local $arOptions[UBound($arFiles)-1][2], $iCount = 0 + For $i=1 To UBound($arFiles)-1 Step 1 ; get icon size for all files + Local $arFileParts = StringRegExp($arFiles[$i], "^.*-(\d+)\.\S+$", 1) + If Not @error Then + $arOptions[$iCount][0] = Int($arFileParts[0]) + $arOptions[$iCount][1] = $arFiles[$i] + $iCount+=1 + EndIf + Next + ReDim $arOptions[$iCount][2] + _ArraySort($arOptions) ; sort by size + For $i=0 To UBound($arOptions)-1 Step 1 ; take the best icon to be used (>= target icon size); Resize will be done later + If $iIconSize<=$arOptions[$i][0] Then + $sIconPath = $arRes[0]&$arOptions[$i][1] + ExitLoop + EndIf + Next + EndIf + ElseIf StringInStr($sRegData, ",") Then ; Handle , e.g.: ...shell32.dll, 0 + Local $arParts = StringRegExp($sRegData, '"?(.*?)"?,(-?\d+)', 1) + If UBound($arParts)=2 Then + $sIconPath = $arParts[0] + $iIconIndex = $arParts[1] + EndIf + ElseIf $sRegData<>"" Then ; Handle path without index + $sIconPath = $sRegData + EndIf + $bAddForExtension = True + EndIf + Local $hBitmap = 0 + If $sIconPath=-1 Then + Local $tSHFILEINFO = DllStructCreate($tagSHFILEINFO) + Local $dwFlags = BitOR($SHGFI_USEFILEATTRIBUTES, $SHGFI_ICON, $SHGFI_LARGEICON) ; $SHGFI_ICON + _WinAPI_ShellGetFileInfo($sPath, $dwFlags, $FILE_ATTRIBUTE_NORMAL, $tSHFILEINFO) + If DllStructGetData($tSHFILEINFO, 1)>0 Then + Local $hIcon = _WinAPI_Create32BitHICON(DllStructGetData($tSHFILEINFO, 1)) + _WinAPI_DestroyIcon(DllStructGetData($tSHFILEINFO, 1)) + $hBitmap = _GDIPlus_BitmapCreateFromHICON($hIcon) + _WinAPI_DestroyIcon($hIcon) + EndIf + EndIf + If $sIconPath<>-1 Or $hBitmap<>0 Then + Local $sIconExt = StringRight($sIconPath, 4) + If $hBitmap=0 And ($sIconExt=".dll" Or $sIconExt=".exe" Or $sIconExt=".ico") Then ; icon to extract + Local $hIcon = _WinAPI_ShellExtractIcon($sIconPath, $iIconIndex, $iIconSize, $iIconSize) + Local $hBitmap = _GDIPlus_BitmapCreateFromHICON($hIcon) + _WinAPI_DestroyIcon($hIcon) + If $hIcon<>0 Then Return $hBitmap + Else ; normal image file + If $hBitmap=0 Then $hBitmap = _GDIPlus_BitmapCreateFromFile($sIconPath) + If $hBitmap<>0 Then + ; todo check size to only scale up + Local $hBitmapResized = _GDIPlus_ImageResize($hBitmap, $iIconSize, $iIconSize) + _GDIPlus_BitmapDispose($hBitmap) + Return $hBitmapResized + EndIf + EndIf + EndIf + Local $hIcon = _WinAPI_ShellExtractIcon("shell32.dll", 0, $iIconSize, $iIconSize) ; Default file icon + If $hIcon<>0 Then Return SetExtended(1, _GDIPlus_BitmapCreateFromHICON($hIcon)) + Return SetError(2, 0, 0) +EndFunc + +; #FUNCTION# ==================================================================================================================== +; Name ..........: __TreeListExplorer_ComboSetDropDownHeight +; Description ...: Set the height of the drop down list of a comboboxex control. +; Syntax ........: __TreeListExplorer_ComboSetDropDownHeight($hView[, $iHeight = 100]) +; Parameters ....: $hView - the handle of the control +; $iHeight - (optional) Default: 100. The height in pixel. +; Return values .: True on success, False otherwise +; Author ........: Kanashius +; Modified ......: +; Remarks .......: +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func __TreeListExplorer_ComboSetDropDownHeight($hView, $iHeight = 100) + If Not IsHWnd($hView) Or Not MapExists($__TreeListExplorer__Data.mViews, $hView) Then Return SetError(1, 1, False) + If Not ($__TreeListExplorer__Data.mViews[$hView].iType = $__TreeListExplorer__Type_Combo Or $__TreeListExplorer__Data.mViews[$hView].iType = $__TreeListExplorer__Type_ComboEx) Then Return SetError(1, 1, False) + If Not IsInt($iHeight) Then Return SetError(1, 2, False) + $__TreeListExplorer__Data["mViews"][$hView]["iComboListHeight"] = $iHeight + __TreeListExplorer__UpdateView($hView) ; no force update required; begin/end update is always called Return True EndFunc +; #FUNCTION# ==================================================================================================================== +; Name ..........: __TreeListExplorer_FreeIconCache +; Description ...: Removes cached icons +; Syntax ........: __TreeListExplorer_FreeIconCache($iIconSize[, $bReload = True]) +; Parameters ....: $iIconSize - (optional) Default: Free all IconSizes. If defined, only for that icon size, if it exists. +; $bReload - (optional) Default: True. Reload views using the cache. +; Return values .: None +; Author ........: Kanashius +; Modified ......: +; Remarks .......: +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func __TreeListExplorer_FreeIconCache($iIconSize = Default, $bReload = True) + Local $arFree[0][0] + If $iIconSize=Default Then + For $iIconSize in MapKeys($__TreeListExplorer__Data.mIcons) + _GUIImageList_Destroy($__TreeListExplorer__Data.mIcons[$iIconSize].hList) + Local $arKeys = MapKeys($__TreeListExplorer__Data.mIcons[$iIconSize]["mViews"]) + MapRemove($__TreeListExplorer__Data.mIcons, $iIconSize) + If $bReload Then + For $hView in $arKeys + __TreeListExplorer_ReloadView($hView, True) + Next + EndIf + Next + Else + If MapExists($__TreeListExplorer__Data.mIcons, $iIconSize) Then + _GUIImageList_Destroy($__TreeListExplorer__Data.mIcons[$iIconSize].hList) + Local $arKeys = MapKeys($__TreeListExplorer__Data.mIcons[$iIconSize]["mViews"]) + MapRemove($__TreeListExplorer__Data.mIcons, $iIconSize) + If $bReload Then + For $hView in $arKeys + __TreeListExplorer_ReloadView($hView, True) + Next + EndIf + EndIf + EndIf +EndFunc + ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_SetCallback ; Description ...: Add/Remove a callback to a TLE TreeView/ListView. Allows for click/load handling, filtering, custom columns, sorting,... @@ -565,6 +829,12 @@ Func __TreeListExplorer_RemoveView($hView) Local $iSystem = $mView.iSystem Local $iType = $mView.iType + ; Remove view from icon map + Local $iIconSize = $__TreeListExplorer__Data["mViews"][$hView]["iIconSize"] + If $iIconSize<>-1 And MapExists($__TreeListExplorer__Data.mIcons, $iIconSize) Then + MapRemove($__TreeListExplorer__Data.mIcons[$iIconSize]["mViews"], $hView) + If UBound(MapKeys($__TreeListExplorer__Data.mIcons[$iIconSize]["mViews"]))<=0 Then __TreeListExplorer_FreeIconCache($iIconSize, False) + EndIf ; Remove from maps first, to prevent events (WinProc) from being handled during deletion MapRemove($__TreeListExplorer__Data.mViews, $hView) MapRemove($__TreeListExplorer__Data["mSystems"][$iSystem]["mViews"], $hView) @@ -583,6 +853,15 @@ Func __TreeListExplorer_RemoveView($hView) WEnd _GUICtrlListView_SetImageList($hView, 0) _GUICtrlListView_EndUpdate($hView) + Case $__TreeListExplorer__Type_Combo + _GUICtrlComboBox_BeginUpdate($hView) + _GUICtrlComboBox_ResetContent($hView) + _GUICtrlComboBox_EndUpdate($hView) + Case $__TreeListExplorer__Type_ComboEx + _GUICtrlComboBoxEx_BeginUpdate($hView) + _GUICtrlComboBoxEx_ResetContent($hView) + _GUICtrlComboBoxEx_SetImageList($hView, 0) + _GUICtrlComboBoxEx_EndUpdate($hView) EndSwitch Return True EndFunc @@ -656,6 +935,40 @@ Func __TreeListExplorer_Reload($hSystem, $bAllFoldersOnPath = False) If $bAllFoldersOnPath Then $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadAllFolders"] = False EndFunc +; #FUNCTION# ==================================================================================================================== +; Name ..........: __TreeListExplorer_ReloadView +; Description ...: Reloads the folders and files in all views of the system. +; Syntax ........: __TreeListExplorer_ReloadView($hView[, $bAllFoldersOnPath = False]) +; Parameters ....: $hSystem - the view handle. +; $bAllFoldersOnPath - [optional] if false, only the current folder is reloaded. +; If true, all folders in the view will be reloaded. +; Default is False. +; Return values .: None +; Author ........: Kanashius +; Modified ......: +; Remarks .......: +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func __TreeListExplorer_ReloadView($hView, $bAllFoldersOnPath = False) + If Not IsHWnd($hView) Then + $hView = GUICtrlGetHandle($hView) + If @error Then Return SetError(2, @error, False) ; $hView is not a control + EndIf + If Not IsHWnd($hView) Or Not MapExists($__TreeListExplorer__Data.mViews, $hView) Then Return SetError(1, 0, False) + Local $mView = $__TreeListExplorer__Data.mViews[$hView] + Local $iSystem = $mView.iSystem + + $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadFolder"] = True + If $bAllFoldersOnPath Then $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadAllFolders"] = True + + __TreeListExplorer__UpdateView($hView) + + $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadFolder"] = False + If $bAllFoldersOnPath Then $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadAllFolders"] = False +EndFunc + ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_GetPath ; Description ...: Get the current folder, relative to the root folder. @@ -950,7 +1263,7 @@ EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__UpdateView ; Description ...: Update a view to match a TLE systems root folder and current folder -; Syntax ........: __TreeListExplorer__UpdateView($hView) +; Syntax ........: __TreeListExplorer__UpdateView($hView[, $bReload = False]) ; Parameters ....: $hView - the control handle. ; $bReload - [optional] Default False. Forces a reload. ; Return values .: None @@ -971,6 +1284,10 @@ Func __TreeListExplorer__UpdateView($hView, $bReload = False) _GUICtrlTreeView_BeginUpdate($hView) Case $__TreeListExplorer__Type_ListView _GUICtrlListView_BeginUpdate($hView) + Case $__TreeListExplorer__Type_Combo + _GUICtrlComboBox_BeginUpdate($hView) + Case $__TreeListExplorer__Type_ComboEx + _GUICtrlComboBoxEx_BeginUpdate($hView) EndSwitch ; Root different Local $bRootOrFolderChanged = False @@ -987,14 +1304,15 @@ Func __TreeListExplorer__UpdateView($hView, $bReload = False) _GUICtrlTreeView_DeleteAll($hView) Local $hRoot If $mSystem.sRoot="" Then - $hRoot = _GUICtrlTreeView_Add($hView, 0, $__TreeListExplorer__Data.arLangData[$__TreeListExplorer__Data.iLang][3], 9, 9) ; maybe remove text here + Local $iIconIndex = $__TreeListExplorer__Data.mIcons[$__TreeListExplorer__Data.mViews[$hView].iIconSize].mCache[$__TreeListExplorer__Icon_This_PC] + $hRoot = _GUICtrlTreeView_Add($hView, 0, $__TreeListExplorer__Data.arLangData[$__TreeListExplorer__Data.iLang][3], $iIconIndex, $iIconIndex) ; maybe remove text here Else Local $arPath = __TreeListExplorer__GetPathAndLast($mSystem.sRoot) $hRoot = _GUICtrlTreeView_Add($hView, 0, $arPath[1], 0, 0) EndIf _GUICtrlTreeView_AddChild($hView, $hRoot, "HasChilds", 10, 10) __TreeListExplorer__ExpandTreeitem($hView, $hRoot) - Case $__TreeListExplorer__Type_ListView + Case $__TreeListExplorer__Type_ListView, $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx $bReload = True EndSwitch __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sRoot, False) @@ -1069,16 +1387,24 @@ Func __TreeListExplorer__UpdateView($hView, $bReload = False) __TreeListExplorer__HandleSystemCallback($iSystem, "sCallbackSelect") EndIf __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, False) - Case $__TreeListExplorer__Type_ListView + Case $__TreeListExplorer__Type_ListView, $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx If $bUpdateFolder Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, True) ; clear old data $__TreeListExplorer__Data["mViews"][$hView]["iIndex"] = -1 __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_UpdateView) - _GUICtrlListView_DeleteAllItems($hView) + Switch $mView.iType + Case $__TreeListExplorer__Type_ListView + _GUICtrlListView_DeleteAllItems($hView) + Case $__TreeListExplorer__Type_Combo + _GUICtrlComboBox_ResetContent($hView) + Case $__TreeListExplorer__Type_ComboEx + _GUICtrlComboBoxEx_SetCurSel($hView, -1) + _GUICtrlComboBoxEx_ResetContent($hView) + EndSwitch ; do not display .. folder in root directory,... - If $mSystem.sFolder<>"" And $mView.bNavigation And $mView.bListViewFolderUp Then - _GUICtrlListView_AddItem($hView, "", 0) + If $mView.iType=$__TreeListExplorer__Type_ListView And $mSystem.sFolder<>"" And $mView.bNavigation And $mView.bListViewFolderUp Then + _GUICtrlListView_AddItem($hView, "", $__TreeListExplorer__Data.mIcons[$__TreeListExplorer__Data.mViews[$hView].iIconSize].mCache[$__TreeListExplorer__Icon_Folder]) _GUICtrlListView_SetItemText($hView, 0, "..", $mView.iPathIndex) EndIf ; collect drives/folders/files @@ -1133,11 +1459,12 @@ Func __TreeListExplorer__UpdateView($hView, $bReload = False) Next EndIf ; add entries to listview + If $mView.iType = $__TreeListExplorer__Type_Combo Then _GUICtrlComboBox_InitStorage(UBound($arPaths), 150, 300) + If $mView.iType = $__TreeListExplorer__Type_ComboEx Then _GUICtrlComboBoxEx_InitStorage(UBound($arPaths), 150, 300) For $i=0 to UBound($arPaths)-1 Local $sFile = $arPaths[$i][$mView.iPathIndex] Local $sFilePath = $sPath & $sFile Local $bDriveOrFolder = __TreeListExplorer__PathIsFolder($sFilePath) - Local $iIconIndex = __TreeListExplorer__FileGetIconIndex($sFilePath) Local $sFileName = $sFile, $sExt = "" If Not $bDriveOrFolder Then Local $arFileParts = StringRegExp($sFilename, "^(.+?)(\.[^.]{1,5}){0,1}$", 1) @@ -1148,32 +1475,68 @@ Func __TreeListExplorer__UpdateView($hView, $bReload = False) EndIf If $mView.sCallbackFilter=Default Or __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", True, $sPath, $sFilename, $sExt) Then If UBound($arPaths, 2)>0 Then - Local $iIndex = _GUICtrlListView_AddItem($hView, $arPaths[$i][0], $iIconIndex) - For $j=1 To UBound($arPaths, 2)-1 - _GUICtrlListView_SetItemText($hView, $iIndex, $arPaths[$i][$j], $j) - Next + Switch $mView.iType + Case $__TreeListExplorer__Type_ListView + Local $iIconIndex = __TreeListExplorer__FileGetIconIndex($hView, $sFilePath) + Local $iIndex = _GUICtrlListView_AddItem($hView, $arPaths[$i][0], $iIconIndex) + For $j=1 To UBound($arPaths, 2)-1 + _GUICtrlListView_SetItemText($hView, $iIndex, $arPaths[$i][$j], $j) + Next + Case $__TreeListExplorer__Type_Combo + _GUICtrlComboBox_AddString($hView, $sFile) + Case $__TreeListExplorer__Type_ComboEx + Local $iIconIndex = __TreeListExplorer__FileGetIconIndex($hView, $sFilePath) + _GUICtrlComboBoxEx_AddString($hView, $sFile, $iIconIndex, $iIconIndex) + EndSwitch EndIf If $mView.sCallbackListViewItemCreated<>Default Then __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackListViewItemCreated", $sFilePath, $sFile, $iIndex, $bDriveOrFolder) EndIf Next __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_UpdateView) - __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, False) EndIf If $mSystem.sSelected<>"" Then Local $sSelected = $mSystem.sSelected - For $i=0 To _GUICtrlListView_GetItemCount($hView) - If _GUICtrlListView_GetItemText($hView, $i, $mView.iPathIndex)=$sSelected Then - _GUICtrlListView_EnsureVisible($hView, $i) - Local $arSel = _GUICtrlListView_GetSelectedIndices($hView, True) - For $j=1 To UBound($arSel)-1 Step 1 - _GUICtrlListView_SetItemSelected($hView, $arSel[$j], False) + Switch $mView.iType + Case $__TreeListExplorer__Type_ListView + For $i=0 To _GUICtrlListView_GetItemCount($hView)-1 + If _GUICtrlListView_GetItemText($hView, $i, $mView.iPathIndex)=$sSelected Then + _GUICtrlListView_EnsureVisible($hView, $i) + Local $arSel = _GUICtrlListView_GetSelectedIndices($hView, True) + For $j=1 To UBound($arSel)-1 Step 1 + _GUICtrlListView_SetItemSelected($hView, $arSel[$j], False) + Next + _GUICtrlListView_SetSelectionMark($hView, $i) + _GUICtrlListView_SetItemSelected($hView, $i) + ExitLoop + EndIf Next - _GUICtrlListView_SetSelectionMark($hView, $i) - _GUICtrlListView_SetItemSelected($hView, $i) - ExitLoop - EndIf - Next + Case $__TreeListExplorer__Type_Combo + Local $sText, $iCount = _GUICtrlComboBox_GetCount($hView) + If $iCount>0 Then + For $i=0 to $iCount-1 + _GUICtrlComboBox_GetLBText($hView, $i, $sText) + If $sText=$sSelected Then + _GUICtrlComboBox_SetEditText($hView, $sSelected) + _GUICtrlComboBox_SetCurSel($hView, $i) + ExitLoop + EndIf + Next + EndIf + Case $__TreeListExplorer__Type_ComboEx + Local $sText, $iCount = _GUICtrlComboBoxEx_GetCount($hView) + If $iCount>0 Then + For $i=0 To $iCount-1 + _GUICtrlComboBoxEx_GetItemText($hView, $i, $sText) + If $sText=$sSelected Then + _GUICtrlComboBoxEx_SetEditText($hView, $sSelected) + _GUICtrlComboBoxEx_SetCurSel($hView, $i) + ExitLoop + EndIf + Next + EndIf + EndSwitch EndIf + If $bUpdateFolder Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, False) Case $__TreeListExplorer__Type_Input If $bFolderChanged Then _GUICtrlEdit_SetText($hView, $mSystem.sFolder) EndSwitch @@ -1184,6 +1547,14 @@ Func __TreeListExplorer__UpdateView($hView, $bReload = False) $mView.bUpdating = False Case $__TreeListExplorer__Type_ListView _GUICtrlListView_EndUpdate($hView) + Case $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx + _GUICtrlComboBox_EndUpdate($hView) + Local $arPos = WinGetPos($mView.hComboList) + If $arPos[3]<>$mView.iComboListHeight Then + $arPos[3] = $mView.iComboListHeight + WinMove($mView.hComboList, "", $arPos[0], $arPos[1], $arPos[2], $arPos[3]) + EndIf + _WinAPI_RedrawWindow($hView) EndSwitch EndFunc @@ -1261,9 +1632,10 @@ EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__FileGetIconIndex -; Description ...: Get the index of an icon in $__TreeListExplorer__Data.hIconList for a given extension and add missing icons. -; Syntax ........: __TreeListExplorer__FileGetIconIndex($sPath) +; Description ...: Get the index of an icon for a given path and add missing icons. +; Syntax ........: __TreeListExplorer__FileGetIconIndex($hView, $sPath) ; Parameters ....: $sPath - the absolute path. +; $hView - the handle to the Tree-/ListView. ; Return values .: The index ; Author ........: Kanashius ; Modified ......: @@ -1272,137 +1644,49 @@ EndFunc ; Link ..........: ; Example .......: No ; =============================================================================================================================== -Func __TreeListExplorer__FileGetIconIndex($sPath) - ; test for drive - Local $arRegExpDrive = StringRegExp($sPath, "^([^\/]+?:)\/*$", 1) - If UBound($arRegExpDrive)>0 Then return __TreeListExplorer__GetDriveIconId($arRegExpDrive[0]) - - ; test for folder - If __TreeListExplorer__PathIsFolder($sPath) Then Return 0 ; Default folder icon - - ; extract and handle cached extensions - Local $arExt = StringRegExp($sPath, "^.*[^\\](\.[^\\]*?)$", 1) - If @error Or UBound($arExt)<>1 Then Return 2 ; Default file icon - Local $sExt = StringLower($arExt[0]) - If MapExists($__TreeListExplorer__Data.mIcons, $sExt) Then Return $__TreeListExplorer__Data.mIcons[$sExt] - If MapExists($__TreeListExplorer__Data.mIcons, $sPath) Then Return $__TreeListExplorer__Data.mIcons[$sPath] +Func __TreeListExplorer__FileGetIconIndex($hView, $sPath) + Local $mView = $__TreeListExplorer__Data.mViews[$hView] + Local $iIconSize = $mView.iIconSize - Local $sIconPath = -1, $iIconIndex = 0, $bAddForExtension = False - ; handle .url (links) - If $sExt=".url" Then - $sIconPath = IniRead($sPath, "InternetShortcut", "IconFile", -1) - $iIconIndex = IniRead($sPath, "InternetShortcut", "IconIndex", -1) + ; handle drives + Local $arRegExpDrive = StringRegExp($sPath, "^([^\/]+?:)\/*$", 1) + If UBound($arRegExpDrive)>0 Then + Local $sType = __TreeListExplorer__GetDriveIconId($arRegExpDrive[0], True) + Return $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$sType] EndIf - ; handle .lnk (shortcuts) - If $sExt=".lnk" Then ; todo maybe add the link symbol (arrow) to the icon - + If __TreeListExplorer__PathIsFolder($sPath) Then + Return $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$__TreeListExplorer__Icon_Folder] EndIf - ; Handling for special extensions - Switch $sExt - Case ".exe" - $sIconPath = $sPath - Case ".url" - $sIconPath = IniRead($sPath, "InternetShortcut", "IconFile", -1) - $iIconIndex = IniRead($sPath, "InternetShortcut", "IconIndex", -1) - Case ".lnk" - Local $arShortcutData = FileGetShortcut($sPath) - If $arShortcutData[4]<>"" Then ; icon file provided - $sIconPath = $arShortcutData[4] - $iIconIndex = $arShortcutData[5] - Else ; otherwise get icon from the linked path - Return __TreeListExplorer__FileGetIconIndex($arShortcutData[0]) - EndIf - EndSwitch - If $sIconPath=-1 Then - Local $sRegData = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt, "ProgID") - If @error Then - $sRegData = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt & "\UserChoice", "ProgID") - If @error Then - $sRegData = RegRead("HKCR\" & $sExt, "") - EndIf - EndIf - If $sRegData<>"" Then $sRegData = RegRead("HKCR\" & $sRegData & "\DefaultIcon", "") - If $sRegData="" Then $sRegData = _WinAPI_AssocQueryString($sExt, $ASSOCSTR_DEFAULTICON) - If StringInStr($sRegData, "@")=1 Then ; Handle urls with @{...} - Local $sIconPath = _WinAPI_LoadIndirectString($sRegData) - If @error Then $sIconPath = -1 - Local $arRes = StringRegExp($sIconPath, "^(.*\\)(.*-)(\d+)(\.\S+)$", 1) - If Not (@error And UBound($arRes)<>4) Then ; check for files with a pixel resolution closer to $iIconSize - Local $iIconSize = $__TreeListExplorer__Data.iIconSize - Local $arFiles = _FileListToArray($arRes[0], $arRes[1]&"*"&$arRes[3]) - Local $arOptions[UBound($arFiles)-1][2], $iCount = 0 - For $i=1 To UBound($arFiles)-1 Step 1 ; get icon size for all files - Local $arFileParts = StringRegExp($arFiles[$i], "^.*-(\d+)\.\S+$", 1) - If Not @error Then - $arOptions[$iCount][0] = Int($arFileParts[0]) - $arOptions[$iCount][1] = $arFiles[$i] - $iCount+=1 - EndIf - Next - ReDim $arOptions[$iCount][2] - _ArraySort($arOptions) ; sort by size - For $i=0 To UBound($arOptions)-1 Step 1 ; take the best icon to be used (>= target icon size); Resize will be done later - If $iIconSize<=$arOptions[$i][0] Then - $sIconPath = $arRes[0]&$arOptions[$i][1] - ExitLoop - EndIf - Next - EndIf - ElseIf StringInStr($sRegData, ",") Then ; Handle , e.g.: ...shell32.dll, 0 - Local $arParts = StringRegExp($sRegData, '"?(.*?)"?,(-?\d+)', 1) - If UBound($arParts)=2 Then - $sIconPath = $arParts[0] - $iIconIndex = $arParts[1] - EndIf - ElseIf $sRegData<>"" Then ; Handle path without index - $sIconPath = $sRegData - EndIf - $bAddForExtension = True - EndIf - If $sIconPath<>-1 Then - Local $sIconExt = StringRight($sIconPath, 4), $sMapKey = $sPath - If $bAddForExtension Then $sMapKey = $sExt - If $sIconExt=".dll" Or $sIconExt=".exe" Or $sIconExt=".ico" Then ; icon to extract - Local $iIconSize = $__TreeListExplorer__Data.iIconSize - Local $hIcon = _WinAPI_ShellExtractIcon($sIconPath, $iIconIndex, $iIconSize, $iIconSize) - If $hIcon<>0 Then - Local $iIndex = _GUIImageList_ReplaceIcon($__TreeListExplorer__Data.hIconList, -1, $hIcon) - If $iIndex>=0 Then - $__TreeListExplorer__Data["mIcons"][$sMapKey] = $iIndex - Return $iIndex - EndIf - EndIf - Else ; normal image file - Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sIconPath) - If @error Then Return 2 ; Default file icon - Local $iIconSize = $__TreeListExplorer__Data.iIconSize - Local $hBitmapResized = _GDIPlus_ImageResize($hBitmap, $iIconSize, $iIconSize) - Local $hImg = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapResized) - Local $iIndex = _GUIImageList_Add($__TreeListExplorer__Data.hIconList, $hImg) - _GDIPlus_BitmapDispose($hBitmap) - _GDIPlus_BitmapDispose($hBitmapResized) - If $iIndex>=0 Then - $__TreeListExplorer__Data["mIcons"][$sMapKey] = $iIndex - Return $iIndex - EndIf - EndIf + ; extract and handle cached extensions + Local $arExt = StringRegExp($sPath, "^.*[^\\](\.[^\\]*?)$", 1), $sExt = Default, $bExtension = False, $bAddFileIcon = False + If Not (@error Or UBound($arExt)<>1) Then $sExt = StringLower($arExt[0]) + If $sExt<>Default And $sExt<>".exe" And $sExt<>".url" And $sExt<>".lnk" Then ; files with these extensions may have icons different from each other + If MapExists($__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"], $sExt) Then Return $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$sExt] + $bExtension = True + ElseIf $sExt=".exe" Or $sExt=".url" Or $sExt=".lnk" Then + If MapExists($__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"], $sPath) Then Return $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$sPath] Else - Local $tSHFILEINFO = DllStructCreate($tagSHFILEINFO) - Local $dwFlags = BitOR($SHGFI_USEFILEATTRIBUTES, $SHGFI_ICON, $SHGFI_ICONLOCATION) - _WinAPI_ShellGetFileInfo($sPath, $dwFlags, $FILE_ATTRIBUTE_NORMAL, $tSHFILEINFO) - If DllStructGetData($tSHFILEINFO, 2)<>0 Then ; ignore missing icons (SystemIcon=0 equals Default file icon) - If DllStructGetData($tSHFILEINFO, 1)>0 Then - Local $iIndex = _GUIImageList_ReplaceIcon($__TreeListExplorer__Data.hIconList, -1, DllStructGetData($tSHFILEINFO, 1)) - If $iIndex>=0 Then - $__TreeListExplorer__Data["mIcons"][$sExt] = $iIndex - Return $iIndex - EndIf - EndIf + Return $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$__TreeListExplorer__Icon_File] + EndIf + ; retrieve bitmap + Local $iIndex = -1 + Local $hBitmap = __TreeListExplorer_FileGetIconBitmap($sPath, $iIconSize, $sExt) + If Not @error And @extended = 1 Then ; handle default file icon + $iIndex = $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$__TreeListExplorer__Icon_File] + ElseIf Not @error Then + Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap, 0x00000000) + $iIndex = _GUIImageList_Add($__TreeListExplorer__Data.mIcons[$iIconSize]["hList"], $hHBitmap) + EndIf + _GDIPlus_BitmapDispose($hBitmap) + If $iIndex>=0 Then + If $bExtension Then + $__TreeListExplorer__Data["mIcons"][$iIconSize]["mCache"][$sExt] = $iIndex Else - If DllStructGetData($tSHFILEINFO, 1)>0 Then _WinAPI_DestroyIcon(DllStructGetData($tSHFILEINFO, 1)) + $__TreeListExplorer__Data["mIcons"][$iIconSize]["mCache"][$sPath] = $iIndex EndIf + Return $iIndex EndIf - Return 2 ; Default file icon + Return $__TreeListExplorer__Data.mIcons[$iIconSize]["mCache"][$__TreeListExplorer__Icon_File] EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== @@ -1456,7 +1740,7 @@ Func __TreeListExplorer__UpdateTreeItemContent($hView, $hItem, $bRecursive = Fal If Not $bRecursive Then __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_LoadTree) ; get absolute path for item - Local $arPath = StringRegExp(StringReplace(_GUICtrlTreeView_GetTree($hView, $hItem), "|", "\"), "[^\\]*\\?(.*)$", 1) ; remove first element (root) + Local $arPath = StringRegExp(__TreeListExplorer__TreeViewGetTree($hView, $hItem), "[^\\]*\\?(.*)$", 1) ; remove first element (root) If @error Or UBound($arPath)<>1 Then Return False Local $sPath = $mSystem.sRoot & $arPath[0] ; Get Content data (drives/folders/files) @@ -1466,7 +1750,7 @@ Func __TreeListExplorer__UpdateTreeItemContent($hView, $hItem, $bRecursive = Fal ReDim $arEntries[UBound($arDrives)][3] For $i=0 To UBound($arDrives)-1 Step 1 $arEntries[$i][0] = $arDrives[$i][0] - $arEntries[$i][1] = $arDrives[$i][1] + $arEntries[$i][1] = $__TreeListExplorer__Data.mIcons[$__TreeListExplorer__Data.mViews[$hView].iIconSize].mCache[__TreeListExplorer__GetDriveIconId($arDrives[$i][0], True)] $arEntries[$i][2] = True If $bHasFilterCallback Then $arEntries[$i][2] = __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", True, "", $arDrives[$i][0], "") @@ -1481,7 +1765,7 @@ Func __TreeListExplorer__UpdateTreeItemContent($hView, $hItem, $bRecursive = Fal ReDim $arEntries[$iSize][3] For $i=1 To UBound($arFolders)-1 Step 1 $arEntries[$i-1][0] = $arFolders[$i] - $arEntries[$i-1][1] = 0 + $arEntries[$i-1][1] = $__TreeListExplorer__Data.mIcons[$__TreeListExplorer__Data.mViews[$hView].iIconSize].mCache[$__TreeListExplorer__Icon_Folder] $arEntries[$i-1][2] = True If $bHasFilterCallback Then $arEntries[$i-1][2] = __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", True, $sPath, $arFolders[$i], "") @@ -1490,7 +1774,7 @@ Func __TreeListExplorer__UpdateTreeItemContent($hView, $hItem, $bRecursive = Fal Local $iIndex = UBound($arFolders)-1-(UBound($arFolders)>0?1:0) For $i=1 To UBound($arFiles)-1 Step 1 $arEntries[$iIndex+$i][0] = $arFiles[$i] - $arEntries[$iIndex+$i][1] = __TreeListExplorer__FileGetIconIndex($sPath & "\" & $arFiles[$i]) + $arEntries[$iIndex+$i][1] = __TreeListExplorer__FileGetIconIndex($hView, $sPath & "\" & $arFiles[$i]) $arEntries[$iIndex+$i][2] = True If $bHasFilterCallback Then Local $sFilename = $arFiles[$i], $sExt = "" @@ -1565,6 +1849,29 @@ Func __TreeListExplorer__UpdateTreeItemContent($hView, $hItem, $bRecursive = Fal Return True EndFunc + +; #INTERNAL_USE_ONLY# =========================================================================================================== +; Name ..........: __TreeListExplorer__TreeViewGetTree +; Description ...: Get the tree of the element seperated by \ without influencing the users GUIDataSeparatorChar +; Syntax ........: __TreeListExplorer__TreeViewGetTree($hView, $hItem) +; Parameters ....: $hView - the treeview handle. +; $hItem - the item handle. +; Return values .: The \ seperated tree +; Author ........: Kanashius +; Modified ......: +; Remarks .......: +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func __TreeListExplorer__TreeViewGetTree($hView, $hItem) + If Not IsHWnd($hView) Then $hView = GUICtrlGetHandle($hView) + Local $sSepBefore = Opt("GUIDataSeparatorChar", "\") + Local $sTree = _GUICtrlTreeView_GetTree($hView, $hItem) + Opt("GUIDataSeparatorChar", $sSepBefore) + Return $sTree +EndFunc + ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__TreeViewDeleteItem ; Description ...: _GUICtrlTreeView_Delete randomly does not work using x64 AutoIt and sometimes randomly deletes controls @@ -1668,19 +1975,7 @@ Func __TreeListExplorer__GetDrives() Local $arResult[UBound($arDrives)-1][2] For $i = 1 To UBound($arDrives)-1 $arResult[$i-1][0] = StringUpper($arDrives[$i]) - Switch DriveGetType($arDrives[$i]) - Case 'Fixed' - $arResult[$i-1][1] = 5 - Case 'CDROM' - $arResult[$i-1][1] = 6 - Case 'RAMDisk' - $arResult[$i-1][1] = 7 - Case 'Removable' - $arResult[$i-1][1] = 4 - If StringLeft($arDrives[$i], 2) = "A:" Or StringLeft($arDrives[$i], 2) = "B:" Then $arResult[$i-1][1] = 3 - Case Else - $arResult[$i-1][1] = 8 - EndSwitch + $arResult[$i-1][1] = __TreeListExplorer__GetDriveIconId($arDrives[$i]) Next Return $arResult EndFunc @@ -1688,10 +1983,11 @@ EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetDriveIconId -; Description ...: Get the icon for a drive. -; Syntax ........: __TreeListExplorer__GetDriveIconId($sDrive) -; Parameters ....: -; Return values .: Id of the icon (or 0 if not matched) +; Description ...: Get the icon id or string for a drive. +; Syntax ........: __TreeListExplorer__GetDriveIconId($sDrive[, $bString = False]) +; Parameters ....: $sDrive - The drive path +; $bString - (optional) Default: False. If True the string for $__TreeListExplorer__Icon_... is provided. +; Return values .: Id/String of the icon (or 0 if not matched) ; Author ........: Kanashius ; Modified ......: ; Remarks .......: @@ -1699,21 +1995,21 @@ EndFunc ; Link ..........: ; Example .......: No ; =============================================================================================================================== -Func __TreeListExplorer__GetDriveIconId($sDrive) +Func __TreeListExplorer__GetDriveIconId($sDrive, $bString = False) Switch DriveGetType($sDrive) Case 'Fixed' - return 5 + return $bString?$__TreeListExplorer__Icon_Harddrive:8 Case 'CDROM' - return 6 + return $bString?$__TreeListExplorer__Icon_CDROM:11 Case 'RAMDisk' - return 7 + return $bString?$__TreeListExplorer__Icon_Networkdrive:12 Case 'Removable' - return 4 - If StringLeft($sDrive, 2) = "A:" Or StringLeft($sDrive, 2) = "B:" Then return 3 + return $bString?$__TreeListExplorer__Icon_ChangeableInput:7 + If StringLeft($sDrive, 2) = "A:" Or StringLeft($sDrive, 2) = "B:" Then return $bString?$__TreeListExplorer__Icon_Disc:5 Case Else - return 8 + return $bString?$__TreeListExplorer__Icon_Unknown:53 EndSwitch - return 0 + return $bString?$__TreeListExplorer__Icon_Folder:3 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== @@ -1765,7 +2061,7 @@ EndFunc ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) - Local $sPath = StringReplace(_GUICtrlTreeView_GetTree($hView, $hItem), "|", "\") + Local $sPath = __TreeListExplorer__TreeViewGetTree($hView, $hItem) $arPath = StringRegExp($sPath, "[^\\]*\\?(.*)$", 1) ; remove first root element If UBound($arPath)>0 Then $sPath = $arPath[0] If $sPath<>"" And StringRight($sPath, 1)<>"\" And __TreeListExplorer__RelPathIsFolder($iSystem, $sPath) Then $sPath &= "\" @@ -1925,10 +2221,10 @@ Func __TreeListExplorer__KeyProc($nCode, $wParam, $lParam) Local $hView = ControlGetHandle($hGui, "", $sControl) Local $arHwnds = MapKeys($__TreeListExplorer__Data.mViews) For $i=0 To UBound($arHwnds)-1 Step 1 - If $arHwnds[$i]<>$hView Then ContinueLoop - Local $mView = $__TreeListExplorer__Data.mViews[$hView] + Local $mView = $__TreeListExplorer__Data.mViews[$arHwnds[$i]] + If $arHwnds[$i]<>$hView And (Not (MapExists($mView, "hComboEdit") And $mView.hComboEdit=$hView)) Then ContinueLoop Local $iSystem = $mView.iSystem - Switch $__TreeListExplorer__Data.mViews[$hView].iType + Switch $mView.iType Case $__TreeListExplorer__Type_Input If $vkCode=13 Then __TreeListExplorer_OpenPath(__TreeListExplorer__GetHandleFromSystemID($iSystem), _GUICtrlEdit_GetText($hView)) Case $__TreeListExplorer__Type_ListView @@ -1942,6 +2238,17 @@ Func __TreeListExplorer__KeyProc($nCode, $wParam, $lParam) Next EndIf EndSwitch + Case $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx + If $vkCode = 13 Then + Local $sPath = _GUICtrlEdit_GetText($mView.hComboEdit) + Local $hSystem = __TreeListExplorer__GetHandleFromSystemID($iSystem) + If $sPath="" Then + $sPath = __TreeListExplorer_GetRoot($hSystem) + ElseIf Not FileExists($sPath) Then + $sPath=__TreeListExplorer_GetRoot($hSystem)&__TreeListExplorer_GetPath($hSystem)&$sPath + EndIf + __TreeListExplorer_OpenPath($hSystem, $sPath) + EndIf EndSwitch Next EndIf @@ -2055,6 +2362,7 @@ Func __TreeListExplorer__WinProc($hWnd, $iMsg, $iwParam, $ilParam) If NOT $__TreeListExplorer__Data.bCTRL_DOWN Then ; do not open/select when CTRL+CLICK multiselecting Local $arPath = __TreeListExplorer__GetPathAndLast(__TreeListExplorer__GetCurrentPath($iSystem) & _GUICtrlListView_GetItemText($hView, $iIndex, $mView.iPathIndex)) Local $mOpenPathData[] + $mOpenPathData.iType = $__TreeListExplorer__Type_ListView $mOpenPathData.sFolder = $arPath[0] $mOpenPathData.sSelect = $arPath[1] $mOpenPathData.iSystem = $iSystem @@ -2087,10 +2395,10 @@ Func __TreeListExplorer__WinProc($hWnd, $iMsg, $iwParam, $ilParam) $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iCol"] = $iCol If BitAND($iFormat, $HDF_SORTUP) Then ; ascending _GUICtrlHeader_SetItemFormat($hHeader, $iCol, BitOR(BitXOR($iFormat, $HDF_SORTUP), $HDF_SORTDOWN)) - $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iDir"] = 0 + $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iDir"] = 1 Else ; descending _GUICtrlHeader_SetItemFormat($hHeader, $iCol, BitOR(BitXOR($iFormat, $HDF_SORTDOWN), $HDF_SORTUP)) - $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iDir"] = 1 + $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iDir"] = 0 EndIf __TreeListExplorer__UpdateView($hView, True) EndIf @@ -2101,6 +2409,31 @@ Func __TreeListExplorer__WinProc($hWnd, $iMsg, $iwParam, $ilParam) ExitLoop Next EndIf + If $iMsg=$WM_COMMAND Then + Local $iCode = _WinAPI_HiWord($iwParam) + Local $hView = $ilParam + Local $arHwnds = MapKeys($__TreeListExplorer__Data.mViews) + For $i=0 To UBound($arHwnds)-1 Step 1 + If $arHwnds[$i]<>$hView Then ContinueLoop + Local $mView = $__TreeListExplorer__Data.mViews[$hView] + Local $iSystem = $mView.iSystem + Local $iType = $__TreeListExplorer__Data.mViews[$hView].iType + Switch $iType + Case $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx + Switch $iCode + Case $CBN_SELENDOK + Local $mOpenPathData[] + $mOpenPathData.iType = $iType + $mOpenPathData.sFolder = __TreeListExplorer__GetCurrentPath($iSystem) + $mOpenPathData.iSystem = $iSystem + $mOpenPathData.hView = $hView + $__TreeListExplorer__Data["mOpenPathViews"][$hView] = $mOpenPathData + __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_WaitOpenPath) + AdlibRegister("__TreeListExplorer__RegisteredOpenPath", 10) + EndSwitch + EndSwitch + Next + EndIf If MapExists($__TreeListExplorer__Data.mGuis, $hWnd) Then Return _WinAPI_CallWindowProc($__TreeListExplorer__Data.mGuis[$hWnd].hPrevProc, $hWnd, $iMsg, $iwParam, $ilParam) EndFunc @@ -2124,15 +2457,31 @@ Func __TreeListExplorer__RegisteredOpenPath() For $i=0 to UBound($arViews)-1 Step 1 If __TreeListExplorer__IsViewUpdating($arViews[$i], $__TreeListExplorer__Status_WaitOpenPath) Then Local $mOpenPathData = $__TreeListExplorer__Data["mOpenPathViews"][$arViews[$i]] - Local $hView = $mOpenPathData.hView - Local $arSel[0] - If $mOpenPathData.bMarquee Then $arSel = _GUICtrlListView_GetSelectedIndices(HWnd($hView), True) - __TreeListExplorer__OpenPath($mOpenPathData.iSystem, $mOpenPathData.sFolder, $mOpenPathData.sSelect) - __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_WaitOpenPath) - If $mOpenPathData.bWasClick Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackClick", $mOpenPathData.iIndex) - For $j=1 To UBound($arSel)-1 - _GUICtrlListView_SetItemSelected($hView, $arSel[$j], True) - Next + Switch $mOpenPathData.iType + Case $__TreeListExplorer__Type_ListView + Local $hView = $mOpenPathData.hView + Local $arSel[0] + If $mOpenPathData.bMarquee Then $arSel = _GUICtrlListView_GetSelectedIndices(HWnd($hView), True) + __TreeListExplorer__OpenPath($mOpenPathData.iSystem, $mOpenPathData.sFolder, $mOpenPathData.sSelect) + __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_WaitOpenPath) + If $mOpenPathData.bWasClick Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackClick", $mOpenPathData.iIndex) + For $j=1 To UBound($arSel)-1 + _GUICtrlListView_SetItemSelected($hView, $arSel[$j], True) + Next + Case $__TreeListExplorer__Type_Combo, $__TreeListExplorer__Type_ComboEx + Local $hCombo = -1 + If $mOpenPathData.iType=$__TreeListExplorer__Type_Combo Then $hCombo = HWnd($mOpenPathData.hView) + If $mOpenPathData.iType=$__TreeListExplorer__Type_ComboEx Then $hCombo = _GUICtrlComboBoxEx_GetComboControl($mOpenPathData.hView) + If $hCombo<>-1 Then + Local $iIndex = _GUICtrlComboBox_GetCurSel($hCombo) + If $iIndex>=0 Then + Local $sSelText + _GUICtrlComboBox_GetLBText($hCombo, $iIndex, $sSelText) + Local $arPath = __TreeListExplorer__GetPathAndLast(__TreeListExplorer__GetCurrentPath($mOpenPathData.iSystem) & $sSelText) + __TreeListExplorer__OpenPath($mOpenPathData.iSystem, $arPath[0], $arPath[1]) + EndIf + EndIf + EndSwitch EndIf MapRemove($__TreeListExplorer__Data.mOpenPathViews, $arViews[$i]) Next @@ -2366,4 +2715,4 @@ EndFunc Func __TreeListExplorer__ConsoleWriteCallbackError($sFunc, $sCallbackName, $iLineNumber, $sLineFunc) ConsoleWrite('Error calling callback function "'&$sFunc&'" provided as $'&$sCallbackName&' to "'&$sLineFunc&'" in Line: '&$iLineNumber& _ ". The function probably has the wrong number of parameters."&@crlf) -EndFunc +EndFunc \ No newline at end of file diff --git a/src/main.au3 b/src/main.au3 index 88db1a4..3976c72 100644 --- a/src/main.au3 +++ b/src/main.au3 @@ -5,15 +5,26 @@ #include #include #include +#include #include #include #include #include #include +Global $hKernel32 = DllOpen('kernel32.dll') +Global $hGdi32 = DllOpen('gdi32.dll') +Global $hUser32 = DllOpen('user32.dll') +Global $hShlwapi = DllOpen('shlwapi.dll') +Global $hShell32 = DllOpen('shell32.dll') + +#include "../lib/SharedFunctions.au3" #include "../lib/GUIFrame_WBD_Mod.au3" #include "../lib/History.au3" #include "../lib/TreeListExplorer.au3" +#include "../lib/ProjectConstants.au3" +#include "../lib/DropSourceObject.au3" +#include "../lib/DropTargetObject.au3" ; CREDITS: ; Kanashius TreeListExplorer UDF @@ -24,9 +35,12 @@ ; argumentum Dark Mode functions ; NoNameCode Dark Mode functions ; Melba23 GUIFrame UDF -; ahmet Non-client painting of white line in dark mode +; ahmet Non-client painting of white menubar line in dark mode ; UEZ Lots and lots and lots ; DonChunior Code review, bug fixes and refactoring +; MattyD Drag and drop code +; jugador ListView multiple item drag and drop +; Danyfirex IFileOperation code Global $sVersion = "0.4.0 - 2026-01-22" @@ -39,35 +53,32 @@ $iDPI = ApplyDPI() #include "../lib/ModernMenuRaw.au3" Opt("GUIOnEventMode", 1) +Opt("GUICloseOnESC", 0) Global $hTLESystem, $iFrame_A, $hSeparatorFrame, $aWinSize2, $idInputPath, $g_hInputPath, $g_hStatus, $idTreeView Global $g_hGUI, $g_hChild, $g_hHeader, $g_hListview, $idListview, $iHeaderHeight, $hParentFrame, $g_iIconWidth, $g_hTreeView Global $g_hSizebox, $g_hOldProc, $g_iHeight, $g_hDots Global $idPropertiesItem, $idPropertiesLV, $sCurrentPath -Global $hListImgList, $iListDragIndex, $aDragSource +Global $hListImgList, $iListDragIndex, $sTargetCtrl, $hTreeItemOrig, $hIcon Global $sBack, $sForward, $sUpLevel, $sRefresh -Global $bDragTreeList = False, $sDragSrc, $sTreeDragItem, $sListDragItems, $bDragToolActive = False +Global $sTreeDragItem, $sListDragItems, $bDragToolActive = False +Global $pLVDropTarget, $pTVDropTarget Global $bPathInputChanged = False, $bLoadStatus = False, $bCursorOverride = False -Global $idExitItem, $idAboutItem +Global $idExitItem, $idAboutItem, $idDeleteItem, $idRenameItem, $idCopyItem, $idPasteItem, $idUndoItem, $idHiddenItem, $idSystemItem +Global $bHideHidden = False, $bHideSystem = False Global $hCursor, $hProc -Global $sSelectedItems, $g_aText -Global $idSeparator, $idThemeItem, $hToolTip1, $hToolTip2, $hToolTip3, $bTooltipActive +Global $sSelectedItems, $g_aText, $gText +Global $idSeparator, $idThemeItem, $hToolTip1, $hToolTip2, $bTooltipActive Global $isDarkMode = _WinAPI_ShouldAppsUseDarkMode() Global $hFolderHistory = __History_Create("_doUnReDo", 100, "_historyChange"), $bFolderHistoryChanging = False Global $hSolidBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, 0x000000) Global $iTopSpacer = Round(12 * $iDPI) Global $aPosTip, $iOldaPos0, $iOldaPos1 +Global $sRenameFrom, $sControlFocus, $bFocusChanged = False, $bSelectChanged = False, $bSaveEdit = False +Global $bCopy = False, $pCopyObj ; force light mode ;$isDarkMode = False -Global $gText - -Global $hKernel32 = DllOpen('kernel32.dll') -Global $hGdi32 = DllOpen('gdi32.dll') -Global $hUser32 = DllOpen('user32.dll') -Global $hShlwapi = DllOpen('shlwapi.dll') -Global $hShell32 = DllOpen('shell32.dll') - ; get Windows build Global $iOSBuild = @OSBuild Global $iRevision = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "UBR") @@ -131,15 +142,14 @@ Func _FilesAu3() EndIf ; Startup of the TreeListExplorer - __TreeListExplorer_StartUp($__TreeListExplorer_Lang_EN, $iTreeListIconSize) + __TreeListExplorer_StartUp($__TreeListExplorer_Lang_EN) ; Create GUI and register events $g_hGUI = GUICreate("Files Au3", @DesktopWidth - 600, @DesktopHeight - 400, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetOnEvent($GUI_EVENT_CLOSE, "_EventsGUI") GUISetOnEvent($GUI_EVENT_MAXIMIZE, "_EventsGUI") GUISetOnEvent($GUI_EVENT_RESIZED, "_EventsGUI") - GUISetOnEvent($GUI_EVENT_PRIMARYUP, "_EventsGUI") - GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "_EventsGUI") + GUISetOnEvent($GUI_EVENT_DROPPED, "_EventsGUI") ; used to determine separator position $FrameWidth1 = (@DesktopWidth - 600) / 3 @@ -156,8 +166,6 @@ Func _FilesAu3() _GUIToolTip_SetMaxTipWidth($hToolTip1, 400) $hToolTip2 = _GUIToolTip_Create(0) _GUIToolTip_SetMaxTipWidth($hToolTip2, 400) - $hToolTip3 = _GUIToolTip_Create(0) - _GUIToolTip_SetMaxTipWidth($hToolTip3, 400) GUISetFont(10, $FW_NORMAL, $GUI_FONTNORMAL, $sButtonFont) @@ -199,25 +207,49 @@ Func _FilesAu3() ; reset GUI font GUISetFont(10, $FW_NORMAL, $GUI_FONTNORMAL, "Segoe UI") - ; Menu - If $isDarkMode Then - Local $idFileMenu = _GUICtrlCreateODTopMenu("& File", $g_hGUI) - Local $idViewMenu = _GUICtrlCreateODTopMenu("& View", $g_hGUI) - Local $idHelpMenu = _GUICtrlCreateODTopMenu("& Help", $g_hGUI) - Else - Local $idFileMenu = _GUICtrlCreateODTopMenu("& File", $g_hGUI) - Local $idViewMenu = _GUICtrlCreateODTopMenu("& View", $g_hGUI) - Local $idHelpMenu = _GUICtrlCreateODTopMenu("& Help", $g_hGUI) - EndIf + ; Menubar + Local $idFileMenu = _GUICtrlCreateODTopMenu("& File", $g_hGUI) + Local $idEditMenu = _GUICtrlCreateODTopMenu("& Edit", $g_hGUI) + Local $idViewMenu = _GUICtrlCreateODTopMenu("& View", $g_hGUI) + Local $idHelpMenu = _GUICtrlCreateODTopMenu("& Help", $g_hGUI) - $idPropertiesItem = GUICtrlCreateMenuItem("&Properties", $idFileMenu) + ; File menu + $idDeleteItem = GUICtrlCreateMenuItem("&Delete" & @TAB & "Delete", $idFileMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idDeleteItem, $GUI_DISABLE) + $idRenameItem = GUICtrlCreateMenuItem("&Rename", $idFileMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idRenameItem, $GUI_DISABLE) + $idPropertiesItem = GUICtrlCreateMenuItem("&Properties" & @TAB & "Shift+P", $idFileMenu) GUICtrlSetOnEvent(-1, "_MenuFunctions") GUICtrlSetState($idPropertiesItem, $GUI_DISABLE) GUICtrlCreateMenuItem("", $idFileMenu) $idExitItem = GUICtrlCreateMenuItem("&Exit", $idFileMenu) GUICtrlSetOnEvent(-1, "_MenuFunctions") + ; Edit menu + $idUndoItem = GUICtrlCreateMenuItem("&Undo" & @TAB & "Ctrl+Z", $idEditMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idUndoItem, $GUI_DISABLE) + GUICtrlCreateMenuItem("", $idEditMenu) + $idCopyItem = GUICtrlCreateMenuItem("&Copy" & @TAB & "Ctrl+C", $idEditMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idCopyItem, $GUI_DISABLE) + $idPasteItem = GUICtrlCreateMenuItem("&Paste" & @TAB & "Ctrl+V", $idEditMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idPasteItem, $GUI_DISABLE) + ; View menu $idThemeItem = GUICtrlCreateMenuItem("&Dark Mode", $idViewMenu) GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlCreateMenuItem("", $idViewMenu) + $idHiddenItem = GUICtrlCreateMenuItem("&Show Hidden Files", $idViewMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idHiddenItem, $GUI_CHECKED) + $bHideHidden = False + $idSystemItem = GUICtrlCreateMenuItem("&Hide Protected System Files", $idViewMenu) + GUICtrlSetOnEvent(-1, "_MenuFunctions") + GUICtrlSetState($idSystemItem, $GUI_CHECKED) + $bHideSystem = True + ; Help menu $idAboutItem = GUICtrlCreateMenuItem("&About", $idHelpMenu) GUICtrlSetOnEvent(-1, "_MenuFunctions") @@ -248,23 +280,22 @@ Func _FilesAu3() $aWinSize1 = WinGetClientSize(_GUIFrame_GetHandle($iFrame_A, 1)) ; create treeview - Local $iStyle = BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS, $TVS_TRACKSELECT) + Local $iStyle = BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS, $TVS_TRACKSELECT, $TVS_EDITLABELS) $idTreeView = GUICtrlCreateTreeView(0, 0, $aWinSize1[0], $iFrameHeight, $iStyle) GUICtrlSetState(-1, $GUI_DROPACCEPTED) GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM) $g_hTreeView = GUICtrlGetHandle($idTreeView) - _GUIToolTip_AddTool($hToolTip3, $g_hGUI, " ", $g_hGUI) - - _GUIToolTip_SetTitle($hToolTip3, 'File Operation', $TTI_INFO_LARGE) - _GUIToolTip_Deactivate($hToolTip3) - ; Create TLE system $hTLESystem = __TreeListExplorer_CreateSystem($g_hGUI, "", "_folderCallback") ; Add Views to TLE system __TreeListExplorer_AddView($hTLESystem, $idInputPath) __TreeListExplorer_AddView($hTLESystem, $idTreeView) + __TreeListExplorer_SetViewIconSize($idTreeView, $iTreeListIconSize) + + ; set callback to allow filtering of hidden and/or protected system files + __TreeListExplorer_SetCallback($idTreeView, $__TreeListExplorer_Callback_Filter, "_filterCallback") ; Create listview frame _GUIFrame_Switch($iFrame_A, 2) @@ -284,19 +315,26 @@ Func _FilesAu3() _GUICtrlHeader_SetItemAlign($g_hHeader, 1, 1) ; Set sort arrow - _GUICtrlHeader_SetItemFormat($g_hHeader, 0, $HDF_SORTUP) + ;_GUICtrlHeader_SetItemFormat($g_hHeader, 0, $HDF_SORTUP) ; get header height $iHeaderHeight = _WinAPI_GetWindowHeight($g_hHeader) ; create listview control Local $iExStyles = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER, $LVS_EX_TRACKSELECT) - $idListview = GUICtrlCreateListView("Name|Size|Date Modified|Type", 0, $iHeaderHeight, $aWinSize2[0], $iFrameHeight - $iHeaderHeight, BitOR($LVS_SHOWSELALWAYS, $LVS_NOCOLUMNHEADER), $iExStyles) + $idListview = GUICtrlCreateListView("Name|Size|Date Modified|Type", 0, $iHeaderHeight, $aWinSize2[0], $iFrameHeight - $iHeaderHeight, BitOR($LVS_SHOWSELALWAYS, $LVS_NOCOLUMNHEADER, $LVS_EDITLABELS), $iExStyles) GUICtrlSetState(-1, $GUI_DROPACCEPTED) GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM) $g_hListview = GUICtrlGetHandle($idListview) + ;Create Target for our GUI & register. + $pLVDropTarget = CreateDropTarget($g_hListview) + RegisterDragDrop($g_hListview, $pLVDropTarget) + + $pTVDropTarget = CreateDropTarget($g_hTreeView) + RegisterDragDrop($g_hTreeView, $pTVDropTarget) + _GUIToolTip_AddTool($hToolTip1, $g_hGUI, "", $g_hListview) ; right align Size column @@ -309,11 +347,15 @@ Func _FilesAu3() ; add listview and callbacks to TLE system __TreeListExplorer_AddView($hTLESystem, $idListview, True, True, True, False, False) + __TreeListExplorer_SetViewIconSize($idListview, $iTreeListIconSize) __TreeListExplorer_SetCallback($idListview, $__TreeListExplorer_Callback_Loading, "_loadingCallback") __TreeListExplorer_SetCallback($idListview, $__TreeListExplorer_Callback_DoubleClick, "_doubleClickCallback") __TreeListExplorer_SetCallback($idListview, $__TreeListExplorer_Callback_ListViewPaths, "_handleListViewData") __TreeListExplorer_SetCallback($idListview, $__TreeListExplorer_Callback_ListViewItemCreated, "_handleListViewItemCreated") + ; set callback to allow filtering of hidden and/or protected system files + __TreeListExplorer_SetCallback($idListview, $__TreeListExplorer_Callback_Filter, "_filterCallback") + ; Set resizing flag for all created frames _GUIFrame_ResizeSet(0) @@ -400,6 +442,26 @@ Func _FilesAu3() Local $i_ExStyle_Old = _WinAPI_GetWindowLong_mod(_GUIFrame_GetHandle($iFrame_A, 1), $GWL_EXSTYLE) _WinAPI_SetWindowLong_mod(_GUIFrame_GetHandle($iFrame_A, 1), $GWL_EXSTYLE, BitOR($i_ExStyle_Old, $WS_EX_COMPOSITED)) + ; add drop files support to treeview frame and listview frame + $i_ExStyle_Old = _WinAPI_GetWindowLong_mod(_GUIFrame_GetHandle($iFrame_A, 1), $GWL_EXSTYLE) + _WinAPI_SetWindowLong_mod(_GUIFrame_GetHandle($iFrame_A, 1), $GWL_EXSTYLE, BitOR($i_ExStyle_Old, $WS_EX_ACCEPTFILES)) + + ; add drop files support to treeview frame and listview frame + $i_ExStyle_Old = _WinAPI_GetWindowLong_mod(_GUIFrame_GetHandle($iFrame_A, 2), $GWL_EXSTYLE) + _WinAPI_SetWindowLong_mod(_GUIFrame_GetHandle($iFrame_A, 2), $GWL_EXSTYLE, BitOR($i_ExStyle_Old, $WS_EX_ACCEPTFILES)) + + Local $sMsg = "Attention: The file operation code is new and caution is advised." & @CRLF & @CRLF + $sMsg &= "Please consider testing any file operations in less important areas of your file system. Creating an area " + $sMsg &= "on your file system with test folders and test files would be a good idea for testing purposes." & @CRLF & @CRLF + $sMsg &= "At the moment, Files Au3 allows you to Undo the most recent drag and drop, copy, move, delete, rename, etc. " + $sMsg &= "by pressing Ctrl+Z or Undo from the Edit menu. Future versions will expand to allow more than just the most " + $sMsg &= "recent Undo operation." + MsgBox($MB_ICONWARNING, "Files Au3", $sMsg) + + ; TreeView has initial focus + $sControlFocus = 'Tree' + $bFocusChanged = True + While True If $bTooltipActive Then ; check if cursor is still over listview @@ -414,8 +476,89 @@ Func _FilesAu3() EndIf EndIf - Sleep(200) + If $bFocusChanged Or $bSelectChanged Then + ; keep track of which control currently has focus to determine which menu items to enable/disable + $bFocusChanged = False + $bSelectChanged = False + Select + Case $sControlFocus = 'List' + ; ListView currently has focus + Local $aSelectedLV = _GUICtrlListView_GetSelectedIndices($idListview, True) + If $aSelectedLV[0] = 0 Then + ; no selections in ListView currently + GUICtrlSetState($idRenameItem, $GUI_DISABLE) + GUICtrlSetState($idCopyItem, $GUI_DISABLE) + HotKeySet("^c") + GUICtrlSetState($idDeleteItem, $GUI_DISABLE) + HotKeySet("{DELETE}") + GUICtrlSetState($idPasteItem, $bCopy ? $GUI_ENABLE : $GUI_DISABLE) + HotKeySet("^v", $bCopy ? "_PasteItems" : "") + GUICtrlSetState($idPropertiesItem, $GUI_ENABLE) + HotKeySet("+p", "_Properties") + GUICtrlSetState($idPropertiesLV, $GUI_ENABLE) + ElseIf $aSelectedLV[0] = 1 Then + ; 1 item selection in ListView + GUICtrlSetState($idRenameItem, $GUI_ENABLE) + GUICtrlSetState($idCopyItem, $GUI_ENABLE) + HotKeySet("^c", "_CopyItems") + GUICtrlSetState($idDeleteItem, $GUI_ENABLE) + HotKeySet("{DELETE}", "_DeleteItems") + Local $sSelectedItem = _GUICtrlListView_GetItemText($idListview, $aSelectedLV[1], 0) + Local $sSelectedLV = __TreeListExplorer_GetPath($hTLESystem) & $sSelectedItem + ; is selected path a folder + If StringInStr(FileGetAttrib($sSelectedLV), "D") Then + GUICtrlSetState($idPasteItem, $bCopy ? $GUI_ENABLE : $GUI_DISABLE) + HotKeySet("^v", $bCopy ? "_PasteItems" : "") + Else + GUICtrlSetState($idPasteItem, $GUI_DISABLE) + HotKeySet("^v") + EndIf + GUICtrlSetState($idPropertiesItem, $GUI_ENABLE) + HotKeySet("+p", "_Properties") + GUICtrlSetState($idPropertiesLV, $GUI_ENABLE) + Else + ; multiple items selected in ListView + GUICtrlSetState($idRenameItem, $GUI_DISABLE) ; not supporting multiple file Rename right now + GUICtrlSetState($idCopyItem, $GUI_ENABLE) + HotKeySet("^c", "_CopyItems") + GUICtrlSetState($idDeleteItem, $GUI_ENABLE) + HotKeySet("{DELETE}", "_DeleteItems") + GUICtrlSetState($idPasteItem, $GUI_DISABLE) + HotKeySet("^v") + GUICtrlSetState($idPropertiesItem, $GUI_ENABLE) + HotKeySet("+p", "_Properties") + GUICtrlSetState($idPropertiesLV, $GUI_ENABLE) + EndIf + Case $sControlFocus = 'Tree' + ; TreeView currently has focus + ; treeview always has a selection + GUICtrlSetState($idRenameItem, $GUI_ENABLE) + GUICtrlSetState($idCopyItem, $GUI_ENABLE) + HotKeySet("^c", "_CopyItems") + GUICtrlSetState($idDeleteItem, $GUI_ENABLE) + HotKeySet("{DELETE}", "_DeleteItems") + GUICtrlSetState($idPasteItem, $bCopy ? $GUI_ENABLE : $GUI_DISABLE) + HotKeySet("^v", $bCopy ? "_PasteItems" : "") + GUICtrlSetState($idPropertiesItem, $GUI_ENABLE) + HotKeySet("+p", "_Properties") + GUICtrlSetState($idPropertiesLV, $GUI_DISABLE) + Case Not $sControlFocus + ; Neither the ListView or TreeView has focus right now + ; in this case likely disable menu options + GUICtrlSetState($idRenameItem, $GUI_DISABLE) + GUICtrlSetState($idCopyItem, $GUI_DISABLE) + HotKeySet("^c") + GUICtrlSetState($idDeleteItem, $GUI_DISABLE) + HotKeySet("{DELETE}") + GUICtrlSetState($idPasteItem, $GUI_DISABLE) + HotKeySet("^v") + GUICtrlSetState($idPropertiesItem, $GUI_DISABLE) + HotKeySet("+p") + GUICtrlSetState($idPropertiesLV, $GUI_DISABLE) + EndSelect + EndIf + Sleep(200) WEnd EndFunc ;==>_FilesAu3 @@ -546,21 +689,6 @@ Func _selectionChangedLV() Local $iItemCount = $iFileCount + $iDirCount - ; Properties dialog - If $iItemCount = 1 Then - $sCurrentPath = $sSelectedLV - GUICtrlSetState($idPropertiesItem, $GUI_ENABLE) - GUICtrlSetState($idPropertiesLV, $GUI_ENABLE) - ElseIf $iItemCount <> 1 And $iItemCount <> 0 Then - ; multi-properties - ; need number of selected items to declare array - GUICtrlSetState($idPropertiesItem, $GUI_ENABLE) - GUICtrlSetState($idPropertiesLV, $GUI_ENABLE) - Else - GUICtrlSetState($idPropertiesItem, $GUI_DISABLE) - GUICtrlSetState($idPropertiesLV, $GUI_DISABLE) - EndIf - If $iItemCount > 1 Then $g_aText[1] = " " & $iItemCount & " items selected" ElseIf $iItemCount = 1 Then @@ -688,6 +816,8 @@ Func WM_NOTIFY2($hWnd, $iMsg, $wParam, $lParam) Local Static $iItemPrev Local $iItemRow + Local $tText + ; header and listview combined functionality Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Local $iCode = DllStructGetData($tNMHDR, "Code") @@ -777,14 +907,40 @@ Func WM_NOTIFY2($hWnd, $iMsg, $wParam, $lParam) _GUIToolTip_UpdateTipText($hToolTip1, $g_hGUI, $g_hListview, $gText) EndIf Case $LVN_ITEMCHANGED + ; follow up in main While loop + $bSelectChanged = True ; item selection(s) have changed _selectionChangedLV() - Case $LVN_BEGINDRAG + Case $LVN_BEGINDRAG, $LVN_BEGINRDRAG Local $tNMListView = DllStructCreate($tagNMLISTVIEW, $lParam) - $bDragTreeList = True - $sDragSrc = "List" - ; fire off adlib to get multiple selection drag details - AdlibRegister("_ListGetSelections", 10) + $hTreeItemOrig = _GUICtrlTreeView_GetSelection($g_hTreeView) + + ; create array with list of selected listview items + Local $aItems = _GUICtrlListView_GetSelectedIndices($tNMHDR.hwndFrom, True) + For $i = 1 To $aItems[0] + $aItems[$i] = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($tNMHDR.hwndFrom, $aItems[$i]) + Next + + Local $pDataObj, $pDropSource + ;$pDataObj = GetDataObjectOfFiles($hWnd, $aItems) ; MattyD function + + _ArrayDelete($aItems, 0) ; only needed for GetDataObjectOfFile_B + $pDataObj = GetDataObjectOfFile_B($aItems) ; jugador function + + ;Create an IDropSource to handle our end of the drag/drop operation. + $pDropSource = CreateDropSource() + + Local $iResult = _SHDoDragDrop($pDataObj, $pDropSource, BitOR($DROPEFFECT_MOVE, $DROPEFFECT_COPY, $DROPEFFECT_LINK)) + ;__TreeListExplorer_Reload($hTLESystem) + + DestroyDropSource($pDropSource) + _Release($pDataObj) + + ; allow Undo if drop returns successful + If $iResult = $DRAGDROP_S_DROP Then _AllowUndo() + + ; there is not supposed to be a Return value on LVN_BEGINDRAG + ; however it fixes an issue with built-in drag-drop mechanism Return 0 Case $LVN_HOTTRACK ; Sent by a list-view control When the user moves the mouse over an item Local $tInfo2 = DllStructCreate($tagNMLISTVIEW, $lParam) @@ -838,17 +994,231 @@ Func WM_NOTIFY2($hWnd, $iMsg, $wParam, $lParam) $bTooltipActive = True EndIf Return 1 ; prevent the hover from being processed + Case $LVN_KEYDOWN + Local $tLVKeyDown = DllStructCreate($tagNMLVKEYDOWN, $lParam) + Local $iVKey = DllStructGetData($tLVKeyDown, "VKey") + If $iVKey = 46 Then + ; create array with list of selected listview items + Local $aItems = _GUICtrlListView_GetSelectedIndices($tNMHDR.hwndFrom, True) + For $i = 1 To $aItems[0] + $aItems[$i] = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($tNMHDR.hwndFrom, $aItems[$i]) + Next + + ;$pDataObj = GetDataObjectOfFiles($hWnd, $aItems) ; MattyD function + + _ArrayDelete($aItems, 0) ; only needed for GetDataObjectOfFile_B + Local $pDataObj = GetDataObjectOfFile_B($aItems) ; jugador function + + Local $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + _IFileOperationDelete($pDataObj, $iFlags) + + __TreeListExplorer_Reload($hTLESystem) + + _Release($pDataObj) + _AllowUndo() + EndIf + Case $LVN_BEGINLABELEDITA, $LVN_BEGINLABELEDITW + Local $aSelectedLV = _GUICtrlListView_GetSelectedIndices($idListview, True) + ; there should only be one selected item during a rename + Local $iItemLV = $aSelectedLV[1] + Local $sRenameItem = _GUICtrlListView_GetItemText($idListview, $iItemLV, 0) + $sRenameFrom = __TreeListExplorer_GetPath($hTLESystem) & $sRenameItem + ; set hotkeys to ensure that file name cannot contain illegal characters + ; \ / : * ? " < > | + HotKeySet ('{\}', "_RenameCheckLV") + HotKeySet ('{/}', "_RenameCheckLV") + HotKeySet ('{:}', "_RenameCheckLV") + HotKeySet ('{*}', "_RenameCheckLV") + HotKeySet ('{?}', "_RenameCheckLV") + HotKeySet ('{"}', "_RenameCheckLV") + HotKeySet ('{<}', "_RenameCheckLV") + HotKeySet ('{>}', "_RenameCheckLV") + HotKeySet ('{|}', "_RenameCheckLV") + Return False + Case $LVN_ENDLABELEDITA, $LVN_ENDLABELEDITW + ; unset hotkeys that block illegal characters from being set + HotKeySet ('{\}') + HotKeySet ('{/}') + HotKeySet ('{:}') + HotKeySet ('{*}') + HotKeySet ('{?}') + HotKeySet ('{"}') + HotKeySet ('{<}') + HotKeySet ('{>}') + HotKeySet ('{|}') + Local $sRenameTo + $tText = DllStructCreate($tagNMLVDISPINFO, $lParam) + Local $tBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tText, "TextMax") & "]", DllStructGetData($tText, "Text")) + Local $sTextRet = DllStructGetData($tBuffer, "Text") + Local $sIllegal = "A file name can't contain any of the following characters:" & @CRLF & @CRLF + $sIllegal &= '\ / : * ? " < > |' + ; A file name can't contain any of the following characters: + ; \/:*?"<>| + Select + Case StringInStr($sTextRet, '\', 2) + Return False + Case StringInStr($sTextRet, '/', 2) + Return False + Case StringInStr($sTextRet, ':', 2) + Return False + Case StringInStr($sTextRet, '*', 2) + Return False + Case StringInStr($sTextRet, '?', 2) + Return False + Case StringInStr($sTextRet, '"', 2) + Return False + Case StringInStr($sTextRet, '<', 2) + Return False + Case StringInStr($sTextRet, '>', 2) + Return False + Case StringInStr($sTextRet, '|', 2) + Return False + Case Not $sTextRet + Return False + Case Else + $sRenameTo = __TreeListExplorer_GetPath($hTLESystem) & $sTextRet + _WinAPI_ShellFileOperation($sRenameFrom, $sRenameTo, $FO_RENAME, BitOR($FOF_ALLOWUNDO, $FOF_NO_UI)) + ; refresh TLE system to pick up any folder changes, file type changes, etc. + __TreeListExplorer_Reload($hTLESystem) + _AllowUndo() + Return True ; allow rename to occur + EndSelect + Case $NM_SETFOCUS + $sControlFocus = 'List' + $bFocusChanged = True + Case $NM_KILLFOCUS + $sControlFocus = '' + $bFocusChanged = True EndSwitch Case $g_hTreeView Switch $iCode - Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW - $aDragSource = "" + Case $TVN_BEGINDRAGW, $TVN_BEGINRDRAGW Local $tTree = DllStructCreate($tagNMTREEVIEW, $lParam) Local $hDragItem = DllStructGetData($tTree, "NewhItem") - $aDragSource = TreeItemToPath($g_hTreeView, $hDragItem, True) - $bDragTreeList = True - $sDragSrc = "Tree" + $hTreeItemOrig = _GUICtrlTreeView_GetSelection($g_hTreeView) + + Local $sItemText = TreeItemToPath($g_hTreeView, $hDragItem) + + Local $pDataObj, $pDropSource + + ;Get an IDataObject representing the file to copy + $pDataObj = GetDataObjectOfFile($hWnd, $sItemText) + If Not @error Then + ;Create an IDropSource to handle our end of the drag/drop operation. + $pDropSource = CreateDropSource() + + If Not @error Then + Local $iResult = _SHDoDragDrop($pDataObj, $pDropSource, BitOR($DROPEFFECT_MOVE, $DROPEFFECT_COPY, $DROPEFFECT_LINK)) + + ;Operation done, destroy our drop source. (Can't just IUnknown_Release() this one!) + DestroyDropSource($pDropSource) + EndIf + + ;Relase the data object so the system can destroy it (prevent memory leaks) + _Release($pDataObj) + + ; allow Undo if drop returns successful + If $iResult = $DRAGDROP_S_DROP Then _AllowUndo() + EndIf + Case $TVN_KEYDOWN + Local $tTVKeyDown = DllStructCreate($tagNMTVKEYDOWN, $lParam) + Local $iVKey = DllStructGetData($tTVKeyDown, "VKey") + If $iVKey = 46 Then + Local $hTreeItemSel = _GUICtrlTreeView_GetSelection($g_hTreeView) + Local $sItemText = TreeItemToPath($g_hTreeView, $hTreeItemSel) + + Local $pDataObj, $pDropSource + + ;Get an IDataObject representing the file to copy + $pDataObj = GetDataObjectOfFile($hWnd, $sItemText) + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + _IFileOperationDelete($pDataObj, $iFlags) + + __TreeListExplorer_Reload($hTLESystem) + + ;Relase the data object so the system can destroy it (prevent memory leaks) + _Release($pDataObj) + _AllowUndo() + EndIf + Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW + HotKeySet("{Enter}", "_SaveEditTV") + HotKeySet("{Esc}", "_CancelEditTV") + $hTreeItemOrig = _GUICtrlTreeView_GetSelection($g_hTreeView) + $sRenameFrom = TreeItemToPath($g_hTreeView, $hTreeItemOrig) + ; set hotkeys to ensure that file name cannot contain illegal characters + ; \ / : * ? " < > | + HotKeySet ('{\}', "_RenameCheckTV") + HotKeySet ('{/}', "_RenameCheckTV") + HotKeySet ('{:}', "_RenameCheckTV") + HotKeySet ('{*}', "_RenameCheckTV") + HotKeySet ('{?}', "_RenameCheckTV") + HotKeySet ('{"}', "_RenameCheckTV") + HotKeySet ('{<}', "_RenameCheckTV") + HotKeySet ('{>}', "_RenameCheckTV") + HotKeySet ('{|}', "_RenameCheckTV") + Return False + Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW + Local $sRenameTo + HotKeySet("{Enter}") + HotKeySet("{Esc}") + ; unset hotkeys that block illegal characters from being set + HotKeySet ('{\}') + HotKeySet ('{/}') + HotKeySet ('{:}') + HotKeySet ('{*}') + HotKeySet ('{?}') + HotKeySet ('{"}') + HotKeySet ('{<}') + HotKeySet ('{>}') + HotKeySet ('{|}') + If $bSaveEdit Then + $bSaveEdit = False + $tText = DllStructCreate($tagNMTVDISPINFO, $lParam) + Local $tBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tText, "TextMax") & "]", DllStructGetData($tText, "Text")) + Local $sTextRet = DllStructGetData($tBuffer, "Text") + ; A file name can't contain any of the following characters: + ; \/:*?"<>| + Select + Case StringInStr($sTextRet, '\', 2) + Return False + Case StringInStr($sTextRet, '/', 2) + Return False + Case StringInStr($sTextRet, ':', 2) + Return False + Case StringInStr($sTextRet, '*', 2) + Return False + Case StringInStr($sTextRet, '?', 2) + Return False + Case StringInStr($sTextRet, '"', 2) + Return False + Case StringInStr($sTextRet, '<', 2) + Return False + Case StringInStr($sTextRet, '>', 2) + Return False + Case StringInStr($sTextRet, '|', 2) + Return False + Case Not $sTextRet + Return False + Case Else + Local $aPath = _StringBetween($sRenameFrom, "\", "\") + Local $sRenameItem = $aPath[UBound($aPath) - 1] + $sRenameTo = StringReplace($sRenameFrom, $sRenameItem, $sTextRet) + _WinAPI_ShellFileOperation($sRenameFrom, $sRenameTo, $FO_RENAME, BitOR($FOF_ALLOWUNDO, $FOF_NO_UI)) + ;__TreeListExplorer_Reload($hTLESystem) + _AllowUndo() + Return True ; allow rename to occur + EndSelect + EndIf + Case $NM_SETFOCUS + $sControlFocus = 'Tree' + $bFocusChanged = True + Case $NM_KILLFOCUS + $sControlFocus = '' + $bFocusChanged = True + Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW + ; follow up in main While loop + $bSelectChanged = True EndSwitch EndSwitch @@ -910,6 +1280,30 @@ Func WM_NOTIFY2($hWnd, $iMsg, $wParam, $lParam) Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY2 +Func _RenameCheckLV() + Local $sIllegal = "A file name can't contain any of the following characters:" & @CRLF & @CRLF + $sIllegal &= '\ / : * ? " < > |' + Local $hEdit = _GUICtrlListView_GetEditControl($g_hListview) + _GUICtrlEdit_ShowBalloonTip($hEdit, '', $sIllegal, $TTI_INFO) +EndFunc + +Func _RenameCheckTV() + Local $sIllegal = "A file name can't contain any of the following characters:" & @CRLF & @CRLF + $sIllegal &= '\ / : * ? " < > |' + Local $hEdit = _GUICtrlTreeView_GetEditControl($g_hTreeView) + _GUICtrlEdit_ShowBalloonTip($hEdit, '', $sIllegal, $TTI_INFO) +EndFunc + +Func _SaveEditTV() + $bSaveEdit = True + _GUICtrlTreeView_EndEdit($g_hTreeView) +EndFunc + +Func _CancelEditTV() + $bSaveEdit = False + _GUICtrlTreeView_EndEdit($g_hTreeView) +EndFunc + Func _removeExStyles() ; remove WS_EX_COMPOSITED from GUI Local $i_ExStyle_Old = _WinAPI_GetWindowLong_mod($hParentFrame, $GWL_EXSTYLE) @@ -1036,7 +1430,8 @@ EndFunc ;==>WM_COMMAND2 Func _About() Local $sMsg - $sMsg = "Version: " & @TAB & @TAB & $sVersion & @CRLF & @CRLF + $sMsg = "Program Version: " & @TAB & $sVersion & @CRLF & @CRLF + $sMsg &= "TreeListExplorer: " & @TAB & _VersionToString(_UDFGetVersion("../lib/TreeListExplorer.au3")) & @CRLF & @CRLF $sMsg &= "Made by: " & @TAB & "AutoIt Community" MsgBox(0, "Files Au3", $sMsg) EndFunc ;==>_About @@ -1046,7 +1441,10 @@ Func _CleanExit() _GUICtrlHeader_Destroy($g_hHeader) _GUIToolTip_Destroy($hToolTip1) _GUIToolTip_Destroy($hToolTip2) - _GUIToolTip_Destroy($hToolTip3) + RevokeDragDrop($g_hListview) + DestroyDropTarget($pLVDropTarget) + RevokeDragDrop($g_hTreeView) + DestroyDropTarget($pTVDropTarget) GUIDelete($g_hGUI) _ClearDarkSizebox() @@ -1082,182 +1480,6 @@ Func _InitDarkSizebox() $g_hDots = CreateDots($g_iHeight, $g_iHeight, 0x00000000 + $iBackColorDef, 0xFF000000 + 0xBFBFBF) EndFunc ;==>_InitDarkSizebox -Func __Timer_QueryPerformanceFrequency_mod() - Local $aCall = DllCall($hKernel32, "bool", "QueryPerformanceFrequency", "int64*", 0) - If @error Then Return SetError(@error, @extended, 0) - Return SetExtended($aCall[0], $aCall[1]) -EndFunc ;==>__Timer_QueryPerformanceFrequency_mod - -Func __Timer_QueryPerformanceCounter_mod() - Local $aCall = DllCall($hKernel32, "bool", "QueryPerformanceCounter", "int64*", 0) - If @error Then Return SetError(@error, @extended, -1) - Return SetExtended($aCall[0], $aCall[1]) -EndFunc ;==>__Timer_QueryPerformanceCounter_mod - -Func _Timer_Diff_mod($iTimeStamp) - Return 1000 * (__Timer_QueryPerformanceCounter_mod() - $iTimeStamp) / __Timer_QueryPerformanceFrequency_mod() -EndFunc ;==>_Timer_Diff_mod - -Func _Timer_Init_mod() - Return __Timer_QueryPerformanceCounter_mod() -EndFunc ;==>_Timer_Init_mod - -Func _WinAPI_ReleaseDC_mod($hWnd, $hDC) - Local $aCall = DllCall($hUser32, "int", "ReleaseDC", "hwnd", $hWnd, "handle", $hDC) - If @error Then Return SetError(@error, @extended, False) - - Return $aCall[0] -EndFunc ;==>_WinAPI_ReleaseDC_mod - -Func _WinAPI_GetDCEx_mod($hWnd, $hRgn, $iFlags) - Local $aCall = DllCall($hUser32, 'handle', 'GetDCEx', 'hwnd', $hWnd, 'handle', $hRgn, 'dword', $iFlags) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_GetDCEx_mod - -Func _WinAPI_CreateRectRgn_mod($iLeftRect, $iTopRect, $iRightRect, $iBottomRect) - Local $aCall = DllCall($hGdi32, "handle", "CreateRectRgn", "int", $iLeftRect, "int", $iTopRect, "int", $iRightRect, _ - "int", $iBottomRect) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_CreateRectRgn_mod - -Func _WinAPI_OffsetRect_mod(ByRef $tRECT, $iDX, $iDY) - Local $aCall = DllCall($hUser32, 'bool', 'OffsetRect', 'struct*', $tRECT, 'int', $iDX, 'int', $iDY) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_OffsetRect_mod - -Func _WinAPI_GetWindowRect_mod($hWnd) - Local $tRECT = DllStructCreate($tagRECT) - Local $aCall = DllCall($hUser32, "bool", "GetWindowRect", "hwnd", $hWnd, "struct*", $tRECT) - If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0) - - Return $tRECT -EndFunc ;==>_WinAPI_GetWindowRect_mod - -Func _WinAPI_ShellGetFileInfo_mod($sFilePath, $iFlags, $iAttributes, ByRef $tSHFILEINFO) - Local $aCall = DllCall($hShell32, 'dword_ptr', 'SHGetFileInfoW', 'wstr', $sFilePath, 'dword', $iAttributes, _ - 'struct*', $tSHFILEINFO, 'uint', DllStructGetSize($tSHFILEINFO), 'uint', $iFlags) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_ShellGetFileInfo_mod - -Func _WinAPI_GetClientRect_mod($hWnd) - Local $tRECT = DllStructCreate($tagRECT) - Local $aCall = DllCall($hUser32, "bool", "GetClientRect", "hwnd", $hWnd, "struct*", $tRECT) - If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0) - - Return $tRECT -EndFunc ;==>_WinAPI_GetClientRect_mod - -Func _WinAPI_GetWindowLong_mod($hWnd, $iIndex) - Local $sFuncName = "GetWindowLongW" - If @AutoItX64 Then $sFuncName = "GetWindowLongPtrW" - Local $aCall = DllCall($hUser32, "long_ptr", $sFuncName, "hwnd", $hWnd, "int", $iIndex) - If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_GetWindowLong_mod - -Func _WinAPI_DefWindowProc_mod($hWnd, $iMsg, $wParam, $lParam) - Local $aCall = DllCall($hUser32, "lresult", "DefWindowProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, _ - "lparam", $lParam) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_DefWindowProc_mod - -Func _WinAPI_SetLastError_mod($iErrorCode, Const $_iCallerError = @error, Const $_iCallerExtended = @extended) - DllCall($hKernel32, "none", "SetLastError", "dword", $iErrorCode) - Return SetError($_iCallerError, $_iCallerExtended, Null) -EndFunc ;==>_WinAPI_SetLastError_mod - -Func _WinAPI_SetWindowLong_mod($hWnd, $iIndex, $iValue) - _WinAPI_SetLastError_mod(0) ; as suggested in MSDN - Local $sFuncName = "SetWindowLongW" - If @AutoItX64 Then $sFuncName = "SetWindowLongPtrW" - Local $aCall = DllCall($hUser32, "long_ptr", $sFuncName, "hwnd", $hWnd, "int", $iIndex, "long_ptr", $iValue) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_SetWindowLong_mod - -Func _WinAPI_SetWindowPos_mod($hWnd, $hAfter, $iX, $iY, $iCX, $iCY, $iFlags) - Local $aCall = DllCall($hUser32, "bool", "SetWindowPos", "hwnd", $hWnd, "hwnd", $hAfter, "int", $iX, "int", $iY, _ - "int", $iCX, "int", $iCY, "uint", $iFlags) - If @error Then Return SetError(@error, @extended, False) - - Return $aCall[0] -EndFunc ;==>_WinAPI_SetWindowPos_mod - -Func _WinAPI_DrawText_mod($hDC, $sText, ByRef $tRECT, $iFlags) - Local $aCall = DllCall($hUser32, "int", "DrawTextW", "handle", $hDC, "wstr", $sText, "int", -1, "struct*", $tRECT, _ - "uint", $iFlags) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_DrawText_mod - -Func _WinAPI_SetBkColor_mod($hDC, $iColor) - Local $aCall = DllCall($hGdi32, "INT", "SetBkColor", "handle", $hDC, "INT", $iColor) - If @error Then Return SetError(@error, @extended, -1) - - Return $aCall[0] -EndFunc ;==>_WinAPI_SetBkColor_mod - -Func _WinAPI_DeleteObject_mod($hObject) - Local $aCall = DllCall($hGdi32, "bool", "DeleteObject", "handle", $hObject) - If @error Then Return SetError(@error, @extended, False) - - Return $aCall[0] -EndFunc ;==>_WinAPI_DeleteObject_mod - -Func _WinAPI_InflateRect_mod(ByRef $tRECT, $iDX, $iDY) - Local $aCall = DllCall($hUser32, 'bool', 'InflateRect', 'struct*', $tRECT, 'int', $iDX, 'int', $iDY) - If @error Then Return SetError(@error, @extended, False) - - Return $aCall[0] -EndFunc ;==>_WinAPI_InflateRect_mod - -Func _WinAPI_FillRect_mod($hDC, $tRECT, $hBrush) - Local $aCall - If IsPtr($hBrush) Then - $aCall = DllCall($hUser32, "int", "FillRect", "handle", $hDC, "struct*", $tRECT, "handle", $hBrush) - Else - $aCall = DllCall($hUser32, "int", "FillRect", "handle", $hDC, "struct*", $tRECT, "dword_ptr", $hBrush) - EndIf - If @error Then Return SetError(@error, @extended, False) - - Return $aCall[0] -EndFunc ;==>_WinAPI_FillRect_mod - -Func _WinAPI_CreateSolidBrush_mod($iColor) - Local $aCall = DllCall($hGdi32, "handle", "CreateSolidBrush", "INT", $iColor) - If @error Then Return SetError(@error, @extended, 0) - - Return $aCall[0] -EndFunc ;==>_WinAPI_CreateSolidBrush_mod - -Func _WinAPI_GetClassName_mod($hWnd) - If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) - Local $aCall = DllCall($hUser32, "int", "GetClassNameW", "hwnd", $hWnd, "wstr", "", "int", 4096) - If @error Or Not $aCall[0] Then Return SetError(@error, @extended, '') - - Return SetExtended($aCall[0], $aCall[2]) -EndFunc ;==>_WinAPI_GetClassName_mod - -Func _WinAPI_SetTextColor_mod($hDC, $iColor) - Local $aCall = DllCall($hGdi32, "INT", "SetTextColor", "handle", $hDC, "INT", $iColor) - If @error Then Return SetError(@error, @extended, -1) - - Return $aCall[0] -EndFunc ;==>_WinAPI_SetTextColor_mod - ; Resize the status bar when GUI size changes Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam @@ -1286,18 +1508,27 @@ Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>WM_SIZE Func _Properties() - Local $aSelectedLV = _GUICtrlListView_GetSelectedIndices($idListview, True) - If $aSelectedLV[0] = 1 Then - _WinAPI_ShellObjectProperties($sCurrentPath) - ElseIf $aSelectedLV[0] = 0 Then - _WinAPI_ShellObjectProperties(__TreeListExplorer_GetPath($hTLESystem)) - Else - ;$sSelectedItems - Local $aFiles = StringSplit($sSelectedItems, "|") - _ArrayDelete($aFiles, $aFiles[0]) - _ArrayDelete($aFiles, 0) - _WinAPI_SHMultiFileProperties(__TreeListExplorer_GetPath($hTLESystem), $aFiles) - EndIf + Select + Case $sControlFocus = 'List' + Local $aSelectedLV = _GUICtrlListView_GetSelectedIndices($idListview, True) + If $aSelectedLV[0] = 1 Then + Local $sSelectedItem = _GUICtrlListView_GetItemText($idListview, $aSelectedLV[1], 0) + Local $sSelectedLV = __TreeListExplorer_GetPath($hTLESystem) & $sSelectedItem + _WinAPI_ShellObjectProperties($sSelectedLV) + ElseIf $aSelectedLV[0] = 0 Then + _WinAPI_ShellObjectProperties(__TreeListExplorer_GetPath($hTLESystem)) + Else + ;$sSelectedItems + Local $aFiles = StringSplit($sSelectedItems, "|") + _ArrayDelete($aFiles, $aFiles[0]) + _ArrayDelete($aFiles, 0) + _WinAPI_SHMultiFileProperties(__TreeListExplorer_GetPath($hTLESystem), $aFiles) + EndIf + Case $sControlFocus = 'Tree' + Local $hTreeItem = _GUICtrlTreeView_GetSelection($g_hTreeView) + Local $sItemText = TreeItemToPath($g_hTreeView, $hTreeItem) + _WinAPI_ShellObjectProperties($sItemText) + EndSelect EndFunc ;==>_Properties ; #FUNCTION# ==================================================================================================================== @@ -1459,13 +1690,6 @@ Func WM_DRAWITEM2($hWnd, $Msg, $wParam, $lParam) Return $GUI_RUNDEFMSG EndFunc ;==>WM_DRAWITEM2 -Func _WinAPI_PathIsRoot_mod($sFilePath) - Local $aCall = DllCall($hShlwapi, 'bool', 'PathIsRootW', 'wstr', $sFilePath & "\") - If @error Then Return SetError(@error, @extended, False) - - Return $aCall[0] -EndFunc ;==>_WinAPI_PathIsRoot_mod - ;============================================== Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam) ; Andreik @@ -1563,7 +1787,7 @@ EndFunc ;==>WM_MOVE Func ApplyDPI() ; apply System DPI awareness and calculate factor ; Returns DPI scaling factor (1.0 = 100%), defaults to 1.0 on error - _WinAPI_SetThreadDpiAwarenessContext($DPI_AWARENESS_CONTEXT_SYSTEM_AWARE) + _WinAPI_SetProcessDpiAwarenessContext($DPI_AWARENESS_CONTEXT_SYSTEM_AWARE) If @error Then Return 1 Local $iDPI2 = Round(_WinAPI_GetDpiForSystem() / 96, 2) @@ -1572,15 +1796,15 @@ Func ApplyDPI() Return $iDPI2 EndFunc ;==>ApplyDPI -Func _WinAPI_SetThreadDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) ; UEZ - Local $aResult = DllCall("user32.dll", "uint", "SetThreadDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ; requires Win10 v1703+ / Windows Server 2016+ - If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) - If Not $aResult[0] Then Return SetError(2, @extended, 0) - Return $aResult[0] -EndFunc ;==>_WinAPI_SetThreadDpiAwarenessContext +Func _WinAPI_SetProcessDpiAwarenessContext($DPI_AWARENESS_CONTEXT_value) ; UEZ + Local $aResult = DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", @AutoItX64 ? "int64" : "int", $DPI_AWARENESS_CONTEXT_value) ;requires Win10 v1703+ / Windows Server 2016+ + If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) + If Not $aResult[0] Then Return SetError(2, @extended, 0) + Return $aResult[0] +EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext Func _WinAPI_GetDpiForSystem() ; UEZ - Local $aResult = DllCall("user32.dll", "uint", "GetDpiForSystem") ; requires Win10 v1607+ / no server support + Local $aResult = DllCall('user32.dll', "uint", "GetDpiForSystem") ; requires Win10 v1607+ / no server support If Not IsArray($aResult) Or @error Then Return SetError(1, @extended, 0) If Not $aResult[0] Then Return SetError(2, @extended, 0) Return $aResult[0] @@ -1798,161 +2022,9 @@ Func _EventsGUI() _resizeLVCols2() Case $GUI_EVENT_RESIZED _resizeLVCols2() - Case $GUI_EVENT_MOUSEMOVE - If Not $bDragTreeList Then ContinueCase - If Not $bDragToolActive Then - ; check drag source to determine where to fetch icon from - If $sDragSrc = "Tree" Then - $hIcon = _GUICtrlTreeView_GetImageListIconHandle($idTreeView, 0) ; always folder icon - _GUIToolTip_SetTitle($hToolTip3, 'File Operation', $hIcon) - ElseIf $sDragSrc = "List" Then - $iImgIndex = _GUICtrlListView_GetItemImage($g_hListview, $iListDragIndex) - $hIcon = _GUIImageList_GetIcon($hListImgList, $iImgIndex) - _GUIToolTip_SetTitle($hToolTip3, 'File Operation', $hIcon) - EndIf - ; temporarily delay regular listview tooltips - _GUICtrlListView_SetHoverTime($idListview, 50000) - _GUIToolTip_Activate($hToolTip3) - _GUIToolTip_TrackActivate($hToolTip3, True, $g_hGUI, $g_hGUI) - $bDragToolActive = True - EndIf - Local $aPosTool3 = MouseGetPos() - _GUIToolTip_TrackPosition($hToolTip3, $aPosTool3[0], $aPosTool3[1]) - - If Not $bTreeOrigStored Then - ; store handle for the original treeview selection to restore selection later - $hTreeItemOrig = _GUICtrlTreeView_GetSelection($g_hTreeView) - $bTreeOrigStored = True - EndIf - Local $aTreeList = GUIGetCursorInfo($g_hGUI) - Local $sTreeListItemText - Local Static $sTreeListItemTextPrev - Select - Case $aTreeList[4] = $idTreeView - Local $hItemHover = TreeItemFromPoint($g_hTreeView) - If $hItemHover <> 0 Then - ; bring focus to treeview to properly show DROPHILITE - _WinAPI_SetFocus($g_hTreeView) - _GUICtrlTreeView_SelectItem($g_hTreeView, $hItemHover) - _GUICtrlTreeView_SetState($g_hTreeView, $hTreeItemOrig, $TVIS_SELECTED, True) - Local $iTreeItem = TreeItemFromPoint($g_hTreeView) - $sTreeListItemText = _GUICtrlTreeView_GetText($g_hTreeView, $iTreeItem) - If $sTreeListItemText <> $sTreeListItemTextPrev Then - _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, "Move to " & $sTreeListItemText) - EndIf - $sTreeListItemTextPrev = $sTreeListItemText - Else - ; restore original treeview selection if cursor leaves treeview - _GUICtrlTreeView_SelectItem($g_hTreeView, $hTreeItemOrig) - $bTreeOrigStored = False - EndIf - - Case $aTreeList[4] = $idListview - Local $iListHover = ListItemFromPoint($g_hListview) - If $iListHover >= 0 Then - ; bring focus to listview to show hot item (needed for listview to listview drag) - _WinAPI_SetFocus($g_hListview) - _GUICtrlListView_SetHotItem($idListview, $iListHover) - Local $iListDrop = ListItemFromPoint($g_hListview) - Local $sListDropPath = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($idListview, $iListDrop, 0) - If __TreeListExplorer__PathIsFolder($sListDropPath) Then - $sTreeListItemText = _GUICtrlListView_GetItemText($idListview, $iListDrop, 0) - If $sTreeListItemTextPrev <> $sTreeListItemText Then - _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, "Move to " & $sTreeListItemText) - EndIf - $sTreeListItemTextPrev = $sTreeListItemText - Else - $sTreeListItemText = __TreeListExplorer_GetPath($hTLESystem) - $sTreeListItemText = _StringBetween($sTreeListItemText, "\", "\")[UBound(_StringBetween($sTreeListItemText, "\", "\")) - 1] - If $sTreeListItemTextPrev <> $sTreeListItemText Then - _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, "Move to " & $sTreeListItemText) - EndIf - $sTreeListItemTextPrev = $sTreeListItemText - EndIf - ElseIf $iListHover = -1 Then - $sTreeListItemText = __TreeListExplorer_GetPath($hTLESystem) - $sTreeListItemText = _StringBetween($sTreeListItemText, "\", "\")[UBound(_StringBetween($sTreeListItemText, "\", "\")) - 1] - If $sTreeListItemTextPrev <> $sTreeListItemText Then - _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, "Move to " & $sTreeListItemText) - EndIf - $sTreeListItemTextPrev = $sTreeListItemText - EndIf - - Case Else - If $sTreeListItemTextPrev <> $sTreeListItemText Then - $sTreeListItemText = " " - _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, $sTreeListItemText) - EndIf - $sTreeListItemTextPrev = $sTreeListItemText - EndSelect - - Case $GUI_EVENT_PRIMARYUP - Local $iTreeItem, $sTreeDropItem, $sDragDest - If $bDragTreeList Then - If $bDragToolActive Then - _GUIToolTip_TrackActivate($hToolTip3, False, $g_hGUI, $g_hGUI) - _GUIToolTip_Deactivate($hToolTip3) - ; restore original listview hover time - _GUICtrlListView_SetHoverTime($idListview, 500) - _GUIImageList_DestroyIcon($hIcon) - _GUIToolTip_SetTitle($hToolTip3, 'File Operation', $TTI_NONE) - $bDragToolActive = False - EndIf - $bDragTreeList = False - $bTreeOrigStored = False - ; restore proper state back to original treeview selection - _GUICtrlTreeView_SelectItem($g_hTreeView, $hTreeItemOrig) - Local $aTreeList = GUIGetCursorInfo($g_hGUI) - If $aTreeList[4] = $idTreeView Then - $iTreeItem = TreeItemFromPoint($g_hTreeView) - $sTreeDropItem = TreeItemToPath($g_hTreeView, $iTreeItem) - $sDragDest = $sTreeDropItem - - ; example showing which source files should go to which destination - _MsgExample($aDragSource, $sDragDest) - - ElseIf $aTreeList[4] = $idListview Then - Select - Case $sDragSrc = "Tree" ; drag and drop from treeview to listview - Local $sListDropItem = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($idListview, _GUICtrlListView_GetHotItem($idListview), 0) - If __TreeListExplorer__PathIsFolder($sListDropItem) Then - $sDragDest = $sListDropItem - Else - $sDragDest = __TreeListExplorer_GetPath($hTLESystem) - EndIf - - Case $sDragSrc = "List" ; drag and drop from listview to listview - Local $iListDrop = ListItemFromPoint($g_hListview) - Local $sListDropItem = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($idListview, $iListDrop, 0) - If __TreeListExplorer__PathIsFolder($sListDropItem) Then - $sDragDest = $sListDropItem - Else - $sDragDest = __TreeListExplorer_GetPath($hTLESystem) - EndIf - EndSelect - - ; example showing which source files should go to which destination - _MsgExample($aDragSource, $sDragDest) - - ElseIf $aTreeList[4] <> $idListview And $aTreeList[4] <> $idTreeView Then - MsgBox($MB_ICONERROR, "Example", "Cursor has been released in an area not yet supported by drag and drop.") - EndIf - EndIf EndSwitch EndFunc ;==>_EventsGUI -Func _MsgExample($aDragSource, $sDestination) - Local $sMsg - $sMsg = "Source Files: " & @CRLF - For $i = 1 To $aDragSource[0] - $sMsg &= $aDragSource[$i] & @CRLF - Next - $sMsg &= @CRLF - $sMsg &= "Destination: " & @CRLF - $sMsg &= $sDestination - MsgBox(0, "Example", $sMsg) -EndFunc ;==>_MsgExample - Func TreeItemFromPoint($hWnd) Local $tMPos = _WinAPI_GetMousePos(True, $hWnd) Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) @@ -1988,9 +2060,195 @@ Func _MenuFunctions() _Properties() Case $idAboutItem _About() + Case $idDeleteItem + _DeleteItems() + _AllowUndo() + Case $idRenameItem + _RenameItem() + _AllowUndo() + Case $idCopyItem + _CopyItems() + Case $idPasteItem + _PasteItems() + _AllowUndo() + Case $idUndoItem + _UndoOp() + Case $idHiddenItem + If BitAND(GUICtrlRead($idHiddenItem), $GUI_CHECKED) = $GUI_CHECKED Then + GUICtrlSetState($idHiddenItem, $GUI_UNCHECKED) + $bHideHidden = True + Else + GUICtrlSetState($idHiddenItem, $GUI_CHECKED) + $bHideHidden = False + EndIf + + __TreeListExplorer_ReloadView($idListView, True) + __TreeListExplorer_ReloadView($idTreeView, True) + Case $idSystemItem + If BitAND(GUICtrlRead($idSystemItem), $GUI_CHECKED) = $GUI_CHECKED Then + GUICtrlSetState($idSystemItem, $GUI_UNCHECKED) + $bHideSystem = False + Else + GUICtrlSetState($idSystemItem, $GUI_CHECKED) + $bHideSystem = True + EndIf + + __TreeListExplorer_ReloadView($idListView, True) + __TreeListExplorer_ReloadView($idTreeView, True) EndSwitch EndFunc ;==>_MenuFunctions +Func _UndoOp() + ; perform Undo by sending Ctrl+Z to the Desktop (Progman class, SysListView32 class) + Local Const $hProgman = WinGetHandle("[CLASS:Progman]") + Local Const $hCurrent = WinGetHandle("[ACTIVE]") + + Local Const $hSHELLDLL_DefView = _WinAPI_FindWindowEx($hProgman, 0, "SHELLDLL_DefView", "") + Local Const $hSysListView32 = _WinAPI_FindWindowEx($hSHELLDLL_DefView, 0, "SysListView32", "FolderView") + + _WinAPI_SetForegroundWindow($hSysListView32) + _WinAPI_SetFocus($hSysListView32) + + ControlSend($hSysListView32, "", "", "^z") + WinActivate($hCurrent) + + __TreeListExplorer_Reload($hTLESystem) + + GUICtrlSetState($idUndoItem, $GUI_DISABLE) + HotKeySet("^z") +EndFunc + +Func _AllowUndo() + GUICtrlSetState($idUndoItem, $GUI_ENABLE) + HotKeySet("^z", "_UndoOp") +EndFunc + +Func _PasteItems() + Local $sFullPath + Select + Case $sControlFocus = 'List' + Local $aSelectedLV = _GUICtrlListView_GetSelectedIndices($idListview, True) + If $aSelectedLV[0] = 0 Then + ; no selections in ListView currently, current path is Paste directory + Local $sSelectedLV = __TreeListExplorer_GetPath($hTLESystem) + $sFullPath = $sSelectedLV + ElseIf $aSelectedLV[0] = 1 Then + ; 1 item selection in ListView + Local $sSelectedItem = _GUICtrlListView_GetItemText($idListview, $aSelectedLV[1], 0) + Local $sSelectedLV = __TreeListExplorer_GetPath($hTLESystem) & $sSelectedItem + ; is selected path a folder + If StringInStr(FileGetAttrib($sSelectedLV), "D") Then + $sSelectedLV = $sSelectedLV + Else + Return + EndIf + EndIf + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + $sAction = "CopyItems" + _IFileOperationFile($pCopyObj, $sFullPath, $sAction, $iFlags) + __TreeListExplorer_Reload($hTLESystem) + Case $sControlFocus = 'Tree' + Local $hTreeItem = _GUICtrlTreeView_GetSelection($g_hTreeView) + Local $sItemText = TreeItemToPath($g_hTreeView, $hTreeItem) + $sFullPath = $sItemText + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + $sAction = "CopyItems" + _IFileOperationFile($pCopyObj, $sFullPath, $sAction, $iFlags) + __TreeListExplorer_Reload($hTLESystem) + EndSelect +EndFunc + +Func _CopyItems() + Select + Case $sControlFocus = 'List' + ; if previous copy object exists and user initiates new copy, release previous object + If $bCopy Then _Release($pCopyObj) + + ; create array with list of selected listview items + Local $aItems = _GUICtrlListView_GetSelectedIndices($g_hListView, True) + For $i = 1 To $aItems[0] + $aItems[$i] = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($g_hListView, $aItems[$i]) + Next + + ;Local $pDataObj = GetDataObjectOfFiles($hWnd, $aItems) ; MattyD function + + _ArrayDelete($aItems, 0) ; only needed for GetDataObjectOfFile_B + $pCopyObj = GetDataObjectOfFile_B($aItems) ; jugador function + + ; we don't want to release this until after Paste + ;_Release($pCopyObj) + + ; keep track of copy status for menu + $bCopy = True + Case $sControlFocus = 'Tree' + ; if previous copy object exists and user initiates new copy, release previous object + If $bCopy Then _Release($pCopyObj) + + Local $hTreeItem = _GUICtrlTreeView_GetSelection($g_hTreeView) + Local $sItemText = TreeItemToPath($g_hTreeView, $hTreeItem) + + ;Get an IDataObject representing the file to copy + $pCopyObj = GetDataObjectOfFile(_GUIFrame_GetHandle($iFrame_A, 1), $sItemText) + + ; we don't want to release this until after Paste + ;_Release($pCopyObj) + + ; keep track of copy status for menu + $bCopy = True + EndSelect +EndFunc + +Func _RenameItem() + Select + Case $sControlFocus = 'List' + Local $aSelectedLV = _GUICtrlListView_GetSelectedIndices($idListview, True) + ; there should only be one selected item during a rename + Local $iItemLV = $aSelectedLV[1] + Local $hEditLabel = _GUICtrlListView_EditLabel($g_hListView, $iItemLV) + Case $sControlFocus = 'Tree' + Local $hTreeItem = _GUICtrlTreeView_GetSelection($g_hTreeView) + _GUICtrlTreeView_EditText($g_hTreeView, $hTreeItem) + EndSelect +EndFunc + +Func _DeleteItems() + Select + Case $sControlFocus = 'List' + ; create array with list of selected listview items + Local $aItems = _GUICtrlListView_GetSelectedIndices($g_hListview, True) + For $i = 1 To $aItems[0] + $aItems[$i] = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($g_hListview, $aItems[$i]) + Next + + ;$pDataObj = GetDataObjectOfFiles($hWnd, $aItems) ; MattyD function + + _ArrayDelete($aItems, 0) ; only needed for GetDataObjectOfFile_B + Local $pDataObj = GetDataObjectOfFile_B($aItems) ; jugador function + + Local $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + _IFileOperationDelete($pDataObj, $iFlags) + + __TreeListExplorer_Reload($hTLESystem) + + _Release($pDataObj) + Case $sControlFocus = 'Tree' + Local $hTreeItemSel = _GUICtrlTreeView_GetSelection($g_hTreeView) + Local $sItemText = TreeItemToPath($g_hTreeView, $hTreeItemSel) + + Local $pDataObj, $pDropSource + + ;Get an IDataObject representing the file to copy + $pDataObj = GetDataObjectOfFile(_GUIFrame_GetHandle($iFrame_A, 1), $sItemText) + $iFlags = BitOR($FOFX_ADDUNDORECORD, $FOFX_RECYCLEONDELETE, $FOFX_NOCOPYHOOKS) + _IFileOperationDelete($pDataObj, $iFlags) + + __TreeListExplorer_Reload($hTLESystem) + + ;Relase the data object so the system can destroy it (prevent memory leaks) + _Release($pDataObj) + EndSelect +EndFunc + Func _EndDrag() ; reorder columns after header drag and drop _reorderLVCols() @@ -2029,7 +2287,7 @@ EndFunc ;==>_PathInputChanged Func _drawUAHMenuNCBottomLine($hWnd) ; ahmet $rcClient = _WinAPI_GetClientRect($hWnd) - Local $aCall = DllCall('user32.dll', "int", "MapWindowPoints", _ + Local $aCall = DllCall($hUser32, "int", "MapWindowPoints", _ "hwnd", $hWnd, _ ; hWndFrom "hwnd", 0, _ ; hWndTo "ptr", DllStructGetPtr($rcClient), _ @@ -2066,36 +2324,312 @@ Func WM_WINDOWPOSCHANGED_Handler($hWnd, $iMsg, $wParam, $lParam) Return $GUI_RUNDEFMSG EndFunc ;==>WM_WINDOWPOSCHANGED_Handler -Func _ListGetSelections() - $sListDragItems = "" - $aDragSource = "" - $aDragSource = _GUICtrlListView_GetSelectedIndices($g_hListview, True) - If $aDragSource[0] = 1 Then - $iListDragIndex = $aDragSource[1] - Else - $iListDragIndex = $aDragSource[1] - EndIf - For $i = 1 To $aDragSource[0] - $aDragSource[$i] = __TreeListExplorer_GetPath($hTLESystem) & _GUICtrlListView_GetItemText($idListview, $aDragSource[$i], 0) - $sListDragItems &= $aDragSource[$i] & " + " +;Convert @error codes from DllCall into win32 codes. +Func TranslateDllError($iError = @error) + Switch $iError + Case 0 + $iError = $ERROR_SUCCESS + Case 1 + $iError = $ERROR_DLL_INIT_FAILED + Case Else + $iError = $ERROR_INVALID_PARAMETER + EndSwitch +EndFunc + +Func CoTaskMemFree($pMemBlock) + DllCall("Ole32.dll", "none", "CoTaskMemFree", "ptr", $pMemBlock) +EndFunc ;==>CoTaskMemFree + +Func _SHDoDragDrop($pDataObj, $pDropSource, $iOKEffects) + ;We must pass a IID_IDropSource ptr. + $pDropSource = _QueryInterface($pDropSource, $sIID_IDropSource) + _Release($pDropSource) + + ;Local $aCall = DllCall($hShell32, "long", "SHDoDragDrop", "hwnd", $g_hGUI, "ptr", $pDataObj, "ptr", $pDropSource, "dword", $iOKEffects, "ptr*", 0) + Local $aCall = DllCall($hShell32, "long", "SHDoDragDrop", "hwnd", Null, "ptr", $pDataObj, "ptr", Null, "dword", $iOKEffects, "ptr*", 0) + + If @error Then Return SetError(@error, @extended, $aCall) + Return '0x' & Hex($aCall[0]) +EndFunc ;==>_SHDoDragDrop + +Func GetDataObjectOfFile($hWnd, $sPath) + ;Get the path as an idList. This is allocated memory that we should free later on. + Local $aCall = DllCall("Shell32.dll", "long", "SHParseDisplayName", "wstr", $sPath, "ptr", 0, "ptr*", 0, "ulong", 0, "ulong*", 0) + Local $iError = @error ? TranslateDllError() : $aCall[0] + If $iError Then Return SetError($iError, 0, False) + Local $pIdl = $aCall[3] + + ;From the idList, get two things: IShellFolder for the parent folder & the item's IDL relative to the parent folder. + Local $tIID_IShellFolder = _WinAPI_GUIDFromString($sIID_IShellFolder) + $aCall = DllCall("Shell32.dll", "long", "SHBindToParent", "ptr", $pIdl, "struct*", $tIID_IShellFolder, "ptr*", 0, "ptr*", 0) + $iError = @error ? TranslateDllError() : $aCall[0] + If $iError Then Return SetError($iError, 0, False) + Local $pShellFolder = $aCall[3] + ;SHBindToParent does not allocate a new PID, so we're not responsible for freeing $pIdlChild. + Local $tpIdlChild = DllStructCreate("ptr") + DllStructSetData($tpIdlChild, 1, $aCall[4]) + Local $ppIdlChild = DllStructGetPtr($tpIdlChild) + + ;We have an interface tag for IShellFolder, so we can use ObjCreateInterface to "convert" it into an object datatype. + ;$oShellFolder will automatically release when it goes out of scope, so we don't need to manually _Release($pShellFolder). + Local $oShellFolder = ObjCreateInterface($pShellFolder, $sIID_IShellFolder, $tagIShellFolder) + Local $pDataObject, $tIID_IDataObject = _WinAPI_GUIDFromString($sIID_IDataObject) + $iError = $oShellFolder.GetUIObjectOf($hWnd, 1, $ppIdlChild, $tIID_IDataObject, 0, $pDataObject) + + ;Free the IDL we initially created + CoTaskMemFree($pIdl) + + Return SetError($iError, 0, Ptr($pDataObject)) +EndFunc ;==>GetDataObjectOfFile + +Func GetDataObjectOfFiles($hWnd, $asPaths) + ;If we use the DesktopFolder object as the parent, children can all be defined by normal file paths. + ;So we don't need to worry about sibling folders to the root etc... + + Local $aCall = DllCall("Shell32.dll", "long", "SHGetDesktopFolder", "ptr*", 0) + Local $iError = @error ? TranslateDllError() : $aCall[0] + If $iError Then Return SetError($iError, 0, False) + + Local $pShellFolder = $aCall[1] + Local $tChildren = DllStructCreate(StringFormat("ptr pIdls[%d]", UBound($asPaths))) + + Local $iEaten, $pChildIDL, $iAttributes + Local $oShellFolder = ObjCreateInterface($pShellFolder, $sIID_IShellFolder, $tagIShellFolder) + + For $i = 1 To $asPaths[0] + $oShellFolder.ParseDisplayName($hWnd, 0, $asPaths[$i], $iEaten, $pChildIDL, $iAttributes) + $tChildren.pIdls(($i)) = $pChildIDL Next - $sListDragItems = StringTrimRight($sListDragItems, 3) - AdlibUnRegister("_ListGetSelections") -EndFunc ;==>_ListGetSelections -Func TreeItemToPath($hTree, $hItem, $bArray = False) - Local $sPath = StringReplace(_GUICtrlTreeView_GetTree($hTree, $hItem), "|", "\") - $sPath = StringTrimLeft($sPath, StringInStr($sPath, "\")) ; remove this pc at the beginning + ;We have an interface tag for IShellFolder, so we can use ObjCreateInterface to "convert" it into an object datatype. + ;$oShellFolder will automatically release when it goes out of scope, so we don't need to manually _Release($pShellFolder). + Local $pDataObject, $tIID_IDataObject = _WinAPI_GUIDFromString($sIID_IDataObject) + $iError = $oShellFolder.GetUIObjectOf($hWnd, $asPaths[0], DllStructGetPtr($tChildren), $tIID_IDataObject, 0, $pDataObject) - If StringInStr(FileGetAttrib($sPath), "D") Then - $sPath &= "\" ; let folders end with \ - EndIf + ;Free the IDLs now we have a data object. + For $i = 1 To $asPaths[0] + CoTaskMemFree($tChildren.pIdls(($i)) & @CRLF) + Next + + Return SetError($iError, 0, Ptr($pDataObject)) +EndFunc ;==>GetDataObjectOfFiles + +Func RegisterDragDrop($hWnd, $pDropTarget) + Local $aCall = DllCall("ole32.dll", "long", "RegisterDragDrop", "hwnd", $hWnd, "ptr", $pDropTarget) + If @error Then Return SetError(TranslateDllError(), 0, False) + Return SetError($aCall[0], 0, $aCall[0] = $S_OK) +EndFunc ;==>RegisterDragDrop + +Func RevokeDragDrop($hWnd) + Local $aCall = DllCall("ole32.dll", "long", "RevokeDragDrop", "hwnd", $hWnd) + If @error Then Return SetError(TranslateDllError(), 0, False) + Return SetError($aCall[0], 0, $aCall[0] = $S_OK) +EndFunc ;==>RevokeDragDrop + + +; jugador code + +Func GetDataObjectOfFile_B(ByRef $sPath) + Local $iCount = UBound($sPath) + If $iCount = 0 Then Return 0 + + Local $sParentPath = StringLeft($sPath[0], StringInStr($sPath[0], "\", 0, -1) - 1) + Local $pParentPidl = _WinAPI_ShellILCreateFromPath($sParentPath) + + Local $tPidls = DllStructCreate("ptr[" & $iCount & "]") + + Local $pFullPidl, $pRelativePidl, $last_SHITEMID + For $i = 0 To $iCount - 1 + $pFullPidl = _WinAPI_ShellILCreateFromPath($sPath[$i]) + $last_SHITEMID = DllCall($hShell32, "ptr", "ILFindLastID", "ptr", $pFullPidl)[0] + $pRelativePidl = DllCall($hShell32, "ptr", "ILClone", "ptr", $last_SHITEMID)[0] + DllStructSetData($tPidls, 1, $pRelativePidl, $i + 1) + DllCall($hShell32, "none", "ILFree", "ptr", $pFullPidl) + Next + + Local $tIID_IDataObject = _WinAPI_GUIDFromString($sIID_IDataObject) + Local $pIDataObject = __SHCreateDataObject($tIID_IDataObject, $pParentPidl, $iCount, DllStructGetPtr($tPidls), 0) + + DllCall($hShell32, "none", "ILFree", "ptr", $pParentPidl) + For $i = 1 To $iCount + DllCall($hShell32, "none", "ILFree", "ptr", DllStructGetData($tPidls, 1, $i)) + Next + + If Not $pIDataObject Then Return 0 + Return $pIDataObject +EndFunc + +Func GetDataObjectOfFile_C(ByRef $sPath) + If UBound($sPath) = 0 Then Return 0 + + Local $tIID_IDataObject = _WinAPI_GUIDFromString($sIID_IDataObject) + Local $pIDataObject = __SHCreateDataObject($tIID_IDataObject, 0, 0, 0, 0) + If Not $pIDataObject Then Return 0 + + Local Const $tag_IDataObject = _ + "GetData hresult(ptr;ptr*);" & _ + "GetDataHere hresult(ptr;ptr*);" & _ + "QueryGetData hresult(ptr);" & _ + "GetCanonicalFormatEtc hresult(ptr;ptr*);" & _ + "SetData hresult(ptr;ptr;bool);" & _ + "EnumFormatEtc hresult(dword;ptr*);" & _ + "DAdvise hresult(ptr;dword;ptr;dword*);" & _ + "DUnadvise hresult(dword);" & _ + "EnumDAdvise hresult(ptr*);" + Local $oIDataObject = ObjCreateInterface($pIDataObject, $sIID_IDataObject, $tag_IDataObject) + If Not IsObj($oIDataObject) Then + _Release($pIDataObject) + Return 0 + Endif + + Local $tFORMATETC, $tSTGMEDIUM + __Fill_tag_FORMATETC($tFORMATETC) + __Fill_tag_STGMEDIUM($tSTGMEDIUM, $sPath) + + $oIDataObject.SetData(DllStructGetPtr($tFORMATETC), DllStructGetPtr($tSTGMEDIUM), 1) + _AddRef($pIDataObject) + + Return $pIDataObject +EndFunc + +Func __Fill_tag_FORMATETC(Byref $tFORMATETC) + Local Const $CF_HDROP = 15 + Local Const $TYMED_HGLOBAL = 1 + + $tFORMATETC = DllStructCreate("ushort cfFormat; ptr ptd; uint dwAspect; int lindex; uint tymed") + DllStructSetData($tFORMATETC, "cfFormat", $CF_HDROP) + DllStructSetData($tFORMATETC, "dwAspect", 1) + DllStructSetData($tFORMATETC, "lindex", -1) + DllStructSetData($tFORMATETC, "tymed", $TYMED_HGLOBAL) +EndFunc + +Func __Fill_tag_STGMEDIUM(Byref $tSTGMEDIUM, Byref $aFiles) + Local Const $CF_HDROP = 15 + Local Const $TYMED_HGLOBAL = 1 + + Local $sFileList = "" + For $i = 0 To UBound($aFiles) - 1 + $sFileList &= $aFiles[$i] & Chr(0) + Next + $sFileList &= Chr(0) + + Local $iSize = 20 + (StringLen($sFileList) * 2) + + Local $hGlobal = DllCall($hKernel32, "ptr", "GlobalAlloc", "uint", 0x2042, "ulong_ptr", $iSize)[0] + Local $pLock = DllCall($hKernel32, "ptr", "GlobalLock", "ptr", $hGlobal)[0] + + Local $tDROPFILES = DllStructCreate("dword pFiles; int x; int y; bool fNC; bool fWide", $pLock) + DllStructSetData($tDROPFILES, "pFiles", 20) + DllStructSetData($tDROPFILES, "fWide", True) + + Local $tPaths = DllStructCreate("wchar[" & StringLen($sFileList) & "]", $pLock + 20) + DllStructSetData($tPaths, 1, $sFileList) + + DllCall($hKernel32, "bool", "GlobalUnlock", "ptr", $hGlobal) + + $tSTGMEDIUM = DllStructCreate("uint tymed; ptr hGlobal; ptr pUnkForRelease") + DllStructSetData($tSTGMEDIUM, "tymed", $TYMED_HGLOBAL) + DllStructSetData($tSTGMEDIUM, "hGlobal", $hGlobal) + DllStructSetData($tSTGMEDIUM, "pUnkForRelease", 0) +EndFunc + +Func __SHCreateDataObject($tIID_IDataObject, $ppidlFolder = 0, $cidl = 0, $papidl = 0, $pdtInner = 0) + Local $aRes = DllCall($hShell32, "long", "SHCreateDataObject", _ + "ptr", $ppidlFolder, _ + "uint", $cidl, _ + "ptr", $papidl, _ + "ptr", $pdtInner, _ + "struct*", $tIID_IDataObject, _ + "ptr*", 0) + If @error Then Return SetError(1, 0, $aRes[0]) + Return $aRes[6] +EndFunc + +; jugador code above + +Func _VersionToString($arVersion, $sSep = " ") + If Not IsArray($arVersion) Or UBound($arVersion, 0)<2 Or UBound($arVersion, 1)<2 Then Return SetError(1, 1, "Version not parsed.") + Local $sVersion = "" + If $arVersion[1][0]>0 Then + $sVersion &= $arVersion[1][1] + EndIf + If $sVersion = "" Then Return "Version unknown" + Return $sVersion +EndFunc + +Func _UDFGetVersion($sFile) + Local $sCode = FileRead($sFile) + If @error Then Return SetError(@error, @extended, 0) + Local $arVersion = _GetVersion($sCode) + If @error Then Return SetError(@error, @extended, -1) + Return $arVersion +EndFunc - If Not $bArray Then - Return $sPath +; #FUNCTION# ==================================================================================================================== +; Name ..........: _GetVersion +; Description ...: Get the AutoIt Version as well as the UDF Version. +; Syntax ........: _GetVersion($sUdfCode) +; Parameters ....: $sUdfCode - the sourcecode of the udf +; Return values .: Array with version information. +; Author ........: Kanashius +; Modified ......: +; Remarks .......: @extended (1 - Only AutoIt Version found, 2 - Only UDF Version found, 3 - Both found) +; Resurns a 2D-Array with: +; [0][0] being the amount of version parts found for the AutoIt Version + 1 +; [0][1] If [0][0]>0 then this is the full autoit version as string +; [0][2] The first part of the autoit version (index 2-5 is a number) +; ... +; [0][6] The last part of the autoit version (last part is a/b/rc) +; [1][0] being the amount of version parts found for the UDF Version + 1 +; [1][1] If [1][0]>0 then this is the full udf version as string +; [1][2] The first part of the udf version (index 2-5 is a number) +; ... +; [1][6] The last part of the udf version (last part is a/b/rc) +; Related .......: +; Link ..........: +; Example .......: No +; =============================================================================================================================== +Func _GetVersion($sUdfCode) + Local $iExtended = 0 + Local $arAutoItVersion = StringRegExp($sUdfCode, "(?m)(?s)^;\s*#INDEX#\s*=*.*?;\s*AutoIt\s*Version\s*\.*:\s((\d+)(?:\.(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?(a|b|rc)?)\s*$", 1) + If Not @error Then $iExtended = 1 + Local $arUDFVersion = StringRegExp($sUdfCode, "(?m)(?s)^;\s*#INDEX#\s*=*.*?;\s*Version\s*\.*:\s((\d+)(?:\.(\d+)(?:\.(\d+))?)?(a|b|rc)?)\s*$", 1) + If Not @error Then $iExtended += 2 + Local $iVerNumbers = UBound($arAutoItVersion) + If UBound($arUDFVersion)>$iVerNumbers Then $iVerNumbers = UBound($arUDFVersion) + Local $arResult[2][$iVerNumbers+1] + $arResult[0][0] = UBound($arAutoItVersion) + For $i=0 to UBound($arAutoItVersion)-1 Step 1 + $arResult[0][$i+1] = $arAutoItVersion[$i] + Next + $arResult[1][0] = UBound($arUDFVersion) + For $i=0 to UBound($arUDFVersion)-1 Step 1 + $arResult[1][$i+1] = $arUDFVersion[$i] + Next + Return SetExtended($iExtended, $arResult) +EndFunc + +Func _filterCallback($hSystem, $hView, $bIsFolder, $sPath, $sName, $sExt) + If $bHideHidden Or $bHideSystem Then + ; ensure that root drive letters do not get hidden + If _WinAPI_PathIsRoot_mod($sPath&$sName&$sExt) Then Return True + + Switch $sName + Case "$RECYCLE.BIN" + Return False + Case "System Volume Information" + Return False + EndSwitch EndIf - Local $aPath = _ArrayFromString($sPath) - _ArrayInsert($aPath, 0, 1) - Return $aPath -EndFunc ;==>TreeItemToPath + Select + Case $bHideSystem + ; filter out files and folders with System attribute + If StringInStr(FileGetAttrib($sPath&$sName&$sExt), "S", 2)>0 Then Return False + Case $bHideHidden + ; filter out files and folders with Hidden attribute + If StringInStr(FileGetAttrib($sPath&$sName&$sExt), "H", 2)>0 Then Return False + EndSelect + + Return True +EndFunc