AutoHotKey - Resizing Windows - resize

I currently have a HTPC connected to a plasma in my living room, and I've had a few issues with image retention. While browsing the web, etc. for an extended period of time I'll run into the issue. However, it looks like it should be relatively easy to set up a script with AutoHotKey to resize the window automatically on a timer. Could anyone help me get started on a script to accomplish this task? (Also open to any other ideas)
Thanks!

I created a script quite a while ago that "normalizes" windows, i.e. resizes, moves, and performs other actions to make a window confirm to my personal preference.
Whenever a window displays for the first time, it is normalized. If it is closed and re-opened, it is normalized again.
Below is a functioning version of the script and should satisfy the requirements from the original question.
The version I use is much more complicated because it has many more features, e.g. it supports multiple monitors and resizes windows while taking into account the height of the Windows task bar. I use the script to make open/save dialogs bigger (they are too small by default). I also use it to auto-login to some websites and applications.
; This script "normalizes" windows, i.e. resizes, moves, and performs other
; actions to make a window confirm to my personal preference.
SetTitleMatchMode, 2
; Go into an infinite loop
loop
{
; Pause so other apps can execute. 250 milliseconds seems to work well.
Sleep, 250
; If hotkeys are suspended for this script, then suspend all functionality
if A_IsSuspended
continue
; We will build a unique window name using the window title and window handle.
; Store each unique name in an array.
WinGet, HWND, ID, A
WinGetTitle, WindowTitle, A
WinGetClass, WindowClass, A
; Remember the previous window we processed
WindowTitleCleanPrevious := WindowTitleClean
; Only normalize windows that we haven't seen before.
; If we haven't already normalized the window, we do
; the normalize, then set a flag so we don't normalize the same window again.
; Strip out all chars that may be invalid in an AHK variable name.
WindowTitleCleanTemp := StringRemoveAllNonAlphaNum(WindowTitle)
; Variable names can be at most 254 chars, so truncate to less than that.
StringLeft, WindowTitleClean, WindowTitleCleanTemp, 230
; Process the window if:
; (1) It wasn't previously processed (i.e. not in our window-name list named WinList)
; (2) And we aren't sitting on the same window during each loop.
if (WinList%HWND%%WindowTitleClean% != 1 and WindowTitleClean != WindowTitleCleanPrevious)
{
; Get the window's position and size
WinGetPos, WinX, WinY, WinWidth, WinHeight, A
; Is this an MS Word window?
if (WindowClass == "OpusApp")
{
; Center the window and resize so it is 80% of the monitor width and 90% of height.
WinMove, A, , (A_ScreenWidth/2)-(WinWidth/2), (A_ScreenHeight/2)-(WinHeight/2), A_ScreenWidth * .8, A_ScreenHeight * .9
}
; Is this the Calculator window?
else if (WindowClass == "SciCalc")
{
; Center the window
WinMove, A, , (A_ScreenWidth/2)-(WinWidth/2), (A_ScreenHeight/2)-(WinHeight/2)
}
; Set a flag indicating this window has been processed so it is
; not processed again.
WinList%HWND%%WindowTitleClean% = 1
}
}
; --- Win+F5 will Reload this script ---
~#F5::Reload
; --- Win+Escape will Pause this script ---
~#Escape::Suspend, Toggle
; --- Win+Alt+Escape will Exit this script ---
; Close this script
~#!Escape::ExitApp
; ===========================================================================
; Removes all non-alphabetic and non-numeric characters from the given
; string. The resulting string is returned.
; ===========================================================================
StringRemoveAllNonAlphaNum(SourceString)
{
StringSplit, SplitSourceString, SourceString
OutputString =
Loop, %SplitSourceString0%
{
Char := SplitSourceString%A_Index%
if (Char >= "a") and (Char <= "z")
OutputString := OutputString Char
else if (Char >= "0") and (Char <= "9")
OutputString := OutputString Char
}
return OutputString
}

I am working on the same problem. Here is a script that opens and centers the Windows calculator based of your current screen size. I am still figuring everything out, but maybe this will get you started.
;This script opens and centers the calculator on your screen.
#NoTrayIcon
Run, calc.exe
WinWait, Calculator
WinGetPos,,, Width, Height, %WinTitle%
WinMove, %WinTitle%,, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2)
Return

You can resize and snap the window using the below short cuts.
Windows Key + Left Arrow = Window snaps to left side of the screen
Windows Key + Right Arrow = Window snaps to right side of the screen
Windows Key + Up Arrow = Window snaps to upper side of the screen
Windows Key + Down Arrow = Window snaps to lower side of the screen
Windows Key + Up & Left Arrow = Window snaps to upper left corner of the screen
Windows Key + Up & Right Arrow = Window snaps to upper right corner of the screen

Related

AutoHotKey not detecting the right key

So I've made a script to snipe rare cars from Auction House in FH5. Simple script, which should work like I've written it.
Thats my script at the point, it's not doing what it should
Send {Enter}
Sleep, 500
Send {Enter}
PixelGetColor, PixelCol0, 730, 270
if (PixelCol0 = "0xF7F7F7") ;car found
{
Loop
{
PixelGetColor, PixelCol1, 900, 240
if (PixelCol1 != "0xF7F7F7") ;site has loaded/able to press Y
{
Sleep, 500
Send {Y}
}
PixelGetColor, PixelCol2, 671, 444
if (PixelCol2 = "0x351734") ;Check if Y was pressed "correctly"
{
Sleep, 500
FOUNDCAR = 1
break
}
}
regarding the X and Y points of the pixels and the colors, it should work. I have another script to get mouse position and pixel color, so it's 100% correct.
My problem now is, it presses ENTER for 2 times, which works but when it has to press Y to open Auctiondetails, it's not opening the Auctiondetails but the Auction itselfs, like you press Enter again. If you're into FH5, you know what I mean!!!
Would be great if someone knows how to fix that, I'm trying to fix that BS since 2 days now and I'm so close to rage!!!!
Thank you!
I would start with making sure that PixelGetColor works correctly. Without any CoordMode settings the coordinates are relative to the window, and it might be that your mousecoordinates were relative to the screen, thus looking at the wrong pixel. I would replace the code with simple messages that show you the outcome of the PixelGetColor. Use two FH5 windows, one with the right colors and one without, just to check the PixelGetColor behaviour first.

How to click and edit text fields in apps?

I need in Davinci Resolve to select in the inspector window the zoom text field using the Acc library:
I used Accessible Info Viewer to find identifying properties but hit a wall trying to selecting the text field and double clicking it to replace its value.
Code:
#+j::
WinGet, hWnd, ID, A
vAcc := Acc_Get("Object", "4.2.2.1.1.2.4.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1", 0, "ahk_id" hWnd)
%vAcc%.accDoDefaultAction(0)
return
How to enter a new value in the zoom box? Manually, you double click it and enter a value. I have a script that does this with SendInput but want to without needing panels to be in specific positions prior to activating the hotkey.
Use UIAutomation instead. It is the successor to the Acc/MSAA framework.
Here is the example1 code
#NoEnv
#SingleInstance force
SetTitleMatchMode, 2
;#include <UIA_Interface> ; Uncomment if you have moved UIA_Interface.ahk to your main Lib folder
#include ..\Lib\UIA_Interface.ahk
Run, notepad.exe
UIA := UIA_Interface() ; Initialize UIA interface
WinWaitActive, ahk_exe notepad.exe
npEl := UIA.ElementFromHandle("ahk_exe notepad.exe") ; Get the element for the Notepad window
documentEl := npEl.FindFirstByType("Document") ; Find the first Document control (in Notepad there is only one). This assumes the user is running a relatively recent Windows and UIA interface version 2+ is available. In UIA interface v1 this control was Edit, so an alternative option instead of "Document" would be "UIA.__Version > 1 ? "Document" : "Edit""
documentEl.Highlight() ; Highlight the found element
documentEl.Value := "Lorem ipsum" ; Set the value for the document control.
; Equivalent ways of setting the value:
; documentEl.CurrentValue := "Lorem ipsum"
; documentEl.SetValue("Lorem ipsum")
ExitApp
Use some find methods (FindFirstByName, FindFirstByType, ...) to get the element you want to click, and then call element.Click().
UIAutomation
Github wiki

Keyboard-free mouse gestures for XMonad

I'm setting up mouse gestures in my xmonad.hs, and I'd like to avoid using a modMask modifier to get keyboard-free gestures. Problem is, there are cases (e.g. empty gesture, just a simple click) where I'd like to let the mouse event go through to the application under the cursor, but I haven't found a way to do that in XMonad. Without that, if i add ((0, button3), mouseGesture gestures), i completely lose the "application-specific" functionality of button3.
I was thinking that, if the events cannot be easily forwarded, perhaps a new one can be created and dispatched. I thought about using spawn "xdotool click 3" but it doesn't seem to work. Has anybody ever tried something similar? Otherwise, I'd need a mouse with at least 4 buttons, since most apps actively use three...
To get xdotool to forward your mouse clicks, you need to make sure that it targets the correct window using the --window parameter. For example, if your window id is 79693135, then xdotool click --window 79693135 3 does exactly what you want.
The following basic xmonad.hs illustrates how to do this in order to get keyboardless mouse gestures working properly:
import XMonad
import qualified XMonad.Actions.CycleWS as Workspace
import XMonad.Actions.MouseGestures ( mouseGesture, Direction2D(..) )
import qualified XMonad.Util.EZConfig as EZ
import XMonad.Util.Run ( safeSpawn )
import qualified Data.Map as Map
mouseGestureButton :: Button
mouseGestureButton = button3 -- right click
sendMouseClickToWindow :: Window -> X ()
sendMouseClickToWindow win =
safeSpawn
"xdotool" ["click", "--window", show win, show mouseGestureButton]
myMouseGestures :: [([Direction2D], Window -> X ())]
myMouseGestures =
[ ([R], const Workspace.nextWS) -- move to the next workspace
, ([L], const Workspace.prevWS) -- move to the previous workspace
, ([], sendMouseClickToWindow)
]
addMouseGestures :: XConfig a -> XConfig a
addMouseGestures =
flip EZ.additionalMouseBindings
[((0, mouseGestureButton), mouseGesture $ Map.fromList myMouseGestures)]
main = xmonad $ addMouseGestures def
N.B.: It's not a good idea to use button 1 for this, because that will interfere with selecting text and other mouse-dragging functionality normally used with button 1. So using button 3 (as the OP did) is definitely the right idea.

How to Use GuiDropFiles with GUI controls?

How can I use GuiDropFiles with GUI controls?
I have several edit fields in my form, and I want to be able to drop files onto them separately and work with them.
This is what I came up with:
First, my controls are set up like this:
WS_EX_ACCEPTFILES=0x10
Gui, add, edit, vedit1, %file_1%
WinSet,ExStyle, +WS_EX_ACCEPTFILES, edit1
And my drag-drop routine is as such:
GuiDropFiles: ; Support drag & drop.
Loop, parse, A_GuiControlEvent, `n
{
thisfile := a_loopfield ; Get the first file only (in case there's more than one).
thiscontrol := a_guicontrol
break
}
alert(thisfile . "`r" . thiscontrol)
if(thiscontrol = edit1)
guicontrol,,%edit1%, %thisfile%
if(thiscontrol = edit2)
guicontrol,,%edit2%, %thisfile%
if(thiscontrol = edit3)
guicontrol,,%edit3%, %thisfile%
return
I am using the basic example from the autohotkey documentation. I also tried the example from here, but it keep saying, "not dropped on an edit box".
Any clue would be great.
Figured it out (after a few lost hours).
First, I didn't need this: WinSet,ExStyle, +WS_EX_ACCEPTFILES, edit1
and I didn't need to set any styles on the edit controls.
All I needed was this, which works since my edit controls have the variable-name starting with "UI_file":
GuiDropFiles: ; Support drag & drop.
Loop, parse, A_GuiEvent, `n
{
thisfile := A_LoopField ; Get the first file only (in case there's more than one).
thiscontrol := a_guicontrol
break
}
;alert(thisfile . "`r" . thiscontrol)
If InStr(A_GuiControl, "UI_file")
guicontrol,,%A_GuiControl%, %thisfile%
return

Rebol/View: How to assign images to layout already created?

Using Rebol/View 2.7.7, I'm trying to create a card game based on Nick's Rebol tutorial at: http://re-bol.com/rebol.html#section-10.18. What I want to do though is read the cards from the binary file Nick created, discard some of the data, and use it to layout a tableau of cards, 4 rows of 3 columns, with the 2 center card locations not used.
Here's my code:
protect-system
random/seed now
do %cards.r ;--include the binary card data
the-tableau: [
size 320x480 backdrop 0.170.0
style tabstyle image 80x100 teal
style holdplace box 80x100 coal
across
at 30x20 tc1: tabstyle
tc2: tabstyle
tc3: tabstyle return
at 30x130 tc4: tabstyle
tc100: holdplace
tc5: tabstyle return
at 30x240 tc6: tabstyle
tc200: holdplace
tc7: tabstyle return
at 30x350 tc8: tabstyle
tc9: tabstyle
tc10: tabstyle
]
lc: copy []
lc: [tc1 tc2 tc3 tc4 tc5 tc6 tc7 tc8 tc9 tc10]
deck-cards: copy [] ; The deck holds all of the cards from the binary file
deck-cards-num: copy []
deck-cards-color: copy []
lay: layout the-tableau
foreach [card label num color pos] cards [
dimg: load to-binary decompress (card)
append deck-cards dimg ;feel movestyle
throw-away-label: label
append deck-cards-num num
append deck-cards-color color
throw-away-pos: pos
]
random-card: does [pick deck-cards random length? deck-cards]
foreach c lc [set-face get c deck-cards]
view lay
do-events
But this doesn't show the cards at all. I'm not even sure it's reading the correctly? Where is the problem?
Actually you didn't use the random-card function in your for loop at the end... :-)
foreach c lc [get c set-face get c random-card ]
You note that you are not sure if data was loaded correctly...
here is a simple way to find out... just print/probe the TYPE? of that data
dimg: load to-binary decompress (card)
probe type? dimg
In this case it will print out image! in the console... so yep... that's working. :-)
As an added little detail, I noticed you didn't compensate your random for the "back face" image in the card data (which is at its end), so the random-card function should be fixed like so:
random-card: does [pick deck-cards random (length? deck-cards) - 1] ; - 1 since we don't want the back face to be picked.
You only need 'do-events if the event loop is not started.
View/new does not start the event loop .. but View does
I'm not addressing your actual problem though :(
to make the do-events note clear, I added a little answer here so I can add some inline code....
here is an example where you'd want your do-events to be used.
view/new lay ; display the interface right now. (with no cards)
random-card: does [pick deck-cards random (length? deck-cards) - 1] ; - 1 since we don't want the back face to be picked.
; deal cards with a half second delay.
foreach c lc [f: get c set-face get c random-card wait 0.5]
do-events
here, any code you put after 'DO-EVENTS will be executed once all view windows have closed.
which can be things like tmp file cleanup, save on exit, "save changes" dialogs, etc.
additional note:
While building graphics code, its a good habit to place this at the very start of you application:
print " "
It will open up the console, and then any view windows will show up in front of it.
When ready to share, just comment the line and remove any print statements in your code.
this is useful for 3 things:
1) Its usually highly annoying when the console always pops-up over your application while its tracing (print/probe/etc) some stuff after your window opens.
2) This also has the more useful side-effect of showing you if your application quit correctly since the console will ALSO quit when all waits have terminated correctly.
In your original example, if you add the above print, then you'll see that the console never closes, so this means the application is still running with no more application windows listening to events.
3) It also has the advantage that you can terminate the graphic app directly by closing the console window. This effectively closes all windows and waits immediately and shortcuts any "on application quit" code you might have (code after do-events).