1

Тема: AHK: Растянуть GUI на весь экран

Делаю один проект, где нужно, чтобы окно растянулось на весь экран, как в играх. Там установишь разрешение экрана, и игра его поменяет, тут аналогичная ситуация. Подумав головой, я определил разрешение своего экрана и сделал GUI под него. Все нормально, но при запуске этой программе на другом ПК - что и стоило ожидать: все объекты сдвинулись со своих мест куда вправо, а мне нужно, чтобы все оставалось на своих местах.
Возможно ли это сделать?

2

Re: AHK: Растянуть GUI на весь экран

Похоже, что Вы использовали абсолютные координаты. В данном случае нужно задавать элементам управления относительные координаты. Чтобы узнать текущее разрешение экрана, используйте встроенные переменные A_ScreenWidth и A_ScreenHeight.

3 (изменено: serzh82saratov, 2019-04-21 21:10:01)

Re: AHK: Растянуть GUI на весь экран


#SingleInstance Force
#NoEnv 
SetBatchLines -1

Gui, +Resize
Gui, Add, Edit, ve1, 1
Gui, Add, Edit, ve2, 2
Gui, Add, Edit, ve3, 3
Gui, Add, Edit, ve4, 4
Gui, Add, Edit, ve5, 5
Gui, Show, w444 h444
Return 

GuiSize:
	If (A_EventInfo = 1) ; The window has been minimized.
		Return

	W := A_GuiWidth, H := A_GuiHeight
	offX := W // 30, offY := H // 30
	xm := offX // 2, ym := offY // 2
	cW := W - xm * 2, cH := H - ym * 2
	
	(xp := xm), (yp := ym), (wp := cW * 0.25), (hp := cH * 0.2)
	GuiControl, % A_Gui ":Move", e1, % "x" xp " y" yp " w" wp " h" hp

	(xp := W - xm - wp)
	GuiControl, % A_Gui ":Move", e2, % "x" xp " y" yp " w" wp " h" hp

	(wp := cW * 0.15), (hp := cH * 0.3), (xp := xm), (yp := H - ym - hp)
	GuiControl, % A_Gui ":Move", e3, % "x" xp " y" yp " w" wp " h" hp

	(xp := xm + wp + offX), (hp := cH * 0.125), (yp := H - ym - hp), (wp := (cW - wp * 2) - offX * 2)
	GuiControl, % A_Gui ":Move", e4, % "x" xp " y" yp " w" wp " h" hp	

	(xp := xp + wp + offX), (wp := cW * 0.15), (hp := cH * 0.3), (yp := H - ym - hp)
	GuiControl, % A_Gui ":Move", e5, % "x" xp " y" yp " w" wp " h" hp
	Return

Такая штука ещё есть, но я с ней не разбирался, может тоже самое проще получится.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

4 (изменено: serzh82saratov, 2019-04-22 19:40:05)

Re: AHK: Растянуть GUI на весь экран

Вариант по нагляднее.

Class AutoResize.


Class AutoResize
{
	;  автор - serzh82saratov
	;  версия - 1.01
	;  23.04.2019
	
	__New(Gui, Options = "") {
		this.A := {xm:0, ym:0, Gui:Gui, B:{}}, this.pr := {}, this.s := {}
		for k, v in ["xm", "ym"]
			RegExMatch(Options, "(?<Key>" v ")(?<Value>\d+)", o), this.A[oKey] := oValue 
	}
	Item(Control, Options, Ex = "") { 
		Options := StrReplace(Options, " ")
		a := {C:Control, M:(Ex ~= "Draw" ? "MoveDraw" : "Move"), Section:!!(Ex ~= "Section")}
		b := StrSplit(Options, ",")
		for k, v in ["x", "y", "w", "h"]
			a[v] := StrSplit(b[k], "+")  
		this.A.B.Push(a)
	}
	Resize(W, H) {
		this.s.w := W
		this.s.h := H
		this.s.cw := W - this.A.xm * 2
		this.s.ch := H - this.A.ym * 2 
		
		for k, v in this.A.B
		{
			this.pr.prwp := this.pr.wp
			this.pr.prhp := this.pr.hp
			this.pr.wp := this.EvalSize("w", v.w)
			this.pr.hp := this.EvalSize("h", v.h)
			this.pr.xp := this.EvalPos("x", v.x)
			this.pr.yp := this.EvalPos("y", v.y)
			If v.Section
				for k2, v2 in ["x", "y", "w", "h"]
					this.pr[v2 "section"] := this.pr[v2 "p"]
			GuiControl, % this.A.Gui ":" v.M, % v.C, % "x" this.pr.xp " y" this.pr.yp " w" this.pr.wp " h" this.pr.hp
		} 
	}
	EvalPos(n, a) {
		s := n = "x" ? "w" : "h", m := 1, ret := 0
		for k, v in a
		{
			If (v ~= "S)^-?\d+$") ;	Num
				ret += (v * m)
			Else If RegExMatch(v, "S)^(?<s>-)?r(?<d>\d+)$", _)  ;	rNum, -rNum
				ret += (this.s["c" s] * (_d / 1000)) * (_s ? -1 : 1) * m
			Else If RegExMatch(v, "S)^(?<s>-)?(?<d>(x|y)m)$", _)  ;	xm, -xm, ym, -ym
				ret += this.A[_d] * (_s ? -1 : 1) * m
			Else If (k = 1)
			{  
				If (v = n "p")  ;	xp, yp
					ret := this.pr[n "p"]
				Else If (v = n)  ;	x, y
					ret := this.pr[n "p"] + this.pr["pr" s "p"]
				Else If (v = "o")  ;	o
					ret := this.A[n "m"] + this.s["c" s] - this.pr[s "p"], m := -1
				Else If (v = n "s")  ;	xs, ys
					ret := this.pr[n "section"]
				Else If (v = n "so")  ;	xso, yso
					ret := this.pr[n "section"] + this.pr[s "section"]
			} 
			Else If RegExMatch(v, "S)(?<s>-)?(?<d>(w|h))(?<pr>p)?$", _)  ;	w, -w, wp, -wp, h, -h, hp, -hp
				ret += this.pr[_pr _d "p"] * (_s ? -1 : 1) * m
			Else If RegExMatch(v, "S)(?<s>-)?(?<d>(w|h))s$", _)  ;	ws, -ws, hs, -hs
				ret += this.pr[_d "section"] * (_s ? -1 : 1) * m
		} 
		Return ret
	}
	EvalSize(n, a) {
		for k, v in a, ret := 0
		{
			If (v ~= "S)^-?\d+$") ;	Num
				ret += v
			Else If RegExMatch(v, "S)^(?<s>-)?r(?<d>\d+)$", _)  ;	rNum, -rNum
				ret += this.s["c" n] * (_d / 1000) * (_s ? -1 : 1)
			Else If (v = n "p")  ;	wp, hp
				ret += this.pr["pr" n "p"]
			Else If (v = n "s")  ;	ws, hs
				ret += this.pr[n "section"] 
		}
		Return ret
	} 
} 

Demo 1.


#SingleInstance Force
#NoEnv 
SetBatchLines -1

Gui, +Resize
Loop 10
	Gui, Add, Edit, vEL%A_Index%, %A_Index%

Gui1 := New AutoResize(1, "xm10 ym10")

Gui1.Item("EL1", "xm, ym, r450, r200")
Gui1.Item("EL2", "o, yp, wp, hp")

Gui1.Item("EL3", "xm, o, r150, r300", "Section")
Gui1.Item("EL4", "o, ys, ws, hs")
Gui1.Item("EL5", "xso + 10, o + r100, r700 + -20, r100")

Gui1.Item("EL6", "xm + r400, ym + r400, r200, r200", "Section")
Gui1.Item("EL7", "xs + -w, ys + -h, 20, 30")
Gui1.Item("EL8", "xs + -w, yso, wp, hp") 
Gui1.Item("EL9", "xso, yso, wp, hp")
Gui1.Item("EL10", "xso, ys + -h, wp, hp")

Gui, Show, x100 y100 w200 h200
Return 

GuiSize:
	If (A_EventInfo = 1) ; The window has been minimized.
		Return
	Gui1.Resize(A_GuiWidth, A_GuiHeight)
	Return

GuiClose:
Escape:: ExitApp

Demo 2. Несколько окон.


#SingleInstance Force
#NoEnv 
SetBatchLines -1
Arr := {}

Gui, New
Gui, +Resize +HWNDhGui1
Loop 2
	Gui, Add, Edit, vEL%A_Index%, %A_Index%
Arr[hGui1] := New AutoResize(hGui1, "xm10 ym10") 
Arr[hGui1].Item("EL1", "xm, ym, r1000, r500")
Arr[hGui1].Item("EL2", "xp, y, r1000, r500")  
Gui, Show, x100 y100 w200 h200

Gui, New
Gui, +Resize +HWNDhGui2
Loop 2
	Gui, Add, Edit, vEL%A_Index%, %A_Index%
Arr[hGui2] := New AutoResize(hGui2) 
Arr[hGui2].Item("EL1", "xm, ym, r500, r1000")
Arr[hGui2].Item("EL2", "x, yp, r500, r1000")  
Gui, Show, x400 y100 w200 h200
Return

GuiSize:
	If (A_EventInfo = 1) ; The window has been minimized.
		Return 
	Arr[A_Gui].Resize(A_GuiWidth, A_GuiHeight)
	Return

GuiClose:
Escape:: ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

Re: AHK: Растянуть GUI на весь экран

Anchor()


#SingleInstance Force
#NoEnv

Gui, 1: +Resize
Gui, 1: Add, Edit, w400 h20 +HWND_edit1_h, Текст
Gui, 1: Add, Button,+HWND_button1_h, Кнопка
Gui, 1: Show,,1

Gui, 2: +Resize
Gui, 2: Add, Edit, w400 h20 +HWND_edit2_h, Текст
Gui, 2: Add, Button,+HWND_button2_h, Кнопка
Gui, 2: Show,,2

Return

GuiSize:
	Anchor(_edit1_h, "w h")
	Anchor(_button1_h, "y")
Return
2GuiSize:
	Anchor(_edit2_h, "w h")
	Anchor(_button2_h, "y")
Return
Esc:
	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/~polyethene/#anchor>
		- Dedicated to the public domain (CC0 1.0) <http://creativecommons.org/publicdomain/zero/1.0/>
*/
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
}

6

Re: AHK: Растянуть GUI на весь экран

Тоже видел это, мне показалось что AutoXYWH аналогично и покороче, но в обоих функциях не смог толком разобраться.
Если вам понятнее что там к чему, интересно было бы посмотреть аналог Demo 1 в №4.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

7

Re: AHK: Растянуть GUI на весь экран

Ни на что не претендую, не подумайте про меня плохо. Ваш пример, как всегда шикарен! Снимаю шляпу.

Хотя, для поведения, вроде "Demo 1 в №4", больше подходит greed, или flex-box в HTML, со всеми этими эффектными штуками-дрюками, которые можно так же прикручивать в гипертекст и раз нелёгкая понесла на спецэффекты, то можно себя ничем не ограничивать.

Кому пока с трудом даются настолько изысканные выражения кодом, описательная способность "Якоря" может показаться не менее привлекательной, чем мне, Ваши примеры. Всё ведь предельно просто, передать "ручку" элемента и описать его поведение самым банальным способом.

8

Re: AHK: Растянуть GUI на весь экран

Я про ту самую банальность и говорю. Я не очень понял что там к чему при всей банальности выражения, и решил написать нечто похожее по выражению на опции элементов. Получается что для пользователя "изысканные выражения кодом" (если вы про код в классе) не имеет никакого значения, а важна только "описательная способность", которую я попытался сделать более понятной (для себя конечно), про более функциональной сказать ничего не могу.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

9

Re: AHK: Растянуть GUI на весь экран

https://github.com/serzh82saratov/AutoResize
Добавил одновременное перемещение любого количества контролов, и ещё фичи, всё в примерах (1 и 2 понажимать).

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui