AutoHotKey: How does the WinTitle work? - windows

I just started playing around with AutoHotKey today but got stuck at moving/resizing windows...
WinMove needs a WinTitle but I can't figure out how the WinTitle works.
When I try the following code:
#SingleInstance force
#y::
run, notepad
Sleep, 1000
WinGetTitle, window,, A
MsgBox, Active window: %window%
Sleep, 1000
WinMove, window,, 0, 0
MsgBox, %window% moved.
return
Notepad dosn't get moved to the top left corner, but why?
I have also tried storing the ID as a string: program := window WinMove, program,, 0, 0 but that didn't work either.

In your example "window" is a variable and "WinMove" is a command.
Commands always use "traditional syntax". Meaning: when you use a variable in a command, you have to enclose the variable in percent signs:
WinMove, %window%,, 0, 0
EDIT:
Btw.
WinGetTitle, window,, A
has to be
WinGetTitle, window, A
EDIT2:
#SingleInstance force
#y::
run, notepad
WinWait, Untitled - Notepad ; title - Use Window Spy to find the exact title of this window
; IfWinNotActive, Untitled - Notepad, ,WinActivate, Untitled - Notepad
; WinWaitActive, Untitled - Notepad
Sleep, 200
WinMove, Untitled - Notepad,, 0, 0
return

Related

Cover inactive windows with GUI, Solutions to Variable Coordinates (AHK)

I collapse all my windows to title bars when not active. I want to cover these inactive windows with different color GUIs. The GUI will only need minimal functionality, just a way to color-code title bars when collapsed, and inactive. That way, I can tell what's what much easier when I look at a desktop full of title bars.
Although I know I have the correct coordinates stored as variables, the gui doesn't show up at all if I specify coordinates as numbers, or as variables. But if I don't specify any coordinates, the GUI appears in the middle of the screen.
This just seems like a combination of
-settimer, and a timer that updates the coordinates when the window moves.
-alwaysontop(ish) of a specific window for each gui(could use some help here, Looking to apply winset, top to a GUI when it's associated window is inactive, but also remain under any newly active window (to keep the GUI visible when looking at the desktop).
-using the corresponding window's y coordinate to know how high to place the GUI(main issue, although I know I have the correct coordinates stored as variables)
-displaying a different color for each GUI.
-The GUI should span across the entire screen width, and be 1/17 the screen height (about the height of the title bar with my screen/resolution).
-winhide a window's gui when it's associated window is active, and winshow when inactive
#SingleInstance,Force
WinGetPos , X_SciTEWindow, Y_SciTEWindow, Width_SciTEWindow, Height_SciTEWindow, ahk_class SciTEWindow ;I don't even need the X_SciTEWindow, because the bars will all be aligned at x0, but it's there...
SysGet, aScreenHeight, 1
bar_height := Round(aScreenHeight / 17)
Gui, Color, aqua,FFB1B1
Gui, Show, w%A_ScreenWidth% h%bar_height%, SomeStupidBar
WinSet, Style, -20xC40000
Winmove, %SomeStupidBar%, x0, y%Y_SciTEWindow%, w%A_ScreenWidth%, h%bar_height%
MsgBox, Time to move the window to x0, y%Y_SciTEWindow%, w%A_ScreenWidth%, h%bar_height%
Winmove, %SomeStupidBar%, x0, y%Y_SciTEWindow%, w%A_ScreenWidth%, h%bar_height%
return
Esc::ExitApp
SetTimer, ShowGui, 500
ShowGui:
IfWinNotExist, ahk_class AutohotkeyGUI
{
Gui, +Owner%WinID% +Border +ToolWindow
Gui, Show, NoActivate x%X% y%Y% w51 h431, %GuiTitle%
}
else
{
WinWaitActive, ahk_class SciTEWindow
WinGetPos, X_SciTEWindow, Y_SciTEWindow,,, ahk_class Notepad
WinGet, WinID, ID, ahk_class SciTEWindow,,,
IfWinNotExist, ahk_class AutohotkeyGUI
WinGetPos, %SomeStupidBar%, , , , ahk_class AutohotkeyGUI
If %SomeStupidBar%<>X - 56
WinMove, ahk_class AutohotkeyGUI, X - 56
}
return
Any help would be greatly appreciated.
#NoEnv
#SingleInstance Force
Gui, SciTE: +Owner -Caption
Gui, SciTE: Color, aqua
Gui, Notepad: +Owner -Caption
Gui, Notepad: Color, red
SysGet, aScreenHeight, 1
bar_height := Round(aScreenHeight / 17)
SetTimer, ShowGui, 500
return
Esc::ExitApp
ShowGui:
If !WinExist("ahk_class SciTEWindow") ; means "NOT"
Gui, SciTE: Cancel
else
{
WinGetPos, X_SciTE, Y_SciTE,,, ahk_class SciTEWindow
If X_SciTE >= 0
Gui, SciTE: Show, NoActivate x%X_SciTE% y%Y_SciTE% w51 h%bar_height%, SciTEWindow
}
If !WinExist("ahk_class Notepad")
Gui, Notepad: Cancel
else
{
WinGetPos, X_Notepad, Y_Notepad,,, ahk_class Notepad
If X_Notepad >= 0
Gui, Notepad: Show, NoActivate x%X_Notepad% y%Y_Notepad% w51 h%bar_height%, Notepad
}
return
#If WinActive("ahk_class AutoHotkeyGUI")
~*LButton Up::
WinGetTitle, ActiveTitle, A
WinActivate, ahk_class %ActiveTitle%
return
#If

Autohotkey script to download to a specific folder on the computer

I need Firefox to always open Desktop in the Save as dialogue on saving files, so I can type in the name of the folder on the Desktop and save the file where I want. That would be a simple and very efficient way of grouping downloaded files. The problem is that Firefox opens the last save folder in the Save as dialogue window, and I can't do this in a reasonable number of steps. To get Desktop automatically opened in the Save as dialogue the best I could think of is this autohotkey script, and I have a problem with it:
!+^s::
MouseMove, %A_CaretX%, %A_CaretY%
CoordMode, Mouse, Screen
MouseGetPos, xpos, ypos
SetMouseDelay, 2
MouseMove,445,46
Click Left
Send,Desktop
Send,{Enter}
MouseMove, %xpos%, %ypos%
Click Left
CoordMode, Mouse, Screen
MouseGetPos, xpos, ypos
SetMouseDelay, 2
MouseMove,445,46
Click Left
MouseMove,%xpos%, %ypos%
Click Left
Input, L, V L1
Loop {
Input, L, V L1 T1.4
If (ErrorLevel = "Timeout")
Break
}
Send,^{Down}
Send,{Enter}
MouseClick,Left,720,473
MouseClick,Left,720,473
return
The problem with this script is the Input command - it doesn't wait for me to type in the name of the folder but executes the following command immediatelly.
EDITED: The script is now fully working (thanks to Forivin). An additional line with Input comamand "Input, L, V L1" was required for the script to pause and wait for the name of the folder to be typed in. I've used MouseClick command and coordinates that work for my monitor to confirm the dialogue box. Confirming the dialog box with Enter (4 times) doesn't work accurately on my computer for some reason. EDIT2: Added two lines, in order to make use of the drop down list folder name suggestions, so the whole folder name doesn't need to be typed in.
Using the Control*-commands would be a much more reliable way of doing this:
!+^s::
WinGet, hWnd, ID, A ;Get handle of active window
;Navigate the the users desktop folder
ControlFocus, ToolbarWindow324, ahk_id %hWnd%
ControlClick, ToolbarWindow324, ahk_id %hWnd%,,,2, NA
ControlSetText, Edit2, `%HOMEPATH`%\Desktop\, ahk_id %hWnd%
ControlSend, Edit2, {Enter}, ahk_id %hWnd%
;Set focus to the folder list
Sleep, 100
ControlFocus, DirectUIHWND2, ahk_id %hWnd%
Input, L, V L1 T2 ;wait until you start typing a folder name (if you just wait 2 seconds, the download will be canceled)
If (ErrorLevel = "Timeout") { ;if you waited too long:
ControlClick, Button2, ahk_id %hWnd%,,,, NA ;click the Cancel button
Return ;end of the hotkey
}
Loop { ;wait until you haven't typed a new letter for 0.4 seconds
Input, L, V L1 T0.4
If (ErrorLevel = "Timeout")
Break
}
ControlGetText, button1Text, Button1, ahk_id %hWnd%
If (button1Text = "&Open") { ;If your windows isn't English, you need to replace the word "Open", if you're confused remove the if statement (but leave the content)
ControlClick, Button1, ahk_id %hWnd%,,,, NA ;click the Open button
Sleep, 100
}
ControlClick, Button1, ahk_id %hWnd%,,,, NA ;click the Save button
Return

How to disable resizeing of a window with autohotkey?

I wrote a script with autohotkey, that keeps the clicked window always on top
~MButton::
CoordMode, Mouse, Window
MouseGetPos, ClickX, ClickY, WindowUnderMouseID
WinActivate, ahk_id %WindowUnderMouseID%
WinGetClass, class, A
MouseGetPos, ClickX, ClickY, WindowUnderMouseID
WinGetPos, x, y, w, h, ahk_id %WindowUnderMouseID%
; check if title bar, with an exception for Firefox with tabs in title bar that can be middle-clicked to close
if (ClickX < w and ClickY < 24 and ClickY > 0 and ClickX > 0 and class != "MozillaWindowClass")
{
WinSet, AlwaysOnTop, Toggle, A
}
Return
Now I want to modify this script to disable the possibility of the window to be resized. I found something with Gui, -resize but I don't see how this would help. Replacing the AlwaysOnTop with resize does not work (Parameter #1 is invalid).
How can I achieve the desired funktionality?
After a quick search, I found the following line of code that disables the resize
WinSet, Style, -0x40000, A
In your case, you would swap out A for your %WindowUnderMouseID%

Focus-follows-mouse conflicts with Resharper navigation

In Windows 7, you can give focus to a window just by hovering over it with the mouse. This feature is not enabled by default, but you can enable it in the Control Panel. (Here is the path to take:
[Ease of Access Center-->Make the mouse easier to use-->check "Activate a window by hovering over it with the mouse"]).
I like this feature a lot, but sometimes it annoys me when I try to open a C# class in Visual Studio using Resharper. I'll hit CTRL+N and type the name of the class I want to see (for example, "MyWpfClass"). Resharper will then show a dropdown of suggestions with "MyWpfClass" on top. I hit return, and now Resharper opens a dropdown which lets me choose between "MyWpfClass.xaml" and "MyWpfClass.xaml.cs". However, if the mouse cursor is in the wrong place, the dropdown closes within a second and I'm back to square one. Is there a way to fix this without turning the focus-follows-mouse feature off?
I was having the same problem with MS Outlook: the auto-suggestions list for contacts would close automatically because Windows treated it as a window rather than part of the New Message window.
You could use NiftyWindows, which has the same option "Focus Follows Mouse", accessible through its context menu.
Alternatively, as it is written in Autohotkey, you could use extract and run its subroutine "XWN_FocusHandler" into a standalone script:
#Persistent
#SingleInstance force
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn All, OutputDebug ; Recommended for catching common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetTimer, XWN_FocusHandler, 100
return
XWN_FocusHandler:
CoordMode, Mouse, Screen
MouseGetPos, XWN_MouseX, XWN_MouseY, XWN_WinID
If ( !XWN_WinID )
Return
If ( (XWN_MouseX != XWN_MouseOldX) or (XWN_MouseY != XWN_MouseOldY) )
{
IfWinNotActive, ahk_id %XWN_WinID%
XWN_FocusRequest = 1
Else
XWN_FocusRequest = 0
XWN_MouseOldX := XWN_MouseX
XWN_MouseOldY := XWN_MouseY
XWN_MouseMovedTickCount := A_TickCount
}
Else
If ( XWN_FocusRequest and (A_TickCount - XWN_MouseMovedTickCount > 500) )
{
WinGetClass, XWN_WinClass, ahk_id %XWN_WinID%
If ( XWN_WinClass = "Progman" )
Return
; checks wheter the selected window is a popup menu
; (WS_POPUP) and !(WS_DLGFRAME | WS_SYSMENU | WS_THICKFRAME)
WinGet, XWN_WinStyle, Style, ahk_id %XWN_WinID%
If ( (XWN_WinStyle & 0x80000000) and !(XWN_WinStyle & 0x4C0000) )
Return
IfWinNotActive, ahk_id %XWN_WinID%
WinActivate, ahk_id %XWN_WinID%
XWN_FocusRequest = 0
}
Return

Assign hotkeys to windows (and remember size & location). AHK

I have found the following script for dynamically assigning hotkeys to already open windows:
Code (Expand):
Loop 10
{
i := A_Index - 1
HotKey #^%i%,DynHotkey
HotKey #%i%, DynHotkey
HotKey #!%i%,DynHotkey
}
Exit
DynHotkey:
StringRight i, A_ThisHotKey, 1
StringMid what,A_ThisHotKey, 2, 1
var := var%i%
IfEqual what, ^, WinGet var%i%, ID, A ; Save ID
Else IfEqual what,!, WinMinimizeAll ; MinimizeAll
WinRestore ahk_id %var%
WinActivate ahk_id %var% ; Switch
Return
(the code was copied from this thread http://www.autohotkey.com/forum/topic38773.html&highlight=dynamic+hot+key)
With the above script you can:
Use Win+Ctrl+0..9 to attach hotkey to current active window.
Use Win+0..9 to switch to correspoding window.
However, if I assign a hotkey to a given window (using Win+Ctrl+0..9), and then I want I want to go back to that window (Win+0..9), the window is reset to a new size & location.
Is there way of saving the size & location of the window along with it's ID?
If so, what would the script look like?
I am running the above script on Windows 7 64-bit.
Thanks a lot,
You dont need to complicate the code :)
Quick question: if your window is minimized you dont have any problems right?
The "problem" on the code is the WinRestore.
The thing is that if the window is not minimized and then you do a WinRestore it will change the size and position to the "not maximized" version of it.
WinActivate automatically does a WinRestore only if the window is minimized, so you can safely remove line 16 (the WinRestore one) since WinActivate will do what you need.
--edit--
this is how the code should look:
Loop 10
{
i := A_Index - 1
HotKey #^%i%,DynHotkey
HotKey #%i%, DynHotkey
HotKey #!%i%,DynHotkey
}
Exit
DynHotkey:
StringRight i, A_ThisHotKey, 1
StringMid what,A_ThisHotKey, 2, 1
var := var%i%
IfEqual what, ^, WinGet var%i%, ID, A ; Save ID
Else IfEqual what,!, WinMinimizeAll ; MinimizeAll
WinActivate ahk_id %var% ; Switch
Return
I tested it, it works perfectly.
You can use WinGetPos to read the actual position and save it. Then you can use WinMove to set the position. Here is a function list: http://www.autohotkey.com/docs/commands.htm.

Resources