The set of three scripts posted here are an enhanced version of the script I described in
'Context Menu Item Puts Any Folder Into a Dialog Window'. I'm calling the new version STDW_V2.1 and using a new thread to avoid confusion with the old script.
I've used many code snippets from the forum, but I'm indebted especially to Serenity, Andreone, ChrisM, and Majkinetor for some important functions. (See the program comments for details).
The program makes it easier to enter the folder you want when using dialog windows such as 'Save' and 'Save As' that expect you to navigate to a folder. When the folder you want is already visible in a folder browser, navigating to it again is wasted effort. The program helps in the following ways:
It adds a new item 'Send to Dialog Window' to the context menu of folders. Click on it and the folder is inserted into the dialog window.
When you open a dialog window a small window pops up containing a list of folders that are open in file browser windows plus a list of folders that have previously been selected by the program. Clicking the left half of the dialog window's Title Bar toggles the pop-up off and on.
A 'Toggle Full Path' button on the pop-up shows folder names with or without the full path.
A button 'Prune Favourites' removes least-used favourites from the list. (Explanations of this and other aspects of the program are in the subroutine DefineHelpMessages in the main script).
Here's a screen shot showing how to enter the path of a folder visible in Explorer (or elsewhere) into Notepad's Save As dialog, either from the folder's context menu or from STDW's pop-up window.

If AutoHotkey is installed on the computer use the non-compiled version:
Download the zip file and extract the contents to a new folder such as AutoHotkey Scripts\STDW. The directory should contain the four files STDW_Main.ahk, STDW_Functions.ahk, STDW_ContextMenu.ahk, and DAT_Red_Arrow.ico.
Click on STDW_Main.ahk to run the script. A red arrow icon will appear in the system tray
and a new file STDW(<your computer name>).ini will appear in the same folder.
If AutoHotkey is not installed on the computer, use the compiled version as follows:
Download STDW_Main.exe to a new folder such as AutoHotkey Scripts\STDW.
Click on it to run it for the first time. A red arrow icon should appear in the tray
and the two extra files STDW_ContextMenu.exe and STDW(<your computer name>).ini will appear in the folder.
After that you can:
Open a 'Save As' window and check that a new window called 'Send to Dialog Window- by DAT' also appears, as in the screen shot.
Left-click in the left half of the dialog window's Title Bar to toggle the new window on and off.
Open a second or third dialog window and note that clicking in the left half of a Title Bar moves the pop-up window to that dialog window.
Right click a folder icon and note the new item 'Send to Dialog Window'. Click on it to automatically enter the folder into the dialog window.
Right click on the tray icon and read 'What it Does' and 'General Hints'.
Normally the program should be left running all the time, but you can close it by clicking Exit from the tray icon. This will also remove the 'Send to Dialog Window' item from folder context menus.
The script works with all the dialog windows I've found in Windows XP, Vista, Office 2003, Directory Opus, and MS Publisher 2000 but it will probably need further tweaking to work properly with Windows 7.
It also works with the 'Move Items' and 'Copy Items' dialog windows from 'Move To...' and 'Copy To...'. These two useful items are easily added to the context menu for files and folders in XP and Vista as described
here, and illustrated below. The two context menu entries are visible in the previous screen shot as 'Move to folder...' and 'Copy to folder...'.
STDW_Main.ahk is the main script but it requires the next two scripts as well.
Code:
; ;;;;;;;;;;;
; SSTDW_Main.ahk
; V2.1
; By DAT, 22-04-2010
;
; Description.
; This is the main script of three scripts plus an icon that make up
; 'Send to Dialog Window, ; Version 2' by DAT. The set replaces my
; previous script 'SendToDialogWindow' at
; http://www.autohotkey.com/forum/topic40764.html&highlight=sendtodialogwindow.
; All three scripts and the icon file should be stored in the same directory.
;
; The object of the scripts is to make it easier to enter the folder you want
; when using dialog windows - windows like 'Save' and 'Save As' that expect
; you to enter a folder and path.
;
; When you run STDW_Main it adds the item 'Send to dialog window' to the
; right-click menu of a folder. Click on it and the folder is inserted
; into the dialog window. (When you close STDW_Main, the new item in the
; context menu item is removed again).
;
; Extra features compared to the original version of 'Send to Dialog Window'
; include:
;
; 1. When a dialog window opens, the script automatically displays a pop-up
; window that shows paths that are currently visible in Windows Explorer
; or in Directory Opus, together with a history of previously selected
; paths.
; 2. The pop-up can be toggled off and on by left-clicking in the left half
; of the dialog window's Title Bar.
; 3. Clicking an entry in the list of paths sends it to the dialog window.
; 4. The more often a path is selected, the higher it rises in the displayed
; list.
; 5. The button 'toggle Full Path' switches between displaying the full path
; or just the target folder in the pop-up.
; 6. The button 'Prune Favorites' successively removes items that have been
; less frequently used. (The way this works is described in IniHintsMsg
; below, which can be displayed by right-clicking the Tray icon when the
; script is running).
; 7. The pop-up window 'remembers' its location relative to the centre of
; the dialog window. (If placed too far from the dialog window it will
; move to be adjacent to the DW the next time it's opened).
; 8. Documentation about the program can be displayed by right-clicking
; the Tray icon when the script is running. (The documentation is in
; the subroutine DefineHelpMessages).
;
; The script works with all the dialog windows I've found in Windows XP,
; Vista, Office 2003, Directory Opus, and MS Publisher 2000. It will
; probably need tweaking to work properly with Windows 7.
;
; It also works with the 'Move Items' and 'Copy Items' dialog windows from
; 'Move To' and 'Copy To'. [These are useful items that you can easily add
; to the context menu for files and folders in XP and Vista. See, eg,
; http://technobabble.com.au/technobabble/html/tweaks/context-menus.htm].
;
;;;;;;;;;;;;;;;;;;
; Special acknowledgements to: Serenity, Andreone, ChrisM, Majkinetor for
; the functions they posted on the AHK forum. See AboutMsg below for more
; details. (Or select 'About this Program' by right-clicking the Tray icon
; when the script is running).
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ................... Still To Do (Possibly) .....................
; 1. Would be better if GUI remained one level up from its dialog window.
; instead of being just 'always on top'.
; 2. Might be useful to have separate 'favourites' list for each type of DW.
; 3. Disable normal double-click action in left half of Title Bar.
; 4. Add a button to include a list of 'recent folders' in the list box.
; ................................................................
; ................... Auto-Execute section.....................
#NoEnv
#SingleInstance , Force
#Include %A_ScriptDir%\STDW_Functions.ahk
SetWorkingDir %A_ScriptDir%
SetBatchLines,-1
SendMode Input
CoordMode , Mouse , Screen
OnExit , ExitSub ; Ensures reg key and event hook removed when script terminates
If A_IsCompiled
SendToScript = %A_ScriptDir%\STDW_ContextMenu.exe ; The compiled companion script
Else
SendToScript = %A_ScriptDir%\STDW_ContextMenu.ahk ; The companion script
IniFile = STDW(%A_ComputerName%).ini ; NB Must be defined the same in the companion script
MsgboxTitle := "Send to Dialog Window - by DAT"
ContextMenuText := "Send to Dialog Window"
Gosub , DefineHelpMessages ; Do this prior to setting up the ini file.
Gosub , DoTray
Gosub , AddRegKey ; Add registry key to generate right-click option for folders
; If no ini file, set one up
IfNotExist , %IniFile%
{
IniWrite , 1 , %IniFile% , Settings, AutoMode
IniWrite , 1 , %IniFile% , Settings, FolderMode ; 1 = folder only, 0 or blank = include path
IniWrite, 3 , %IniFile% , Settings, PruneFactor
IniWrite , 140 , %IniFile% , Settings, Xoffset ; default offset from centre of dialog window
IniWrite , 140 , %IniFile% , Settings, Yoffset
IniWrite, %A_Space% , %IniFile% , Favourites, History
IniWrite, %IniHintsMsg% , %IniFile% , IniHints, Prune works like this:
}
; Get the Automode parameter from the ini file
IniRead , AutoMode , %IniFile% , Settings, AutoMode
If AutoMode = Error
IniWrite , 1 , %IniFile% , Settings, AutoMode
; Automode has an effect only with multiple dialog windows. Change it in the
; ini file to try it either way and see which you prefer. Options are as follows.
;
; If AutoMode = 1 [default]
; The first time a new dialog window gets focus it auto-triggers a GUI, but not
; thereafter (unless closed and reopened). With multiple dialog windows running,
; if you click in the left half of Title Bar of a DW, the GUI moves to it. If
; you click anywhere else, the window gets focus but the GUI remains where it was.
;
; If AutoMode =
; When a dialog window gets focus, a GUI appears on it no matter how it got focus.
HookProcAdr := RegisterCallback( "HookProc", "F" )
hWinEventHook := SetWinEventHook( 0x3, 0x3, 0, HookProcAdr, 0, 0, 0 )
Return
; .................... End of Auto-Execute Section ......................
; .................... Manual Activation section ......................
; Detects click by left mouse button in left half of Title Bar of a
; dialog window.
~LButton::
MouseGetPos , x1 , y1 , ID1
StartTime = %A_TickCount%
Return
~LButton Up::
ElapsedTime := A_TickCount - StartTime
gosub , ManualTrigger
Return
ManualTrigger:
MouseGetPos , x2 , y2
WinGetPos , xloc, yloc , wloc, hloc, ahk_id %ID1%
If Abs(x2-x1)>2 OR Abs(y2-y1)>2
Return ; avoids activation when dragging or moving the window
If (x2-xloc)>wloc/2 Or !IsOverTitleBar(x2, y2, ID1) Or !IsOpenSave(ID1)
Return ; activate only when over left half of window header.
;SoundBeep , 3000, 100
;tooltip , autoflag=%autoflag%
IfEqual , AutoFlag, 1 , Return ; Avoid possible double call to GUI
; If pre-existing DW was clicked, toggle the GUI.
; If new DW was clicked, close any existing GUI, and open GUI on the new DW.
If (ID1 = CurrentID) ; Toggle the GUI
{
IfWinExist , %MsgboxTitle%
Gosub, CloseGUI
Else
Gosub , DoGUI
Return
}
CurrentID = %ID1% ; It's a different dialog window so give it the GUI
Gosub, CloseGUI
gosub , DoGUI
Return
; .................... End of Manual Activation section......................
; .................... Automatic Activation section......................
; Adapted from WinEventHook Messages v0.3 by Serenity
; http://www.autohotkey.com/forum/viewtopic.php?t=35659.
; Automatically triggers a GUI when a dialog window appears. If it's appearing
; for the first time, always open a GUI for it. If it's not the first time,
; open a new GUI only if the AutoMode flag permits.
HookProc( hWinEventHook, Event, hWnd, idObject, idChild, dwEventThread, dwmsEventTime )
{
global CurrentID, AutoFlag, DWCount, DWList, NewAutoID, AutoMode
if Event ; EVENT_SYSTEM_FOREGROUND = 0x3 ; EVENT_SYSTEM_DIALOGSTART = 0x10
{
IfEqual , hWnd, %CurrentID% , Return ; Existing dialog window detected again.
WinWait , ahk_id %hWnd% , , 0.4 ; Necessary for IsOpenSave() to work.
If ErrorLevel
Return
If IsOpenSave(hWnd)
{
NewFlag = 1 ; Assume it's a new DW.
If hWnd Contains %DWList%
NewFlag = ; It's not a new DW.
NewAutoID = %hWnd%
Gosub , CountDWs
If ((AutoMode = 1) And (DWCount>1) And (NewFlag<>1))
Return
CurrentID = %hWnd% ; New DW validated, so do new GUI.
AutoFlag = 1 ; Blocks manual trigger until GUI completed.
gosub, closegui
gosub , DoGUI
}
}
}
SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
DllCall("CoInitialize", Uint, 0)
return DllCall("SetWinEventHook"
, Uint,eventMin
, Uint,eventMax
, Uint,hmodWinEventProc
, Uint,lpfnWinEventProc
, Uint,idProcess
, Uint,idThread
, Uint,dwFlags)
}
UnhookWinEvent()
{
Global
DllCall( "UnhookWinEvent", Uint,hWinEventHook )
DllCall( "GlobalFree", UInt,&HookProcAdr ) ; free up allocated memory for RegisterCallback
}
CountDWs: ; Keeps list of current dialogue windows and counts them.
NewList =
Loop , Parse, DWList , `,
{
IfWinExist , ahk_id%A_LoopField%
NewList = %NewList%%A_LoopField%`,
}
DWList = %NewList%%NewAutoID% ; Add new DW to list
Sort , DWList , D`, U ; Remove duplicates
DWCount =
Loop, Parse , DWList , `,
DWCount += 1
Return
; .................... End of Automatic Activation section......................
DoGUI:
; Get the paths currently open in folder browsers and sort alphabetically.
; Note:
; Could append class names for other browsers to the comma-separated list
; provided they too keep the path in Edit1. (Use Window Spy to find out).
; The ahk_classes below are Explorer in Vista, ditto in XP, Directory Opus.
ClassNames := "CabinetWClass,ExploreWClass,dopus.lister"
PathBox := "Edit1" ; The ClassNN control that contains the path.
PathList := GetPathList(ClassNames,PathBox)
Sort , PathList , C D|
IniRead , DisplayedHistory , %IniFile% , Favourites, History ; get stored list
Sort , DisplayedHistory , C D| R ; R puts most used item at top of list
Separator := "------------Stored Favourites Below------------"
DisplayList = %PathList% |%Separator%| |%DisplayedHistory% ; Current plus stored paths, with separator.
DisplayList := RegExReplace(DisplayList, "[0-9]+>", "" ) ; Remove weights
; Respond to the type-of-display flag.
IniRead , DisplayMode , %IniFile% , Settings, FolderMode
If DisplayMode = Error
IniWrite , 1 , %IniFile% , Settings, FolderMode
If DisplayMode
ActualDisplayList := RemovePath(DisplayList) ;Folders only
Else
ActualDisplayList := DisplayList ;Folders and paths
; Get location of dialog window.
WinActivate , ahk_id %CurrentID%
WinGetPos , xDWPosn, yDWPosn , wDWWidth, hDWHt, ahk_id %CurrentID%
; If no data, window has closed since the trigger (eg, its 'close' button was clicked).
if !xDWPosn
return ; Abort since dialog window no longer exists
SetTimer , DialogWinGone , 300 ; Will close GUI when dialog window closes.
; Calculate location of GUI window
IniRead , Xoffset , %IniFile% , Settings, Xoffset, 140
If !Xoffset
Xoffset = 140 ; in case ini file contains empty key value.
IniRead , Yoffset , %IniFile% , Settings, Yoffset, 140
If !Yoffset
Yoffset = 140
xGUIPosn := (xDWPosn + wDWWidth/2 - Xoffset)
yGUIPosn := (yDWPosn + hDWHt/2 - Yoffset)
; Define dimensions for GUI items
CharWidth = 5.2 ; approx pixels per character . 6.3 is ok for Verdana. 5.2 for Tahoma.
Width := CharWidth*GetMaxLength(ActualDisplayList) ;Width of List Box
Rows := GetRows(ActualDisplayList) ; Number of rows in the Listbox
bwdth:=120 ; button width
bht:=15 ; button height
ButtonSeparation := Width - 2*bwdth
; Display GUI
Gui,-MaximizeBox -MinimizeBox +toolwindow +AlwaysOnTop ;+LastFound
Gui, Margin, 1,1
Gui, Font, S8 CDefault, Tahoma
; Add listbox only if folders exist.
If (PathList = "") And (DisplayedHistory = "")
Gui, Add, Text, , No Explorer window found, and no favourites are stored.`n`n%HintsMsg%`n`n(These Hints can also be viewed by right-clicking the Tray icon).
Else
{
Gui, Add, Text, w%Width% +Center, Click an entry to send it to dialog window, and to add it to favourites
Gui, Add, ListBox, vPath2 gGetResult w%Width% R%Rows% , %ActualDisplayList%
Gui, Add, Button, xm y+5 w%bwdth% h%bht% gTogglePath, Toggle Full Path
; Add Prune button only if History exist.
If (DisplayedHistory != "")
Gui, Add, Button, x+%ButtonSeparation% yp w%bwdth% h%bht% gPrune, Prune Favourites
}
Gui, Show,X%xGUIPosn% Y%yGUIPosn%, %MsgboxTitle%
AutoFlag=
Return
GetRows(List)
{
Loop, Parse , List , `|
Rows := (A_Index -1)
IfLessOrEqual , Rows, 2 ; set min height
Rows = 2
Return , Rows
}
GetResult: ; Jumps here when you click on a Listbox entry
GuiControlGet, Path2 ; Get the path selected from the Listbox.
If (Path2=Separator Or Path2=A_Space)
Return
Path2 := MakeIntoFullPath(Path2,DisplayList)
If A_IsCompiled
Run , "%SendToScript%" "%Path2%" "0" ; Call compiled companion script to send path to dialog box.
Else
Run , AutoHotkey.exe "%SendToScript%" "%Path2%" "0" ; Call companion script to send path to dialog box.
GuiClose:
GuiEscape:
Gosub, CloseGUI
Return
TogglePath:
If DisplayMode
DisplayMode =
Else
DisplayMode = 1
IniWrite ,%DisplayMode% , %IniFile% , Settings, FolderMode
Gosub, CloseGUI
Goto , DoGUI
Return
Prune:
; Note: Increase PruneFactor to remove more favourites on each click
IniRead , PruneFactor , %IniFile% , Settings, PruneFactor
If PruneFactor = Error
IniWrite, 3 , %IniFile% , Settings, PruneFactor
Prune(IniFile,PruneFactor)
Gosub, CloseGUI
Gosub, DoGUI
Return
DialogWinGone:
IfWinNotExist, ahk_id %CurrentID%
{
Gosub, CloseGUI
SetTimer , DialogWinGone , off
CurrentID =
}
Return
CloseGUI:
; Calculate and store position of popup window relative to dialog window.
WinGetPos , xGUIPosn, yGUIPosn , GUIWidth , GUIHt, %MsgboxTitle% ; New actual positions of GUI
if xGUIPosn = ; eg if GUI was closed using its Close button
{
GUI , Destroy
Return
}
; Set placement limits so GUI can't get lost off-screen
If (xGUIPosn > (xDWPosn + wDWWidth))
xGUIPosn := xDWPosn + wDWWidth
If (xGUIPosn < (xDWPosn - GUIWidth))
xGUIPosn := xDWPosn - GUIWidth
If (yGUIPosn > (yDWPosn + hDWHt))
yGUIPosn := yDWPosn + hDWHt
If (yGUIPosn < (yDWPosn - GUIHt))
yGUIPosn := yDWPosn - GUIHt
Xoffset := xDWPosn+wDWWidth/2-xGUIPosn
Yoffset := yDWPosn+hDWHt/2-yGUIPosn
IniWrite , %Xoffset% , %IniFile% , Settings, Xoffset ; Store current GUI relative position
IniWrite , %Yoffset% , %IniFile% , Settings, Yoffset
GUI , Destroy
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; !!!! Danger Zone !!!!
; !!!! Caution: The next section writes to the registry, which is !!!!
; !!!! potentially harmful. Don't alter anything in RegDelete !!!!
; !!!! or RegWrite unless you know what you're doing. !!!!
;
; Deletes and re-installs registry key on starting and removes on finishing
AddRegKey:
; remove original key
RegDelete , HKEY_CLASSES_ROOT, Folder\shell\%MsgboxTitle%
RegWrite , REG_SZ, HKEY_CLASSES_ROOT, Folder\shell\%MsgboxTitle% ,, %ContextMenuText%
If A_IsCompiled
RegWrite , REG_SZ, HKEY_CLASSES_ROOT, Folder\shell\%MsgboxTitle%\Command ,, "%SendToScript%" "`%1" "1"
Else
RegWrite , REG_SZ, HKEY_CLASSES_ROOT, Folder\shell\%MsgboxTitle%\Command ,, "C:\Program Files\AutoHotkey\AutoHotkey.exe" "%SendToScript%" "`%1" "1"
Return
; Removes context menu option for folders when program closes
ExitSub:
Gosub , CloseGUI
RegDelete , HKEY_CLASSES_ROOT, Folder\shell\%MsgboxTitle%
UnhookWinEvent()
ExitApp
;
; !!!! End of Danger Zone !!!!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Define Tray properties
DoTray:
;Menu, Tray, NoStandard
If Not A_IsCompiled
{
Menu, Tray, add ; Creates a separator line.
IfExist , DAT_Red_Arrow.ico
Menu , Tray, Icon , %A_ScriptDir%\DAT_Red_Arrow.ico
}
Menu, Tray, Tip, Send to Dialog Box - by DAT
Menu, Tray, add, What it Does, Description
Menu, Tray, add, User Hints, Hints
Menu, Tray, add, How 'Prune' Works, PruneHint
Menu, Tray, add, About This Program, About
Menu, Tray, add ; Creates a separator line.
Menu, Tray, add, Exit, ExitSub
Return
Description:
msgbox ,320, %MsgboxTitle%, %DescriptionMsg%
Return
PruneHint:
msgbox ,320, %MsgboxTitle%, %IniHintsMsg%
Return
Hints:
msgbox ,320, %MsgboxTitle%, %HintsMsg%
Return
About:
msgbox ,320, %MsgboxTitle%, %AboutMsg%
Return
DefineHelpMessages:
DescriptionMsg =
(
What it Does:
The object of this program is to make it easier to enter the folder
you want when using dialog windows. Dialog windows, like 'Save' and
'Save As' expect you to enter a folder and path by navigating
a folder tree. Often the required folder will be open or visible in
a folder browser already, so navigating to it again is wasted effort.
The program helps in the following ways:
(1) It adds the item '%ContextMenuText%' to the context menu
of folders. Click on it and the folder is inserted into the dialog
window. (The context item is removed again when the program exits).
(2) It superimposes over the dialog window a small window
showing folders that are currently open in file browser windows
together with a list of 'favourites'. Clicking one of the items
in the display enters it into the dialog window. 'Favourites' are
folders that have previously been selected by the program. The
most frequently used folders are at the top of the list.
(4) The pop-up window appears automatically when a new dialog
window is opened. Clicking in the left half of the dialog
window's Title Bar toggles it off and on. (Or simply press Esc
to close it).
(5) A button 'Toggle Full Path' on the pop-up window lets you
choose whether or not to show the full path.
(6) If the list of favourites gets too long, use repeated clicks on the
Prune button to weed out less frequently used favourites as required,
or until they're all gone. (For details right-click on the Tray icon
and select 'How Prune Works').
)
IniHintsMsg =
(
Each Favourite is stored in the ini file as a path with a four
digit number prepended to it and with | as separator. The number
represents the 'popularity' of the path. It is the number of times
that the path has been selected from either the context menu option
that the program adds to folders, or from the list box in the GUI
window. The maximum value is set to 999. When any number exceeds
this, all the numbers are divided by three and ones that go below
zero are deleted.
Clicking the 'Prune' button divides all the numbers by the
'PruneFactor' value in the ini file. Ones that go below zero
are deleted. With PruneFactor set to 3 (default) all favourites
can be deleted by <=7 clicks, so there's no need for a 'delete
all' button.
)
HintsMsg =
(
Hints on Using It:
The 'Send to Dialog Window' (STDW) display appears automatically
when a dialog window opens for the first time. You can press Esc
to close it, or toggle it off and on with a left-click in the
left-hand half of the dialog window's Title Bar.
Only one STDW can appear at once. If more than one dialog window
is open and you click in the left half of the Title Bar of one of
them, the STDW display will transfer to the active dialog window.
A convenient way to add a folder to favourites is to right-click the
folder icon (eg, in Explorer) and then click on the context menu entry
'Send to Dialog Window'. There's no need to have a dialog window open
when doing this. (If this is done when the GUI is on-screen, the new
'favourite' won't show in the display until the GUI is refreshed by
toggling it off and on, or using the 'Toggle Full Path' button).
The script remembers the position of the STDW relative to the centre
of the dialog window between appearances, except that if the STDW
would be lost from view it will reappear adjacent to the dialog window.
When the script is first run it generates an 'ini' file in the
working directory. The file name is STDW(<your computer name>).ini
and it stores the settings for the 'Toggle Full Path' button, the
relative position of the STDW display, and the favourites.
When it starts running, the script installs the entry 'Send
to Dialog Window' in the context menu for folders, and removes
it again when it shuts down.
To stop the script, right click the Tray icon and select 'Exit'.
)
AboutMsg =
(
"Send To Dialog Window"
Version 2.1
Written by DAT
This script has been tested with XP and Vista but not Windows 7.
Acknowledgements:
Andreone for IsOverTitleBar (http://www.autohotkey.com/forum/topic22178.html).
ChrisM for the prototype of f_Open_Target ("Easy Access to Favorite Shortcuts" at http://www.autohotkey.com/forum/topic5414.html).
I modified it to work with Directory Opus, 'Move To' and 'Copy To', and 'Export Registry File' in Vista and XP.
Serenity for WinEventHook Messages v0.3 at http://www.autohotkey.com/forum/viewtopic.php?t=35659.
The check for Open/Save dialogs is based on Majkinetor's FavMenu at http://www.autohotkey.com/forum/topic12412-105.html,
(and see also http://www.autohotkey.com/forum/topic10286.html and http://www.autohotkey.com/forum/topic12585.html).
I drew the icon in Word and converted it to an ico file using SimplyIcon from http://www.smoothdraw.com/product/freeware.htm.
)
Return
STDW_ContextMenu.ahk is called by STDW_Main.ahk and by the new folder context menu entry. This is what actually enters the path into a dialog box.
Code:
; ;;;;;;;;;;;
; STDW_ContextMenu.ahk
; By DAT, 09-04-2010
;
; One of three scripts that make up 'Send to Dialog Window, Version 2' by DAT.
; Called by STDW_Main.ahk, or by clicking on an item in the context menu
; for folders that appears when STDW_Main.ahk is running.
;
; For details and acknowledgements, please refer to STDW_Main.ahk.
;
SetWorkingDir , %A_ScriptDir%
#Include %A_ScriptDir%\STDW_Functions.ahk
#SingleInstance force
; ******* Path and name of IniFile must be the same in the companion script******.
IniFile = STDW(%A_ComputerName%).ini
; *********************************************************************************.
MsgboxTitle := "Send to Dialogue Window"
; Get parameters passed from parent script
Path = %1%
SourceFlag = %2% ; 0 if called from parent program, 1 if from context menu
If Path contains ::,`;,My Computer,My Network Places,Recycle Bin ; Reject unsuitable paths
{
ShowMessage("Can't handle this type of folder")
Sleep, 3000
ExitApp
}
; When 'folder' is a drive, %1% from the context menu returns a value with
; a trailing " tacked on, as in C:". So remove any " characters.
StringReplace , Path , Path , "
; Add selected path to the stored history and check for overrun.
Path2 = 0000>%Path%| ; Format to suit DoHistory
;DoHistory(path2, DataFileName)
DoHistory(path2, IniFile)
f_window_id := Sort() ; Get top-most dialog window and fill global variable HowMany.
If Not f_window_id
{
MsgBox, 0, %MsgboxTitle%, No dialog window found`, but`n`n%path%`n`nwas added to list of favourites., 4
ExitApp
}
WinGetClass, f_class, ahk_id %f_window_id%
ControlGetPos, f_Edit1Pos,,,, Edit1, ahk_id %f_window_id%
ControlGetPos, f_Edit2Pos,,,, Edit2, ahk_id %f_window_id%
sleep , 200
; Add a backslash to avoid warnings from XP 'Save As' windows
Path = %Path%\ ; needed when sending drive names to 'Save As' in Word 2003 .
f_Open_Target(Path) ; Put the data into the window
WinActivate , ahk_id %f_window_id%
If (HowMany > 1) And SourceFlag ; issue advisory message window
{
Number := TextFromNumber(HowMany)
msg = %Number% dialogue windows are open. `n`nMake sure this is the one you want to use.
ShowMessage(msg)
Sleep , 3000
}
ExitApp
;;;;;;;;;;;;;;;;;;;;;;;;
STDW_Functions.ahk contains most of the functions:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;
;
; STDW_Functions.ahk
; By DAT, 09-04-2010
;
; One of three scripts that make up 'Send to Dialog Window, Version 2' by DAT.
; Contains functions that are used by the other two scripts.
; For details and acknowledgements, please refer to STDW_Main.ahk.
;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
; Convert numeral to text
TextFromNumber(Number)
{
IfEqual , Number , 2
Return , "Two"
IfEqual , Number , 3
Return , "Three"
IfEqual , Number , 4
Return , "Four"
IfEqual , Number , 5
Return , "Five"
Else
Return , Number
}
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;
; Puts message in centre of dialog window, or if none, in centre of screen.
ShowMessage(Msg)
{
Global f_window_id
If f_window_id
{
WinGetPos , xloc, yloc , wloc, hloc, ahk_id %f_window_id%
progw := 200
progh := 100
xloc := (xloc + wloc/2 - progw/2) ;Calculate x coordinate of Progress window
yloc := (yloc + hloc/2 - progh/2) ;Calculate y coordinate of Progress window
}
Else
{
progw := 200
progh := 100
xloc := A_ScreenWidth/2 - progw/2 ;Calculate x coordinate of Progress window
yloc := A_ScreenHeight/2 - progh/2 ;Calculate y coordinate of Progress window
}
Progress, B2 x%xloc% Y%yloc% M zh0 w%progw% h%progh%, , %Msg%
Return
}
;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;
Sort()
{
Global HowMany
; Get id of top-most dialog-type window
WinGet, Item, list,,, Program Manager
index := "" ; counts number of windows in selection
Loop, %Item% ; loop thro' all current windows, top down.
{
this_Item := Item%A_Index% ; Item1 contains id of first window, etc
WinGetTitle , Title , ahk_id %this_item%
WinGetClass, f_class, ahk_id %this_item%
If Not IsOpenSave(this_Item)
{
Item%A_Index% := ""
continue ; since not a suitable window
}
index++ ; increment pointer
Item%index% = %this_Item%
}
HowMany:= index ; number of dialog-type windows collected
return , Item1
}
;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; Enter path of selected folder into dialog window
;
; Based on ChrisM's f_Open_Target ("Easy Access to Favorite Shortcuts" at
; http://www.autohotkey.com/forum/topic5414.html). Modified by DAT to work
; with Directory Opus, 'Move To' and 'Copy To', and 'Export Registry File'
; in Vista and XP.
f_Open_Target( target )
{
global f_class, f_Edit1Pos, f_Edit2Pos, f_window_id
WinGetTitle, Title , ahk_id %f_window_id%
; It's a dialog
If (f_class = "#32770")
{
If (f_Edit1Pos <> "" And f_Edit2Pos <> "" And Title <> "Export Registry File")
; Has Edit1 and Edit2 so put folder into Edit2, except if title is 'Export Registry File'
; eg could be 'Save As' in Vista or Browse in DOpus.
{
;;;;;;;;
; A puzzle for anyone who understands these things:
; There's something funny about the next four lines. The third line works on its own
; for most windows in XP and some in Vista. But to be reliable it needs all four. The
; Save As window in SCite seems especially fastidious.
ControlGet , temp , Hwnd ,, Edit2, ahk_id %f_window_id%
ControlClick ,, ahk_id %temp%
ControlClick ,ToolbarWindow324, ahk_id %f_window_id%
sleep , 200 ; especially needed for 'Save As' with Scite4AutoHotkey in Vista
;;;;;;;;;;;;;;;;
ControlSetText, Edit2, %target%, ahk_id %f_window_id%
ControlSend, Edit2, {Enter}, ahk_id %f_window_id%
Return
}
Else If (f_Edit1Pos <> "" And f_Edit2Pos <> "" And Title = "Export Registry File")
; like Reg Export in XP and Vista
{
ControlGetText, text, Edit1, ahk_id %f_window_id% ; store filename
ControlSetText, Edit1, %target%, ahk_id %f_window_id%
ControlSend, Edit1, {Enter}, ahk_id %f_window_id%
Sleep, 100 ; needs extra time on some dialogs or in some cases.
ControlSetText, Edit1, %text%, ahk_id %f_window_id% ; reinstate stored filename
Return
}
Else If (f_Edit1Pos <> "" And f_Edit2Pos = "") ; has Edit1 but not Edit2
{
ControlGetText, text, Edit1, ahk_id %f_window_id% ; store filename
ControlSetText, Edit1, %target%, ahk_id %f_window_id% ; target folder into File Name
If (A_OSVersion = "WIN_VISTA")
Return
Else ; special treatment for XP
; Unlike 'SaveAs', Copy Items', 'Move Items', and 'Browse' windows contain SysTreeView321
{
winget , ctrls , ControlList , ahk_id %f_window_id%
Loop, Parse, ctrls, `n
IfEqual , A_LoopField , SysTreeView321
{
WinGetText, FName, ahk_id %f_window_id% ; Name of file to be moved or copied
StringSplit, FName, FName, ' ; is between single quotes
WinGetTitle, Title , ahk_id %f_window_id%
StringSplit , Title , Title , %A_Space%
Message=You selected %Target%
IfEqual , Title2 , Items
Message=Will %Title1% '%FName2%' to %Target%
MsgBox, 1, , %Message%
IfMsgBox Cancel
return
}
ControlSend, Edit1, {Enter}, ahk_id %f_window_id% ; implement change of target folder
Sleep, 100 ; It needs extra time on some dialogs or in some cases.
ControlSetText, Edit1, %text%, ahk_id %f_window_id% ; reinstate stored filename
Return
}
}
}
; Microsoft Office application
Else IfInString, f_class, bosa_sdm_
{
; Retrieve any file name that might already be in the File name
; control, so that it can be restored after the switch to the new
; folder.
ControlGetText, text, RichEdit20W2, ahk_id %f_window_id%
ControlClick, RichEdit20W2, ahk_id %f_window_id%
ControlSetText, RichEdit20W2, %target%, ahk_id %f_window_id%
ControlSend, RichEdit20W2, {Enter}, ahk_id %f_window_id%
Sleep, 100 ; It needs extra time on some dialogs or in some case
ControlSetText, RichEdit20W2, %text%, ahk_id %f_window_id%
Return
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;
; Makes list of the destination folder paths displayed in Explorer and DOpus.
; Puts them into into 'PathList' with '|' as separator. (This is the default
; separator expected by ListBox in the GUI command).
GetPathList(ClassNames,PathBox)
{
WinGet, id, list
PathList := ; Pipe delimited list of paths in file browsers
;Number := ; The number of paths found
Length := ; The number of characters in the longest path
Loop, %id%
{
this_id := id%A_Index%
WinGetClass, this_class, ahk_id %this_id%
If this_class contains %ClassNames%
{
;number ++ ; increment
ControlGet , this_path , Line, 1 , %Pathbox%, ahk_id %this_id%
this_path = %this_path% ; Strip any peripheral spaces
; Bodge for XP. Copying 'My Documents' from the title bar or from Edit1 of Explorer,
; in XP gives just that, not a path, so the next two lines convert it.
IfEqual , this_path, My Documents
this_path := A_MyDocuments
PathList = %PathList%0000>%this_path%| ; Adds 4-digit weight plus | as line separator
}
}
Return , PathList
}
;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;
; Take each new path in turn, then search for same path in History.
; If found, update the stored weight value. If not found, add new
; path to the history. Outputs PruneFlag.
DoHistory(pathlist, IniFile)
{
;FileRead , History , %DataFileName% ; get stored list
IniRead , History , %IniFile% , Favourites, History
OverRun = ; If a weight exceeds an upper limit, this flag will be set.
Loop , Parse , pathlist ,`| ; Take each new path in turn, then search for similar in History
{
IfEqual , A_LoopField ; Must have reached end of pathlist
Break
StringSplit , Section , A_LoopField , > ; Section1=weight, Section2=path
; Now check for same path in contents of History. Compare the new path plus separator with
; each entry in history.
Section2 = %Section2%|
Posn := InStr(History , Section2) ; gets position of first occurrence in History
IfNotEqual , Posn , 0 ; If search for Path was successful
{
Posn -= 5 ; Point to first digit of its weight number
OldWeight := SubStr(History , Posn, 4) ; get the weight digits
IfGreater , OldWeight , 999 ;99 ; Parameter must be =< 9998 to avoid overflow.
OverRun = 1 ; Triggers a rescaling procedure if limit was exceeded.
; Replace existing weight and path in History with an updated version
SearchText = %OldWeight%>%Section2% ; This is the old entry if it exists
NewWeight = %OldWeight%
NewWeight +=1
NewWeight := SubStr("0000" . NewWeight, -3) ; Format as 4-digits with leading zeros (see Help for SetFormat).
NewValue = %NewWeight%>%Section2%
StringReplace , History , History , %SearchText% , %NewValue%
}
Else ; New weight and path not in History, so append it
History = %History%%A_LoopField%`|
}
If OverRun
{
Prune(IniFile,3) ; Divides all weights in the history by the parameter
Return , OverRun
}
IniWrite, %History% , %IniFile% , Favourites, History
Return , OverRun
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;
; Removes paths and leaves just folder names.
RemovePath(DisplayList)
{
NewDisplayList = %DisplayList%
Loop, Parse , DisplayList , `|
{
SplitPath , A_LoopField , name , dir
StringReplace , NewDisplayList, NewDisplayList, %dir%
; msgbox , A_LoopField=%A_LoopField%`ndir=%dir%`nname=%name%`nNewDisplayList=%NewDisplayList%
}
Return , NewDisplayList
}
;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;
; Adds full path back again after RemovePath() has removed them.
MakeIntoFullPath(Path,DisplayList)
{
Loop, Parse , DisplayList , `|
{
StringGetPos , Posn , A_LoopField , %Path% , R
If !ErrorLevel
{
temp = %A_LoopField%
StringReplace , temp , temp , %Path% , ``
StringSplit , item , temp , ``
If !Item2
Return , A_LoopField
}
}
}
;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
; Get number of characters in longest path
GetMaxLength(DisplayList)
{
Lngth =
Loop, Parse , DisplayList , `|
{
If StrLen(A_LoopField)>Lngth
Lngth := StrLen(A_LoopField)
}
Return , Lngth
}
;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;
; Divides all stored weights by a factor and drops those that become zero
Prune(IniFile,PruneFactor)
{
IniRead , History , %IniFile% , Favourites, History ; get stored list
;FileRead , History , %DataFileName% ; get stored list
NewHistory =
Loop , Parse , History ,`|
{
Item= %A_LoopField% ; contains weight and path
StringSplit , Section , Item , > ; Section1=weight, Section2=path
IfEqual , Item ; Must have reached end of History
Break
Section1 /=%PruneFactor%
IfNotEqual , Section1 , 0 ; If weight has not dropped to zero
{
Section1 := SubStr("0000" . Section1, -3) ; Show as a 4-digit number with leading zeros - see Help for SetFormat).
NewHistory = %NewHistory%%Section1%>%Section2%|
}
}
IniDelete, %IniFile% , Favourites, History
IniWrite, %NewHistory% , %IniFile% , Favourites, History
;FileDelete , %DataFileName% ; Delete old history
;FileAppend , %NewHistory% , %DataFileName% ; Store new history
Return
}
;;;;;;;;
;;;;;;;;;;;
; Function by Andreone at http://www.autohotkey.com/forum/topic22178.html
; 31-12-2008
;
IsOverTitleBar(x, y, hWnd)
{
SendMessage, 0x84,, (x & 0xFFFF) | (y & 0xFFFF) << 16,, ahk_id %hWnd%
if ErrorLevel in 2,3,8,9,20,21
return true
else
return false
}
;;;;;;;;;;;;;;;;;;;
;------------------------------------------------------------------------------------------------
; The following functions are by Majkinetor with hacks by DAT for
; 'Move Items' and 'Copy Items', MS Publisher2000, and to give some
; functionality for Vista.
; To include windows 7, a good place to start might be the post by rs dated 06-01-2010 at
; http://www.autohotkey.com/forum/topic12412-105.html
IsOpenSave(dlg)
{
global FavMenu_dlgInput, FavMenu_dlgType
FavMenu_dlgType =
toolbar := FavMenu_FindWindowExID(dlg, "ToolbarWindow32", 0x440) ;windows XP
if (toolbar = "0")
toolbar := FavMenu_FindWindowExID(dlg, "ToolbarWindow32", 0x001) ;windows 2k
combo := FavMenu_FindWindowExID(dlg, "ComboBoxEx32", 0x47C) ; comboboxex field
button := FavMenu_FindWindowExID(dlg, "Button", 0x001) ; second button
edit := FavMenu_FindWindowExID(dlg, "Edit", 0x480) ; edit field
if (toolbar && (combo || edit) && button)
{
FavMenu_dlgInput := combo + edit
FavMenu_dlgType := "OpenSave"
return 1
}
return FavMenu_IsOffice03(dlg)
}
;------------------------------------------------------------------------------------------------
FavMenu_IsOffice03(dlg)
{
global FavMenu_dlgInput, FavMenu_dlgType
WinGetClass cls, ahk_id %dlg%
if cls contains bosa_sdm_
{
snake := FavMenu_FindWindowExID(dlg, "Snake List", 0)
FavMenu_dlgInput := FavMenu_FindWindowExID(dlg, "RichEdit20W", 54)
if ! (snake && FavMenu_dlgInput)
return, Misc_Others(dlg)
FavMenu_dlgType := "Office03"
return 1
}
return , Misc_Others(dlg)
}
;-------------------------------------------------------------------------------
Misc_Others(dlg) ; Hacked in by DAT 28-03-2010
{
global FavMenu_dlgInput, FavMenu_dlgType
WinGetClass cls, ahk_id %dlg%
If (cls <> "#32770") And (cls <> "bosa_sdm_Mso96")
Return 0
; check for 'Move Items' and 'Copy Items'
WinGetTitle , Title , ahk_id %dlg%
If Title In Save,Save File,Save As,Move Items,Copy Items,Browse For Folder,Browse ; Add extras here, with one comma and no spaces between each.
return 1
; check for Office2000 [Tested only for Publisher 2000]
If (cls = "bosa_sdm_Mso96")
return 1
Return, 0
}
;------------------------------------------------------------------------------------------------
; Iterate through controls with the same class, find the one with ctrlID and return its handle
; Used for finding a specific control on a dialog
FavMenu_FindWindowExID(dlg, className, ctrlId)
{
local ctrl, id
ctrl = 0
Loop
{
ctrl := DllCall("FindWindowEx", "uint", dlg, "uint", ctrl, "str", className, "uint", 0 )
if (ctrlId = "0")
return ctrl
if (ctrl != "0")
{
id := DllCall( "GetDlgCtrlID", "uint", ctrl )
if (id = ctrlId)
return ctrl
}
else
return 0
}
}
;----------------------------------------------------------