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

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

Related

AutoHotKey: How does the WinTitle work?

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

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

AutoHotKey: InputBox with multiline input

In AutoHotKey, I want to have something like InputBox except that the text input is multiline. (i.e. like a textarea).
I want there to be two buttons, "Ok" and "Cancel", and I want them both to have accelerators. I want this code to be in the form of a function that I can call from other hotkeys to get multiline user input whenever I want. I want to be able to set the default text shown when the dialog is shown. I want the function to return null or empty string if the cancel button was pressed. I want the Esc key to cause the dialog to be closed as if the cancel button was pressed (and not exit the entire script). I want the dialog to show in the center of the screen, and to use the font that Windows usually uses for dialogs.
try this
!1::
MsgBox % MultiLineInputBox("Hello World:", "stuff, more stuff", "Custom Caption")
return
MultiLineInputBox(Text:="", Default:="", Caption:="Multi Line Input Box"){
static
ButtonOK:=ButtonCancel:= false
if !MultiLineInputBoxGui{
Gui, MultiLineInputBox: add, Text, r1 w600 , % Text
Gui, MultiLineInputBox: add, Edit, r10 w600 vMultiLineInputBox, % Default
Gui, MultiLineInputBox: add, Button, w60 gMultiLineInputBoxOK , &OK
Gui, MultiLineInputBox: add, Button, w60 x+10 gMultiLineInputBoxCancel, &Cancel
MultiLineInputBoxGui := true
}
GuiControl,MultiLineInputBox:, MultiLineInputBox, % Default
Gui, MultiLineInputBox: Show,, % Caption
SendMessage, 0xB1, 0, -1, Edit1, A
while !(ButtonOK||ButtonCancel)
continue
if ButtonCancel
return
Gui, MultiLineInputBox: Submit, NoHide
Gui, MultiLineInputBox: Cancel
return MultiLineInputBox
;----------------------
MultiLineInputBoxOK:
ButtonOK:= true
return
;----------------------
MultiLineInputBoxGuiEscape:
MultiLineInputBoxCancel:
ButtonCancel:= true
Gui, MultiLineInputBox: Cancel
return
}
You can keep it pretty short:
(tested and works)
MultiLineInput(Text:="Waiting for Input") {
Global MLI_Edit
Gui, Add, Edit, vMLI_Edit x2 y2 w396 r4
Gui, Add, Button, gMLI_OK x1 y63 w199 h30, &OK
Gui, Add, Button, gMLI_Cancel x200 y63 w199 h30, &Cancel
Gui, Show, h94 w400, %Text%
Goto, MLI_Wait
MLI_OK:
GuiControlGet, MLI_Edit
MLI_Cancel:
GuiEscape:
ReturnNow := True
MLI_Wait:
While (!ReturnNow)
Sleep, 100
Gui, Destroy
Return %MLI_Edit%
}
MsgBox % MultiLineInput("Tell me 5 things you like.")
This is what it could look like:
And here is what it returns printed in a MsgBox: Click
Updated version from answer https://stackoverflow.com/a/25800045/2043349 that fixes the bug that the Prompt Text won't be updated if you use the function multiple times:
MultiLineInputBox(Text:="", Default:="", Caption:="Multi Line Input Box")
{
static
ButtonOK:=ButtonCancel:= false
Gui GuiMLIB:New,, % Caption
Gui, add, Text, w600, % Text
Gui, add, Edit, r10 w600 vMLIBEdit, % Default
Gui, add, Button, w60 gMLIBOK , &OK
Gui, add, Button, w60 x+10 gMLIBCancel, &Cancel
Gui, Show
while !(ButtonOK||ButtonCancel)
continue
if ButtonCancel
return
Gui, Submit
return MLIBEdit
;----------------------
MLIBOK:
ButtonOK:= true
return
;----------------------
GuiMLIBGuiEscape:
GuiMLIBGuiClose:
MLIBCancel:
ButtonCancel:= true
Gui, Cancel
return
}
Here is a code:
Version 1 (with Gosub):
return
StartGui:
Gui, Add, Edit, x22 y19 w240 h120 vMyEdit, Here is default text
Gui, Add, Button, x22 y179 w100 h30 gGuiCloseOk, Ok
Gui, Add, Button, x162 y179 w100 h30 gGuiCloseCancel, Cancel
; Generated using SmartGUI Creator for SciTE
Gui, Show, w286 h231, My Gui Name
WinGetPos,,, Width, Height, My Gui Name
WinMove, My Gui Name,, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2)
return
return
GuiCloseOK:
GuiControlGet, MyEdit
Gui, Destroy
return
GuiCloseCancel:
MyEdit:=""
Gui, Destroy
return
return
Esc::
Gui, Destroy
return
Place that code in your script anywhere you like. To call for the GUI add anywhere you want Gosub, StartGui. The content of Edit control you will get in MyEdit variable.
For example, if you want to call GUI by CTRL+ALT+z put that code in script anywhere you want:
return
!^z::
Gosub, StartGui
return
Version 2 (with function):
GuiFunc(DefaultText)
{
global MyEdit
MyEdit:=""
Gui, Add, Edit, x22 y19 w240 h120 vMyEdit, %DefaultText%
Gui, Add, Button, x22 y179 w100 h30 gGuiCloseOk, &Ok
Gui, Add, Button, x162 y179 w100 h30 gGuiCloseCancel, &Cancel
; Generated using SmartGUI Creator for SciTE
Gui, Show, w286 h231, My Gui Name
WinGetPos,,, Width, Height, My Gui Name
WinMove, My Gui Name,, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2)
return
return
GuiCloseOK:
GuiControlGet, MyEdit
Gui, Destroy
return
GuiCloseCancel:
MyEdit:=""
Gui, Destroy
return
}
return
Esc::
Gui, Destroy
return
Place that code in your script anywhere you like. To call for the GUI, call GuiFunc(DefaultText) function with parameter that is text to display in Edit control by default. After running function global variable MyEdit is set to the content of Edit control. So you can use MyEdit variable anywhere outside the function. I know that you wanted function to return content of MyEdit variable but I tried it many ways with no success.
For example, put that code in your script anywhere you want. To call GUI press CTRL+ALT+z and to display content of MyEdit variable press CTRL+ALT+a :
return
!^z::
DefaultText:= "Here is default text"
GuiFunc(DefaultText)
return
return
!^a::
MsgBox, %MyEdit%
return
For both versions, if you decide to rename Window Title My Gui Name then keep in mind that you need to rename it in 3 places for script to work properly.
Also, always use AutoHotkey and its documenatation from http://ahkscript.org/ (current uptodate version, new official website)! AutoHotkey and its documentation from autohotkey.com is outdated and you may have some problems using them!
Based on alpha bravo's answer and Thierry Dalon's answer.
This is fixing the problem of either always having ErrorLevel=1 even when
the user clicks Ok button or not having ErrorLevel=1 when user clicks the cancel button or exits/interrupts the input box.
Also it uses WinWaitClose instead of while loop that seems better for me.
Removes unneeded lines having GuiControl and SendMessage.
MultiLineInputBox(Text:="", Defualt:="", Caption:="Multi Line Input Box"){
static
; futher helper variables
local is_interrupted := "" ; helper variable to know if submitted/interrupted [tn1]
Gui MultiLineInputBox:New,, % Caption
Gui, MultiLineInputBox: add, Text, r1 w600 , % Text
Gui, MultiLineInputBox: add, Edit, r10 w600 vMultiLineInputBoxContent, % DefaultText
Gui, MultiLineInputBox: add, Button, w60 gMultiLineInputBoxOK , &OK
Gui, MultiLineInputBox: add, Button, w60 x+10 gMultiLineInputBoxCancel, &Cancel
Gui, MultiLineInputBox: Show
Gui, MultiLineInputBox:+HwndMultiLineInputBox_hwnd
WinWaitClose, ahk_id %MultiLineInputBox_hwnd%
if (is_interrupted) {
ErrorLevel := 1
}
return MultiLineInputBoxContent
;----------------------
MultiLineInputBoxOK:
Gui, MultiLineInputBox:Submit
Gui, MultiLineInputBox:Destroy
return
;----------------------
MultiLineInputBoxCancel:
MultiLineInputBoxClose:
MultiLineInputBoxGuiEscape:
Gui, MultiLineInputBox: Cancel
Gui, MultiLineInputBox:Destroy
is_interrupted := True
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

Resources