
4 options to change the current folder in Windows Explorer
- joedf
- Posts: 8716
- Joined: 29 Sep 2013, 17:08
- Facebook: J0EDF
- Google: +joedf
- GitHub: joedf
- Location: Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
ill test whatever, i use virtualbox with the consumer preview that i never deleted 






Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x8GB G.Skill RipJaws V - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Populate the AHK MiniCity!] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
Re: 4 options to change the current folder in Windows Explor
LearningOne, I took the liberty of cleaning up your code. I hope you don't mind. It looks like it suffered from the common case of "over-commenting". A good rule of thumb is to avoid using end-of-line comments and to limit the length of a line to 100 columns/characters.
As far as I know, I didn't change any of the code at all except for formatting/spacing inconsistencies.
Code: Select all
;===Hotkeys for testing===
F1::RMApp_NavControlHandler(A_WinDir)
F2::RMApp_NavControlHandler("C:\")
F3::RMApp_NavControlHandler(A_MyDocuments)
Escape::ExitApp
;==================================================================================================
;~ Part of Radial menu codes posted by Learning one at
;~ http://www.autohotkey.com/board/topic/46856-radial-menu-scripts/
;~ RM's Navigator is a drop down menu that helps you easily navigate to folders that you often use.
;~ It navigates to your favourite folders in Windows Explorer, My Computer, and other standard
;~ Open, Save, Export, Import, Upload, Select, etc. dialogue windows.
RMApp_NavControlHandler(FolderPath, ActiveWinID="")
;~ RM executes this function after the user selects an item in Navigator menu,
;~ if it is a folder or disk path.
;~ "ActiveWinID" is hwnd/ID of active window, for example: "0xa03f0".
;~ "FolderPath" can be disk or folder path, for example: "C:\Program Files".
;~ "ActiveWinID" and "FolderPath" parameters are provided by RM.
;~ RMApp_IsControlVisible() returns 1 if control is visible
;~ RMApp_ControlSetTextR() same as ControlSetText command, but more reliable
;~ RMApp_ControlSetFocusR() same as ControlSetFocus command, but more reliable
{
; Check if FolderPath exists in the filesystem
IfNotExist, %FolderPath%
return
if (ActiveWinID = "")
ActiveWinID := WinExist("A")
; turn on "restore initial content of control" switch
RestoreInitText := 1
WinGetTitle, ActiveWinTitle, ahk_id %ActiveWinID%
WinGetClass, ActiveWinClass, ahk_id %ActiveWinID%
; ---------------------------------------------------------------------------------------------
; Find which control to which to set to FolderPath,
; and depending on the control, whether to restore the control's initial contents.
; ---------------------------------------------------------------------------------------------
; Windows Explorer
if ActiveWinClass in ExploreWClass,CabinetWClass
{
; Windows 7 and Vista: click on address bar to hide ToolbarWindow322 and show Edit1 control
if A_OSVersion in WIN_7,WIN_VISTA
{
ControlGetPos, x, y, , , ToolbarWindow322, ahk_class %ActiveWinClass%
; Determine click location: in by 6px of upper left corner of ToolbarWindow322 (on icon)
PosToClick := "x" (x + 6) " y" (y + 6)
ControlClick, %PosToClick%, ahk_class %ActiveWinClass%
; Wait for Edit1 to show
Loop
{
Sleep, 20
; 600 ms passed and Edit1 is not shown
if (A_Index = 30)
return
} Until (RMApp_IsControlVisible("ahk_id " ActiveWinID,"Edit1") = 1)
; Edit1 is shown, so set Edit1 contents to FolderPath. Do not restore initial content.
Control := "Edit1"
RestoreInitText := 0
;~ Some less reliable solutions to show the Edit1 control:
;~ * Click in centre of control: will not work if breadcrumbs extend past halfway
;~ -> ControlClick, ToolbarWindow322, ahk_class CabinetWClass
;~ * Use the Alt+d keyboard shortcut: locale-dependent
;~ -> Send, !D
}
; Windows XP and older
else
{
; Address bar is visible, so set Edit1 contents to FolderPath.
; Do not restore initial content.
if (RMApp_IsControlVisible("ahk_id " ActiveWinID,"Edit1") = 1)
{
Control := "Edit1"
RestoreInitText := 0
}
else return
}
}
; Open/Save dialogue box class #32770
else if (ActiveWinClass = "#32770")
{
; Standard dialogue boxes
if RMApp_IsControlVisible("ahk_id " ActiveWinID,"Edit1")
Control := "Edit1"
; Microsoft Office dialogue boxes
else if RMApp_IsControlVisible("ahk_id " ActiveWinID,"Edit2")
Control := "Edit2"
else return
}
; Non-standard dialogue box (not class #32770)
else if ActiveWinTitle contains Open,Save,Export,Import,Upload,Select
{
; Edit1 control exists
if RMApp_IsControlVisible("ahk_id " ActiveWinID,"Edit1")
Control := "Edit1"
; RichEdit20W2 control exists
else if RMApp_IsControlVisible("ahk_id " ActiveWinID,"RichEdit20W2")
Control := "RichEdit20W2"
else return
}
; All other cases
else
{
Run, explore %FolderPath%
return
}
; ---------------------------------------------------------------------------------------------
; Set contents of control to FolderPath, and depending on circumstances, restore initial
; content of control after navigation.
; ---------------------------------------------------------------------------------------------
if RestoreInitText
ControlGetText, InitControlText, %Control%, ahk_id %ActiveWinID%
; Set contents of control to FolderPath
RMApp_ControlSetTextR(Control, FolderPath, "ahk_id " ActiveWinID)
; Focus control
RMApp_ControlSetFocusR(Control, "ahk_id " ActiveWinID)
; If initialy active window loses focus, refocus it
if (WinExist("A") != ActiveWinID)
WinActivate, ahk_id %ActiveWinID%
; Silly but necessary!
SendInput, {End}{Space}{Backspace}{enter}
;~ Question: Why not use the following?
;~ -> ControlSetText, ...
;~ -> ControlSend, %Control%, {enter}, ahk_id %ActiveWinID%
;~ Answer: In some "Save as" dialoguess in certain programmes, this auto saves the file
;~ instead of navigating to the specified folder. After a lot of testing, I concluded that
;~ the most reliable method, which works and prevents this, is the one that looks weird and
;~ silly: after setting the text using ControlSetText, the control must be focused and some
;~ dummy text sent to it using SendInput (in this case space), then deleted, and than enter,
;~ which navigates to the specified folder. Tests show that this is the most reliable method.
; Restore the content of the control, if necessary
if RestoreInitText
{
Sleep, 60
ControlGetText, ControlTextAfterNavigation, %Control%, ahk_id %ActiveWinID%
; if control content was not automatically restored, restore it
if not (ControlTextAfterNavigation = InitControlText)
RMApp_ControlSetTextR(Control, InitControlText, "ahk_id " ActiveWinID)
}
; Refocus window
if not (WinExist("A") = ActiveWinID)
WinActivate, ahk_id %ActiveWinID%
;~ Question: Why not focus the control that was initialy focused?
;~ Answer: In some cases it causes problems in Windows Explorer.
;~ ; Get the class of the control that had focus in the window that was initiallt active
;~ InitFocusedControl := RMApp_Reg("ControlFocClass")
;~ if (InitFocusedControl != "") and (RMApp_IsControlVisible("ahk_id " ActiveWinID, InitFocusedControl))
;~ ; focus initialy focused control
;~ RMApp_ControlSetFocusR(InitFocusedControl, "ahk_id " ActiveWinID)
;~ An old method which looks more proper, but is much less reliable:
;~ if RestoreInitText
;~ ControlGetText, InitControlText, %Control%, ahk_id %ActiveWinID%
;~ RMApp_ControlSetTextR(Control, FolderPath, "ahk_id " ActiveWinID)
;~ Sleep, 60
;~ ControlSend, %Control%, {enter}, ahk_id %ActiveWinID%
;~ Sleep, 60
;~ if RestoreInitText
;~ RMApp_ControlSetTextR(Control, InitControlText, "ahk_id " ActiveWinID)
;~ if (WinExist("A") != ActiveWinID)
;~ WinActivate, ahk_id %ActiveWinID%
}
RMApp_IsControlVisible(WinTitle,ControlClass)
{
ControlGet, IsControlVisible, Visible,, %ControlClass%, %WinTitle%
return IsControlVisible
}
RMApp_ControlSetFocusR(Control, WinTitle="", Tries=3)
; More reliable than ControlSetFocus
{
Loop, %Tries%
{
ControlFocus, %Control%, %WinTitle%
Sleep, 50
ControlGetFocus, FocusedControl, %WinTitle%
if (FocusedControl = Control)
return 1
}
}
RMApp_ControlSetTextR(Control, NewText="", WinTitle="", Tries=3)
; More reliable than ControlSetText
{
Loop, %Tries%
{
ControlSetText, %Control%, %NewText%, %WinTitle%
Sleep, 50
ControlGetText, CurControlText, %Control%, %WinTitle%
if (CurControlText = NewText)
return 1
}
}
- Learning one
- Posts: 172
- Joined: 04 Oct 2013, 13:59
- Location: Croatia
- Contact:
Re: 4 options to change the current folder in Windows Explor
chaz, thanks for cleaning up my code from over-commenting 
joedf, it would be great if you could test code below on Win 8
* * *
New, upgraded (I hope) Navigator is now available for testing. I tested it on Win 7 and it works fine for me. Tell me does it work for you... (+ please write your OS Version)

joedf, it would be great if you could test code below on Win 8

* * *
New, upgraded (I hope) Navigator is now available for testing. I tested it on Win 7 and it works fine for me. Tell me does it work for you... (+ please write your OS Version)

Code: Select all
;=== Hotkeys for testing ===
F1::RMApp_NavControlHandler("C:\")
F2::RMApp_NavControlHandler(A_MyDocuments)
F3::RMApp_NavControlHandler(3) ; Control Panel
F4::RMApp_NavControlHandler(17) ; My Computer
F5::RMApp_NavControlHandler(10) ; Recycle Bin
Esc::ExitApp
; ShellSpecialFolderConstants: http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
;===Functions===========================================================================
/*
Part of Radial menu codes posted by Learning one.
http://www.autohotkey.com/board/topic/46856-radial-menu-scripts/
http://ahkscript.org/boards/viewtopic.php?p=4673#p4673
RM's Navigator is a drop down menu which helps you to easily navigate to folders that you often use. It navigates to your favorite folders in Windows explorer, My Computer, and in other standard Open, Save, Export, Import, Upload, Select dialog windows.
*/
RMApp_NavControlHandler(FolderPath, hwnd="", FocusedControl="") {
/*
RM executes this function after user selects item in Navigator menu, if it is a folder path, drive path or ShellSpecialFolderConstant.
All parameters are provided by RM.
Note that you can't always navigate to all ShellSpecialFolders. For example, you can't navigate to Control panel while you're in standard "Open File" dialog box window, but you can always navigate there while you're in Windows explorer.
"FolderPath" can be folder path, drive path or ShellSpecialFolderConstant, for example: "C:\Program Files", "C:\", "10"
"hwnd" is handle to window, for example: "0xa03f0".
"FocusedControl" is control of the target window which has input focus, if any. Example: "Button2"
Some functions in use:
RMApp_IsControlVisible() returns 1 if control is visible
RMApp_ControlSetTextR() same as ControlSetText command, but a little bit more reliable
RMApp_ControlSetFocusR() same as ControlSetFocus command, but a little bit more reliable
RMApp_Explorer_Navigate() navigates to specified folder in Windows Explorer or MyComputer
*/
RestoreInitText := 1 ; turn on "restore control's initial text after navigating to specified folder" switch
hwnd := (hwnd="") ? WinExist("A") : hwnd ; if omitted, use active window
WinGetTitle, WinTitle, ahk_id %hwnd% ; get window's title
WinGetClass,WinClass, ahk_id %hwnd% ; get window's class
if (FocusedControl="")
ControlGetFocus, FocusedControl, ahk_id %hwnd% ; if not specified, get FocusedControl
if FolderPath is integer
FolderPath := Round(FolderPath) ; for some strange reason, this has to be done although it looks like nonsense, otherwise try RMApp_Explorer_Navigate(FolderPath, hwnd) won't work properly if FolderPath if ShellSpecialFolderConstant
;=== If window is Windows Explorer or MyComputer ===
if WinClass in ExploreWClass,CabinetWClass
{
try RMApp_Explorer_Navigate(FolderPath, hwnd)
if (FocusedControl != "" and RMApp_IsControlVisible("ahk_id " hwnd, FocusedControl) = 1)
RMApp_ControlSetFocusR(FocusedControl, "ahk_id " hwnd) ; focus initialy focused control
return
}
;=== Other cases (not Windows Explorer or MyComputer) - first we'll decide to which control we will send FolderPath ===
if (WinClass = "#32770") { ; dialog box class
if RMApp_IsControlVisible("ahk_id " hwnd, "Edit1")
Control := "Edit1" ; in standard dialog windows, "Edit1" control is the right choice
Else if RMApp_IsControlVisible("ahk_id " hwnd, "Edit2")
Control := "Edit2" ; but sometimes in MS office, if condition above fails, "Edit2" control is the right choice
Else ; if above fails - just return and do nothing.
Return
}
Else if WinTitle contains Open,Save,Export,Import,Upload,Select ; this is the case in some MS office dialog windows, which are not #32770 class.
{
if RMApp_IsControlVisible("ahk_id " hwnd, "Edit1")
Control := "Edit1" ; if "Edit1" control exists, it is the right choice.
Else if RMApp_IsControlVisible("ahk_id " hwnd, "RichEdit20W2")
Control := "RichEdit20W2" ; some MS office dialogs don't have "Edit1" control, but they have "RichEdit20W2" control, which is then the right choice.
Else ; if above fails - just return and do nothing.
Return
}
Else { ; in all other cases, we'll explore FolderPath, and return from this function
ComObjCreate("Shell.Application").Explore(FolderPath) ; http://msdn.microsoft.com/en-us/library/windows/desktop/bb774073%28v=vs.85%29.aspx
Return
}
;=== Refine ShellSpecialFolderConstant ===
if FolderPath is integer
{
if (FolderPath = 17) ; My Computer --> 17 or 0x11
FolderPath := "::{20d04fe0-3aea-1069-a2d8-08002b30309d}" ; because you can't navigate to "17" but you can navigate to "::{20d04fe0-3aea-1069-a2d8-08002b30309d}"
else ; don't allow other ShellSpecialFolderConstants. For example - you can't navigate to Control panel while you're in standard "Open File" dialog box window.
return
}
/*
ShellSpecialFolderConstants: http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
CSIDL: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx
KNOWNFOLDERID: http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457%28v=vs.85%29.aspx
*/
;===In this part (if we reached it), we'll send FolderPath to control and optionaly restore control's initial text after navigating to specified folder===
if (RestoreInitText = 1) ; if we want to restore control's initial text after navigating to specified folder
ControlGetText, InitControlText, %Control%, ahk_id %hwnd% ; we'll get and store control's initial text first
RMApp_ControlSetTextR(Control, FolderPath, "ahk_id " hwnd) ; set control's text to FolderPath
RMApp_ControlSetFocusR(Control, "ahk_id " hwnd) ; focus control
if (WinExist("A") != hwnd) ; in case that some window just popped out, and initialy active window lost focus
WinActivate, ahk_id %hwnd% ; we'll activate initialy active window
;=== Avoid accidental hotkey & hotstring triggereing while doing SendInput - can be done simply by #UseHook, but do it if user doesn't have #UseHook in the script ===
If (A_IsSuspended = 1)
WasSuspended := 1
if (WasSuspended != 1)
Suspend, On
SendInput, {End}{Space}{Backspace}{enter} ; silly but necessary part - go to end of control, send dummy space, delete it, and then send enter
if (WasSuspended != 1)
Suspend, Off
/*
Question: Why not use ControlSetText, and then send enter to control via ControlSend, %Control%, {enter}, ahk_id %hwnd% ?
Because in some "Save as" dialogs in some programs, this causes auto saving file instead of navigating to specified folder! After a lot of testing, I concluded that most reliable method, which works and prevents this, is the one that looks weird & silly; after setting text via ControlSetText, control must be focused, then some dummy text must be sent to it via SendInput (in this case space, and then backspace which deletes it), and then enter, which causes navigation to specified folder.
Question: Ok, but is "SendInput, {End}{Space}{Backspace}{enter}" really necessary? Isn't "SendInput, {enter}" sufficient?
No. Sending "{End}{Space}{Backspace}{enter}" is definitely more reliable then just "{enter}". Sounds silly but tests showed that it's true.
*/
if (RestoreInitText = 1) { ; if we want to restore control's initial text after we navigated to specified folder
Sleep, 70 ; give some time to control after sending {enter} to it
ControlGetText, ControlTextAfterNavigation, %Control%, ahk_id %hwnd% ; sometimes controls automatically restore their initial text
if (ControlTextAfterNavigation != InitControlText) ; if not
RMApp_ControlSetTextR(Control, InitControlText, "ahk_id " hwnd) ; we'll set control's text to its initial text
}
if (WinExist("A") != hwnd) ; sometimes initialy active window loses focus, so we'll activate it again
WinActivate, ahk_id %hwnd%
if (FocusedControl != "" and RMApp_IsControlVisible("ahk_id " hwnd, FocusedControl) = 1)
RMApp_ControlSetFocusR(FocusedControl, "ahk_id " hwnd) ; focus initialy focused control
/*
;==Old method which looks more proper, but is definitely less reliable==
if RestoreInitText
ControlGetText, InitControlText, %Control%, ahk_id %hwnd%
RMApp_ControlSetTextR(Control, FolderPath, "ahk_id " hwnd)
Sleep, 60
ControlSend, %Control%, {enter}, ahk_id %hwnd%
Sleep, 60
if RestoreInitText
RMApp_ControlSetTextR(Control, InitControlText, "ahk_id " hwnd)
if (WinExist("A") != hwnd)
WinActivate, ahk_id %hwnd%
*/
}
RMApp_Explorer_Navigate(FullPath, hwnd="") { ; by Learning one
; http://ahkscript.org/boards/viewtopic.php?p=4568#p4568
; http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
; http://msdn.microsoft.com/en-us/library/aa752094
hwnd := (hwnd="") ? WinExist("A") : hwnd ; if omitted, use active window
WinGet, ProcessName, ProcessName, % "ahk_id " hwnd
if (ProcessName != "explorer.exe") ; not Windows explorer
return
For pExp in ComObjCreate("Shell.Application").Windows
{
if (pExp.hwnd = hwnd) { ; matching window found
if FullPath is integer ; ShellSpecialFolderConstant
pExp.Navigate2(FullPath)
else
pExp.Navigate("file:///" FullPath)
return
}
}
}
RMApp_IsControlVisible(WinTitle,ControlClass) { ; used in Navigator
ControlGet, IsControlVisible, Visible,, %ControlClass%, %WinTitle%
return IsControlVisible
}
RMApp_ControlSetFocusR(Control, WinTitle="", Tries=3) { ; used in Navigator. More reliable ControlSetFocus
Loop, %Tries%
{
ControlFocus, %Control%, %WinTitle% ; focus control
Sleep, 50
ControlGetFocus, FocusedControl, %WinTitle% ; check
if (FocusedControl = Control) ; if OK
return 1
}
}
RMApp_ControlSetTextR(Control, NewText="", WinTitle="", Tries=3) { ; used in Navigator. More reliable ControlSetText
Loop, %Tries%
{
ControlSetText, %Control%, %NewText%, %WinTitle% ; set
Sleep, 50
ControlGetText, CurControlText, %Control%, %WinTitle% ; check
if (CurControlText = NewText) ; if OK
return 1
}
}
My Website • Join DropBox
- joedf
- Posts: 8716
- Joined: 29 Sep 2013, 17:08
- Facebook: J0EDF
- Google: +joedf
- GitHub: joedf
- Location: Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
Works Perfectly/Flawlessly Under WinXP, Win7, Win8 - Confirmed
nice script btw!






Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x8GB G.Skill RipJaws V - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Populate the AHK MiniCity!] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
@LearningOne: Maybe the following approach would avoid the need to rely on dialog box titles to detect MS Office dialog boxes and would work with any localization of MS Office apps:LearningOne wrote: Else if WinTitle contains Open,Save,Export,Import,Upload,Select ; this is the case in some MS office dialog windows, which are not #32770 class.
Code: Select all
Else if InStr(WinClass, "bosa_sdm_") ; for some MS office dialog windows, which are not #32770 class.



- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
@joedf: Thanks for testing !
@LearningOne: I did some cherry picking in your code. Many thanks.
@All: I posted the ALPHA version of my code on GitHub (download these two files: PopupFolders.ahk and PopupFolders_LANG.ahk). This is (yet) another favorite folders popup menu. But this one will be my preferred
Once loaded, press MIDDLE mouse button when mouse is over Windows Explorer, Desktop or a file dialog box to open the folders popup menu. You can also press SHIFT+MIDDLE mouse button anywhere.
The settings Gui is not implemented yet but you can edit the settings directly in the .ini file if you wish. There is a lot of debugging code in the script but it will not interfere with its execution.
Next in the pipeline: support for Console support, implements Gui buttons commands, implement Add Folder and Add Dialog boxes, etc.
Fell free to report bugs or suggestions/comments here on in the GitHub Issues.
@LearningOne: I did some cherry picking in your code. Many thanks.
@All: I posted the ALPHA version of my code on GitHub (download these two files: PopupFolders.ahk and PopupFolders_LANG.ahk). This is (yet) another favorite folders popup menu. But this one will be my preferred

Once loaded, press MIDDLE mouse button when mouse is over Windows Explorer, Desktop or a file dialog box to open the folders popup menu. You can also press SHIFT+MIDDLE mouse button anywhere.
The settings Gui is not implemented yet but you can edit the settings directly in the .ini file if you wish. There is a lot of debugging code in the script but it will not interfere with its execution.
Next in the pipeline: support for Console support, implements Gui buttons commands, implement Add Folder and Add Dialog boxes, etc.
Fell free to report bugs or suggestions/comments here on in the GitHub Issues.



- joedf
- Posts: 8716
- Joined: 29 Sep 2013, 17:08
- Facebook: J0EDF
- Google: +joedf
- GitHub: joedf
- Location: Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
Console support?? LibCon? http://joedf.github.io/libcon/
what do you mean?
what do you mean?





Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x8GB G.Skill RipJaws V - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Populate the AHK MiniCity!] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
Re: 4 options to change the current folder in Windows Explor
Console support as in you can use the middle-click menu to go to one of your favourite folders in Command Prompt, instead of the default C:\\.joedf wrote:Console support?? LibCon? http://joedf.github.io/libcon/
what do you mean?
- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
Your console app looks interesting but all I need is to change directory while the mouse is over the console (SendInput cd /d %Path% {Enter}).joedf wrote:Console support?? LibCon? http://joedf.github.io/libcon/
what do you mean?
This has been added to v0.3 ALPHA that is now online: PopupFolders.ahk and PopupFolders_LANG.ahk.



Re: 4 options to change the current folder in Windows Explor
To be honest, JnLlnd, I prefer rbrtryn's way of doing it, with the functions instead of the labels. To me, using labels in place of functions is a poor approach because it makes everything so much more difficult to follow/read, and totally goes against the concept of encapsulation--that is, hiding all the nitty-gritty work of how it's done inside a function and providing an interface, the function call. Plus, it's less reliable precisely because there's no concept of scope anywhere--everything is at the top level, and it shouldn't be.
The only fault of rbrtryn's script was that he tied the front- and back-ends together too much, and it seems like you're doing exactly the same thing. Plus, navigating to the current folder wasn't totally reliable, and there was no support for special folders. Using LearningOne's method of programmatic navigation, this is easily solved. All that is needed is to determine if an added folder matches a special folder, then save the associated number in its place. Separating the UI code from the rest wouldn't be very hard either.
I don't mean to be an idiot by saying this, because your script is still good, but I just wanted to state my opinion.
The only fault of rbrtryn's script was that he tied the front- and back-ends together too much, and it seems like you're doing exactly the same thing. Plus, navigating to the current folder wasn't totally reliable, and there was no support for special folders. Using LearningOne's method of programmatic navigation, this is easily solved. All that is needed is to determine if an added folder matches a special folder, then save the associated number in its place. Separating the UI code from the rest wouldn't be very hard either.
I don't mean to be an idiot by saying this, because your script is still good, but I just wanted to state my opinion.
- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
I respect your opinion and if I was writing my script for other programmers, I would agree with your comments. But I'm writing this first for users and for myself. 1) For users, my goal is to make it as reliable, convenient and easy to use as possible. 2) And, being the one who will primarily maintain it, I prefer the script to be be written following my coding style. Not to say that it is better than other's. Just that it is just better for me. And regarding variable scope and these concerns, I'm confident that in a script of this size the risk is under control.



- Learning one
- Posts: 172
- Joined: 04 Oct 2013, 13:59
- Location: Croatia
- Contact:
Re: 4 options to change the current folder in Windows Explor
@joedf: Thank you very much for testing! 
@JnLlnd: I wrote:Actually, the code comment I wrote there is not correct - I remember there were some dialog boxes which were not #32770 nor "bosa_sdm_" class, and that's why I used Open,Save... etc WinTitle keywords.
I tried your PopupFolders. Good job!

@JnLlnd: I wrote:
Code: Select all
Else if WinTitle contains Open,Save,Export,Import,Upload,Select ; this is the case in some MS office dialog windows, which are not #32770 class.
I tried your PopupFolders. Good job!

My Website • Join DropBox
- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
Thank you! About the dialog boxes, I use MS Office a lot. If whenever I find this situation in the future, I will report it here and adapt my code.LearningOne wrote:Actually, the code comment I wrote there is not correct - I remember there were some dialog boxes which were not #32770 nor "bosa_sdm_" class, and that's why I used Open,Save... etc WinTitle keywords.
I tried your PopupFolders. Good job!



- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
@LearningOne: Just found how to make Explorer_Navigate work with UNC locations. An example of UNC is a Sharepoint WebDAV folder: "\\[email protected]\DavWWWRoot\Folder\Subfolder".
I added an "else if" to your code to detect a UNC (check if the first 2 characters are "\\").
I'm not very familiar with this but, from my tests, I found that, in this case we must keep the path as is (ie not adding the "file:///" prefix).
I added an "else if" to your code to detect a UNC (check if the first 2 characters are "\\").
I'm not very familiar with this but, from my tests, I found that, in this case we must keep the path as is (ie not adding the "file:///" prefix).
Code: Select all
;------------------------------------------------------------
NavigateExplorer(varPath, strWinId)
;------------------------------------------------------------
/*
Excerpt and adapted from RMApp_Explorer_Navigate(FullPath, hwnd="") by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa752094
*/
{
For pExp in ComObjCreate("Shell.Application").Windows
if (pExp.hwnd = varWinId) ; matching window found
if varPath is integer ; ShellSpecialFolderConstant
pExp.Navigate2(varPath)
else if InStr(varPath, "\\") = 1 ; This is a UNC (e.g. \\[email protected]\DavWWWRoot\Folder\Subfolder)
pExp.Navigate(varPath)
else
pExp.Navigate("file:///" . varPath)
return
}
;------------------------------------------------------------



- joedf
- Posts: 8716
- Joined: 29 Sep 2013, 17:08
- Facebook: J0EDF
- Google: +joedf
- GitHub: joedf
- Location: Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
"\\" is the correct method, also
in cmd (console) you can do it by doing the following:
or something like that...
here! found this, it will help
http://superuser.com/questions/282963/c ... ping-it-to
and this: http://support.microsoft.com/kb/317379
in cmd (console) you can do it by doing the following:
Code: Select all
pushd \\UNC_Path\Sharename
here! found this, it will help

http://superuser.com/questions/282963/c ... ping-it-to
and this: http://support.microsoft.com/kb/317379





Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x8GB G.Skill RipJaws V - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Populate the AHK MiniCity!] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
- Learning one
- Posts: 172
- Joined: 04 Oct 2013, 13:59
- Location: Croatia
- Contact:
Re: 4 options to change the current folder in Windows Explor
@JnLlnd: great, thanks for sharing 

My Website • Join DropBox
- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
Another approach that I'm trying is to simply remove the "file:///" prefix. This make the same pExp.Navigate call work with both files and UNC. Up to now, it works well on Win7 and XP. But I'm not sure if this would work in any situation?JnLlnd wrote:I added an "else if" to your code to detect a UNC (check if the first 2 characters are "\\").
Code: Select all
;------------------------------------------------------------
NavigateExplorer(varPath, strWinId)
;------------------------------------------------------------
/*
Excerpt and adapted from RMApp_Explorer_Navigate(FullPath, hwnd="") by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa752094
*/
{
For pExp in ComObjCreate("Shell.Application").Windows
{
if (pExp.hwnd = strWinId)
if varPath is integer ; ShellSpecialFolderConstant
{
try pExp.Navigate2(varPath)
catch, objErr
Oops(lNavigateSpecialError, varPath)
}
else
{
; try pExp.Navigate("file:///" . varPath) ; make it work with UNC
try pExp.Navigate(varPath)
catch, objErr
Oops(lNavigateFileError, varPath)
}
}
}
;------------------------------------------------------------



- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
I'm almost finished with PopupFolders app. If you want to give a try to v0.5, the last alpha version.
Changes since the last version posted here:
- add GuiSave, GuiCancel, RemoveFolder, EditFolder, AddSeparator, MoveFolderUp/Down, RemoveDialog, EditDialog, fix bug in GuiShow, add tray icon
- add settings hotkey to ini file (default Crtl-Windows-F), enable AddThisFolder in all version Explorer and only in WIN_7/Win_8 dialog boxes (not working in WIN_XP)
- implemented GuiAbout and GuiHelp, added About and Help to tray menu, tray tip displayed only 5 times
- removed file:/// protocol prefix, added support for ExploreWClass, implemented try/catch to Explore shell method, offer to add manually when add folder failed
All functionality are implemented. There is still a lot of (inactive) debugging code that will be removed in the beta version coming soon.
This script is also available on GitHub: PopupFolders.ahk
*** Also download the language file: PopupFolders_LANG.ahk. ***
Changes since the last version posted here:
- add GuiSave, GuiCancel, RemoveFolder, EditFolder, AddSeparator, MoveFolderUp/Down, RemoveDialog, EditDialog, fix bug in GuiShow, add tray icon
- add settings hotkey to ini file (default Crtl-Windows-F), enable AddThisFolder in all version Explorer and only in WIN_7/Win_8 dialog boxes (not working in WIN_XP)
- implemented GuiAbout and GuiHelp, added About and Help to tray menu, tray tip displayed only 5 times
- removed file:/// protocol prefix, added support for ExploreWClass, implemented try/catch to Explore shell method, offer to add manually when add folder failed
All functionality are implemented. There is still a lot of (inactive) debugging code that will be removed in the beta version coming soon.
Code: Select all
;===============================================
/*
PopupFolders
Written using AutoHotkey_L v1.1.09.03+ (http://l.autohotkey.net/)
By Jean Lalonde (JnLlnd on AHKScript.org forum), based on DirMenu v2 by Robert Ryan (rbrtryn on AutoHotkey.com forum)
Version: PopupFolders v0.5 ALPHA (last alpha version)
- implemented GuiAbout and GuiHelp, added About and Help to tray menu, tray tip displayed only 5 times
- removed file:/// protocol prefix, added support for ExploreWClass, implemented try/catch to Explore shell method, offer to add manualy when add folder failed
Version: PopupFolders v0.4 ALPHA
- add settings hotkey to ini file (default Crtl-Windows-F), enable AddThisFolder in all version Explorer and only in WIN_7/Win_8 dialog boxes (not working in WIN_XP)
- add GuiSave, GuiCancel, RemoveFolder, EditFolder, AddSeparator, MoveFolderUp/Down, RemoveDialog, EditDialog, fix bug in GuiShow, add tray icon
Version: PopupFolders v0.3 ALPHA
- add NavigateConsole for console support (command prompt CMD)
- change .ini filename to new app name
Version: PopupFolders v0.2 ALPHA
- renamed app PopupFolders, isolate text into language variables
Version: DirMenu3 v0.1 ALPHA
- init skeleton, read ini file and create arrays for folders menu and supported dialog boxes
- create language file, build gui, tray menu and folder menu, skeleton for front end buttons and commands
- create AddThisDialog menu, MButton condition, CanOpenFavorite improvements with WindowIsAnExplorer, WindowIsDesktop and DialogIsSupported
- add SpecialFolders menu, OpenFavorite for Explorer and Desktop, NavigateExplorer
- support MS Office dialog boxes on WinXP (bosa_sdm_), open special folders in explorers
- NavigateDialog, add Desktop, Document and Pictures special folders, open these special menus in dialog boxes, enabling/disabling the appropriate menus in dialog boxes or explorers
Version: DirMenu v2.2 (never released / not stable - base of a total rewrite to DirMenu3)
- manage (add, modify or delete) supported dialog box titles in the Gui
- suggest current dialog box when adding a name
- save the supported dialog box names on the first line of the settings file (dirmenu.txt)
- add "Add This Dialog" to the MButton menu to add the current dialog box name (need to desactivate when in an already supported dialog box)
- added Win8 to the list of supported versions (assumed as equal to Win7 - could not test myself)
- removed the "Menu File" button because not needed anymore
- fixed an issue when 2 folders had the same name (now preventing the use of an existing name)
- change default setting filename to "DirMenu2.txt" to avoid upgrade errors
- upgrade previous versions settings files to v2.2
- ask confirmation before discarding changes with Revert or Cancel buttons
- replaces RegEx on strDialogNames with DialogIsSupported() function on the ListView
Version: DirMenu v2.1
- make it work with any locale (still working with English)
- put supported dialog box titles in a variable (strDialogNames) at the top of the script for easy editing
- put DirMenu data file name in a variable (strDirMenuFile) at the top of the script for easy editing
- add "Add This Folder" to the MButton menu to add the current folder
- add "Menu File" button to open de DirMenu.txt file for edition in Notepad
- propose the deepest folder name as default name for a new folder
*/
;===============================================
; --- COMPILER DIRECTIVES ---
; Doc: http://fincs.ahk4.net/Ahk2ExeDirectives.htm
; Note: prefix comma with `
;@Ahk2Exe-SetName DirMenu3
;@Ahk2Exe-SetDescription Popup menu to jump from one folder to another
;@Ahk2Exe-SetVersion 0.1
;@Ahk2Exe-SetOrigFilename DirMenu.exe
;============================================================
; INITIALIZATION
;============================================================
#NoEnv
#SingleInstance force
#Include %A_ScriptDir%\PopupFolders_LANG.ahk
SetWorkingDir %A_ScriptDir%
global strIniFile := A_ScriptDir . "\" . lAppName . ".ini"
;@Ahk2Exe-IgnoreBegin
; Piece of code for developement phase only - won't be compiled
if (A_ComputerName = "JEAN-PC") ; for my home PC
strIniFile := A_ScriptDir . "\" . lAppName . "-HOME.ini"
else if InStr(A_ComputerName, "STIC") ; for my work hotkeys
strIniFile := A_ScriptDir . "\" . lAppName . "-WORK.ini"
; / Piece of code for developement phase only - won't be compiled
;@Ahk2Exe-IgnoreEnd
Gosub, BuildSpecialFoldersMenu
Gosub, LoadIniFile
Gosub, BuildFoldersMenu
Gosub, BuildGUI
Gosub, BuildAddDialogMenu
Gosub, BuildTrayMenu
if (blnDisplayTrayTip)
TrayTip, % L(lTrayTipInstalledTitle, lAppName, lAppVersionLong)
, % L(lTrayTipInstalledDetail, lAppName), , 1
return
;============================================================
; BACK END FUNCTIONS AND COMMANDS
;============================================================
;-----------------------------------------------------------
LoadIniFile:
;-----------------------------------------------------------
blnDebug := False
global arrGlobalFolders := Object()
global arrGlogalDialogs := Object()
strSettingsHotkeyDefault := "^#f"
IfNotExist, %strIniFile%
FileAppend,
(LTrim Join`r`n
[Global]
SettingsHotkey=%strSettingsHotkeyDefault%
DisplayTrayTip=5
[Folders]
Folder1=C:\|C:\
Folder2=Windows|%A_WinDir%
Folder3=Program Files|%A_ProgramFiles%
[Dialogs]
Dialog1=Export
Dialog2=Import
Dialog3=Insert
Dialog4=Open
Dialog5=Save
Dialog6=Select
Dialog7=Upload
)
, %strIniFile%
IniRead, blnDisplayTrayTip, %strIniFile%, Global, DisplayTrayTip
if (blnDisplayTrayTip)
IniWrite, % (blnDisplayTrayTip - 1), %strIniFile%, Global, DisplayTrayTip
IniRead, strSettingsHotkey, %strIniFile%, Global, SettingsHotkey
if (strSettingsHotkey = "ERROR")
{
IniWrite, %strSettingsHotkeyDefault%, %strIniFile%, Global, SettingsHotkey
strSettingsHotkey := strSettingsHotkeyDefault
}
Hotkey, %strSettingsHotkey%, GuiShow
Loop
{
IniRead, strIniLine, %strIniFile%, Folders, Folder%A_Index%
if (strIniLine = "ERROR")
Break
StringSplit, arrThisObject, strIniLine, |
objFolder := Object()
objFolder.Name := arrThisObject1
objFolder.Path := arrThisObject2
arrGlobalFolders.Insert(objFolder)
}
if (blnDebug)
Loop, % arrGlobalFolders.MaxIndex()
###_D("Folder" . A_Index . ": " . arrGlobalFolders[A_Index].Name . " -> " . arrGlobalFolders[A_Index].Path)
Loop
{
IniRead, strIniLine, %strIniFile%, Dialogs, Dialog%A_Index%
if (strIniLine = "ERROR")
Break
arrGlogalDialogs.Insert(strIniLine)
}
if (blnDebug)
Loop, % arrGlogalDialogs.MaxIndex()
###_D("Dialog" . A_Index . ": " . arrGlogalDialogs[A_Index])
blnDebug := False
return
;------------------------------------------------------------
;============================================================
; FRONT END FUNCTIONS AND COMMANDS
;============================================================
;------------------------------------------------------------
#If, CanOpenFavorite(strGlobalWinId, strGlobalClass)
MButton::
;------------------------------------------------------------
blnDebug := false
if (blnDebug)
###_D("Yes: " . strGlobalWinId . " " . strGlobalClass)
; Can't find how to navigate a dialog box to My Computer or Network Neighborhood... need help ???
Menu, menuSpecialFolders
, % WindowIsConsole(strGlobalClass) or WindowIsDialog(strGlobalClass) ? "Disable" : "Enable"
, %lMenuMyComputer%
Menu, menuSpecialFolders
, % WindowIsConsole(strGlobalClass) or WindowIsDialog(strGlobalClass) ? "Disable" : "Enable"
, %lMenuNetworkNeighborhood%
; There is no point to navigate a dialog box or console to Control Panel or Recycle Bin
Menu, menuSpecialFolders
, % WindowIsConsole(strGlobalClass) or WindowIsDialog(strGlobalClass) ? "Disable" : "Enable"
, %lMenuControlPanel%
Menu, menuSpecialFolders
, % WindowIsConsole(strGlobalClass) or WindowIsDialog(strGlobalClass) ? "Disable" : "Enable"
, %lMenuRecycleBin%
WinActivate, % "ahk_id " . strGlobalWinId
if (WindowIsAnExplorer(strGlobalClass) or WindowIsDesktop(strGlobalClass) or WindowIsConsole(strGlobalClass) or DialogIsSupported(strGlobalWinId))
{
; Enable Add This Folder only if the mouse is over an Explorer (tested on WIN_XP and WIN_7) or a dialog box (works on WIN_7, not on WIN_XP)
; Other tests shown that WIN_8 behaves like WIN_7. So, I assume WIN_8 to work. If someone could confirm (until I can test it myself)?
Menu, menuFolders
, % WindowIsAnExplorer(strGlobalClass) or (WindowIsDialog(strGlobalClass) and InStr("WIN_7|WIN_8", A_OSVersion)) ? "Enable" : "Disable"
, %lMenuAddThisFolder%
Menu, menuFolders, Show
}
else
Menu, menuAddDialog, Show
blnDebug := false
return
#If
;------------------------------------------------------------
;------------------------------------------------------------
+MButton::
;------------------------------------------------------------
blnDebug := false
MouseGetPos, , , strGlobalWinId
WinGetClass strGlobalClass, % "ahk_id " . strGlobalWinId
; In case it was disabled while in a dialog box
Menu, menuSpecialFolders, Enable, %lMenuMyComputer%
Menu, menuSpecialFolders, Enable, %lMenuNetworkNeighborhood%
Menu, menuSpecialFolders, Enable, %lMenuControlPanel%
Menu, menuSpecialFolders, Enable, %lMenuRecycleBin%
; Enable Add This Folder only if the mouse is over an Explorer (tested on WIN_XP and WIN_7) or a dialog box (works on WIN_7, not on WIN_XP)
; Other tests shown that WIN_8 behaves like WIN_7. So, I assume WIN_8 to work. If someone could confirm (until I can test it myself)?
Menu, menuFolders
, % WindowIsAnExplorer(strGlobalClass) or (WindowIsDialog(strGlobalClass) and InStr("WIN_7|WIN_8", A_OSVersion)) ? "Enable" : "Disable"
, %lMenuAddThisFolder%
Menu, menuFolders, Show
blnDebug := false
return
;------------------------------------------------------------
;------------------------------------------------------------
BuildTrayMenu:
;------------------------------------------------------------
Menu, Tray, Icon, %A_ScriptDir%\ico\Visualpharm-Icons8-Metro-Style-Folders-Likes.ico, 1
Menu, Tray, Add
Menu, Tray, Add, %lMenuEditFoldersMenu%, GuiShow
Menu, Tray, Add, %lMenuHelp%, GuiHelp
Menu, Tray, Add, %lMenuAbout%, GuiAbout
Menu, Tray, Default, %lMenuEditFoldersMenu%
return
;------------------------------------------------------------
;------------------------------------------------------------
BuildSpecialFoldersMenu:
;------------------------------------------------------------
Menu, menuSpecialFolders, Add, %lMenuDesktop%, OpenSpecialFolder
Menu, menuSpecialFolders, Add, %lMenuDocuments%, OpenSpecialFolder
Menu, menuSpecialFolders, Add, %lMenuPictures%, OpenSpecialFolder
Menu, menuSpecialFolders, Add
Menu, menuSpecialFolders, Add, %lMenuMyComputer%, OpenSpecialFolder
Menu, menuSpecialFolders, Add, %lMenuNetworkNeighborhood%, OpenSpecialFolder
Menu, menuSpecialFolders, Add
Menu, menuSpecialFolders, Add, %lMenuControlPanel%, OpenSpecialFolder
Menu, menuSpecialFolders, Add, %lMenuRecycleBin%, OpenSpecialFolder
return
;------------------------------------------------------------
;------------------------------------------------------------
BuildFoldersMenu:
;------------------------------------------------------------
blnDebug := False
Menu, menuFolders, Add
Menu, menuFolders, DeleteAll
Loop, % arrGlobalFolders.MaxIndex()
{
if (blnDebug)
###_D(arrGlobalFolders[A_Index].Name)
if (arrGlobalFolders[A_Index].Name = lMenuSeparator)
Menu, menuFolders, Add
else
Menu, menuFolders, Add, % arrGlobalFolders[A_Index].Name, OpenFavorite
}
Menu, menuFolders, Add
Menu, menuFolders, Add, %lMenuSpecialFolders%, :menuSpecialFolders
Menu, menuFolders, Add
Menu, menuFolders, Add, %lMenuSettings%, GuiShow
Menu, menuFolders, Default, %lMenuSettings%
Menu, menuFolders, Add, %lMenuAddThisFolder%, AddThisFolder
if (blnDebug)
Menu, menuFolders, Show
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
BuildAddDialogMenu:
;------------------------------------------------------------
blnDebug := False
Menu, menuAddDialog, Add, %lMenuDialogNotSupported%, AddThisDialog
Menu, menuAddDialog, Disable, %lMenuDialogNotSupported%
Menu, menuAddDialog, Add, %lMenuAddThisDialog%, AddThisDialog
Menu, menuAddDialog, Add
Menu, menuAddDialog, Add, %lMenuEditFoldersMenu%, GuiShow
Menu, menuAddDialog, Default, %lMenuAddThisDialog%
if (blnDebug)
Menu, menuAddDialog, Show
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
BuildGui:
;------------------------------------------------------------
blnDebug := false
Gui, Font, s12 w700, Verdana
Gui, Add, Picture, x10 y5, %A_ScriptDir%\ico\Folders-Likes-icon-48.png
Gui, Add, Text, y25 w490 h25, %lAppName%
Gui, 1:Font, s8 w400, Arial
Gui, Add, Button, y10 x400 w45 h22 gGuiAbout, % L(lGuiAbout)
Gui, 1:Font, s8 w400, Verdana
Gui, Add, ListView, x10 w350 h220 Count32 -Multi NoSortHdr LV0x10 vlvFoldersList, %lGuiLvFoldersHeader%
Gui, Add, Button, x+10 w75 r1 gGuiAddFolder, %lGuiAddFolder%
Gui, Add, Button, w75 r1 gGuiRemoveFolder, %lGuiRemoveFolder%
Gui, Add, Button, w75 r1 gGuiEditFolder, %lGuiEditFolder%
Gui, Add, Button, w75 r1 gGuiAddSeparator, %lGuiSeparator%
Gui, Add, Button, w75 r1 gGuiMoveFolderUp, %lGuiMoveFolderUp%
Gui, Add, Button, w75 r1 gGuiMoveFolderDown, %lGuiMoveFolderDown%
Gui, Add, ListView
, x10 w350 h120 Count16 -Multi NoSortHdr +0x10 LV0x10 vlvDialogsList, %lGuiLvDialogsHeader%
Gui, Add, Button, x+10 w75 r1 gGuiAddDialog, %lGuiAddDialog%
Gui, Add, Button, w75 r1 gGuiRemoveDialog, %lGuiRemoveDialog%
Gui, Add, Button, w75 r1 gGuiEditDialog, %lGuiEditDialog%
Gui, Add, Button, x100 w75 r1 Disabled Default gGuiSave, %lGuiSave%
Gui, Add, Button, x+40 w75 r1 gGuiCancel, %lGuiCancel%
Gui, Add, Button, x+80 w75 r1 gGuiHelp, %lGuiHelp%
if (blnDebug)
Gui, Show, w455 h455, % L(lGuiTitle, lAppName, lAppVersionLong)
blnDebug := false
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiAddFolder:
;------------------------------------------------------------
FileSelectFolder, strNewPath, *C:\, 3, %lDialogAddFolderSelect%
if (strNewPath = "")
return
AddFolder(strNewPath)
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiRemoveFolder:
;------------------------------------------------------------
blnDebug := False
GuiControl, Focus, lvFoldersList
Gui, ListView, lvFoldersList
intItemToRemove := LV_GetNext()
if (blnDebug)
###_D(intItemToRemove)
if !(intItemToRemove)
{
Oops(lDialogSelectItemToRemove)
return
}
LV_Delete(intItemToRemove)
if (blnDebug)
{
LV_GetText(str, intItemToRemove)
###_D(str)
}
LV_Modify(intItemToRemove, "Select Focus")
LV_ModifyCol(1, "AutoHdr")
LV_ModifyCol(2, "AutoHdr")
GuiControl, Enable, %lGuiSave%
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiEditFolder:
;------------------------------------------------------------
Gui, +OwnDialogs
GuiControl, Focus, lvFoldersList
Gui, ListView, lvFoldersList
intRowToEdit := LV_GetNext()
LV_GetText(strCurrentName, intRowToEdit, 1)
if !StrLen(strCurrentName)
{
Oops(lDialogSelectItemToEdit)
return
}
LV_GetText(strCurrentPath, intRowToEdit, 2)
FileSelectFolder, strNewPath, *%strCurrentPath%, 3, %lDialogEditFolderSelect%
if (strNewPath = "")
return
Loop
{
InputBox strNewName, % L(lDialogEditFolderTitle, lAppName, lAppVersionLong)
, %lDialogEditFolderPrompt%, , 250, 120, , , , , %strCurrentName%
if (ErrorLevel)
return
} until (strNewName = strCurrentName) or FolderNameIsNew(strNewName)
LV_Modify(intRowToEdit, "Select Focus", strNewName, strNewPath)
LV_ModifyCol(1, "AutoHdr")
LV_ModifyCol(2, "AutoHdr")
GuiControl, Enable, %lGuiSave%
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiAddSeparator:
;------------------------------------------------------------
GuiControl, Focus, lvFoldersList
Gui, ListView, lvFoldersList
LV_Insert(LV_GetCount() ? (LV_GetNext() ? LV_GetNext() : 0xFFFF) : 1, "Select Focus", lMenuSeparator, lMenuSeparator)
GuiControl, Enable, %lGuiSave%
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiMoveFolderUp:
;------------------------------------------------------------
GuiControl, Focus, lvFoldersList
Gui, ListView, lvFoldersList
intSelectedRow := LV_GetNext()
if (intSelectedRow = 1)
return
LV_GetText(strThisName, intSelectedRow, 1)
LV_GetText(strThisPath, intSelectedRow, 2)
LV_GetText(PriorName, intSelectedRow - 1, 1)
LV_GetText(PriorPath, intSelectedRow - 1, 2)
LV_Modify(intSelectedRow, "", PriorName, PriorPath)
LV_Modify(intSelectedRow - 1, "Select Focus Vis", strThisName, strThisPath)
GuiControl, Enable, %lGuiSave%
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiMoveFolderDown:
;------------------------------------------------------------
GuiControl, Focus, lvFoldersList
Gui, ListView, lvFoldersList
intSelectedRow := LV_GetNext()
if (intSelectedRow = LV_GetCount())
return
LV_GetText(strThisName, intSelectedRow, 1)
LV_GetText(strThisPath, intSelectedRow, 2)
LV_GetText(NextName, intSelectedRow + 1, 1)
LV_GetText(NextPath, intSelectedRow + 1, 2)
LV_Modify(intSelectedRow, "", NextName, NextPath)
LV_Modify(intSelectedRow + 1, "Select Focus Vis", strThisName, strThisPath)
GuiControl, Enable, %lGuiSave%
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiAddDialog:
;------------------------------------------------------------
AddDialog("")
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiRemoveDialog:
;------------------------------------------------------------
blnDebug := False
GuiControl, Focus, lvDialogsList
Gui, ListView, lvDialogssList
intItemToRemove := LV_GetNext()
if (blnDebug)
###_D(intItemToRemove)
if !(intItemToRemove)
{
Oops(lDialogSelectItemToRemove)
return
}
LV_Delete(intItemToRemove)
if (blnDebug)
{
LV_GetText(str, intItemToRemove)
###_D(str)
}
LV_Modify(intItemToRemove, "Select Focus")
GuiControl, Enable, %lGuiSave%
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiEditDialog:
;------------------------------------------------------------
Gui, +OwnDialogs
GuiControl, Focus, lvDialogsList
Gui, ListView, lvDialogsList
intRowToEdit := LV_GetNext()
LV_GetText(strCurrentDialog, intRowToEdit, 1)
InputBox strNewDialog, % L(lDialogEditDialogTitle, lAppName, lAppVersionLong)
, %lDialogEditDialogPrompt%, , 250, 120, , , , , %strCurrentDialog%
if (ErrorLevel) or !StrLen(strNewDialog) or (strNewDialog = strCurrentDialog)
return
Gui, ListView, lvDialogsList
Loop, % LV_GetCount()
{
LV_GetText(strThisDialog, A_Index, 1)
if (strNewDialog = strThisDialog)
{
Oops(lDialogAddDialogAlready)
return
}
}
LV_Modify(intRowToEdit, "Select Focus", strNewDialog)
LV_ModifyCol(1, "AutoHdr")
LV_ModifyCol(1, "Sort")
LV_Modify(LV_GetNext(), "Vis")
GuiControl, Enable, %lGuiSave%
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiSave:
;------------------------------------------------------------
blnDebug := False
IniDelete, %strIniFile%, Folders
Gui, ListView, lvFoldersList
Loop % LV_GetCount()
{
LV_GetText(strName, A_Index, 1)
LV_GetText(strPath, A_Index, 2)
IniWrite, %strName%|%strPath%, %strIniFile%, Folders, Folder%A_Index%
}
IniDelete, %strIniFile%, Dialogs
Gui, ListView, lvDialogsList
Loop % LV_GetCount()
{
LV_GetText(strDialog, A_Index, 1)
IniWrite, %strDialog%, %strIniFile%, Dialogs, Dialog%A_Index%
}
Gosub, LoadIniFile
Gosub, BuildFoldersMenu
GuiControl, Disable, %lGuiSave%
Gosub, GuiCancel
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiShow:
;------------------------------------------------------------
Gosub, LoadSettingsToGui
Gui, Show, w455 h455, % L(lGuiTitle, lAppName, lAppVersionLong)
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiCancel:
;------------------------------------------------------------
blnDebug := False
GuiControlGet, blnSaveEnabled, Enabled, %lGuiSave%
if (blnSaveEnabled)
{
Gui, +OwnDialogs
MsgBox, 36, % L(lDialogCancelTitle, lAppName, lAppVersionLong), %lDialogCancelPrompt%
IfMsgBox, Yes
GuiControl, Disable, %lGuiSave%
IfMsgBox, No
return
}
Gui, Cancel
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiClose:
;------------------------------------------------------------
GoSub, GuiCancel
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiAbout:
;------------------------------------------------------------
intGui1WinID := WinExist("A")
Gui, 1:Submit, NoHide
Gui, 2:New, , % L(lAboutTitle, lAppName, lAppVersionLong)
Gui, 2:+Owner1
Gui, Add, Picture, x10 y5, %A_ScriptDir%\ico\Folders-Likes-icon-192.png
str32or64 := A_PtrSize * 8
Gui, Font, s12 w700, Verdana
Gui, Add, Link, y10 vlblAboutText1, % L(lAboutText1, lAppName, lAppVersionLong, str32or64)
Gui, Font, s8 w400, Verdana
Gui, Add, Link, , % L(lAboutText2)
Gui, Add, Link, , % L(lAboutText3)
Gui, Font, s10 w400, Verdana
Gui, Add, Link, , % L(lAboutText4)
Gui, Font, s8 w400, Verdana
Gui, 2:Add, Button, y+20 g2GuiClose, %lGui2Close%
Gui, 2:Show, AutoSize Center
Gui, 1:+Disabled
return
;------------------------------------------------------------
;------------------------------------------------------------
GuiHelp:
;------------------------------------------------------------
intGui1WinID := WinExist("A")
Gui, 1:Submit, NoHide
Gui, 2:New, , % L(lHelpTitle, lAppName, lAppVersionLong)
Gui, 2:+Owner1
Gui, Add, Picture, x10 y5, %A_ScriptDir%\ico\Folders-Likes-icon-256.png
intWidth := 450
Gui, Font, s10 w400, Verdana
Gui, 2:Add, Link, y10 w%intWidth%, %lHelpText1%
Gui, Font, s8 w400, Verdana
Gui, 2:Add, Link, w%intWidth%, %lHelpText2%
Gui, 2:Add, Link, w%intWidth%, %lHelpText3%
Gui, 2:Add, Link, w%intWidth%, %lHelpText4%
Gui, 2:Add, Link, w%intWidth%, %lHelpText5%
Gui, 2:Add, Link, w%intWidth%, %lHelpText6%
Gui, 2:Add, Link, w%intWidth%, %lHelpText7%
Gui, 2:Add, Link, w%intWidth%, %lHelpText8%
Gui, 2:Add, Button, y+20 g2GuiClose, %lGui2Close%
Gui, 2:Show, AutoSize Center
Gui, 1:+Disabled
return
;------------------------------------------------------------
;------------------------------------------------------------
2GuiClose:
2GuiEscape:
;------------------------------------------------------------
Gui, 1:-Disabled
Gui, 2:Destroy
WinActivate, ahk_id %intGui1WinID%
return
;------------------------------------------------------------
;------------------------------------------------------------
AddThisFolder:
;------------------------------------------------------------
blnDebug := false
objPrevClipboard := ClipboardAll ; Save the entire clipboard
ClipBoard := ""
; Add This folder menu is active only if we are in Explorer (WIN_XP, WIN_7 or WIN_8) or in a Dialog box (WIN_7 or WIN_8).
; In all these OS, the key sequence {F4}{Esc} selects the current location of the window.
intWaitTimeIncrement := 150 ; time required on an XP average machine
intTries := 3
Loop, %intTries%
{
Sleep, intWaitTimeIncrement * A_Index
Send {F4}{Esc} ; F4 move the caret the "Go To A Different Folder box" and {Esc} select it content ({Esc} could be replaced by ^a to Select All)
Sleep, intWaitTimeIncrement * A_Index
Send ^c ; Copy
Sleep, intWaitTimeIncrement * A_Index
} Until (StrLen(ClipBoard))
strCurrentFolder := ClipBoard
If StrLen(strCurrentFolder)
{
Gosub, GuiShow
AddFolder(strCurrentFolder)
}
else
{
Gui, +OwnDialogs
MsgBox, 52, % L(lDialogAddFolderManuallyTitle, lAppName, lAppVersionLong), %lDialogAddFolderManuallyPrompt%
IfMsgBox, Yes
{
Gosub, GuiShow
Gosub, GuiAddFolder
}
}
Clipboard := objPrevClipboard ; Restore the original clipboard
objPrevClipboard := "" ; Free the memory in case the clipboard was very large
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
AddFolder(strPath)
;------------------------------------------------------------
{
blnDebug := false
GuiControl, Focus, lvFoldersList
Gui, +OwnDialogs
; suggest the deepest folder's name as default name for the added folder
SplitPath, strPath, strDefaultName, , , , strDrive
if (blnDebug)
###_D("strPath: " . strPath . "`nstrDefaultName: " . strDefaultName . "`nstrDrive: " . strDrive)
if !StrLen(strDefaultName) ; we are probably at the root of a drive
strDefaultName := strDrive
Loop
{
InputBox strName, % L(lDialogTitle, lAppName, lAppVersionLong) . lDialogFolderNameTitle, %lDialogFolderNamePrompt%, , 250, 120, , , , , %strDefaultName%
if (ErrorLevel) or !StrLen(strName)
return
} until FolderNameIsNew(strName)
Gui, ListView, lvFoldersList
if (blnDebug)
###_D("LV_GetCount: " . LV_GetCount() . "`nLV_GetNext: " . LV_GetNext() . "`nResult: " . LV_GetCount() ? (LV_GetNext() ? LV_GetNext() : 1) : 1)
LV_Insert(LV_GetCount() ? (LV_GetNext() ? LV_GetNext() : 0xFFFF) : 1, "Select Focus", strName, strPath)
LV_Modify(LV_GetNext(), "Vis")
LV_ModifyCol(1, "AutoHdr")
LV_ModifyCol(2, "AutoHdr")
GuiControl, Enable, %lGuiSave%
blnDebug := false
}
;------------------------------------------------------------
;------------------------------------------------------------
FolderNameIsNew(strCandidateName)
;------------------------------------------------------------
{
Gui, ListView, lvFoldersList
Loop, % LV_GetCount()
{
LV_GetText(strThisName, A_Index, 1)
if (strCandidateName = strThisName)
{
Oops(lDialogFolderNameNotNew, strCandidateName)
return False
}
}
return True
}
;------------------------------------------------------------
;------------------------------------------------------------
AddThisDialog:
;------------------------------------------------------------
blnDebug := false
WinGetTitle, strDialogTitle, ahk_id %strGlobalWinId%
Gosub, GuiShow
AddDialog(strDialogTitle)
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
AddDialog(strCurrentDialogTitle)
;------------------------------------------------------------
{
Gui, +OwnDialogs
GuiControl, Focus, lvDialogsList
InputBox, strNewDialog, % L(lDialogAddDialogTitle, lAppName, lAppVersionLong), %lDialogAddDialogPrompt%, , 250, 150, , , , , %strCurrentDialogTitle%
if (ErrorLevel) or !StrLen(strNewDialog)
return
Gui, ListView, lvDialogsList
Loop, % LV_GetCount()
{
LV_GetText(strThisDialog, A_Index, 1)
if (strNewDialog = strThisDialog)
{
Oops(lDialogAddDialogAlready)
return
}
}
LV_Add("Select Focus", strNewDialog)
LV_Modify(LV_GetNext(), "Vis")
LV_ModifyCol(1, "AutoHdr")
GuiControl, Enable, %lGuiSave%
}
;------------------------------------------------------------
;============================================================
; MIDDLESTUFF
;============================================================
;------------------------------------------------------------
LoadSettingsToGui:
;------------------------------------------------------------
blnDebug := false
GuiControlGet, blnSaveEnabled, Enabled, %lGuiSave%
if (blnSaveEnabled)
return
Gui, ListView, lvFoldersList
LV_Delete()
Gui, ListView, lvDialogsList
LV_Delete()
Gui, ListView, lvFoldersList
Loop, % arrGlobalFolders.MaxIndex()
{
if (blnDebug)
###_D(arrGlobalFolders[A_Index].Name . " " . arrGlobalFolders[A_Index].Path)
If !StrLen(arrGlobalFolders[A_Index].Name)
LV_Add()
else
LV_Add(, arrGlobalFolders[A_Index].Name, arrGlobalFolders[A_Index].Path)
}
LV_Modify(1, "Select Focus")
LV_ModifyCol(1, "AutoHdr")
LV_ModifyCol(2, "AutoHdr")
Gui, ListView, lvDialogsList
Loop, % arrGlogalDialogs.MaxIndex()
{
if (blnDebug)
###_D(arrGlogalDialogs[A_Index])
LV_Add(, arrGlogalDialogs[A_Index])
}
LV_Modify(1, "Select Focus")
LV_ModifyCol(1, "AutoHdr")
GuiControl, Focus, lvFoldersList
blnDebug := False
return
;------------------------------------------------------------
;------------------------------------------------------------
OpenFavorite:
;------------------------------------------------------------
blnDebug := false
strPath := GetPahtFor(A_ThisMenuItem)
if (blnDebug)
###_D("strGlobalWinId: " . strGlobalWinId . "`nstrGlobalClass: " . strGlobalClass . "`nstrPath: " . strPath)
if (A_ThisHotkey = "+MButton") or WindowIsDesktop(strGlobalClass)
ComObjCreate("Shell.Application").Explore(strPath)
; http://msdn.microsoft.com/en-us/library/windows/desktop/bb774073%28v=vs.85%29.aspx
else if WindowIsAnExplorer(strGlobalClass)
NavigateExplorer(strPath, strGlobalWinId)
else if WindowIsConsole(strGlobalClass)
NavigateConsole(strPath, strGlobalWinId)
else
NavigateDialog(strPath, strGlobalWinId, strGlobalClass)
blnDebug := false
return
;------------------------------------------------------------
;------------------------------------------------------------
OpenSpecialFolder:
;------------------------------------------------------------
blnDebug := false
if (blnDebug)
###_D("strGlobalWinId: " . strGlobalWinId . "`nstrGlobalClass: " . strGlobalClass . "`nA_ThisMenuItem: " . A_ThisMenuItem)
; ShellSpecialFolderConstants: http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
if (A_ThisMenuItem = lMenuDesktop)
intSpecialFolder := 0
else if (A_ThisMenuItem = lMenuControlPanel)
intSpecialFolder := 3
else if (A_ThisMenuItem = lMenuDocuments)
intSpecialFolder := 5
else if (A_ThisMenuItem = lMenuRecycleBin)
intSpecialFolder := 10
else if (A_ThisMenuItem = lMenuMyComputer)
intSpecialFolder := 17
else if (A_ThisMenuItem = lMenuNetworkNeighborhood)
intSpecialFolder := 18
else if (A_ThisMenuItem = lMenuPictures)
intSpecialFolder := 39
if (A_ThisHotkey = "+MButton") or WindowIsDesktop(strGlobalClass)
ComObjCreate("Shell.Application").Explore(intSpecialFolder)
; http://msdn.microsoft.com/en-us/library/windows/desktop/bb774073%28v=vs.85%29.aspx
else if WindowIsAnExplorer(strGlobalClass)
NavigateExplorer(intSpecialFolder, strGlobalWinId)
else ; this is the console or a dialog box
{
if (intSpecialFolder = 0)
strPath := A_Desktop
else if (intSpecialFolder = 5)
strPath := A_MyDocuments
else if (intSpecialFolder = 39)
{
; do not use: StringReplace, strPath, A_MyDocuments, Documents, Pictures
; because A_MyDocument could contain a "Documents" string before the final folder
StringLeft, strPath, A_MyDocuments, % StrLen(A_MyDocuments) - StrLen("Documents")
strPath := strPath . "Pictures"
}
else ; we do not support this special folder
return
if WindowIsConsole(strGlobalClass)
NavigateConsole(strPath, strGlobalWinId)
else
NavigateDialog(strPath, strGlobalWinId, strGlobalClass)
}
blnDebug := false
return
;------------------------------------------------------------
;------------------------------------------------------------
WinGetClassA()
;------------------------------------------------------------
{
WinGetClass strClass, A
return strClass
}
;------------------------------------------------------------
WinUnderMouseClass()
;------------------------------------------------------------
{
WinGetClass strClass, % "ahk_id " . WinUnderMouseID()
return strClass
}
;------------------------------------------------------------
;------------------------------------------------------------
WinUnderMouseID()
;------------------------------------------------------------
{
MouseGetPos, , , strWinId
return strWinId
}
;------------------------------------------------------------
;------------------------------------------------------------
GetPahtFor(strName)
;------------------------------------------------------------
{
blnDebug := false
if (blnDebug)
Loop, % arrGlobalFolders.MaxIndex()
###_D(strName . " = " . arrGlobalFolders[A_Index].Name)
Loop, % arrGlobalFolders.MaxIndex()
if (strName = arrGlobalFolders[A_Index].Name)
return arrGlobalFolders[A_Index].Path
blnDebug := false
return
}
;------------------------------------------------------------
;------------------------------------------------------------
CanAddFolder(strClass)
;------------------------------------------------------------
{
}
;------------------------------------------------------------
;------------------------------------------------------------
CanOpenFavorite(ByRef strWinId, ByRef strClass)
;------------------------------------------------------------
; "CabinetWClass" -> Explorer
; "ProgMan" -> Desktop
; "WorkerW" -> Desktop
; "ConsoleWindowClass" -> Console (CMD)
; "#32770" -> Dialog
{
blnDebug := false
MouseGetPos, , , strWinId
WinGetClass strClass, % "ahk_id " . strWinId
if (blnDebug)
if WindowIsAnExplorer(strClass) or WindowIsDesktop(strClass) or WindowIsConsole(strClass) or WindowIsDialog(strClass)
###_D(strClass . " is OK")
else
###_D(strClass . " is NOT OK")
return WindowIsAnExplorer(strClass) or WindowIsDesktop(strClass) or WindowIsConsole(strClass) or WindowIsDialog(strClass)
blnDebug := false
}
;------------------------------------------------------------
;------------------------------------------------------------
WindowIsAnExplorer(strClass)
;------------------------------------------------------------
{
return (strClass = "CabinetWClass") or (strClass = "ExploreWClass")
}
;------------------------------------------------------------
;------------------------------------------------------------
WindowIsDesktop(strClass)
;------------------------------------------------------------
{
return (strClass = "ProgMan") or (strClass = "WorkerW")
}
;------------------------------------------------------------
;------------------------------------------------------------
WindowIsConsole(strClass)
;------------------------------------------------------------
{
return (strClass = "ConsoleWindowClass")
}
;------------------------------------------------------------
;------------------------------------------------------------
WindowIsDialog(strClass)
;------------------------------------------------------------
{
return (strClass = "#32770") or InStr(strClass, "bosa_sdm_")
}
;------------------------------------------------------------
;------------------------------------------------------------
DialogIsSupported(strWinId)
;------------------------------------------------------------
{
blnDebug := false
WinGetTitle, strDialogTitle, ahk_id %strWinId%
if (blnDebug)
loop, % arrGlogalDialogs.MaxIndex()
###_D("DialogIsSupported? " . strDialogTitle . " " . arrGlogalDialogs[A_Index] . " " InStr(strDialogTitle, arrGlogalDialogs[A_Index]))
loop, % arrGlogalDialogs.MaxIndex()
if InStr(strDialogTitle, arrGlogalDialogs[A_Index])
return True
return False
}
;------------------------------------------------------------
;------------------------------------------------------------
NavigateExplorer(varPath, strWinId)
;------------------------------------------------------------
/*
Excerpt and adapted from RMApp_Explorer_Navigate(FullPath, hwnd="") by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa752094
*/
{
blnDebug := false
if (blnDebug)
###_D(varPath . " " . strWinId)
For pExp in ComObjCreate("Shell.Application").Windows
{
if (blnDebug)
{
SetFormat, IntegerFast, D
strTemp := strWinId + 0
###_D(A_Index . " hndw: " . pExp.hwnd . " strWinId: " . strTemp)
}
if (pExp.hwnd = strWinId)
if varPath is integer ; ShellSpecialFolderConstant
{
try pExp.Navigate2(varPath)
catch, objErr
Oops(lNavigateSpecialError, varPath)
}
/*
else if InStr(varPath, "\\") = 1 ; This must be = 1 (not true). For UNC (e.g. \\[email protected]\DavWWWRoot\Folder\Subfolder)
{
try pExp.Navigate(varPath)
catch, objErr
Oops(lNavigateUNCError, varPath, lAppName)
}
*/
else
{
; try pExp.Navigate("file:///" . varPath)
try pExp.Navigate(varPath)
catch, objErr
Oops(lNavigateFileError, varPath)
}
}
}
;------------------------------------------------------------
;------------------------------------------------------------
NavigateConsole(strPath, strWinId)
;------------------------------------------------------------
{
blnDebug := false
if (blnDebug)
###_D("strPath: " . strPath . ";nstrWinId: " . strWinId)
if (WinExist("A") <> strWinId) ; in case that some window just popped out, and initialy active window lost focus
WinActivate, ahk_id %strWinId% ; we'll activate initialy active window
SendInput, CD /D %strPath%{Enter}
}
;------------------------------------------------------------
;------------------------------------------------------------
NavigateDialog(strPath, strWinId, strClass)
;------------------------------------------------------------
/*
Excerpt from RMApp_Explorer_Navigate(FullPath, hwnd="") by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
*/
{
blnDebug := false
if (blnDebug)
###_D("Dialog: " . strPath)
if (strClass = "#32770")
{
if ControlIsVisible("ahk_id " . strWinId, "Edit1")
strControl := "Edit1"
; in standard dialog windows, "Edit1" control is the right choice
Else if ControlIsVisible("ahk_id " . strWinId, "Edit2")
strControl := "Edit2"
; but sometimes in MS office, if condition above fails, "Edit2" control is the right choice
Else ; if above fails - just return and do nothing.
{
if (blnDebug)
###_D("strClass is #32770 but no valid control is visible.")
Return
}
}
Else if InStr(strClass, "bosa_sdm_") ; for some MS office dialog windows, which are not #32770 class
{
if ControlIsVisible("ahk_id " . strWinId, "Edit1")
strControl := "Edit1"
; if "Edit1" control exists, it is the right choice
Else if ControlIsVisible("ahk_id " . strWinId, "RichEdit20W2")
strControl := "RichEdit20W2"
; some MS office dialogs don't have "Edit1" control, but they have "RichEdit20W2" control, which is then the right choice.
Else ; if above fails, just return and do nothing.
{
if (blnDebug)
###_D("strClass is bosa_sdm_ but no valid control is visible.")
Return
}
}
Else ; in all other cases, open a new Explorer and return from this function
{
if (blnDebug)
###_D("Dialog box strClass is not in #32770 or bosa_sdm_. Open a new Explorer.")
ComObjCreate("Shell.Application").Explore(strPath)
; http://msdn.microsoft.com/en-us/library/windows/desktop/bb774073%28v=vs.85%29.aspx
Return
}
;===In this part (if we reached it), we'll send strPath to control and restore control's initial text after navigating to specified folder===
ControlGetText, strPrevControlText, %strControl%, ahk_id %strWinId% ; we'll get and store control's initial text first
ControlSetTextR(strControl, strPath, "ahk_id " . strWinId) ; set control's text to strPath
ControlSetFocusR(strControl, "ahk_id " . strWinId) ; focus control
if (WinExist("A") <> strWinId) ; in case that some window just popped out, and initialy active window lost focus
WinActivate, ahk_id %strWinId% ; we'll activate initialy active window
;=== Avoid accidental hotkey & hotstring triggereing while doing SendInput - can be done simply by #UseHook, but do it if user doesn't have #UseHook in the script ===
If (A_IsSuspended)
blnWasSuspended := True
if (!blnWasSuspended)
Suspend, On
SendInput, {End}{Space}{Backspace}{Enter} ; silly but necessary part - go to end of control, send dummy space, delete it, and then send enter
if (!blnWasSuspended)
Suspend, Off
Sleep, 70 ; give some time to control after sending {Enter} to it
ControlGetText, strControlTextAfterNavigation, %strControl%, ahk_id %strWinId% ; sometimes controls automatically restore their initial text
if (strControlTextAfterNavigation <> strPrevControlText) ; if not
ControlSetTextR(strControl, strPrevControlText, "ahk_id " . strWinId) ; we'll set control's text to its initial text
if (WinExist("A") <> strWinId) ; sometimes initialy active window loses focus, so we'll activate it again
WinActivate, ahk_id %strWinId%
}
ControlIsVisible(strWinTitle, strControlClass)
/*
Adapted from ControlIsVisible(WinTitle,ControlClass) by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
*/
{ ; used in Navigator
ControlGet, blnIsControlVisible, Visible, , %strControlClass%, %strWinTitle%
return blnIsControlVisible
}
ControlSetFocusR(strControl, strWinTitle = "", intTries = 3)
/*
Adapted from RMApp_ControlSetFocusR(Control, WinTitle="", Tries=3) by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
*/
{ ; used in Navigator. More reliable ControlSetFocus
Loop, %intTries%
{
ControlFocus, %strControl%, %strWinTitle% ; focus control
Sleep, 50
ControlGetFocus, strFocusedControl, %strWinTitle% ; check
if (strFocusedControl = strControl) ; if OK
return True
}
}
ControlSetTextR(strControl, strNewText = "", strWinTitle = "", intTries = 3)
/*
Adapted from from RMApp_ControlSetTextR(Control, NewText="", WinTitle="", Tries=3) by Learning One
http://ahkscript.org/boards/viewtopic.php?f=5&t=526&start=20#p4673
*/
{ ; used in Navigator. More reliable ControlSetText
Loop, %intTries%
{
ControlSetText, %strControl%, %strNewText%, %strWinTitle% ; set
Sleep, 50
ControlGetText, strCurControlText, %strControl%, %strWinTitle% ; check
if (strCurControlText = strNewText) ; if OK
return True
}
}
;============================================================
; TOOLS
;============================================================
; ### DELETE UNUSED FUNCTIONS BEDORE FINAL RELEASE
; ------------------------------------------------
Help(strMessage, objVariables*)
; ------------------------------------------------
{
Gui, +OwnDialogs
StringLeft, strTitle, strMessage, % InStr(strMessage, "$") - 1
StringReplace, strMessage, strMessage, %strTitle%$
MsgBox, 0, % L(lFuncHelpTitle, lAppName, lAppVersionLong, strTitle), % L(strMessage, objVariables*)
}
; ------------------------------------------------
; ------------------------------------------------
Oops(strMessage, objVariables*)
; ------------------------------------------------
{
Gui, +OwnDialogs
MsgBox, 48, % L(lFuncOopsTitle, lAppName, lAppVersionLong), % L(strMessage, objVariables*)
}
; ------------------------------------------------
; ------------------------------------------------
L(strMessage, objVariables*)
; ------------------------------------------------
{
Loop
{
if InStr(strMessage, "~" . A_Index . "~")
StringReplace, strMessage, strMessage, ~%A_Index%~, % objVariables[A_Index]
else
break
}
return strMessage
}
; ------------------------------------------------
###_D(str, blnAgain := 0)
{
static blnSkip### := false
if (blnSkip###)
if (blnAgain)
blnSkip### := false
else
return
intOption := 6 + 512 ; 6 Cancel/Try Again/Continue + 512 Makes the 2nd button the default
MsgBox, % intOption, ###_D(ébug), %str%
IfMsgBox TryAgain
ExitApp
else IfMsgBox Cancel
blnSkip### := true
else
return
}
*** Also download the language file: PopupFolders_LANG.ahk. ***



- JnLlnd
- Posts: 434
- Joined: 29 Sep 2013, 21:29
- GitHub: JnLlnd
- Location: Montreal, Quebec, Canada
- Contact:
Re: 4 options to change the current folder in Windows Explor
Final beta version of my new app is now released. Just decided to rename to "Folders Popup" it in the last minute (what a crazy idea!).
Apps source: https://github.com/JnLlnd/FoldersPopup
Apps home page: http://code.jeanlalonde.ca/folderspopup/
Thank you all for your help (as mentioned in the app's About page).
Apps source: https://github.com/JnLlnd/FoldersPopup
Apps home page: http://code.jeanlalonde.ca/folderspopup/
Thank you all for your help (as mentioned in the app's About page).



Re: 4 options to change the current folder in Windows Explor
Hi.
About this code...
It works fine on a regular windows explorer window but it won't work on Open/Save dialogs.
Any help?
Thanks
About this code...
Code: Select all
location := "c:\windows"
WinGet, hwnd_id, ID, A
msgbox % hwnd_id
For pExp in ComObjCreate("Shell.Application").Windows
if (pExp.hwnd = hwnd_id) ; matching window found
pExp.Navigate(location)
Any help?
Thanks
Who is online
Users browsing this forum: Cornelius-Figgle, Fios_Huang, gya, jonjon, MeNameDark, RDC and 74 guests