很久以前写的脚本,以下仅供参考
/* ===============百度网盘非标窗口加按钮和拦截控件================ 通过鼠标对窗口相对位置的判断和计算实现自定义功能,也可以添加按钮图标文字等 左上角自定义按钮,点击图标弹出对话框 右上角最大化按钮拦截并改成窗口居中 右上角关闭按钮拦截是为了弥补Class Dock函数,在非标失去窗口显示出错的bug */ #NoEnv #SingleInstance Force SetTitleMatchMode, 2 ;如果不是管理员,就自动切换管理员运行 if not A_IsAdmin Run *RunAs "%A_AhkPath%" /r "%A_ScriptFullPath%" WinWaitActive ahk_class DuiHostWnd ; 首次启动脚本判断,避免取不到ID的bug Loop { CoordMode, Mouse, Screen MouseGetPos, , , 窗口ID WinGetClass, 从任务栏唤起 , ahk_id %窗口ID% if 从任务栏唤起 in Shell_TrayWnd,NotifyIconOverflowWindow { WinActivate ahk_class Shell_TrayWnd WinWaitActive ahk_class DuiHostWnd } else { Break } } Gui重新加载标记: CoordMode, Mouse, Window WinGet, HostHwnd, ID, ahk_id %窗口ID% WinActivate ahk_id %窗口ID% Gui, +hwndClienthwnd +ToolWindow +AlwaysOnTop -SysMenu -Caption ;+E0x08000000 Gui, Color, CCCCCC Gui, Add, Picture,g按钮 x3 y0 w16 h16 +icon1, %A_AhkPath% Gui, Font, c000000 s11 wbold, terminal Gui, Add, Text, xp+20 , 百毒云盘,下载速度100k! Instance := new Dock(Hosthwnd, Clienthwnd) Instance.CloseCallback := Func("CloseCallback") Gui, Show, AutoSize NoActivate h18 w240 WinSet, TransColor, CCCCCC 255, ahk_class AutoHotkeyGUI Instance.Position("Relative 200 26") Return 按钮: MsgBox, 0, 测试, 添加你的代码 WinActivate ahk_id %窗口ID% ; 切回原窗口,避免bug Return #IfWinActive ahk_class DuiHostWnd ; 通过鼠标对窗口相对位置的判断和计算实现自定义功能 LButton:: Click Down IfWinNotActive ahk_class DuiHostWnd { Gui, -AlwaysOnTop ; 取消Gui置顶,避免bug Winset, Top, , A KeyWait LButton Click Up } Return LButton Up:: MouseGetPos, 横坐标, 纵坐标, 窗口ID WinGetPos, , , 窗口宽度, 窗口高度, ahk_id %窗口ID% If (A_ThisHotkey ~= "LButton") { If (横坐标>窗口宽度-50*(A_ScreenDPI/120)) && (横坐标<窗口宽度-28*(A_ScreenDPI/120)) && (纵坐标>27*(A_ScreenDPI/120)) && (纵坐标<51*(A_ScreenDPI/120)) { ; 从右上角计算关闭图标相对位置 Gui, Destroy Sleep 200 Click Up WinWaitActive ahk_class DuiHostWnd ; 按关闭按钮前先销毁外挂图标,再等待原窗口再次唤起 WinActivate ahk_class Shell_TrayWnd Goto, Gui重新加载标记 } Else If (横坐标>窗口宽度-88*(A_ScreenDPI/120)) && (横坐标<窗口宽度-61*(A_ScreenDPI/120)) && (纵坐标>34*(A_ScreenDPI/120)) && (纵坐标<48*(A_ScreenDPI/120)) { ; 从右上角计算最大化图标相对位置,自定义截取示例 WinGetPos,,, 宽度, 高度, ahk_id %窗口ID% WinMove, ahk_id %窗口ID%,, (A_ScreenWidth/2)-(宽度/2), (A_ScreenHeight/2)-(高度/2) WinActivate ahk_id %窗口ID% } Click Up } Click Up Return #IfWinActive Move_TT() { ToolTip Return } ;========== 下面是Class Dock.ahk的类和函数 ========== CloseCallback(self) { WinKill, % "ahk_id " self.hwnd.Client ExitApp } /* Class Dock Attach a window to another Author Soft (visionary1 예지력) version 0.1 (2017.04.20) 0.2 (2017.05.06) 0.2.1 (2017.05.07) 0.2.1.1 bug fixed (2017.05.09) 0.2.2 testing multiple docks... (2017.05.09) 0.2.3 adding relative (2018.12.16) 在WinSetTop(hwnd)里加里一句Gui,+AlwaysOnTop,避免bug (2021.04.02) License WTFPL (http://wtfpl.net/) Dev env Windows 10 pro x64 AutoHotKey H v1.1.25.01 32bit To Do... Multiple Dock, group windows... thanks to Helgef for overall coding advices */ class Dock { static EVENT_OBJECT_LOCATIONCHANGE := 0x800B , EVENT_OBJECT_FOCUS := 0x8005, EVENT_OBJECT_DESTROY := 0x8001 , EVENT_MIN := 0x00000001, EVENT_MAX := 0x7FFFFFFF ;for debug , EVENT_SYSTEM_FOREGROUND := 0x0003 /* Instance := new Dock(Host hwnd, Client hwnd, [Callback], [CloseCallback]) Host hwnd hwnd of a Host window Client hwnd hwnd of a window that follows Host window (window that'll be attached to a Host window) [Callback] a func object, or a bound func object if omitted, default EventsHandler will be used, which is hard-coded in 'Dock.EventsHandler' To construct your own events handler, I advise you to see Dock.EventsHandler first [CloseCallback] a func object, or a bound func object called when Host window is destroyed, see 'Dock Example.ahk' for practical usuage */ __New(Host, Client, Callback := "", CloseCallback := ""){ this.hwnd := [] this.hwnd.Host := Host this.hwnd.Client := Client WinSet, ExStyle, +0x80, % "ahk_id " this.hwnd.Client this.Bound := [] this.Callback := IsObject(Callback) ? Callback : ObjBindMethod(Dock.EventsHandler, "Calls") this.CloseCallback := IsFunc(CloseCallback) || IsObject(CloseCallback) ? CloseCallback this.hookProcAdr := RegisterCallback("_DockHookProcAdr",,, &this) /* idProcess */ ;WinGet, idProcess, PID, % "ahk_id " . this.hwnd.Host idProcess := 0 /* idThread */ ;idThread := DllCall("GetWindowThreadProcessId", "Ptr", this.hwnd.Host, "Int", 0) idThread := 0 DllCall("CoInitialize", "Int", 0) this.Hook := DllCall("SetWinEventHook" , "UInt", Dock.EVENT_SYSTEM_FOREGROUND ;eventMin , "UInt", Dock.EVENT_OBJECT_LOCATIONCHANGE ;eventMax , "Ptr", 0 ;hmodWinEventProc , "Ptr", this.hookProcAdr ;lpfnWinEventProc , "UInt", idProcess ;idProcess , "UInt", idThread ;idThread , "UInt", 0) ;dwFlags } /* Instance.Unhook() unhooks Dock and frees memory */ Unhook(){ DllCall("UnhookWinEvent", "Ptr", this.Hook) DllCall("CoUninitialize") DllCall("GlobalFree", "Ptr", this.hookProcAdr) this.Hook := "" this.hookProcAdr := "" this.Callback := "" WinSet, ExStyle, -0x80, % "ahk_id " this.hwnd.Client } __Delete(){ this.Delete("Bound") If (this.Hook) this.Unhook() this.CloseCallback := "" } /* provisional */ Add(hwnd, pos := ""){ static last_hwnd := 0 this.Bound.Push( new this( !NumGet(&this.Bound, 4*A_PtrSize) ? this.hwnd.Client : last_hwnd, hwnd ) ) If pos Contains Top,Bottom,R,Right,L,Left,Relative this.Bound[NumGet(&this.Bound, 4*A_PtrSize)].Position(pos) last_hwnd := hwnd } /* Instance.Position(pos) pos - sets position to dock client window Top - sets to Top side of the host window Bottom - sets to bottom side of the host window R or Right - right side L or Left - left side */ Position(pos){ this.pos := pos Return this.EventsHandler.EVENT_OBJECT_LOCATIONCHANGE(this, "host") } /* Default EventsHandler */ class EventsHandler extends Dock.HelperFunc { Calls(self, hWinEventHook, event, hwnd){ Critical If (hwnd = self.hwnd.Host){ Return this.Host(self, event) } If (hwnd = self.hwnd.Client){ Return this.Client(self, event) } } Host(self, event){ If (event = Dock.EVENT_SYSTEM_FOREGROUND){ Return this.EVENT_SYSTEM_FOREGROUND(self.hwnd.Client) } If (event = Dock.EVENT_OBJECT_LOCATIONCHANGE){ Return this.EVENT_OBJECT_LOCATIONCHANGE(self, "host") } If (event = Dock.EVENT_OBJECT_DESTROY){ self.Unhook() If (IsFunc(self.CloseCallback) || IsObject(self.CloseCallback)) Return self.CloseCallback() } } Client(self, event){ If (event = Dock.EVENT_SYSTEM_FOREGROUND){ Return this.EVENT_SYSTEM_FOREGROUND(self.hwnd.Host) } If (event = Dock.EVENT_OBJECT_LOCATIONCHANGE){ Return this.EVENT_OBJECT_LOCATIONCHANGE(self, "client") } } /* Called when host window got focus without this, client window can't be showed (can't set to top) */ EVENT_SYSTEM_FOREGROUND(hwnd){ Return this.WinSetTop(hwnd) } /* Called when host window is moved */ EVENT_OBJECT_LOCATIONCHANGE(self, via){ Host := this.WinGetPos(self.hwnd.Host) Client := this.WinGetPos(self.hwnd.Client) If InStr(self.pos, "Relative"){ If (via = "host"){ Return this.MoveWindow(self.hwnd.Client ;hwnd , Host.x + StrSplit(self.pos,A_Space).2 ;x , Host.y + StrSplit(self.pos,A_Space).3 ;y , Client.w ;width , Client.h) ;height } If (via = "client"){ Return this.MoveWindow(self.hwnd.Host ;hwnd , Host.x ;x , Host.y ;y , Host.w ;width , Host.h) ;height } } If InStr(self.pos, "Top"){ If (via = "host"){ Return this.MoveWindow(self.hwnd.Client ;hwnd , Host.x ;x , Host.y - Client.h ;y , Client.w ;width , Client.h) ;height } If (via = "client"){ Return this.MoveWindow(self.hwnd.Host ;hwnd , Client.x ;x , Client.y + Client.h ;y , Host.w ;width , Host.h) ;height } } If InStr(self.pos, "Bottom"){ If (via = "host"){ Return this.MoveWindow(self.hwnd.Client ;hwnd , Host.x ;x , Host.y + Host.h ;y , Client.w ;width , Client.h) ;height } If (via = "client"){ Return this.MoveWindow(self.hwnd.Host ;hwnd , Client.x ;x , Client.y - Host.h ;y , Host.w ;width , Host.h) ;height } } If InStr(self.pos, "R"){ If (via = "host"){ Return this.MoveWindow(self.hwnd.Client ;hwnd , Host.x + Host.w ;x , Host.y ;y , Client.w ;width , Client.h) ;height } If (via = "client"){ Return this.MoveWindow(self.hwnd.Host ;hwnd , Client.x - Host.w ;x , Client.y ;y , Host.w ;width , Host.h) ;height } } If InStr(self.pos, "L"){ If (via = "host"){ Return this.MoveWindow(self.hwnd.Client ;hwnd , Host.x - Client.w ;x , Host.y ;y , Client.w ;width , Client.h) ;height } If (via = "client"){ Return this.MoveWindow(self.hwnd.Host ;hwnd , Client.x + Client.w ;x , Client.y ;y , Host.w ;width , Host.h) ;height } } } } class HelperFunc { WinGetPos(hwnd){ WinGetPos, hX, hY, hW, hH, % "ahk_id " . hwnd Return {x: hX, y: hY, w: hW, h: hH} } WinSetTop(hwnd){ WinSet, AlwaysOnTop, On, % "ahk_id " . hwnd WinSet, AlwaysOnTop, Off, % "ahk_id " . hwnd Gui,+AlwaysOnTop } MoveWindow(hwnd, x, y, w, h){ Return DllCall("MoveWindow", "Ptr", hwnd, "Int", x, "Int", y, "Int", w, "Int", h, "Int", 1) } Run(Target){ Try Run, % Target,,, OutputVarPID Catch, Throw, "Couldn't run " Target WinWait, % "ahk_pid " OutputVarPID Return WinExist("ahk_pid " OutputVarPID) } } } _DockHookProcAdr(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime){ this := Object(A_EventInfo) this.Callback.Call(this, hWinEventHook, event, hwnd) }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)