Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
138 lines (111 sloc) 6.02 KB
/* Title: DockA
Dock AHK windows.
Using dock module you can glue windows to an AHK window.
Docked windows are called Clients and the window that keeps their position relative to itself is called the Host.
Once Clients are connected to the Host, this group of windows will behave like single window - moving, sizing, focusing, hiding and other
OS events will be handled by the module so that the "composite window" behaves like the single window.
This module is version of Dock module that supports only AHK hosts (hence A in the name).
Unlike Dock module, it doesn't uses system hook to monitor windows changes.
Function: DockA
Hwnd - HWND of the Client GUI. Dock is created or updated (if already exists) for that hwnd.
DockDef - Dock definition, see bellow. To remove dock client pass "-".
If you pass empty string, client will be docked to the host according to its current position relative to the host.
Dock definition:
Dock definition is white space separated combination of parameters which describe Client's position relative to the Host.
Parameters are grouped into 4 classes - x, y, w & h parameters. Classes and their parameters are optional.
>  Syntax: x(hw,cw,dx) y(hh,ch,dy) w(hw,dw) h(hh,dh)
o The *X* coordinate of the top, left corner of the client window is computed as
> x(hw,cw,dx) = HostX + hw*HostWidth + cw*ClientWidth + dx
o The *Y* coordinate of the top, left corner of the client window is computed as
> y(hh,ch,dy) = HostY + hh*HostHeight + ch*ClientHeight + dy
o The width *W* of the client window is computed as
> w(hw,dw) = hw*HostWidth + dw
o The height *H* of the client window is computed as
> h(hh,dh) = hh*HostHeight + dh
If you omit any of the class parameters it will default to 0. So, the following expressions all have the same effect :
>  x(0,0,0) = x(0,0) = x(0,0,) = x(0) = x(0,)= x(0,,) = x() = x(0,,0) = x(,0,0) = x(,,0) = ...
> y(0,1,0) = y(0,1) = y(,1) = y(,1,) = y(,1,0) = ...
Notice that x() is not the same as omitting x entirely. First case is equal to x(0,0,0) so it will set Client's X coordinate to be equal as Host's.
In second case, x coordinate of the client will not be affected by the module (client will keep whatever x it has).
You can monitor WM_WINDOWPOSCHANGED=0x47 to detect when user move clients (if they are movable) in order to update dock properties
DockA(HHost="", HClient="", DockDef="") {
DockA_(HHost+0, HClient+0, DockDef, "")
DockA_(HHost, HClient, DockDef, Hwnd) {
if HClient && (DockDef != 3)
If !init
init := OnMessage(3, A_ThisFunc) ; WM_MOVE ;adrSetWindowPos := DllCall("GetProcAddress", "uint", DllCall("GetModuleHandle", "str", "user32"), "str", "SetWindowPos")
HClient += 0, HHost += 0
if (DockDef="-")
if InStr(%HHost%, HClient) {
StringReplace, %HHost%, %HHost%, %A_Space%%HClient%
} else return
if (DockDef = "") { ;pin
WinGetPos hX, hY,,, ahk_id %HHost%
WinGetPos cX, cY,,, ahk_id %HClient%
DockDef := "x(0,0," cX - hX ") y(0,0," cY - hY ")"
%HClient%_x1 := %HClient%_x2 := %HClient%_y1 := %HClient%_y2 := %HClient%_h1 := %HClient%_w1 := %HClient%_x3 := %HClient%_y3 := %HClient%_h2 := %HClient%_w2 := ""
loop, parse, DockDef, %A_Space%%A_Tab%
ifEqual, A_LoopField,,continue
t := A_LoopField, c := SubStr(t,1,1), t := SubStr(t,3,-1)
StringReplace, t, t,`,,|,UseErrorLevel
t .= !ErrorLevel ? "||" : (ErrorLevel=1 ? "|" : "")
loop, parse, t,|,%A_Space%%A_Tab%
%HClient%_%c%%A_Index% := A_LoopField ? A_LoopField : 0
DllCall("SetWindowLong", "uint", HClient, "int", -8, "uint", hHost)
return %HHost% .= (%HHost% = "" ? " " : "") HClient " "
ifEqual, HHost, 0,SetEnv, HHost, %Hwnd%
ifEqual, %HHost%,,return
oldDelay := A_WinDelay, oldCritical := A_IsCritical
SetWinDelay, -1
critical 100
WinGetPos hX, hY, hW, hH, ahk_id %HHost%
loop, parse, %HHost%, %A_Space%
ifEqual, A_LoopField,,continue
else j := A_LoopField
WinGetPos cX, cY, cW, cH, ahk_id %j%
w := %j%_w1*hW + %j%_w2, h := %j%_h1*hH + %j%_h2
, x := hX + %j%_x1*hW + %j%_x2*(w ? w : cW) + %j%_x3
, y := hY + %j%_y1*hH + %j%_y2*(h ? h : cH) + %j%_y3
WinMove ahk_id %j%,,x,y, w ? w : "" ,h ? h : "" ; DllCall(adrSetWindowPos, "uint", hwnd, "uint", 0, "uint", x ? x : cX, "uint", y ? y : cY, "uint", w ? w : cW, "uint", h ? h :cH, "uint", 1044) ;4 | 0x10 | 0x400
SetWinDelay, %oldDelay%
critical %oldCritical%
Group: Presets
This section contains some common docking setups. You can just copy/paste dock definition strings in your script.
x(,-1) y() - top left, own size.
x(,-1,10) y() - top left, own size, 10px padding.
x(,-1) y() h(1) - top left, use host's height, keep own width.
x(,-1,20) y() w(,50) h(1) - top left, use host's height, set width to 50 and padding to 20px.
x(,-1) y(.5,-.5) - middle left, keep own size.
x(,-1) y(1,-1) w(,20) h(,20) - bottom left, fixed width & height to 20px.
x(,-1) y(1,-1) h(.5) - bottom left, keep height half of the Host's height, keep own width.
x(1,-1) y(1) w(.25) h(.25) - bottom right, width and height 1/5 of the Host.
x() y(1) w(1) h(,100) - below the host, use host's width, height = 100.
x() y(,-1,-5) w(1) - above the host, use host's width, keep own height, 5px padding.
x(.5,-.5) y(,-1) w(,200) h(,30) - center above the host, width=200, height=30.
x(.5,-.5) y(1) w(0.3) h(,30) - center bellow the host, use 1/3 Host's width, height=30.
x(1) y() - top right, own size.
x(1) y() w(,40) h(1) - top right, use host's height, width = 40.
x(1) y(.5,-.5) - middle right, keep own size.
Group: About
o Ver 1.0 by majkinetor.
o Licenced under BSD <>
You can’t perform that action at this time.