Я использую такой скрипт для сворачивания любых окон в трей, может вам подойдёт, как есть, или приспособите под свои нужды:
#Requires AutoHotkey v2.0
#NoTrayIcon
hider := HideToTray()
!6:: hider.Hide(WinExist('A'))
!7:: hider.RestoreLast()
!8:: hider.RestoreAll()
class HideToTray
{
; add classes here to exclude from hiding:
excludeClasses := ['Progman', 'WorkerW', 'Shell_TrayWnd', 'ApplicationFrameWindow']
static __New() => SingletonDecorator.ApplyTo(this)
__New() {
this.test := ''
this.exclude := Map()
for winClass in this.excludeClasses {
this.exclude[winClass] := ''
}
this.hiddenWindows := []
this.knownWindows := Map()
this.knownWindows.DefineProp('DeleteIfExists', {call: (s, p) => s.Has(p) && s.Delete(p)})
this.SetHooks()
Loop 2 {
ObjRelease(ObjPtr(this))
}
}
; public methods
Hide(hWnd) {
if !this.exclude.Has(WinGetClass(hWnd)) {
this.stopHook := true
this.hiddenWindows.Push(HideToTray.HiddenWindow(hWnd))
this.knownWindows[hWnd] := ''
this.stopHook := false
}
}
RestoreAll() => (this.stopHook := true, this.hiddenWindows := [], this.stopHook := false)
RestoreLast() => this.hiddenWindows.Has(1) && this.hiddenWindows.Pop()
; private methods
SetHooks() {
static EVENT_SYSTEM_MINIMIZESTART := 0x0016
, EVENT_SYSTEM_MINIMIZEEND := 0x0017
, EVENT_OBJECT_DESTROY := 0x8001
, OBJID_WINDOW := 0
this.HasOwnProp('stopHook') || (
this.stopHook := false,
OnMessage(0x404, this.OnNotify := ObjBindMethod(this, 'AHK_NOTIFYICON')),
this.destroyHook := WinEventHook(EVENT_OBJECT_DESTROY , EVENT_OBJECT_DESTROY , HookProc),
this.minHook := WinEventHook(EVENT_SYSTEM_MINIMIZESTART, EVENT_SYSTEM_MINIMIZEEND, HookProc)
)
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
if idObject = OBJID_WINDOW && !this.stopHook {
switch event {
case EVENT_OBJECT_DESTROY : this.knownWindows.DeleteIfExists(hwnd), this.UnHide(hwnd)
case EVENT_SYSTEM_MINIMIZESTART : this.knownWindows.Has(hwnd) && this.Hide(hwnd)
case EVENT_SYSTEM_MINIMIZEEND : this.UnHide(hwnd)
}
}
}
}
UnHide(hWnd) {
try for i, wnd in this.hiddenWindows {
continue
} until wnd.hwnd = hwnd && this.hiddenWindows.RemoveAt(i)
}
AHK_NOTIFYICON(wp, lp, msg, hwnd) {
static WM_LBUTTONDOWN := 0x201, WM_RBUTTONUP := 0x205
, iconID := 0x404, iconMsg := 0x404, maxLenMenuStr := 40
if !(lp = WM_LBUTTONDOWN || lp = WM_RBUTTONUP) {
return
}
for i, wnd in this.hiddenWindows {
if wnd.icon.wnd.hwnd = hwnd {
switch lp {
case WM_RBUTTONUP: ShowMenu(i)
case WM_LBUTTONDOWN: this.hiddenWindows.RemoveAt(i)
}
break
}
}
ShowMenu(idx) {
title := this.hiddenWindows[idx].title
b := StrLen(title) > maxLenMenuStr
menuText := 'Restore «' . SubStr(title, 1, maxLenMenuStr) . (b ? '...' : '') . '»'
iconMenu := Menu()
iconMenu.Add(menuText, (*) => this.AHK_NOTIFYICON(iconID, WM_LBUTTONDOWN, iconMsg, hwnd))
iconMenu.SetIcon(menuText, 'HICON:*' . this.hiddenWindows[idx].icon.hIcon)
iconMenu.Add('Restore all windows', (*) => this.RestoreAll())
iconMenu.Show()
iconMenu.Delete()
}
}
__Delete() {
Loop 2 {
ObjAddRef(ObjPtr(this))
}
this.DeleteProp('minHook')
this.DeleteProp('destroyHook')
OnMessage(0x404, this.OnNotify, 0)
this.RestoreAll()
}
class HiddenWindow {
__New(hWnd) {
this.title := WinGetTitle(hWnd)
this.icon := TrayIcon(this.GetWindowIcon(hWnd), this.title)
WinMinimize(hWnd), WinHide(hWnd)
this.hwnd := hWnd
}
__Delete() {
try WinExist(this.hwnd) && (WinShow(), WinRestore(), WinActivate())
}
GetWindowIcon(hWnd) {
static WM_GETICON := 0x007F, ICON_SMALL := 0, GCLP_HICONSM := -34
, GetClassLong := 'GetClassLong' . (A_PtrSize = 4 ? '' : 'Ptr')
((hIcon := SendMessage(WM_GETICON, ICON_SMALL, A_ScreenDPI, , hWnd))
|| (hIcon := DllCall(GetClassLong, 'Ptr', hWnd, 'Int', GCLP_HICONSM, 'Ptr'))
|| (hIcon := LoadPicture('Shell32', 'Icon3', &IMAGE_ICON := 1)))
return hIcon
}
}
}
class TrayIcon
{
NIF_MESSAGE := 1, NIF_ICON := 2, NIF_TIP := 4
NIM_ADD := 0, NIM_DELETE := 2
iconID := 0x404, iconMsg := 0x404
__New(hIcon, tip?) {
flags := this.NIF_MESSAGE | this.NIF_ICON | (IsSet(tip) ? this.NIF_TIP : 0)
this.wnd := Gui(), this.hIcon := hIcon
this.NOTIFYICONDATA := Buffer(396, 0)
NumPut(
'Ptr' , this.NOTIFYICONDATA.size,
'Ptr' , this.wnd.hwnd,
'UInt', this.iconID,
'UInt', flags,
'Ptr' , this.iconMsg,
'Ptr' , hIcon, this.NOTIFYICONDATA
)
if IsSet(tip) {
StrPut(tip, this.NOTIFYICONDATA.ptr + 4 * A_PtrSize + 8, 'CP0')
}
DllCall('Shell32\Shell_NotifyIcon', 'UInt', this.NIM_ADD, 'Ptr', this.NOTIFYICONDATA)
}
__Delete() {
DllCall('Shell32\Shell_NotifyIcon', 'UInt', this.NIM_DELETE, 'Ptr', this.NOTIFYICONDATA)
this.wnd.Destroy()
}
}
class WinEventHook
{
; Event Constants: https://is.gd/tRT5Wr
__New(eventMin, eventMax, hookProc, options := '', idProcess := 0, idThread := 0, dwFlags := 0) {
this.callback := CallbackCreate(hookProc, options, 7)
this.hHook := DllCall('SetWinEventHook', 'UInt', eventMin, 'UInt', eventMax, 'Ptr', 0, 'Ptr', this.callback
, 'UInt', idProcess, 'UInt', idThread, 'UInt', dwFlags, 'Ptr')
}
__Delete() {
DllCall('UnhookWinEvent', 'Ptr', this.hHook)
CallbackFree(this.callback)
}
}
class SingletonDecorator
{
static ApplyTo(targetClass) {
proto := targetClass.Prototype
origCall := targetClass.GetMethod('Call')
origNew := proto.HasMethod('__New') ? proto.GetMethod('__New') : ''
origDel := proto.HasMethod('__Delete') ? proto.GetMethod('__Delete') : ''
targetClass.DefineProp('Call', {Call: (cls, p*) => cls.HasProp('singleton') ? cls.singleton : origCall(cls, p*)})
proto.DefineProp('__New', {Call: (inst, p*) => (
(origNew && origNew(inst, p*)),
targetClass.singleton := inst,
ObjRelease(ObjPtr(inst))
)})
proto.DefineProp('__Delete', {Call: inst => (
ObjAddRef(ObjPtr(inst)),
(origDel && origDel(inst)),
targetClass.DeleteProp('singleton')
)})
}
}