吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 29159|回复: 115
上一主题 下一主题
收起左侧

[Windows] 自动化脚本 AutoHotkey v2.0.2

    [复制链接]
跳转到指定楼层
楼主
xkj 发表于 2023-1-19 21:06 回帖奖励
本帖最后由 xkj 于 2023-1-22 22:47 编辑

官网:https://www.autohotkey.com/

简介:
按键绑定
定义鼠标和键盘的热键、重新映射键或按钮以及类似自动更正的替换。创建简单的热键从未如此简单;你可以在几行或更少的时间内完成!
什么是 AutoHotkey
AutoHotkey 是一种适用于 Windows 的免费开源脚本语言,允许用户轻松地为各种任务创建小到复杂的脚本,例如:表单填写、自动点击、宏等。

载图:无界面,右键菜单英文,右键新建ahk脚本运行。

查找坐标

按住CTRL暂停,复制坐标后松开。

用法:我只会些简单的,也就映射键盘按键,当你厌倦按多个按键时,可以设置成一个按键。
列如:按下z键 关闭 CTRL+W
z::
Send ^w
Return

右键菜单 新建 ahk脚本
z::可更改为任意键
--------------------------
功能键要加上大括号如:{Enter}
Send {Enter 10} 按下10次Enter键

#        Win
!         Alt
^         Ctrl
+        Shift

文本模式:
Send {Text}

屏幕绝对坐标:【坐标位置仅供参考,通过查找坐标替换】
CoordMode, Mouse, Screen    ;不添加这句代码就是活动窗口的相对坐标。
click,1000,500,0

Click right ; 鼠标位置右键点击
Click ; 在鼠标光标的当前位置点击鼠标左键.
Click 100, 200 ; 在指定坐标处点击鼠标左键.
Click 100, 200, 0 ; 移动而不点击鼠标.
Click 100, 200 right ; 点击鼠标右键.
Click 2 ; 执行双击.
Click down ; 按下鼠标左键不放.
Click up right ; 释放鼠标右键.

【延迟】
Sleep 1000  ;  1 秒.

按住或释放按键: 把按键名称和单词 Down 或 Up 写入到大括号中. 例如:
Send {Up down}  ; 按下向上键.
Sleep 1000  ; 按住 1 秒.
Send {Up up}  ; 释放向上键.
剪贴板:
clipboard := "my text"   ; 在剪贴板中存入新内容.
clipboard := ""   ; 清空剪贴板.
clipboard := clipboard    ; 把任何复制的文件, HTML 或其他格式的文本转换为纯文本.
clipboard := clipboard " Text to append."   ; 追加一些文本到剪贴板.
StringReplace, clipboard, clipboard, ABC, DEF, All   ; 把剪贴板中所有 ABC 替换为 DEF (同时把剪贴板的内容转换为纯文本).

文本替换:
StringReplace, clipboard, clipboard, [被代替文本], [代替的文本], UseErrorLevel
如:
0::
StringReplace, clipboard, clipboard, /, /, All
StringReplace, clipboard, clipboard, \, \, All
send ^v

-----------------------------------
软件调用粘贴板搜索用法:
6::
Send ^c
Sleep 100
Data := StrReplace(Clipboard, """")
Run "E:\Everything\Everything.exe" -s "%Data%"
return


循环列子:10次输入123
1::
Loop
{

Send {Text} 123
Send {Down}
if (A_Index = 10)
        break  ; 终止循环
}

Return
Pause::Pause

详细参考:https://wyagd001.github.io/v2/docs/lib/Send.htm

更新日期:2023/01/02

蓝奏云:https://wwpl.lanzoue.com/b02py2rne 密码:5ecm

免费评分

参与人数 24吾爱币 +22 热心值 +20 收起 理由
leskady + 1 + 1 我很赞同!
Zdoat2 + 1 + 1 谢谢@Thanks!
muyexueshang + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qujian0453 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
congtongzaihui + 1 谢谢@Thanks!
c199188177c + 1 + 1 谢谢@Thanks!
Akose + 1 + 1 谢谢@Thanks!
kingzswang + 1 + 1 用心讨论,共获提升!
haihaome + 1 + 1 我很赞同!
LinkNow171 + 1 + 1 谢谢@Thanks!
papapo + 1 + 1 谢谢@Thanks!
cooday + 1 + 1 我很赞同!
q6063336 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
记得住记得住 + 1 + 1 我很赞同!
youngxiaohao + 1 + 1 我很赞同!
nndyky + 1 + 1 鼓励转贴优秀软件安全工具和文档!
745237896 + 1 + 1 我很赞同!
小猪佩奇007 + 1 + 1 谢谢@Thanks!
dogox + 1 + 1 我很赞同!
way824325223 + 1 谢谢@Thanks!
Cudet + 1 谢谢@Thanks!
dddda0809 + 1 + 1 谢谢@Thanks!
xunqitt + 1 + 1 谢谢@Thanks!
guiwuzhe + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
bluechen 发表于 2023-1-20 15:50
分享个收集的脚本,目前自用。AHK1.1.35版本下用的。
[Asm] 纯文本查看 复制代码
; AutoHotKey  # = Windows键  ! = Alt  ^ = Ctrl  + = Shift
;热键列表
;Ctrl + Alt + r                 重新加载脚本
;Win + t                        定时器
;Win + f                        Everything
;Win + l                        锁屏同时关闭显示器
;Win + z                        循环切换窗口为1/4、1/3、2/3

;Ctrl + Alt + k                 任务管理器
;Ctrl + Alt + m                 mstsc
;Ctrl + Alt + n                 Notepad记事本

;CapsLoc + e                    EditPlus
;CapsLoc + p                    procexp
;CapsLoc + w                    WinWord
;CapsLoc + x                    Excel
;CapsLoc + c                    当前目录下打开CMD
;CapsLoc + 鼠标左键             任意位置移动当前窗口
;CapsLoc + 鼠标右键             缩放当前窗口大小

;ALT + ↑                        新建虚拟桌面
;ALT + ↓                        关闭当前虚拟桌面
;ALT + ←                        切换到左侧虚拟桌面
;ALT + →                        切换到右侧虚拟桌面
;ALT + Home                     显示虚拟桌面
;Win + 1			切换到虚拟桌面1
;Win + Shift + 1		移动当前窗口到虚拟桌面1
;Win + Alt + 1			移动所有窗口到虚拟桌面1
;Win + 数字1-0			分别切换到不同的虚拟桌面
;Win + Shift + 数字1-0		移动当前窗口到指定的虚拟桌面
;Win + Alt + 数字1-0		移动所有窗口到指定的虚拟桌面

;Ctrl + ;                       当前日期YYYY-MM-DD
;Ctrl + Shift + ;               当前日期时间YYYY-MM-DD Hour:Min:Sec
;ttt                            当前时间Hour:Min:Sec

;让脚本持久运行,直至用户关闭或遇到ExitApp
;#Persistent

;强制加载新的脚本,只允许运行一个脚本的实例
#SingleInstance force

;注释掉;即可不显示图标
;#NoTrayIcon
;尝试加载图标
IfExist, myAHK.ico ;花括号{ 不能和 IfExist 写在同一行
{
Menu TRAY, Icon, myAHK.ico
}
SetWorkingDir, %A_ScriptDir%
;重新加载脚本
^!r::
Reload
TrayTip,AutoHotKey, 脚本已重启
return
!F10::
suspend
traytip,AutoHotKey,脚本状态已切换
return

;定时器 输入为分钟
#t::
InputBox ,time,定时器,请输入一个时间(单位分钟),,200,100
time := time*1000*60
Sleep, %time%
MsgBox,,提示信息, 主人,您设置的定时时间到了
return

;Win + F打开everything
#f::
Run %A_ProgramFiles%\Everything\Everything.exe
return

; Win + L 锁屏时同时关闭显示器
; Run rundll32.exe user32.dll LockWorkStation, , Hide
;    cmdScreenOff := "cmd /c start """" powershell (Add-Type '[DllImport(\""user32.dll\"")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1, 0x0112, 0xF170, 2)"
;    SendMessage, 0x112, 0xF170, 2, , Program Manager
~#l::
{
Sleep, 200
DllCall("LockWorkStation")
Sleep, 500
;关闭显示器:0x112为WM_SYSCOMMAND,oxF170为SC_MONITORPOWER,可用-1代替2
SendMessage,0x112,0xF170,2,,Program Manager
;Run %cmdScreenOff%, , Hide
}
return


;脚本功能是调整当前窗口的大小
;sunwind 
;2013年8月25日

;需求是多爱英提出,我用了面向对象的ahk来实现的。
;~ 按一下热键(win+z)
;~ 切换到  右下角1/4
;~ 再按一下
;~ 切换到  右下角 1/3
;~ 再按一下 
;~ 切换到 右下角 2/3
;~ 再按一下
;~ 切换到  右下角 1/4
SetTitleMatchMode, 3
event_index:=-1
#z::
WinGetTitle, current_win, A
if (current_win!=old_win)
	event_index=-1
if(event_index=-1)
{
	old_win:=current_win
	WinGetPos, X, Y, current_Width, current_Height, %current_win%  ;这里A应该改成目标窗口,只获取一次某窗口的大小
  	;quarter := new quarter(current_Width,current_Height)
  	;one_third:= new one_third(current_Width,current_Height)
  	;two_third:= new two_third(current_Width,current_Height)
  	;若针对窗体而不是屏幕则解除上面注释 并给窗体值

  	;用SysGet, MonitorWorkArea,而未用A_ScreenWidth A_ScreenHeight 避免任务条的影响
  	SysGet, MonitorWorkArea, MonitorWorkArea,1
  	;MsgBox, Monitor:`t`nLeft:`t%MonitorLeft% (%MonitorWorkAreaLeft% work)`nTop:`t%MonitorTop% (%MonitorWorkAreaTop% work)`nRight:`t%MonitorRight% (%MonitorWorkAreaRight% work)`nBottom:`t%MonitorBottom% (%MonitorWorkAreaBottom% work)
  	quarter := new quarter(MonitorWorkAreaRight ,MonitorWorkAreaBottom)
  	one_third:= new one_third(MonitorWorkAreaRight ,MonitorWorkAreaBottom)
  	two_third:= new two_third(MonitorWorkAreaRight ,MonitorWorkAreaBottom)
}
	event_index+=1
	event_index:=Mod(event_index, 3)  ;3个状态循环,模3,模运算得出 0,1,2
	commandArray := ["quarter", "one_third", "two_third"]
    runner:=commandArray[event_index+1] ;因为ahk的数组是从1开始的,对于索引为0时是空值,加一避免此问题
  	%runner%.zoom()
  	;TrayTip, %current_win%缩放%runner%,% "w=" %runner%.getNewWidth()  ",h="  %runner%.getNewHeight() , 10,
  	NewWidth:=%runner%.getNewWidth() 
  	NewHeight:=%runner%.getNewHeight()
  	WinMove, %current_win%,,MonitorWorkAreaRight-NewWidth,MonitorWorkAreaBottom-NewHeight,NewWidth,NewHeight
Return

class WinSize
{
   Width :=0
   Height := 0
   NewWidth:=0
   NewHeight:=0
   ;SetWidth(val){
   ;   Width := val ; Can set the color using a function of the class
   ;}
   ;SetHeight(val){
   ;   Height := val ; Can set the color using a function of the class
   ;}
   GetWidth(){
      Return this.Width ;需要增加this
   }

   GetHeight(){
      Return this.Height  ;需要增加this
   }

   GetNewWidth(){
      Return this.NewWidth ;需要增加this
   }
   GetNewHeight(){
      Return this.NewHeight  ;需要增加this
   }
	__New(w="",h=""){
		if (w="")
			this.Width :=A_ScreenWidth
		Else
			this.Width :=w		
		if (h="")	
			this.Height:=A_ScreenHeight
		Else
			this.Height := h
	}
}

Class half extends WinSize{
	zoom()
	{
		this.NewWidth:=  this.Width//2  ;向下舍除 (//)
		this.NewHeight:=  this.Height
	}
}

Class quarter extends WinSize{
	zoom()
	{
		this.NewWidth:=  this.Width//2
		this.NewHeight:=  this.Height//2
	}
}

Class one_third extends WinSize{
	zoom()
	{
		this.NewWidth:= this.Width//3
		this.NewHeight:= this.Height
	}
}

Class two_third extends WinSize{
	zoom()
	{
		this.NewWidth:= this.Width*2//3
		this.NewHeight:= this.Height
	}	
}


;打开任务管理器
^!k::
Run taskmgr
return

;远程连接mstsc
^!m::
Run mstsc
return

;新建或激活记事本窗口
^!n::
IfWinExist ahk_class Notepad
WinActivate
else
Run Notepad
return

;EditPlus
CapsLock & e::
If WinExist("EditPlus")
   WinActivate
else
   Run d:\Program Files\EditPlus\editplus.exe
return

;ProcExp
CapsLock & p::
IfWinExist ahk_exe procexp.exe
   WinActivate
else
   Run d:\Program Files\procexp.exe
return

;Winword
CapsLock & w::
IfWinExist ahk_exe winword.exe
   WinActivate
else
   Run winword
return

;Excel
CapsLock & x::
IfWinExist, ahk_exe EXCEL.EXE
{
   WinActivate ahk_exe EXCEL.EXE
}
else
{
   Run excel
}
return


;当前资源管理器目录打开CMD
CapsLock & c::CMD()
CMD(){
   If WinActive("ahk_class CabinetWClass") || WinActive("ahk_class ExplorerWClass"){
      WinHWND := WinActive()
      For win in ComObjCreate("Shell.Application").Windows
         If (win.HWND = WinHWND){
	    dir := SubStr(win.LocationURL,9) ;remove "file:///"
	    dir := RegExReplace(dir, "%20"," ")
	    Break
	 }
	 Run cmd, %dir%
   }
   else{
      Run *RunAs cmd, %A_Desktop% ;,max
   }
}
return

;CapsLoc + 鼠标左键移动窗口
CapsLock & LButton::
CoordMode,Mouse
MouseGetPos,EWD_MouseStartX,EWD_MouseStartY,EWD_MouseWin
WinGetPos, EWD_OriginalPosX, EWD_OriginalPosY,,,ahk_id %EWD_MouseWin%
WinGet,EWD_WinState,MinMax,ahk_id %EWD_MouseWin%
If EWD_WinState = 0
SetTimer, EWD_WatchMouse, 10
return
EWD_WatchMouse:
GetKeyState, EWD_LButtonState, LButton, P
if EWD_LButtonState = U
{
setTimer, EWD_WatchMouse, off
return
}
GetKeyState, EWD_EscapeState, Escape, P
if EWD_EscapeState = D
{
setTimer, EWD_WatchMouse, off
WinMove ahk_id %EWD_MouseWin%,,%EWD_OriginalPosX%,%EWD_OriginalPosY%
return
}
CoordMode, Mouse
MouseGetPos, EWD_MouseX, EWD_MouseY
WinGetPos, EWD_WinX, EWD_WinY,,,ahk_id %EWD_MouseWin%
SetWinDelay, -1
WinMove, ahk_id %EWD_MouseWin%,, EWD_WinX + EWD_MouseX - EWD_MouseStartX, EWD_WinY + EWD_MouseY - EWD_MouseStartY
EWD_MouseStartX := EWD_MouseX
EWD_MouseStartY := EWD_MouseY
return

;CapsLock + 鼠标右键调整窗口大小
CapsLock & RButton::
CoordMode,Mouse, Screen
MouseGetPos,EWD_X1,EWD_Y1,EWD_id
WinGet,EWD_Win,MinMax,ahk_id %EWD_id%
If EWD_Win
    return
; Get the initial window position and size.
WinGetPos,EWD_WinX1,EWD_WinY1,EWD_WinW,EWD_WinH,ahk_id %EWD_id%
; Define the window region the mouse is currently in.
; The four regions are Up and Left, Up and Right, Down and Left, Down and Right.
If (EWD_X1 < EWD_WinX1 + EWD_WinW / 2)
   EWD_WinLeft := 1
Else
   EWD_WinLeft := -1
If (EWD_Y1 < EWD_WinY1 + EWD_WinH / 2)
   EWD_WinUp := 1
Else
   EWD_WinUp := -1
Loop
{
    GetKeyState,EWD_Button,RButton,P ; Break if button has been released.
    If EWD_Button = U
        break
    MouseGetPos,EWD_X2,EWD_Y2 ; Get the current mouse position.
    ; Get the current window position and size.
    WinGetPos,EWD_WinX1,EWD_WinY1,EWD_WinW,EWD_WinH,ahk_id %EWD_id%
    EWD_X2 -= EWD_X1 ; Obtain an offset from the initial mouse position.
    EWD_Y2 -= EWD_Y1
    ; Then, act according to the defined region.
    WinMove,ahk_id %EWD_id%,, EWD_WinX1 + (EWD_WinLeft+1)/2*EWD_X2  ; X of resized window
                            , EWD_WinY1 +   (EWD_WinUp+1)/2*EWD_Y2  ; Y of resized window
                            , EWD_WinW  -     EWD_WinLeft  *EWD_X2  ; W of resized window
                            , EWD_WinH  -       EWD_WinUp  *EWD_Y2  ; H of resized window
    EWD_X1 := (EWD_X2 + EWD_X1) ; Reset the initial position for the next iteration.
    EWD_Y1 := (EWD_Y2 + EWD_Y1)
}
return


;虚拟桌面
;ALT + ↑:新建虚拟桌面
;ALT + ↓:关闭当前虚拟桌面
;ALT + ←:切换到左侧虚拟桌面
;ALT + →:切换到右侧虚拟桌面
;ALT + Home:显示虚拟桌面
!Up::Send #^{d}
!Down::Send #^{F4}
!Left::Send #^{Left}
!Right::Send #^{Right}
!Home::Send #{Tab}

; Add or delete desktop
!Backspace:: SendEvent ^#{F4}
!+Backspace:: SendEvent ^#d



; Switch to desktop
#1::SwitchToDesktop(1)
#2::SwitchToDesktop(2)
#3::SwitchToDesktop(3)
#4::SwitchToDesktop(4)
#5::SwitchToDesktop(5)
#6::SwitchToDesktop(6)
#7::SwitchToDesktop(7)
#8::SwitchToDesktop(8)
#9::SwitchToDesktop(9)
#0::SwitchToDesktop(10)

; Move the current window to the X-th desktop
#+1::MoveActiveWindowToDesktop(1)
#+2::MoveActiveWindowToDesktop(2)
#+3::MoveActiveWindowToDesktop(3)
#+4::MoveActiveWindowToDesktop(4)
#+5::MoveActiveWindowToDesktop(5)
#+6::MoveActiveWindowToDesktop(6)
#+7::MoveActiveWindowToDesktop(7)
#+8::MoveActiveWindowToDesktop(8)
#+9::MoveActiveWindowToDesktop(9)
#+0::MoveActiveWindowToDesktop(10)

; Move the ALL visible window to the X-th desktop
#!1::MoveAllVisibleWindowToDesktop(1)
#!2::MoveAllVisibleWindowToDesktop(2)
#!3::MoveAllVisibleWindowToDesktop(3)
#!4::MoveAllVisibleWindowToDesktop(4)
#!5::MoveAllVisibleWindowToDesktop(5)
#!6::MoveAllVisibleWindowToDesktop(6)
#!7::MoveAllVisibleWindowToDesktop(7)
#!8::MoveAllVisibleWindowToDesktop(8)
#!9::MoveAllVisibleWindowToDesktop(9)
#!0::MoveAllVisibleWindowToDesktop(10)


; API definitions
/*
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4")]
internal interface IVirtualDesktop
{
bool IsViewVisible(IApplicationView view);
Guid GetId();
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("F31574D6-B682-4CDC-BD56-1827860ABEC6")]
internal interface IVirtualDesktopManagerInternal
{
int GetCount();
void MoveViewToDesktop(IApplicationView view, IVirtualDesktop desktop);
bool CanViewMoveDesktops(IApplicationView view);
IVirtualDesktop GetCurrentDesktop();
void GetDesktops(out IObjectArray desktops);
[PreserveSig]
int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
void SwitchDesktop(IVirtualDesktop desktop);
IVirtualDesktop CreateDesktop();
void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
IVirtualDesktop FindDesktop(ref Guid desktopid);
}
1
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("A5CD92FF-29BE-454C-8D04-D82879FB3F1B")]
internal interface IVirtualDesktopManager
{
bool IsWindowOnCurrentVirtualDesktop(IntPtr topLevelWindow);
Guid GetWindowDesktopId(IntPtr topLevelWindow);
void MoveWindowToDesktop(IntPtr topLevelWindow, ref Guid desktopId);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("4CE81583-1E4C-4632-A621-07A53543148F")]
internal interface IVirtualDesktopPinnedApps
{
bool IsAppIdPinned(string appId);
void PinAppID(string appId);
void UnpinAppID(string appId);
bool IsViewPinned(IApplicationView applicationView);
void PinView(IApplicationView applicationView);
void UnpinView(IApplicationView applicationView);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("92CA9DCD-5622-4BBA-A805-5E9F541BD8C9")]
internal interface IObjectArray
{
void GetCount(out int count);
void GetAt(int index, ref Guid iid, [MarshalAs(UnmanagedType.Interface)]out object obj);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
internal interface IServiceProvider10
{
[Return: MarshalAs(UnmanagedType.IUnknown)]
object QueryService(ref Guid service, ref Guid riid);
}

*/
; api define
; IServiceProvider                := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
; IVirtualDesktopManagerInternal  := ComObjQuery(IServiceProvider, "{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}", "{F31574D6-B682-4CDC-BD56-1827860ABEC6}")
; GetCount                        := vtable(IVirtualDesktopManagerInternal, 3)
; MoveViewDesktop                 := vtable(IVirtualDesktopManagerInternal, 4)
; CanViewMoveDesktops             := vtable(IVirtualDesktopManagerInternal, 5)
; GetCurrentDesktop               := vtable(IVirtualDesktopManagerInternal, 6)
; GetDesktops                     := vtable(IVirtualDesktopManagerInternal, 7)
; GetAdjacentDesktop              := vtable(IVirtualDesktopManagerInternal, 8)
; SwitchDesktop                   := vtable(IVirtualDesktopManagerInternal, 9)
; CreateDesktopW                  := vtable(IVirtualDesktopManagerInternal, 10)
; RemoveDesktop                   := vtable(IVirtualDesktopManagerInternal, 11)
; FindDesktop                     := vtable(IVirtualDesktopManagerInternal, 12)

; IVirtualDesktopManager          := ComObjCreate("{AA509086-5CA9-4C25-8F95-589D3C07B48A}", "{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}")
; IsWindowOnCurrentVirtualDesktop := vtable(IVirtualDesktopManager, 3)
; GetWindowDesktopId              := vtable(IVirtualDesktopManager, 4)
; MoveWindowToDesktop             := vtable(IVirtualDesktopManager, 5)


; Move the current window to another desktop
MoveActiveWindowWithAction(action)
{
    activeWin := WinActive("A")
    WinHide ahk_id %activeWin%
    SendInput %action%
    WinShow ahk_id %activeWin%
    WinActivate ahk_id %activeWin%
}
MoveActiveWindowToNewDesktop()
{
    activeWin := WinActive("A")
    WinHide ahk_id %activeWin%
    SendInput ^#d
    WinShow ahk_id %activeWin%
    WinActivate ahk_id %activeWin%
}
MoveActiveWindowToDesktop(idx)
{
    activeWin := WinActive("A")
    WinHide ahk_id %activeWin%
    SwitchToDesktop(idx)
    WinShow ahk_id %activeWin%
    WinActivate ahk_id %activeWin%
}
MoveAllVisibleWindowToDesktop(idx)
{
    listOfWindow := WindowsListOfMonitorFast(arrangeFlags | ARRANGE_MAXWINDOW | ARRANGE_MINWINDOW)
    
    loop Parse, listOfWindow, `n
    {
        hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
        if(!hWnd)
            continue
        ; WinHide ahk_id %hWnd%
        DllCall("ShowWindowAsync", UInt, hWnd, UInt, (SW_HIDE := 0x0) )
    }
    SwitchToDesktop(idx)
    Sleep 128
    loop Parse, listOfWindow, `n
    {
        hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
        if(!hWnd)
            continue
        
        DllCall("ShowWindowAsync", UInt, hWnd, UInt, (SW_SHOWNOACTIVATE := 0x4) )
    }
}
SwitchToDesktop(idx)
{
    if (SwitchToDesktopByInternalAPI(idx)) {
        ; ok
    } else if (SwitchToDesktopByHotkey(idx)) {
        Tooltip, WARN SwitchToDesktopByHotkey %idx%
    } else {
        Tooltip, WARN SwitchToDesktop FAILED
    }
    EnsureCurrentEnviromentRule(idx)
    return idx
}
EnsureCurrentEnviromentRule(idx)
{
    listOfWindow := WindowsListInAllVirtualDesktop()
    out:=""
    pinPatterns := VirtualDesktopPinPattern1 "`n" VirtualDesktopPinPattern2 "`n" VirtualDesktopPinPattern3 "`n" VirtualDesktopPinPattern4 "`n" VirtualDesktopPinPattern5 "`n" VirtualDesktopPinPattern6 "`n" VirtualDesktopPinPattern7 "`n" VirtualDesktopPinPattern8 "`n" VirtualDesktopPinPattern9 "`n" VirtualDesktopPinPattern0
    loop, Parse, listOfWindow, `n
    {
        win := A_LoopField
        hWnd := RegExReplace(win, "^.*?ahk_id (\S+).*?$", "$1")
        if (IsWindowOnCurrentVirtualDesktop(hWnd)) {
            continue
        }
        k:= 0
        loop, Parse, pinPatterns, `n
        {
            k := k + 1
            pattern := A_LoopField
            if (idx == k && RegExMatch(win, "i)" pattern)) {
                WinHide ahk_id %hWnd%
                WinShow ahk_id %hWnd%
            }
        }
    }
    tooltip %out%
}

SwitchToDesktopByHotkey(idx)
{
    static lastIdx := ""
    if (!lastIdx || idx == 1) {
        Loop 10 {
            SendEvent ^#{Left}
        }
        lastIdx := 1
    }
    offset := idx - lastIdx
    offsetRight := max(offset, 0)
    offsetLeft := max(-offset, 0)
    Loop %offsetRight% {
        SendEvent ^#{Right}
    }
    Loop %offsetLeft% {
        SendEvent ^#{Left}
    }
    lastIdx := idx
    
    return idx
}
IsWindowOnCurrentVirtualDesktop(hWnd)
{
    IVirtualDesktopManager := ComObjCreate("{AA509086-5CA9-4C25-8F95-589D3C07B48A}", "{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}")
    ; 如果这个对象不存在那就没有虚拟桌面的说法了,那它一定在当前桌面下就默认返回true好了
    if (!IVirtualDesktopManager)
        Return true
    IsWindowOnCurrentVirtualDesktop := vtable(IVirtualDesktopManager, 3)
    bool := 0
    DllCall(IsWindowOnCurrentVirtualDesktop, "UPtr", IVirtualDesktopManager, "UInt", hWnd, "UIntP", bool)
    ObjRelease(IVirtualDesktopManager)
    Return %bool%
}

SwitchToDesktopByInternalAPI(idx)
{
    succ := 0
    IServiceProvider := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
    IVirtualDesktopManagerInternal_Win11 := ComObjQuery(IServiceProvider, "{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}", "{B2F925B9-5A0F-4D2E-9F4D-2B1507593C10}")
    IVirtualDesktopManagerInternal_Win10 := ComObjQuery(IServiceProvider, "{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}", "{F31574D6-B682-4CDC-BD56-1827860ABEC6}")
    win11 := !!IVirtualDesktopManagerInternal_Win11
    win10 := !!IVirtualDesktopManagerInternal_Win10
    IVirtualDesktopManagerInternal := !!IVirtualDesktopManagerInternal_Win11 ? IVirtualDesktopManagerInternal_Win11 : IVirtualDesktopManagerInternal_Win10
    ; tooltip win %win11% %win10%
    ObjRelease(IServiceProvider)
    if (IVirtualDesktopManagerInternal) {
        ; tooltip %idx%
        GetCount := vtable(IVirtualDesktopManagerInternal, 3)
        GetDesktops := vtable(IVirtualDesktopManagerInternal, 7)
        SwitchDesktop := vtable(IVirtualDesktopManagerInternal, 9)
        ; TrayTip, , % IVirtualDesktopManagerInternal
        pDesktopIObjectArray := 0
        _ := win10 && DllCall(GetDesktops, "Ptr", IVirtualDesktopManagerInternal, "Ptr*", pDesktopIObjectArray)
        _ := win11 && DllCall(GetDesktops, "Ptr", IVirtualDesktopManagerInternal, "Ptr", 0, "Ptr*", pDesktopIObjectArray)
        ; Tooltip %pDesktopIObjectArray%
        if (pDesktopIObjectArray) {
            GetDesktopCount := vtable(pDesktopIObjectArray, 3)
            GetDesktopAt := vtable(pDesktopIObjectArray, 4)
            _ := win10 && DllCall(GetDesktopCount, "Ptr", IVirtualDesktopManagerInternal, "UInt*", DesktopCount)
            _ := win11 && DllCall(GetDesktopCount, "Ptr", IVirtualDesktopManagerInternal, "Ptr", 0, "UInt*", DesktopCount)
            ; tooltip 切换到桌面 %idx% / %DesktopCount%
            ; if idx-th desktop doesn't exists then create a new desktop
            if (idx > DesktopCount) {
                diff := idx - DesktopCount
                loop %diff% {
                    SendEvent ^#d
                }
            }
            ; if desktop count is more than 10 then delete them
            if (DesktopCount > 10) {
                delCount := DesktopCount - 10 + 1
                SendEvent ^#d
                loop %delCount% {
                    SendEvent ^#{F4}
                }
            }
            _ := win10 && GetGUIDFromString(IID_IVirtualDesktop, "{FF72FFDD-BE7E-43FC-9C03-AD81681E88E4}")
            _ := win11 && GetGUIDFromString(IID_IVirtualDesktop, "{536D3495-B208-4CC9-AE26-DE8111275BF8}")
            DllCall(GetDesktopAt, "Ptr", pDesktopIObjectArray, "UInt", idx - 1, "Ptr", &IID_IVirtualDesktop, "Ptr*", VirtualDesktop)
            ObjRelease(pDesktopIObjectArray)
            if (VirtualDesktop) {
                _ := win10 && DllCall(SwitchDesktop, "Ptr", IVirtualDesktopManagerInternal, "Ptr", VirtualDesktop)
                _ := win11 && DllCall(SwitchDesktop, "Ptr", IVirtualDesktopManagerInternal, "Ptr", 0, "Ptr", VirtualDesktop)
                ObjRelease(VirtualDesktop)
                succ := idx
            }
        }
        ObjRelease(IVirtualDesktopManagerInternal)
    }
    Return succ
}
GetGUIDFromString(ByRef GUID, sGUID) ; Converts a string to a binary GUID
{
    VarSetCapacity(GUID, 16, 0)
    DllCall("ole32\CLSIDFromString", "Str", sGUID, "Ptr", &GUID)
}

vtable(ptr, n)
{
    ; NumGet(ptr+0) Returns the address of the object's virtual function
    ; table (vtable for short). The remainder of the expression retrieves
    ; the address of the nth function's address from the vtable.
    Return NumGet(NumGet(ptr+0), n*A_PtrSize)
}

WindowsListInAllVirtualDesktop()
{
    windowsMatches := ""
    ; 常量定义
    WS_EX_TOOLWINDOW := 0x00000080
    WS_EX_APPWINDOW := 0x00040000
    WS_CAPTION := 0x00C00000
    WS_EX_NOANIMATION := 0x04000000
    WS_EX_NOACTIVATE := 0x08000000
    WS_POPUP := 0x80000000
    DetectHiddenWindows, Off
    WinGet, id, List, , , 
    loop %id% {
        hWnd := id%A_Index%
        filter := !WindowsListOfMonitorInAllVirtualDesktopFilter(hWnd)
        if (filter) {
            continue
        }
        WinGet, this_exe, ProcessName, ahk_id %hWnd%
        WinGetTitle, this_title, ahk_id %hWnd%
        windowsMatches .= "ahk_exe " this_exe " ahk_id " hWnd " " . this_title . "`n"
        ; windowsMatches .= "ahk_pid " this_pid " ahk_id " hWnd "`n" ; . "`t" . this_title . "`n"
    }
    Sort windowsMatches, R
    return windowsMatches
}
WindowsListOfMonitorInAllVirtualDesktopFilter(hWnd)
{
    ; 常量定义
    WS_EX_TOOLWINDOW := 0x00000080
    WS_EX_APPWINDOW := 0x00040000
    WS_CAPTION := 0x00C00000
    WS_EX_NOANIMATION := 0x04000000
    WS_EX_NOACTIVATE := 0x08000000
    WS_POPUP := 0x80000000
    WinGet, style, style, ahk_id %hWnd%
    ; ; 跳过无标题窗口
    ; if !(style & WS_CAPTION)
    ;     Continue
    ; ; 跳过工具窗口
    ; if (style & WS_EX_TOOLWINDOW)
    ;     Continue
    ; if (style & WS_POPUP)
    ;     Continue
    ; 只显示Alt+TAB里有的窗口
    if (!(style & WS_EX_APPWINDOW)) {
        return False ; ; 跳 过弹出窗口
    }
    ; ToolTip, %hWnd% mi %MonitorIndex%
    ; 尝试跳过隐藏窗口
    GWL_STYLE := -16
    GWL_EXSTYLE := -20
    ; WS_STYLE := DllCall("GetWindowLong" (A_PtrSize=8 ? "Ptr" : ""), "Ptr", hWnd, "Int", GWL_STYLE, "PTR")
    WS_VISIBLE := 0x10000000
    if (!(style & WS_VISIBLE)) {
        return False
    }
    ; 跳过不在当前虚拟桌面的窗口
    ; if (!IsWindowOnCurrentVirtualDesktop(hWnd)) {
    ;     return False
    ; }
    ; 排除不归属于当前参数显示器的窗口
    ; if (!!MonitorIndex) {
    ;     this_monitor := GetMonitorIndexFromWindow(hWnd)
    ;     if (MonitorIndex != this_monitor) {
    ;         return False
    ;     }
    ; }
    ; 尝试跳过隐藏窗口
    if ( !DllCall("IsWindowVisible", "Ptr", hWnd, "PTR") ) {
        return False
    }
    ; ; 跳过最大化窗口
    ; WinGet, minmax, minmax, ahk_id %hWnd%
    ; if (minmax == 1 && !(arrangeFlags & ARRANGE_MAXWINDOW)) {
    ;     return False
    ; }
    ; ; 跳过最小化的窗口
    ; if (minmax == -1 && !(arrangeFlags & ARRANGE_MINWINDOW)) {
    ;     return False
    ; }
    WinGetTitle, this_title, ahk_id %hWnd%
    ; 排除空标题窗口
    if (!RegExMatch(this_title, ".+")) {
        return False ; If (this_class == "Progman") ; return False ; 排除 Win10 的常驻窗口管理器
    }
    ; 跳过不可见的 UWP 窗口
    WinGetClass, this_class, ahk_id %hWnd%
    if ( this_class == "ApplicationFrameWindow") {
        return False
    }
    ; true
    return True
}
GetMonitorIndexFromWindowByWindowsCenterPoint(hWnd)
{
    WinGetPos, X, Y, W, H, ahk_id %hWnd%
    CX := X + W / 2
    CY := Y + H / 2
    SysGet, monitorCount, MonitorCount
    MonitorIndex := "" ; default
    loop %monitorCount% {
        SysGet, M, Monitor, %A_Index%
        ; Compare center position to determine the monitor index.
        if (( abs(min(max(MLeft, CX), MRight) - CX) <= 1)&& ( abs(min(max(MTop, CY), MBottom) - CY) <= 1)) {
            msgbox, , %title%, %A_Index% %MLeft% %CX% %MRight% %EQ%
            MonitorIndex := A_Index
            break
        }
    }
    Return %MonitorIndex%
}
; below function is modified from [How to determine a window is in which monitor? - Ask for Help - AutoHotkey Community]( https://autohotkey.com/board/topic/69464-how-to-determine-a-window-is-in-which-monitor/ )
GetMonitorIndexFromWindow(hWnd)
{
    ; default is 0 to prevent ...
    MonitorIndex := ""
    VarSetCapacity(monitorInfo, 40)
    NumPut(40, monitorInfo)
    monitorHandle := DllCall("MonitorFromWindow", "uint", hWnd, "uint", 0x2)
    if (monitorHandle && DllCall("GetMonitorInfo", "uint", monitorHandle, "uint", &monitorInfo)) {
        monitorLeft := NumGet(monitorInfo, 4, "Int")
        monitorTop := NumGet(monitorInfo, 8, "Int")
        monitorRight := NumGet(monitorInfo, 12, "Int")
        monitorBottom := NumGet(monitorInfo, 16, "Int")
        workLeft := NumGet(monitorInfo, 20, "Int")
        workTop := NumGet(monitorInfo, 24, "Int")
        workRight := NumGet(monitorInfo, 28, "Int")
        workBottom := NumGet(monitorInfo, 32, "Int")
        isPrimary := NumGet(monitorInfo, 36, "Int") & 1
        
        ; msgbox, , , workLeft%workLeft% workTop%workTop% workRight%workRight% workBottom%workBottom%
        
        SysGet, monitorCount, MonitorCount
        loop %monitorCount%
        {
            SysGet, tempMon, Monitor, %A_Index%
            ; Compare location to determine the monitor index.
            if ((monitorLeft = tempMonLeft) and (monitorTop = tempMonTop)and (monitorRight = tempMonRight) and (monitorBottom = tempMonBottom)) {
                MonitorIndex := A_Index
                break
            }
        }
    }
    if (MonitorIndex) {
        Return %MonitorIndex%
    }
    MonitorIndex := GetMonitorIndexFromWindowByWindowsCenterPoint(hWnd)
    if (MonitorIndex) {
        Return %MonitorIndex%
    }
    Return 1
}
WindowsListOfMonitorFast(arrangeFlags, MonitorIndex := 0)
{
    windowsMatches := ""
    ; 常量定义
    WS_EX_TOOLWINDOW := 0x00000080
    WS_EX_APPWINDOW := 0x00040000
    WS_CAPTION := 0x00C00000
    WS_EX_NOANIMATION := 0x04000000
    WS_EX_NOACTIVATE := 0x08000000
    WS_POPUP := 0x80000000
    WS_VISIBLE := 0x10000000
    
    DetectHiddenWindows, Off
    WinGet, id, List, , , 
    loop %id% {
        hWnd := id%A_Index%
        WinGet, style, style, ahk_id %hWnd%
        ; 跳过无标题窗口
        if (!(style & WS_CAPTION)) {
            Continue
        }
        ; 跳过工具窗口
        if (style & WS_EX_TOOLWINDOW) {
            Continue
        }
        if (style & WS_POPUP) {
            Continue
        }
        ; 只显示Alt+TAB里有的窗口
        if (!(style & WS_EX_APPWINDOW)) {
            continue ; ; 跳 过弹出窗口
        }
        ; 尝试跳过隐藏窗口
        if (!(style & WS_VISIBLE)) {
            continue
        }
        ; 跳过不在当前虚拟桌面的窗口
        if (!IsWindowOnCurrentVirtualDesktop(hWnd)) {
            continue
        }
        ; 排除不归属于当前参数显示器的窗口
        if (!!MonitorIndex) {
            this_monitor := GetMonitorIndexFromWindow(hWnd)
            if (MonitorIndex != this_monitor) {
                continue
            }
        }
        WinGet, this_exe, ProcessName, ahk_id %hWnd%
        windowsMatches .= "ahk_exe " this_exe " ahk_id " hWnd "`n" ; . "`t" . this_title . "`n"
        ; windowsMatches .= "ahk_pid " this_pid " ahk_id " hWnd "`n" ; . "`t" . this_title . "`n"
    }
    return windowsMatches
}
WindowsListOfMonitorInCurrentDesktop(arrangeFlags, MonitorIndex := 0)
{
    windowsMatches := ""
    ; 常量定义
    WS_EX_TOOLWINDOW := 0x00000080
    WS_EX_APPWINDOW := 0x00040000
    WS_CAPTION := 0x00C00000
    WS_EX_NOANIMATION := 0x04000000
    WS_EX_NOACTIVATE := 0x08000000
    WS_POPUP := 0x80000000
    
    DetectHiddenWindows, Off
    WinGet, id, List, , , 
    loop %id% {
        hWnd := id%A_Index%
        WinGet, style, style, ahk_id %hWnd%
        ; ; 跳过无标题窗口
        ; if !(style & WS_CAPTION)
        ;     Continue
        ; ; 跳过工具窗口
        ; if (style & WS_EX_TOOLWINDOW)
        ;     Continue
        ; if (style & WS_POPUP)
        ;     Continue
        ; 只显示Alt+TAB里有的窗口
        if (!(style & WS_EX_APPWINDOW)) {
            continue ; ; 跳 过弹出窗口
        }
        ; 尝试跳过隐藏窗口
        GWL_STYLE := -16
        GWL_EXSTYLE := -20
        ; WS_STYLE := DllCall("GetWindowLong" (A_PtrSize=8 ? "Ptr" : ""), "Ptr", hWnd, "Int", GWL_STYLE, "PTR")
        WS_VISIBLE := 0x10000000
        if (!(style & WS_VISIBLE)) {
            continue
        }
        ; 跳过不在当前虚拟桌面的窗口
        if (!IsWindowOnCurrentVirtualDesktop(hWnd)) {
            continue
        }
        ; 排除不归属于当前参数显示器的窗口
        if (!!MonitorIndex) {
            this_monitor := GetMonitorIndexFromWindow(hWnd)
            if (MonitorIndex != this_monitor) {
                continue
            }
        }
        ; 尝试跳过隐藏窗口
        if ( !DllCall("IsWindowVisible", "Ptr", hWnd, "PTR") ) {
            continue
        }
        ; 跳过最大化窗口
        WinGet, minmax, minmax, ahk_id %hWnd%
        if (minmax == 1 && !(arrangeFlags & ARRANGE_MAXWINDOW)) {
            continue
        }
        ; 跳过最小化的窗口
        if (minmax == -1 && !(arrangeFlags & ARRANGE_MINWINDOW)) {
            continue
        }
        WinGetTitle, this_title, ahk_id %hWnd%
        ; 排除空标题窗口
        if (!RegExMatch(this_title, ".+")) {
            Continue ; If (this_class == "Progman") ; Continue ; 排除 Win10 的常驻窗口管理器
        }
        ; 跳过不可见的 UWP 窗口
        WinGetClass, this_class, ahk_id %hWnd%
        if ( this_class == "ApplicationFrameWindow") {
            Continue
        }
        
        WinGet, this_exe, ProcessName, ahk_id %hWnd%
        windowsMatches .= "ahk_exe " this_exe " ahk_id " hWnd "`n" ; . "`t" . this_title . "`n"
        ; windowsMatches .= "ahk_pid " this_pid " ahk_id " hWnd "`n" ; . "`t" . this_title . "`n"
    }
    Sort windowsMatches, R
    return windowsMatches
}
WindowsWalkToDirection右上左下(arrangeFlags = "0", direction := 0)
{
    ; 列出所有窗口
    static listOfWindow_cache := ""
    static listOfWindow_cache_time := 0
    if (listOfWindow_cache_time + 5000 < A_TickCount ) {
        listOfWindow_cache := ""
    }
    if (listOfWindow_cache ) {
        listOfWindow := listOfWindow_cache
    } else {
        listOfWindow := WindowsListOfMonitorFast(arrangeFlags) ; 目前这个函数扔然是最大的性能瓶颈
        listOfWindow_cache := listOfWindow
        listOfWindow_cache_time := A_TickCount
    }
    ; tooltip %listOfWindow%
    
    ; 相对当前窗口的位置计算
    hWnd := WinActive("A")
    WinGetPos, X, Y, W, H, ahk_id %hWnd%
    this_CX := X + W / 2
    this_CY := Y + H / 2
    最优距离 := 0
    最优方向 := ""k
    最优HWND := hWnd
    n := StrSplit(listOfWindow, "`n", "`r").Count() - 1
    loop Parse, listOfWindow, `n
    {
        hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
        if (!hWnd) {
            continue
        }
        WinGetPos, X, Y, W, H, ahk_id %hWnd%
        CX := X + W / 2
        CY := Y + H / 2
        DX := CX - this_CX
        DY := CY - this_CY
        cos45 := Cos(-45 / 180 * 3.1415926535)
        sin45 := Sin(-45 / 180 * 3.1415926535)
        rotatedDX := DX * cos45 - DY * sin45
        rotatedDY := -(DX * sin45 + DY * cos45)
        方向 := ""
        if (rotatedDX > 0 && rotatedDY > 0) {
            方向 := "右"
        }
        if (rotatedDX < 0 && rotatedDY > 0) {
            方向 := "上"
        }
        if (rotatedDX < 0 && rotatedDY < 0) {
            方向 := "左"
        }
        if (rotatedDX > 0 && rotatedDY < 0) {
            方向 := "下"
        }
        距离 := ( DX**2 + DY**2 ) ** (1/2)
        ; WinGetTitle, 当前标题, ahk_id %hWnd%
        ; msgbox %当前标题% `n 方向 %方向% %距离% `n %DX% %DY% `n %rotatedDX% %rotatedDY%
        if (距离 && (距离 < 最优距离 || !最优距离) && ( 0
        || (direction == 1 && 方向 == "右")
        || (direction == 2 && 方向 == "上")
        || (direction == 3 && 方向 == "左")
        || (direction == 4 && 方向 == "下")))
        {
            最优HWND := hWnd
            最优距离 := 距离
            最优方向 := 方向
        }
    }
    if (最优距离) {
        WinGetTitle, Title, ahk_id %最优HWND%
        WinActivate, ahk_id %最优HWND%
        ; TrayTip, CapsLockX 窗口增强, 切换到窗口 %Title% `n 方向 %最优方向% `n 距离 %最优距离%
        return True
    }
    return False
}
ArrangeWindows(arrangeFlags = "0")
{
    arrangeFlags += 0 ; string to number
    SysGet, MonitorCount, MonitorCount
    ; 列出每个显示器内的窗口
    loop %MonitorCount% {
        MonitorIndex := A_Index
        listOfWindow_%MonitorIndex% := WindowsListOfMonitorInCurrentDesktop(arrangeFlags, MonitorIndex)
    }
    ; 位置调整
    loop %MonitorCount% {
        MonitorIndex := A_Index
        if (arrangeFlags & ARRANGE_STACKED) {
            ArrangeWindowsStacked(listOfWindow_%MonitorIndex%, arrangeFlags | ARRANGE_MOVING, MonitorIndex)
        } else {
            ArrangeWindowsSideBySide(listOfWindow_%MonitorIndex%, arrangeFlags | ARRANGE_MOVING, MonitorIndex)
        }
    }
    ; Z_Order 调整
    loop %MonitorCount% {
        MonitorIndex := A_Index
        if (arrangeFlags & ARRANGE_STACKED) {
            ArrangeWindowsStacked(listOfWindow_%MonitorIndex%, arrangeFlags | ARRANGE_Z_ORDERING, MonitorIndex)
        } else {
            ArrangeWindowsSideBySide(listOfWindow_%MonitorIndex%, arrangeFlags | ARRANGE_Z_ORDERING, MonitorIndex)
        }
    }
}
ArrangeWindowsSideBySide(listOfWindow, arrangeFlags = "0", MonitorIndex = "")
{
    arrangeFlags += 0 ; string to number
    n := StrSplit(listOfWindow, "`n", "`r").Count() - 1
    ; TrayTip DEBUG_AW_listOfWindow_%n%, %listOfWindow%
    ; try parse work rect from monitor
    if (!MonitorIndex) {
        AreaX := 0
        AreaY := 0
        AreaW := A_ScreenWidth
        AreaH := A_ScreenHeight
    } else {
        SysGet, MonitorWorkArea, MonitorWorkArea, %MonitorIndex%
        ; SysGet, Monitor, Monitor, %MonitorIndex%
        AreaX := MonitorWorkAreaLeft
        AreaY := MonitorWorkAreaTop
        AreaW := MonitorWorkAreaRight - MonitorWorkAreaLeft
        AreaH := MonitorWorkAreaBottom - MonitorWorkAreaTop
    }
    if (arrangeFlags & ARRANGE_MOVING) {
        ; AreaH /= 2
        ; TrayTip DEBUG Area, %AreaX% %AreaY% %AreaW% %AreaH%
        ; calc rows and cols
        ; shorten edge first
        if (AreaW <= AreaH) {
            ; row more than cols
            col := Sqrt(n) | 0
            row := Ceil(n / col)
        } else {
            ; col more than rows
            row := Sqrt(n) | 0
            col := Ceil(n / row)
        }
        size_x := AreaW / col
        size_y := AreaH / row
        k := n - 1
        lasthWnd := 0
        loop Parse, listOfWindow, `n
        {
            hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
            
            ; 同一进程窗口长边优先排列
            if (AreaW >= AreaH) {
                ; row first
                nx := Mod(k, col)
                ny := k / col | 0
            } else {
                ; col first
                nx := k / row | 0
                ny := Mod(k, row)
            }
            x := AreaX + nx * size_x
            y := AreaY + ny * size_y
            
            ; 填满窗口间的缝隙
            x:= x-8, y:=y, w:=size_x+16, h:=size_y+8
            
            ; 左上角不要出界,否则不同DPI的显示器连接处宽度计算不正常
            dX := max(AreaX - x, 0), x += dX, w -= dX
            dY := max(AreaY - y, 0), y += dY, h -= dY
            ; 右下角也不要出界,下边留出1px让wallpaper engine 的bgm放出来
            w := min(x + w, AreaX + AreaW) - x
            h := min(y + h, AreaY + AreaH - 1) - y
            
            FastResizeWindow(hWnd, x, y, w, h)
            lasthWnd := hWnd
            k-=1
        }
        WinGet, hWnd, , A
        ; DllCall( "FlashWindow", UInt, hWnd, Int, True )
        
        ; loop Parse, listOfWindow, `n
        ; {
        ;     hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
        ;     WinActivate ahk_id %hWnd%
        ; }
        ; Sleep, 1000
    }
    if (arrangeFlags & ARRANGE_Z_ORDERING) {
        SWP_NOACTIVATE := 0x0010
        SWP_ASYNCWINDOWPOS:= 0x4000
        SWP_NOMOVE := 0x0002
        SWP_NOSIZE := 0x0001
        lasthWnd := -2
        loop, Parse, listOfWindow, `n
        {
            hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
            ; WinActivate ahk_id %hWnd%
            DllCall("SetWindowPos"
            , "UInt", hWnd ; handle
            , "UInt", lasthWnd ; z-index
            , "Int", 0 ;  x
            , "Int", 0 ; y
            , "Int", 0 ; width
            , "Int", 0 ; height
            , "UInt", SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE) ; SWP_ASYNCWINDOWPOS
            lasthWnd := hWnd
        }
    }
}
ArrangeWindowsStacked(listOfWindow, arrangeFlags = "0", MonitorIndex = "")
{
    
    dx := 96
    dy := 96
    
    arrangeFlags += 0 ; string to number
    n := StrSplit(listOfWindow, "`n", "`r").Count() - 1
    ; try parse work rect from monitor
    if (!MonitorIndex) {
        AreaX := 0
        AreaY := 0
        AreaW := A_ScreenWidth
        AreaH := A_ScreenHeight
    } else {
        SysGet, MonitorWorkArea, MonitorWorkArea, %MonitorIndex%
        AreaX := MonitorWorkAreaLeft
        AreaY := MonitorWorkAreaTop
        AreaW := MonitorWorkAreaRight - MonitorWorkAreaLeft
        AreaH := MonitorWorkAreaBottom - MonitorWorkAreaTop
    }
    
    if (arrangeFlags & ARRANGE_MOVING) {
        k := 0
        w := AreaW - 2 * dx - n * dx + dx
        h := AreaH - 2 * dy - n * dy + dy
        lasthWnd := -2
        loop, Parse, listOfWindow, `n
        {
            hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
            ; fix hidden UWP ApplicationFrameWindow Window
            WinGetClass, this_class, ahk_id %hWnd%
            if (this_class == "ApplicationFrameWindow") {
                WinActivate, ahk_id %hWnd%
            }
            
            x := AreaX + (n - k) * dx
            y := AreaY + (n - k) * dy
            FastResizeWindow(hWnd, x, y, w, h)
            lasthWnd := hWnd
            ; FastResizeWindow(hWnd, x, y, w, h)
            k+=1
        }
    }
    if (arrangeFlags & ARRANGE_Z_ORDERING) {
        WinActivate ahk_id %lasthWnd%
        SWP_NOACTIVATE := 0x0010
        SWP_ASYNCWINDOWPOS:= 0x4000
        SWP_NOMOVE := 0x0002
        SWP_NOSIZE := 0x0001
        lasthWnd := -2
        loop, Parse, listOfWindow, `n
        {
            hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
            ; WinActivate ahk_id %hWnd%
            DllCall("SetWindowPos"
            , "UInt", hWnd ; handle
            , "UInt", lasthWnd ; z-index
            , "Int", 0 ; x
            , "Int", 0 ; y
            , "Int", 0 ; width
            , "Int", 0 ; height
            , "UInt", SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_ASYNCWINDOWPOS) ; SWP_ASYNCWINDOWPOS
            lasthWnd := hWnd
        }
        
    }
    ; loop, Parse, listOfWindow, `n
    ; {
    ;     hWnd := RegExReplace(A_LoopField, "^.*?ahk_id (\S+?)$", "$1")
    ;     WinActivate ahk_id %hWnd%
    ; }
}
FastResizeWindow(hWnd, x, y, w, h, Active := 0, zIndex := 0)
{
    ; 如有必要则还原最大化最小化的窗口
    WinGet, minmax, minmax, ahk_id %hWnd%
    if (minmax != 0) {
        WinRestore, ahk_id %hWnd%
        ; needSetTOPMOST := 1
    }
    ; ref: [SetWindowPos function (winuser.h) - Win32 apps | Microsoft Docs]( https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos )
    HWND_TOPMOST := -1
    HWND_BOTTOM := 1
    HWND_TOP := 0
    HWND_NOTOPMOST := -2
    SWP_NOACTIVATE := 0x0010
    SWP_ASYNCWINDOWPOS:= 0x4000
    SWP_NOZORDER := 0x0004
    SWP_NOMOVE := 0x0002
    SWP_NOSIZE := 0x0001
    ; 先置顶(否则会显示在最大化窗口的后面 -- 被挡住)
    if (Active) {
        WinActivate ahk_id %hWnd%
    }
    if (zIndex) {
        DllCall("SetWindowPos"
        , "UInt", hWnd ; handle
        , "UInt", zIndex ; z-index
        , "Int", x ;  x
        , "Int", y ; y
        , "Int", w ; width
        , "Int", h ; height
        , "UInt", SWP_NOACTIVATE) ; SWP_ASYNCWINDOWPOS
    } else {
        DllCall("SetWindowPos"
        , "UInt", hWnd ;handle
        , "UInt", 0 ; z-index
        , "Int", x
        , "Int", y
        , "Int", w
        , "Int", h
        , "UInt", SWP_NOZORDER | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS) ; SWP_ASYNCWINDOWPOS
    }
}
CurrentWindowSetAsBackground()
{
    ; 后置当前窗口
    WinGet hWnd, id, A
    上次mstsc窗口hWnd := hWnd
    WinSet Bottom, , ahk_id %hWnd%
    ; 激活任务栏,夺走焦点
    WinActivate ahk_class Shell_TrayWnd
}


;当前日期
^;::
d = %A_YYYY%-%A_MM%-%A_DD%
Send %d%
return
;当前日期时间
^+;::
dt = %A_YYYY%-%A_MM%-%A_DD% %A_Hour%:%A_Min%:%A_Sec%
Send %dt%
return

;获取当前系统时间
::ttt::
d = %A_Hour%:%A_Min%:%A_Sec%
clipboard = %d%
Send ^v
return


免费评分

参与人数 2吾爱币 +1 热心值 +2 收起 理由
leskady + 1 + 1 谢谢@Thanks!
congtongzaihui + 1 热心回复!

查看全部评分

推荐
jun269 发表于 2023-1-20 19:50
推荐
anyouxi 发表于 2023-1-20 10:17
4#
bearkr 发表于 2023-1-20 10:11
和Quicker对比如何?!
5#
2911 发表于 2023-1-20 12:06
脚本文件可以直接生成EXE文件,使用起来就方便多了
6#
JDKx 发表于 2023-1-20 13:30
2911 发表于 2023-1-20 12:06
脚本文件可以直接生成EXE文件,使用起来就方便多了

可以的,自带ahk2exe程序
7#
monnpc 发表于 2023-1-20 13:35
类似于按键精灵吧
8#
theBigOne68 发表于 2023-1-20 15:22
相当实用,感谢。
9#
mealted 发表于 2023-1-20 15:30
感谢分享啊
10#
momohei1018 发表于 2023-1-20 18:01
感谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 19:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表