[feature] support scaling
This commit is contained in:
parent
2718a2c321
commit
3c051ec2ac
|
@ -1,161 +0,0 @@
|
|||
;------------------------------
|
||||
;
|
||||
; Function: WinGetPosEx
|
||||
;
|
||||
; Original author: jballi (https://autohotkey.com/boards/viewtopic.php?t=3392)
|
||||
;
|
||||
; Update author: RiseUp
|
||||
;
|
||||
; Description:
|
||||
;
|
||||
; Gets the position, size, and offset of a window. See the *Remarks* section
|
||||
; for more information.
|
||||
;
|
||||
; Parameters:
|
||||
;
|
||||
; hWindow - Handle to the window.
|
||||
;
|
||||
; X, Y, Width, Height - Output variables. [Optional] If defined, these
|
||||
; variables contain the coordinates of the window relative to the
|
||||
; upper-left corner of the screen (X and Y), and the Width and Height of
|
||||
; the window.
|
||||
;
|
||||
; Offset_Left, Offset_Top, Offset_Right, Offset_Bottom - Output variables.
|
||||
; [Optional] Offset, in pixels, of the actual position of the window
|
||||
; versus the position of the window as reported by GetWindowRect. If
|
||||
; moving the window to specific coordinates, add these offset values to
|
||||
; the appropriate coordinate (X and/or Y) to reflect the true size of the
|
||||
; window.
|
||||
;
|
||||
; Returns:
|
||||
;
|
||||
; If successful, the address of a RECTPlus structure is returned. The first
|
||||
; 16 bytes contains a RECT structure that contains the dimensions of the
|
||||
; bounding rectangle of the specified window. The dimensions are given in
|
||||
; screen coordinates that are relative to the upper-left corner of the screen.
|
||||
; The next 16 bytes contain the offsets (4-byte integer for each of left,
|
||||
; top, right, and bottom offsets).
|
||||
;
|
||||
; Also if successful (and if defined), the output variables (X, Y, Width,
|
||||
; Height, Offset_Left, Offset_Top, Offset_Right, and Offset_Bottom) are
|
||||
; updated. See the *Parameters* section for more more information.
|
||||
;
|
||||
; If not successful, FALSE is returned.
|
||||
;
|
||||
; Requirement:
|
||||
;
|
||||
; Windows 2000+
|
||||
;
|
||||
; Remarks, Observations, and Changes:
|
||||
;
|
||||
; * Starting with Windows Vista, Microsoft includes the Desktop Window Manager
|
||||
; (DWM) along with Aero-based themes that use DWM. Aero themes provide new
|
||||
; features like a translucent glass design with subtle window animations.
|
||||
; Unfortunately, the DWM doesn't always conform to the OS rules for size and
|
||||
; positioning of windows. If using an Aero theme, many of the windows are
|
||||
; actually larger than reported by Windows when using standard commands (Ex:
|
||||
; WinGetPos, GetWindowRect, etc.) and because of that, are not positioned
|
||||
; correctly when using standard commands (Ex: gui Show, WinMove, etc.). This
|
||||
; function was created to 1) identify the true position and size of all
|
||||
; windows regardless of the window attributes, desktop theme, or version of
|
||||
; Windows and to 2) identify the appropriate offset that is needed to position
|
||||
; the window if the window is a different size than reported.
|
||||
;
|
||||
; * The true size, position, and offset of a window cannot be determined until
|
||||
; the window has been rendered. See the example script for an example of how
|
||||
; to use this function to position a new window.
|
||||
;
|
||||
; * 20150906: The "dwmapi\DwmGetWindowAttribute" function can return odd errors
|
||||
; if DWM is not enabled. One error I've discovered is a return code of
|
||||
; 0x80070006 with a last error code of 6, i.e. ERROR_INVALID_HANDLE or "The
|
||||
; handle is invalid." To keep the function operational during this types of
|
||||
; conditions, the function has been modified to assume that all unexpected
|
||||
; return codes mean that DWM is not available and continue to process without
|
||||
; it. When DWM is a possibility (i.e. Vista+), a developer-friendly messsage
|
||||
; will be dumped to the debugger when these errors occur.
|
||||
;
|
||||
; * 20171126: (RiseUp) Changed function to return 4 offset values instead of 2.
|
||||
; Windows 10 has different offsets for the top versus the bottom of a window,
|
||||
; so this function no longer assumes a symmetrical offset border around a
|
||||
; given window.
|
||||
;
|
||||
; Credit:
|
||||
;
|
||||
; Idea and some code from *KaFu* (AutoIt forum)
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
WinGetPosEx(hWindow,ByRef X="",ByRef Y="",ByRef Width="",ByRef Height=""
|
||||
,ByRef Offset_Left="",ByRef Offset_Top=""
|
||||
,ByRef Offset_Right="",ByRef Offset_Bottom="")
|
||||
{
|
||||
Static Dummy5693
|
||||
,RECTPlus
|
||||
,S_OK:=0x0
|
||||
,DWMWA_EXTENDED_FRAME_BOUNDS:=9
|
||||
|
||||
;-- Workaround for AutoHotkey Basic
|
||||
PtrType:=(A_PtrSize=8) ? "Ptr":"UInt"
|
||||
|
||||
;-- Get the window's dimensions
|
||||
; Note: Only the first 16 bytes of the RECTPlus structure are used by the
|
||||
; DwmGetWindowAttribute and GetWindowRect functions.
|
||||
VarSetCapacity(RECTPlus,32,0)
|
||||
DWMRC:=DllCall("dwmapi\DwmGetWindowAttribute"
|
||||
,PtrType,hWindow ;-- hwnd
|
||||
,"UInt",DWMWA_EXTENDED_FRAME_BOUNDS ;-- dwAttribute
|
||||
,PtrType,&RECTPlus ;-- pvAttribute
|
||||
,"UInt",16) ;-- cbAttribute
|
||||
|
||||
if (DWMRC<>S_OK)
|
||||
{
|
||||
if ErrorLevel in -3,-4 ;-- Dll or function not found (older than Vista)
|
||||
{
|
||||
;-- Do nothing else (for now)
|
||||
}
|
||||
else
|
||||
outputdebug,
|
||||
(ltrim join`s
|
||||
Function: %A_ThisFunc% -
|
||||
Unknown error calling "dwmapi\DwmGetWindowAttribute".
|
||||
RC=%DWMRC%,
|
||||
ErrorLevel=%ErrorLevel%,
|
||||
A_LastError=%A_LastError%.
|
||||
"GetWindowRect" used instead.
|
||||
)
|
||||
|
||||
;-- Collect the position and size from "GetWindowRect"
|
||||
DllCall("GetWindowRect",PtrType,hWindow,PtrType,&RECTPlus)
|
||||
}
|
||||
|
||||
;-- Populate the output variables
|
||||
X:=Left := NumGet(RECTPlus,0,"Int")
|
||||
Y:=Top := NumGet(RECTPlus,4,"Int")
|
||||
Right := NumGet(RECTPlus,8,"Int")
|
||||
Bottom := NumGet(RECTPlus,12,"Int")
|
||||
Width := Right-Left
|
||||
Height := Bottom-Top
|
||||
Offset_Left := 0
|
||||
Offset_Top := 0
|
||||
Offset_Right := 0
|
||||
Offset_Bottom := 0
|
||||
|
||||
;-- If DWM is not used (older than Vista or DWM not enabled), we're done
|
||||
if (DWMRC<>S_OK)
|
||||
Return &RECTPlus
|
||||
|
||||
;-- Collect dimensions via GetWindowRect
|
||||
VarSetCapacity(RECT,16,0)
|
||||
DllCall("GetWindowRect",PtrType,hWindow,PtrType,&RECT)
|
||||
GWR_Left := NumGet(RECT,0,"Int")
|
||||
GWR_Top := NumGet(RECT,4,"Int")
|
||||
GWR_Right := NumGet(RECT,8,"Int")
|
||||
GWR_Bottom := NumGet(RECT,12,"Int")
|
||||
|
||||
;-- Calculate offsets and update output variables
|
||||
NumPut(Offset_Left := Left - GWR_Left,RECTPlus,16,"Int")
|
||||
NumPut(Offset_Top := Top - GWR_Top ,RECTPlus,20,"Int")
|
||||
NumPut(Offset_Right := GWR_Right - Right ,RECTPlus,24,"Int")
|
||||
NumPut(Offset_Bottom := GWR_Bottom - Bottom ,RECTPlus,28,"Int")
|
||||
|
||||
Return &RECTPlus
|
||||
}
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
InitWindowManager() {
|
||||
LogDebug("InitWindowManager")
|
||||
global RATIO := 0.618
|
||||
; global RATIO := 0.618
|
||||
global RATIO := 0.382
|
||||
global ID_SEEN := Object()
|
||||
global ARRANGEMENT := Object()
|
||||
|
@ -64,12 +64,24 @@ FocusWinByPos(x, y) {
|
|||
|
||||
GetCursorMonGeometry(ByRef x, ByRef y, ByRef w, ByRef h) {
|
||||
MouseGetPos, MouseX, MouseY
|
||||
GetMonGeometryByPos(MouseX, MouseY, x, y, w, h)
|
||||
}
|
||||
|
||||
GetActiveWindowMonGeometry(ByRef x, ByRef y, ByRef w, ByRef h) {
|
||||
WinGetPos, wx, wy, ww, wh, A
|
||||
GetMonGeometryByPos(wx + ww / 2, wy + wh / 2, x, y, w, h)
|
||||
}
|
||||
|
||||
GetMonGeometryByPos(px, py, ByRef x, ByRef y, ByRef w, ByRef h) {
|
||||
; find monitor by position
|
||||
SysGet, mc, MonitorCount
|
||||
; find current monitor
|
||||
mi := 0
|
||||
loop {
|
||||
if (mi > mc) {
|
||||
break
|
||||
}
|
||||
SysGet, mon, MonitorWorkArea, %mi%
|
||||
if (monLeft < MouseX and monRight > MouseX) {
|
||||
if (monLeft < px and monRight > px and monTop < py and monBottom > py) {
|
||||
x := monLeft
|
||||
y := monTop
|
||||
w := monRight - monLeft
|
||||
|
@ -77,11 +89,9 @@ GetCursorMonGeometry(ByRef x, ByRef y, ByRef w, ByRef h) {
|
|||
return
|
||||
}
|
||||
mi := mi + 1
|
||||
if (mi >= mc) {
|
||||
MsgBox, "unable to find monitor under the cursor"
|
||||
return
|
||||
}
|
||||
}
|
||||
msg := Format("unable to find monitor for pos {1}, {2}", px, py)
|
||||
MsgBox, %msg%
|
||||
}
|
||||
|
||||
FocusWinByDirection(direction) {
|
||||
|
@ -94,6 +104,70 @@ FocusWinByDirection(direction) {
|
|||
FocusWinByPos(x + w * wf, y + h * hf)
|
||||
}
|
||||
|
||||
GetActiveWindowMargins(hwnd, monX, monY, monW, monH, ByRef l, ByRef t, ByRef r, ByRef b) {
|
||||
Static Dummy5693
|
||||
,RECTPlus
|
||||
,S_OK:=0x0
|
||||
,DWMWA_EXTENDED_FRAME_BOUNDS:=9
|
||||
|
||||
;-- Workaround for AutoHotkey Basic
|
||||
PtrType:=(A_PtrSize=8) ? "Ptr":"UInt"
|
||||
|
||||
;-- Get the window's dimensions (excluding shadows)
|
||||
; Note: Only the first 16 bytes of the RECTPlus structure are used by the
|
||||
; DwmGetWindowAttribute and GetWindowRect functions.
|
||||
VarSetCapacity(RECTPlus,32,0)
|
||||
DWMRC:=DllCall("dwmapi\DwmGetWindowAttribute"
|
||||
,PtrType,hwnd ;-- hwnd
|
||||
,"UInt",DWMWA_EXTENDED_FRAME_BOUNDS ;-- dwAttribute
|
||||
,PtrType,&RECTPlus ;-- pvAttribute
|
||||
,"UInt",16) ;-- cbAttribute
|
||||
|
||||
if (DWMRC<>S_OK)
|
||||
{
|
||||
if ErrorLevel in -3,-4 ;-- Dll or function not found (older than Vista)
|
||||
{
|
||||
;-- Do nothing else (for now)
|
||||
}
|
||||
else
|
||||
{
|
||||
outputdebug,
|
||||
(ltrim join`s
|
||||
Function: %A_ThisFunc% -
|
||||
Unknown error calling "dwmapi\DwmGetWindowAttribute".
|
||||
RC=%DWMRC%,
|
||||
ErrorLevel=%ErrorLevel%,
|
||||
A_LastError=%A_LastError%.
|
||||
"GetWindowRect" used instead.
|
||||
)
|
||||
}
|
||||
|
||||
;-- Collect the position and size from "GetWindowRect"
|
||||
DllCall("GetWindowRect",PtrType,hWindow,PtrType,&RECTPlus)
|
||||
}
|
||||
|
||||
;-- Populate the output variables
|
||||
x1 := NumGet(RECTPlus,0,"Int")
|
||||
y1 := NumGet(RECTPlus,4,"Int")
|
||||
x2 := NumGet(RECTPlus,8,"Int")
|
||||
y2 := NumGet(RECTPlus,12,"Int")
|
||||
|
||||
WinGetPos, winX, winY, winW, winH, A
|
||||
;-- Convert to scaled unit
|
||||
scale := Round((x2 - x1) / winW*10)/10
|
||||
x1 := (x1 - monX) / scale + monX
|
||||
y1 := (y1 - monY) / scale + monY
|
||||
x2 := (x2 - monX) / scale + monX
|
||||
y2 := (y2 - monY) / scale + monY
|
||||
w := (x2 - x1)
|
||||
h := (y2 - y1)
|
||||
l := x1 - winX
|
||||
t := y1 - winY
|
||||
r := winX+winW-x2
|
||||
b := winY+winH-y2
|
||||
LogDebug("active window margins: {1} {2} {3} {4}", l, t, r, b)
|
||||
}
|
||||
|
||||
MoveActiveWinByDirection(direction) {
|
||||
WinGet, isMax, MinMax, A
|
||||
if (isMax) {
|
||||
|
@ -101,24 +175,36 @@ MoveActiveWinByDirection(direction) {
|
|||
}
|
||||
global RATIO
|
||||
global PADDING
|
||||
GetCursorMonGeometry(x, y, w, h)
|
||||
activeWinId := WinExist("A")
|
||||
WinGetPosEx(activeWinId, wx, wy, ww, wh, l, t, r, b)
|
||||
GetActiveWindowMonGeometry(x, y, w, h)
|
||||
GetActiveWindowMargins(activeWinId, x, y, w, h, l, t, r, b)
|
||||
LogDebug("monitor geometry x: {1}, y: {2}, w: {3}, h: {4}", x, y, w, h)
|
||||
; left
|
||||
wx := x
|
||||
wy := y
|
||||
ww := floor(w * RATIO)
|
||||
wh := h
|
||||
LogDebug("left geometry: x: {1}, y: {2}, w: {3}, h: {4}", wx, wy, ww, wh)
|
||||
; right
|
||||
if (direction = "right") {
|
||||
wx := ww + floor(PADDING / 2)
|
||||
wx := wx + ww
|
||||
ww := w - ww
|
||||
LogDebug("right geometry: x: {1}, y: {2}, w: {3}, h: {4}", wx, wy, ww, wh)
|
||||
} else {
|
||||
wx := wx + PADDING
|
||||
}
|
||||
; adjust for aero margins
|
||||
wx := wx - l
|
||||
wy := wy - t
|
||||
ww := ww + l + r
|
||||
wh := wh + t + b
|
||||
; padding
|
||||
wx := wx + floor(PADDING / 2)
|
||||
ww := ww - floor(PADDING * 1.5)
|
||||
wy := wy + PADDING
|
||||
wh := wh - PADDING * 2
|
||||
WinMove, A,, wx - l, wy - t, ww + l + r, wh + t + b
|
||||
LogDebug("move {1} to {2}", activeWinId, direction)
|
||||
WinMove, A,, wx, wy, ww, wh
|
||||
LogDebug("move win to x: {1}, y: {2}, w: {3}, h: {4}", wx, wy, ww, wh)
|
||||
SaveActiveWindowDirection(direction)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user