Window Positioning with AutoHotkey

May 22nd 2020 AutoHotkey Windows

When looking for a way to quickly position an application window at an exact predefined position, I chose AutoHotkey as the best tool for the job. The ability to create a script that moves a window and assign it to a keyboard shortcut was exactly what I needed. It still required some tweaking before it worked well enough for my needs.

I started with the following simple script based on an article I found:

ResizeWin(Left = 0, Top = 0, Width = 0, Height = 0)
{
    WinGetPos,X,Y,W,H,A
    If %Width% = 0
        Width := W

    If %Height% = 0
        Height := H

    WinMove,A,,%Left%,%Top%,%Width%,%Height%
}

#!F2::ResizeWin(1080,0,1280,720)

Although it worked great for some windows (e.g. Visual Studio Code, Visual Studio 2019), it positioned others (e.g. Total Commander, Firefox, OneNote) with a few pixels of offset. This is explained best with the following screenshot (the bottom window is positioned correctly):

AutoHotkey WinMove positioned some windows incorrectly

Further research revealed that this is a known issue with Desktop Window Manager based themes introduced in Windows Vista. The WinGetPosEx function attached to the linked post returns the horizontal and vertical offset values so that the positioning can be adjusted accordingly.

Even that didn't fix the issue for all applications because the offsets weren't symmetrical. Fortunately, the post linked to an alternative implementation of the same function that returns offsets separate for each side. Using the values it returns, I managed to update my function to work correctly for all application windows:

ResizeWin(Left = 0, Top = 0, Width = 0, Height = 0)
{
    ; restore the  window first because maximized window can't be moved
    WinRestore,A

    ; get the active window handle for the WinGetPosEx call
    WinGet,Handle,ID,A

    ; get the offsets
    WinGetPosEx(Handle,X,Y,W,H,Offset_Left,Offset_Top,Offset_Right,Offset_Bottom)

    If %Width% = 0
        Width := W

    If %Height% = 0
        Height := H

    ; adjust the position using the offsets
    Left -= Offset_Left
    Top -= Offset_Top
    Width += Offset_Left + Offset_Right
    Height += Offset_Top + Offset_Bottom

    ; finally position the window
    WinMove,A,,%Left%,%Top%,%Width%,%Height%
}

#!F2::ResizeWin(1080,0,1280,720)

; import the function from a file in the same folder
#include WinGetPosEx.ahk

In the script above, there's only a single keyboard shortcut defined but this can be easily extended with additional hotkeys for alternate window positions.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License