如何调整大小或者 shift+resize?
How to resize and alternatively shift+resize?
在设计某个应用程序时,我需要在一个小 GUI 中有两个编辑框 window,这样您就可以 resize window并且只调整第一个编辑框的大小,但是 shift+resize 会改为调整第二个编辑框的大小。
(请忽略我屏幕截图中的图钉图标;它是 DisplayFusion 放置在那里的一个 ontop-button,不会影响此线程)
我一直在尝试使用 anchor.ahk
和 autoxywh.ahk
库,它们会自动调整控件的大小。这是我的示例代码以及 autoxywh 的副本(您应该能够粘贴并 运行 它)。
使用 AutoXYWH.ahk 库:
#noenv
#singleinstance force
apptitle := "ShiftResize"
def_uiw := 212
Gui, +Hwnd%apptitle% +resize
Gui, +minsize%def_UIw%
gui, margin, 4
Gui, Add, Edit, vEdit1 HwndhEdit1 w100,
Gui, Add, Edit, vEdit2 HwndhEdit2 w100 x+4,
Gui, Show
return
GuiSize:
If !pre_GuiWidth
pre_GuiWidth := A_GuiWidth
guicontrolget, edit1, pos
guicontrolget, edit2, pos
if(getkeystate("shift","P")){
If (edit2w < 100) && (A_GuiWidth-pre_GuiWidth < 0)
Return
If (lastResize != "Edit2")
lastResize := "Edit2", autoxywh("update_ctrl_info")
autoxywh("w", hEdit2)
}else{
If (edit1w < 100) && (A_GuiWidth-pre_GuiWidth < 0)
Return
If (lastResize != "Edit1")
lastResize := "Edit1", autoxywh("update_ctrl_info")
autoxywh("x", hEdit2)
autoxywh("w", hEdit1)
}
pre_GuiWidth := A_GuiWidth
return
GuiClose:
ExitApp
; =============================================================================
; Function: AutoXYWH
; Move and resize control automatically when GUI resizes.
; Parameters:
; DimSize - Can be one or more of x/y/w/h optional followed by a fraction
; add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
; cList - variadic list of ControlIDs
; ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
; The later (displayed text) is possible but not recommend since not very reliable
; Examples:
; AutoXYWH("xy", "Btn1", "Btn2")
; AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
; AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
; =============================================================================
; Here is how GuiSize works with AutoXYWH (mod by toralf):
;http://ahkscript.org/boards/viewtopic.php?f=5&t=7696&p=45882#p45786
;The first time Gui, Show executing, the GuiSize lable will be called. At that time then, AutoXYWH stores the initial x/y/w/h of Controls and GuiWidth/GuiHeight.
;Initial_GuiWidth := A_GuiWidth
;Initial_GuiHeight := A_GuiHeight
;GuiControlGet, Initial_Control, Pos, %ControlID%
;; Initial_ControlX
;; Initial_ControlY
;; Initial_ControlW
;; Initial_ControlH
;After that, when user resizing the Gui window, GuiSize lable will be called, AutoXYWH then calculates the changes of Gui Width and Height.
;Diff_GuiWidth := A_GuiWidth - Initial_GuiWidth
;Diff_GuiHeight := A_GuiHeight - Initial_GuiHeight
;Then, the new values:
;New_ControlW := Diff_GuiWidth + Initial_ControlW
;New_ControlX := Diff_GuiWidth + Initial_ControlX
;New_ControlH := Diff_GuiHeight + Initial_ControlH
;New_ControlY := Diff_GuiHeight + Initial_ControlY
; -----------------------------------------------------------------------------
; Release date: 2015-5-17
; Author : tmplinshi (mod by toralf)
; requires AHK version : 1.1.13.01+
; =============================================================================
AutoXYWH(DimSize, cList*){ ; http://ahkscript.org/boards/viewtopic.php?t=1079
static cInfo := {}
If (DimSize = "update_ctrl_info") {
For ctrlid, obj in cInfo
{
GuiControlGet, i, Pos, %ctrlid%
cInfo[ctrlid].x := ix
cInfo[ctrlid].y := iy
cInfo[ctrlid].w := iw
cInfo[ctrlid].h := ih
}
Return
}
For i, ctrl in cList {
ctrlid := A_Gui ":" ctrl
If ( cInfo[ctrlid].x = "" ){
GuiControlGet, i, %A_Gui%:Pos, %ctrl%
GuiControlGet, Hwnd, %A_Gui%:Hwnd, %ctrl%
MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
fx := fy := fw := fh := 0
For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]")))
If !RegExMatch(DimSize, "i)" dim "\s*\K[\d.-]+", f%dim%)
f%dim% := 1
cInfo[ctrlid] := { x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a , m:MMD}
}Else If ( cInfo[ctrlid].a.1) {
dgx := dgw := A_GuiWidth - cInfo[ctrlid].gw , dgy := dgh := A_GuiHeight - cInfo[ctrlid].gh
For i, dim in cInfo[ctrlid]["a"]
Options .= dim (dg%dim% * cInfo[ctrlid]["f" dim] + cInfo[ctrlid][dim]) A_Space
GuiControl, % A_Gui ":" cInfo[ctrlid].m , % ctrl, % Options
} } }
Maestrith 想出了这个替代方案:
#SingleInstance,Force
SetBatchLines,-1
Gui,+minsize230 +Resize +hwndmain
Gui,Add,Edit,w100 hwndedit1
Gui,Add,Edit,x+10 w100
ControlGetPos,x,y,w,h,,ahk_id%edit1%
SysGet,Border,32
SysGet,Caption,4
OnMessage(0xA1,"sizemove")
Gui,Show
return
GuiSize:
if(Resize="Left"&&offsetx&&A_GuiWidth-offsetx<=100){
Gui,+minsize%A_GuiWidth%
}
if(Resize="Left"&&offsetx&&A_GuiWidth-offsetx>=100){
GuiControl,1:Move,Edit2,% "x" A_GuiWidth-offsetx
GuiControl,1:move,Edit1,% "w" A_GuiWidth+offsetw
}
if(Resize="right"&&offsetx&&A_GuiWidth+woffset>=100){
GuiControl,1:move,Edit2,% "w" A_GuiWidth+woffset
}
if(Resize="right"&&offsetx&&A_GuiWidth+woffset<=100)
Gui,+MinSize%A_GuiWidth%
return
GuiClose:
GuiEscape:
ExitApp
return
sizemove(){
global
resize:=GetKeyState("Shift","P")?"Right":"Left"
ControlGetPos,x,y,w,h,Edit2,ahk_id%main%
ControlGetPos,xx,yy,ww,hh,Edit1,ahk_id%main%
VarSetCapacity(rect,16)
DllCall("GetClientRect",UPtr,main,UPtr,&rect),width:=NumGet(rect,8),height:=NumGet(rect,12)
offsetx:=width-x+border
offsetw:=ww-width
woffset:=w-width
}
这些解决方案都不能完美工作。如果你玩 window 和大小和调整大小,收缩和增长同时使用 resize 和 shift+resize 盒子会出来重击。例如,尝试 resize 增长 edit1
,然后 shift+resize 增长 edit2
到合适的长度,然后 shift+resize 缩小 edit2
。你明白了,其中 edit2
偏离边缘 运行,或者第二张图像 edit1
偏离边缘 edit2
甚至不可见:
完美工作:
- 每个编辑框的最小尺寸需要
100px
,并且不应缩小到该尺寸以下。
- 两个编辑框都应保持可见 - 换句话说,缩小 GUI 永远不会使其中一个框不可见。
- resize 应该只调整大小
edit1
- shift+resize 应该只调整
edit2
现在,我意识到我可以只堆叠编辑框然后忘记它,但这不是我想要做的。
现在,I have a thread on ahkscript.org,但是进展很慢,所以我希望在这里引起更多关注,并希望找到一个可行的解决方案。
Just Me on the Autohotkey forum solved this perfectly:
#NoEnv
#SingleInstance Force
SetBatchLines, -1 ; important !!!
AppTitle := "ShiftResize"
MinSize := False
MarginX := 4
Gui, +Hwnd%AppTitle% +Resize
Gui, Margin, %MarginX%
Gui, Add, Edit, vEdit1 HwndhEdit1 w100,
Gui, Add, Edit, vEdit2 HwndhEdit2 w100 x+4,
Gui, Show, , %AppTitle%
Return
GuiClose:
ExitApp
GuiSize:
If (MinSize = False) { ; first call of GuiSize
GuiControlGet, Edit1, Pos
MinWidth1 := Edit1W
GuiControlGet, Edit2, Pos
MinWidth2 := Edit2W
Gui, +MinSize%A_GuiWidth%x
MinSize := True
Return
}
Margin := A_GuiWidth - (Edit2X + Edit2W) - MarginX
If GetKeyState("Shift", "P") { ; Edit2
Edit2W += Margin
If (Edit2W < MinWidth2)
Edit2W := MinWidth2
Edit2X := A_GuiWidth - Edit2W - MarginX
GuiControl, Move, Edit2, x%Edit2X% w%Edit2W%
Edit1W := Edit2X - MarginX - MarginX
GuiControl, Move, Edit1, w%Edit1W%
}
Else { ; Edit1
Edit1W += Margin
If (Edit1W < MinWidth1)
Edit1W := MinWidth1
GuiControl, Move, Edit1, w%Edit1W%
Edit2X := Edit1X + Edit1W + MarginX
Edit2W := A_GuiWidth - Edit2X - MarginX
GuiControl, Move, Edit2, x%Edit2X% w%Edit2W%
}
Return
在设计某个应用程序时,我需要在一个小 GUI 中有两个编辑框 window,这样您就可以 resize window并且只调整第一个编辑框的大小,但是 shift+resize 会改为调整第二个编辑框的大小。
(请忽略我屏幕截图中的图钉图标;它是 DisplayFusion 放置在那里的一个 ontop-button,不会影响此线程)
我一直在尝试使用 anchor.ahk
和 autoxywh.ahk
库,它们会自动调整控件的大小。这是我的示例代码以及 autoxywh 的副本(您应该能够粘贴并 运行 它)。
使用 AutoXYWH.ahk 库:
#noenv
#singleinstance force
apptitle := "ShiftResize"
def_uiw := 212
Gui, +Hwnd%apptitle% +resize
Gui, +minsize%def_UIw%
gui, margin, 4
Gui, Add, Edit, vEdit1 HwndhEdit1 w100,
Gui, Add, Edit, vEdit2 HwndhEdit2 w100 x+4,
Gui, Show
return
GuiSize:
If !pre_GuiWidth
pre_GuiWidth := A_GuiWidth
guicontrolget, edit1, pos
guicontrolget, edit2, pos
if(getkeystate("shift","P")){
If (edit2w < 100) && (A_GuiWidth-pre_GuiWidth < 0)
Return
If (lastResize != "Edit2")
lastResize := "Edit2", autoxywh("update_ctrl_info")
autoxywh("w", hEdit2)
}else{
If (edit1w < 100) && (A_GuiWidth-pre_GuiWidth < 0)
Return
If (lastResize != "Edit1")
lastResize := "Edit1", autoxywh("update_ctrl_info")
autoxywh("x", hEdit2)
autoxywh("w", hEdit1)
}
pre_GuiWidth := A_GuiWidth
return
GuiClose:
ExitApp
; =============================================================================
; Function: AutoXYWH
; Move and resize control automatically when GUI resizes.
; Parameters:
; DimSize - Can be one or more of x/y/w/h optional followed by a fraction
; add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
; cList - variadic list of ControlIDs
; ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
; The later (displayed text) is possible but not recommend since not very reliable
; Examples:
; AutoXYWH("xy", "Btn1", "Btn2")
; AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
; AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
; =============================================================================
; Here is how GuiSize works with AutoXYWH (mod by toralf):
;http://ahkscript.org/boards/viewtopic.php?f=5&t=7696&p=45882#p45786
;The first time Gui, Show executing, the GuiSize lable will be called. At that time then, AutoXYWH stores the initial x/y/w/h of Controls and GuiWidth/GuiHeight.
;Initial_GuiWidth := A_GuiWidth
;Initial_GuiHeight := A_GuiHeight
;GuiControlGet, Initial_Control, Pos, %ControlID%
;; Initial_ControlX
;; Initial_ControlY
;; Initial_ControlW
;; Initial_ControlH
;After that, when user resizing the Gui window, GuiSize lable will be called, AutoXYWH then calculates the changes of Gui Width and Height.
;Diff_GuiWidth := A_GuiWidth - Initial_GuiWidth
;Diff_GuiHeight := A_GuiHeight - Initial_GuiHeight
;Then, the new values:
;New_ControlW := Diff_GuiWidth + Initial_ControlW
;New_ControlX := Diff_GuiWidth + Initial_ControlX
;New_ControlH := Diff_GuiHeight + Initial_ControlH
;New_ControlY := Diff_GuiHeight + Initial_ControlY
; -----------------------------------------------------------------------------
; Release date: 2015-5-17
; Author : tmplinshi (mod by toralf)
; requires AHK version : 1.1.13.01+
; =============================================================================
AutoXYWH(DimSize, cList*){ ; http://ahkscript.org/boards/viewtopic.php?t=1079
static cInfo := {}
If (DimSize = "update_ctrl_info") {
For ctrlid, obj in cInfo
{
GuiControlGet, i, Pos, %ctrlid%
cInfo[ctrlid].x := ix
cInfo[ctrlid].y := iy
cInfo[ctrlid].w := iw
cInfo[ctrlid].h := ih
}
Return
}
For i, ctrl in cList {
ctrlid := A_Gui ":" ctrl
If ( cInfo[ctrlid].x = "" ){
GuiControlGet, i, %A_Gui%:Pos, %ctrl%
GuiControlGet, Hwnd, %A_Gui%:Hwnd, %ctrl%
MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
fx := fy := fw := fh := 0
For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]")))
If !RegExMatch(DimSize, "i)" dim "\s*\K[\d.-]+", f%dim%)
f%dim% := 1
cInfo[ctrlid] := { x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a , m:MMD}
}Else If ( cInfo[ctrlid].a.1) {
dgx := dgw := A_GuiWidth - cInfo[ctrlid].gw , dgy := dgh := A_GuiHeight - cInfo[ctrlid].gh
For i, dim in cInfo[ctrlid]["a"]
Options .= dim (dg%dim% * cInfo[ctrlid]["f" dim] + cInfo[ctrlid][dim]) A_Space
GuiControl, % A_Gui ":" cInfo[ctrlid].m , % ctrl, % Options
} } }
Maestrith 想出了这个替代方案:
#SingleInstance,Force
SetBatchLines,-1
Gui,+minsize230 +Resize +hwndmain
Gui,Add,Edit,w100 hwndedit1
Gui,Add,Edit,x+10 w100
ControlGetPos,x,y,w,h,,ahk_id%edit1%
SysGet,Border,32
SysGet,Caption,4
OnMessage(0xA1,"sizemove")
Gui,Show
return
GuiSize:
if(Resize="Left"&&offsetx&&A_GuiWidth-offsetx<=100){
Gui,+minsize%A_GuiWidth%
}
if(Resize="Left"&&offsetx&&A_GuiWidth-offsetx>=100){
GuiControl,1:Move,Edit2,% "x" A_GuiWidth-offsetx
GuiControl,1:move,Edit1,% "w" A_GuiWidth+offsetw
}
if(Resize="right"&&offsetx&&A_GuiWidth+woffset>=100){
GuiControl,1:move,Edit2,% "w" A_GuiWidth+woffset
}
if(Resize="right"&&offsetx&&A_GuiWidth+woffset<=100)
Gui,+MinSize%A_GuiWidth%
return
GuiClose:
GuiEscape:
ExitApp
return
sizemove(){
global
resize:=GetKeyState("Shift","P")?"Right":"Left"
ControlGetPos,x,y,w,h,Edit2,ahk_id%main%
ControlGetPos,xx,yy,ww,hh,Edit1,ahk_id%main%
VarSetCapacity(rect,16)
DllCall("GetClientRect",UPtr,main,UPtr,&rect),width:=NumGet(rect,8),height:=NumGet(rect,12)
offsetx:=width-x+border
offsetw:=ww-width
woffset:=w-width
}
这些解决方案都不能完美工作。如果你玩 window 和大小和调整大小,收缩和增长同时使用 resize 和 shift+resize 盒子会出来重击。例如,尝试 resize 增长 edit1
,然后 shift+resize 增长 edit2
到合适的长度,然后 shift+resize 缩小 edit2
。你明白了,其中 edit2
偏离边缘 运行,或者第二张图像 edit1
偏离边缘 edit2
甚至不可见:
完美工作:
- 每个编辑框的最小尺寸需要
100px
,并且不应缩小到该尺寸以下。 - 两个编辑框都应保持可见 - 换句话说,缩小 GUI 永远不会使其中一个框不可见。
- resize 应该只调整大小
edit1
- shift+resize 应该只调整
edit2
现在,我意识到我可以只堆叠编辑框然后忘记它,但这不是我想要做的。
现在,I have a thread on ahkscript.org,但是进展很慢,所以我希望在这里引起更多关注,并希望找到一个可行的解决方案。
Just Me on the Autohotkey forum solved this perfectly:
#NoEnv
#SingleInstance Force
SetBatchLines, -1 ; important !!!
AppTitle := "ShiftResize"
MinSize := False
MarginX := 4
Gui, +Hwnd%AppTitle% +Resize
Gui, Margin, %MarginX%
Gui, Add, Edit, vEdit1 HwndhEdit1 w100,
Gui, Add, Edit, vEdit2 HwndhEdit2 w100 x+4,
Gui, Show, , %AppTitle%
Return
GuiClose:
ExitApp
GuiSize:
If (MinSize = False) { ; first call of GuiSize
GuiControlGet, Edit1, Pos
MinWidth1 := Edit1W
GuiControlGet, Edit2, Pos
MinWidth2 := Edit2W
Gui, +MinSize%A_GuiWidth%x
MinSize := True
Return
}
Margin := A_GuiWidth - (Edit2X + Edit2W) - MarginX
If GetKeyState("Shift", "P") { ; Edit2
Edit2W += Margin
If (Edit2W < MinWidth2)
Edit2W := MinWidth2
Edit2X := A_GuiWidth - Edit2W - MarginX
GuiControl, Move, Edit2, x%Edit2X% w%Edit2W%
Edit1W := Edit2X - MarginX - MarginX
GuiControl, Move, Edit1, w%Edit1W%
}
Else { ; Edit1
Edit1W += Margin
If (Edit1W < MinWidth1)
Edit1W := MinWidth1
GuiControl, Move, Edit1, w%Edit1W%
Edit2X := Edit1X + Edit1W + MarginX
Edit2W := A_GuiWidth - Edit2X - MarginX
GuiControl, Move, Edit2, x%Edit2X% w%Edit2W%
}
Return