自动化脚本 AutoHotkey v2.0.2

文章正文
发布时间:2025-12-14 09:49

[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