I was trying to create an AutoIt script to create a new folder and then highlight it for renaming like if we right click and create a new folder.
Here is my script. What I wanted to achieve is create the new folder, highlight it, then press F2.
#include <WinAPI.au3>
HotKeySet("#y", "NewFolder")
While 1
Sleep(200)
WEnd
Func NewFolder()
Local $hWnd = WinGetHandle("[ACTIVE]")
Local $class = _WinAPI_GetClassName($hWnd)
If StringCompare($class, "CabinetWClass") = 0 Then
Local $sSelected_Path = _GetWindowsExplorerPath($hWnd) & "\NewFolder" & $count
Local $iFileExists = FileExists($sSelected_Path)
If $iFileExists Then
$count += 1
Else
Local $success = DirCreate($sSelected_Path)
Sleep(500)
If $success = 1 Then
Local $Finditem = ControlListView($hWnd, "", "[CLASS:SysListView32; INSTANCE:1]", "Finditem", "NewFolder")
MsgBox(0, "", $Finditem)
Local $Select = ControlListView($hWnd, "", "[CLASS:SysListView32; INSTANCE:1]", "Select", $Finditem)
$count += 1
EndIf
EndIf
EndIf
EndFunc
Func _GetWindowsExplorerPath($hWnd)
Local $pv, $pidl, $return = "", $ret, $hMem, $pid, $folderPath = DllStructCreate("char[260]"), $className
Local $bPIDL = False
Local Const $CWM_GETPATH = 0x400 + 12;
; Check the classname of the window first
$className = DllCall("user32.dll", "int", "GetClassName", "hwnd", $hWnd, "str", "", "int", 4096)
If @error Then Return SetError(2, 0, "")
If ($className[2] <> "ExploreWClass" And $className[2] <> "CabinetWClass") Then Return SetError(1, 0, "")
; Retrieve the process ID for our process
$pid = DllCall("kernel32.dll", "int", "GetCurrentProcessId")
If @error Then Return SetError(2, 0, "")
; Send the CWM_GETPATH message to the window
$hMem = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $CWM_GETPATH, "wparam", $pid[0], "lparam", 0)
If @error Then Return SetError(2, 0, "")
If $hMem[0] = 0 Then Return SetError(1, 0, "")
; Lock the shared memory
$pv = DllCall("shell32.dll", "ptr", "SHLockShared", "uint", $hMem[0], "uint", $pid[0])
If @error Then Return SetError(2, 0, "")
If $pv[0] Then
$pidl = DllCall("shell32.dll", "ptr", "ILClone", "uint", $pv[0]) ; Clone the PIDL
If @error Then Return SetError(2, 0, "")
$bPIDL = True
DllCall("shell32.dll", "int", "SHUnlockShared", "uint", $pv) ; Unlock the shared memory
EndIf
DllCall("shell32.dll", "int", "SHFreeShared", "uint", $hMem, "uint", $pid) ; Free the shared memory
If $bPIDL Then
; Retrieve the path from the PIDL
$ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", $pidl[0], "ptr", DllStructGetPtr($folderPath))
If (@error = 0) And ($ret[0] <> 0) Then $return = DllStructGetData($folderPath, 1) ; Retrieve the value
DllCall("shell32.dll", "none", "ILFree", "ptr", $pidl[0]) ; Free up the PIDL that we cloned
Return SetError(0, 0, $return) ; Success
EndIf
Return SetError(2, 0, "") ; Failed a WinAPI call
EndFunc
This works for me in Win7 - should work in xp as long as address bar is turned on. MUCH simpler than using the DLL calls. I left you a little bit of work to do :)
HotKeySet("#y","_NewFolder")
HotKeySet("#n","_EXIT")
While 1
Sleep(250)
WEnd
FUNC _NewFolder() ; make all vars local
$TEXT = WinGetText("[active]")
; handle error here
$SPLIT = StringSplit($TEXT,@CR & @LF & @CRLF) ;split on new lines (idk which one of the three it uses)
IF IsArray($SPLIT) Then
; trigger = true
FOR $I = 1 to $SPLIT[0]
IF StringInStr($SPLIT[$i],"Address: ") Then
; trigger = false
$STRING = StringReplace($SPLIT[$i],"Address: ","")
$INPUT = InputBox("New Folder","Name your new folder")
; add some enforcement to input box, i like do until loops
$PATH = $STRING & "\" & $INPUT
$CREATE = DirCreate($PATH)
; handle error here
Return SetError(0,0,$PATH)
EndIf
Next
; if trigger then error
Else
Return SetError(1,0,0) ;if split is not an array - could add some more here in case address is the only line returned
EndIf
EndFunc
Func _Exit()
Exit
EndFunc