由于一些窗口特效的原故, WinGetPos获取的窗口大小与显示效果是不一致的, 可以看到有很大的空隙
可以用另一个函数获得更精确的位置和大小
WinGetPosEx(hwnd, byref x := 0, byref y := 0, byref w := 0, byref h := 0){
VarSetCapacity(rect, 16)
if !DllCall("dwmapi\DwmGetWindowAttribute", "ptr", hwnd, "uint", 9, "ptr", &rect, "uint", 16) {
x := NumGet(rect, "int")
y := NumGet(rect, 4, "int")
w := NumGet(rect, 8, "int") - x
h := NumGet(rect, 12, "int") - y
return true
}
}
使用:
hwnd := WinExist("A")
WinGetPos, x1, y1, w1, h1, ahk_id %hwnd%
WinGetPosEx(hwnd, x2, y2, w2, h2)
MsgBox % "
(
WinGetPos`t|`tWinGetPosEx
x1: " x1 "`t`t|`tx2: " x2 "
y1: " y1 "`t`t|`ty2: " y2 "
w1: " w1 "`t`t|`tw2: " w2 "
h1: " h1 "`t`t|`th2: " h2 "
)"
这样就完美贴合了
给使用V2的朋友等效的函数:
WinGetPosEx(hwnd, &x?, &y?, &w?, &h?){
if !DllCall("dwmapi\DwmGetWindowAttribute", "ptr", hwnd, "uint", 9, "ptr", rect := Buffer(16), "uint", 16) {
x := NumGet(rect, "int")
y := NumGet(rect, 4, "int")
w := NumGet(rect, 8, "int") - x
h := NumGet(rect, 12, "int") - y
return true
}
}
WinMove有类似的函数吗?
不清楚你的意思, 涉及到窗口坐标可以通过这两个函数间接实现
WinMove和WinGetPos的xywh都是一 一对应的。 你用WinMove的时候,对xy加上或者减去相应的误差就可以了。 可以参考这个函数,它返回了xy的误差(注:y的误差它计算错了,其实用两个y值相减就行)。 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=3392 WinGetPosEx(hWindow,ByRef X=””,ByRef Y=””,ByRef Width=””,ByRef Height=””,ByRef Offset_X=””,ByRef Offset_Y=””) { 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,24,0) DWMRC:=DllCall(“dwmapiDwmGetWindowAttribute” ,PtrType,hWindow ;– hwnd ,”UInt”,DWMWA_EXTENDED_FRAME_BOUNDS ;– dwAttribute ,PtrType,&RECTPlus ;– pvAttribute ,”UInt”,16) ;– cbAttribute if (DWMRCS_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 “dwmapiDwmGetWindowAttribute”. 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_X:=0 OffSet_Y:=0 ;– If DWM is not used (older than Vista or DWM not enabled), we’re done if (DWMRCS_OK) Return &RECTPlus ;– Collect dimensions via GetWindowRect VarSetCapacity(RECT,16,0) DllCall(“GetWindowRect”,PtrType,hWindow,PtrType,&RECT) GWR_Width :=NumGet(RECT,8,”Int”)-NumGet(RECT,0,”Int”) ;– Right minus Left GWR_Height:=NumGet(RECT,12,”Int”)-NumGet(RECT,4,”Int”) ;– Bottom minus Top ;– Calculate offsets and update output variables NumPut(Offset_X:=(Width-GWR_Width)//2,RECTPlus,16,”Int”) NumPut(Offset_Y:=(Height-GWR_Height)//2,RECTPlus,20,”Int”) Return &RECTPlus }
您好,我想用在窗口分屏的代码里。代码的思路是获取显示器的长和宽,计算出所需要 窗口的x,y,w,h。但就是您所研究的“误差”,导致a窗口和b窗口之间会有缝隙。 分屏代码最后一步WinMove, A,, x, y, w, h。所以想知道能不能有个WinMoveEx函数啊,对其校正,实现无缝
WinGetPosEx 获取的xywh 和 WinGetPos 获取的xywh 相差多少,你使用WinMove的时候,加减相应的差就可以了。