Да, я не совсем верно тебя понял.
Так известно, что универсальность далеко не всегда хороша! Ну вот, например, "универсальный" размер кресел в маршрутках китайского производства. Для китайцев, может, и ничего, а для нас тесновато!
Вот тебе конкретный пример.
При уменьшении ширины окна кнопки "сталкиваются":
Gui, +Resize
Gui, Add, Edit, x0 y0 w200 h170
Gui, Add, Button, x145 y175 h20 w50, Exit
Gui, Add, Button, x5 yp hp wp, OK
Gui, Show, w200 h200
Return
GuiSize:
Anchor("Edit1", "wh"), Anchor("Button1", "xy", 1), Anchor("Button2", "y", 1)
Return
GuiClose:
ButtonExit:
ExitApp
/*
Function: Anchor
Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.
Parameters:
cl - a control HWND, associated variable name or ClassNN to operate on
a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
optionally followed by a relative factor, e.g. "x h0.5"
r - (optional) true to redraw controls, recommended for GroupBox and Button types
Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
Remarks:
To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
However if the control had been created with DllCall() and has its own parent window,
the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
For a complete example see anchor-example.ahk.
License:
- Version 4.60a <http://www.autohotkey.net/~Titan/#anchor>
- Simplified BSD License <http://www.autohotkey.net/~Titan/license.txt>
*/
Anchor(i, a = "", r = false) {
static c, cs = 12, cx = 255, cl = 0, g, gs = 8, gl = 0, gpi, gw, gh, z = 0, k = 0xffff
If z = 0
VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), z := true
If (!WinExist("ahk_id" . i)) {
GuiControlGet, t, Hwnd, %i%
If ErrorLevel = 0
i := t
Else ControlGet, i, Hwnd, , %i%
}
VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), "UInt", &gi)
, giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
If (gp != gpi) {
gpi := gp
Loop, %gl%
If (NumGet(g, cb := gs * (A_Index - 1)) == gp) {
gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
Break
}
If (!gf)
NumPut(gp, g, gl), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
}
ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
Loop, %cl%
If (NumGet(c, cb := cs * (A_Index - 1)) == i) {
If a =
{
cf = 1
Break
}
giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
, cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
Loop, Parse, a, xywh
If A_Index > 1
av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
, d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
DllCall("SetWindowPos", "UInt", i, "Int", 0, "Int", dx, "Int", dy
, "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
If r != 0
DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
Return
}
If cf != 1
cb := cl, cl += cs
bx := NumGet(gi, 48), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
If cf = 1
dw -= giw - gw, dh -= gih - gh
NumPut(i, c, cb), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
, NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
Return, true
}
Универсально, но криво.
А вот так всё в порядке:
Этот пример — просто первое, что пришло в голову. На практике наверняка можно столкнуться и с другими проблемами.
Вывод: такие "универсальные" вещи можно использовать ограниченно, если думать лень!