<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: аналог altTab для окон определенной программы]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=16202</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=16202&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: аналог altTab для окон определенной программы».]]></description>
		<lastBuildDate>Sun, 01 Sep 2024 12:11:31 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=161547#p161547</link>
			<description><![CDATA[<div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>Без недокументированных функций я так и не обнаружил возможность определить из-за чего наложен cloak shell - из-за того, что окно бекграундное/системное или из-за того, что оно находится на другом виртуальном дисплее.</p></blockquote></div><p>Поправил с помощью GetWindowDesktopId().<br />Особо не тестировал, но так должно возвращать список окон в alt-tab, используя только документированное апи.<br /></p><div class="codebox"><pre><code>DetectHiddenWindows On
arr := EnumerateAltTabWindows()
for k, v in arr
{
   WinGetClass, winClass, ahk_id %v%
   WinGetTitle, title, ahk_id %v%
   altTabWindows .= A_Index &quot;`nTitle: &quot; title &quot;`nClass: &quot; winClass &quot;`nhWnd: &quot; v &quot;`nLastActivePopup: &quot; format(&quot;0x{:x}&quot;, GetLastActivePopup(v)) &quot;`n`n&quot;
}
MsgBox, % altTabWindows


EnumerateAltTabWindows()
{
   AltTabList := []
   WinGet, list, List
   Loop % list
   {
      if IsAltTabWindow(list%A_Index%)
         AltTabList.Push(list%A_Index%)
   }
   Return AltTabList
}

IsAltTabWindow(hWnd)
{
   static WS_EX_APPWINDOW := 0x40000, WS_EX_TOOLWINDOW := 0x80, DWMWA_CLOAKED := 14, DWM_CLOAKED_SHELL := 2, WS_EX_NOACTIVATE := 0x8000000, GA_PARENT := 1, GW_OWNER := 4, MONITOR_DEFAULTTONULL := 0, VirtualDesktopAltTabFilter := &quot;null&quot;, VirtualDesktopExist, PropEnumProcEx := RegisterCallback(&quot;PropEnumProcEx&quot;, &quot;Fast&quot;, 4)
   if (VirtualDesktopAltTabFilter = &quot;null&quot;)
   {
      RegRead, VirtualDesktopAltTabFilter, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, VirtualDesktopAltTabFilter
      OSbuildNumber := StrSplit(A_OSVersion, &quot;.&quot;)[3]
      if (OSbuildNumber &lt; 14393)
         VirtualDesktopExist := 0
      else
         VirtualDesktopExist := 1
   }
   if !DllCall(&quot;IsWindowVisible&quot;, &quot;uptr&quot;, hWnd)
      return
   DllCall(&quot;DwmApi\DwmGetWindowAttribute&quot;, &quot;uptr&quot;, hWnd, &quot;uint&quot;, DWMWA_CLOAKED, &quot;uint*&quot;, cloaked, &quot;uint&quot;, 4)
   if (cloaked = DWM_CLOAKED_SHELL) and (!VirtualDesktopExist or IsWindowOnCurrentVirtualDesktop(hWnd) or !GetWindowDesktopId(hWnd))
      return
   if (realHwnd(DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_PARENT, &quot;ptr&quot;)) != realHwnd(DllCall(&quot;GetDesktopWindow&quot;, &quot;ptr&quot;)))
      return
   WinGetClass, winClass, ahk_id %hWnd%
   if (winClass = &quot;Windows.UI.Core.CoreWindow&quot;)
      return
   if (winClass = &quot;ApplicationFrameWindow&quot;)
   {
      varsetcapacity(ApplicationViewCloakType, 4, 0)
      DllCall(&quot;EnumPropsEx&quot;, &quot;uptr&quot;, hWnd, &quot;ptr&quot;, PropEnumProcEx, &quot;ptr&quot;, &amp;ApplicationViewCloakType)
      if (numget(ApplicationViewCloakType, 0, &quot;int&quot;) = 1)   ; https://github.com/kvakulo/Switcheroo/commit/fa526606d52d5ba066ba0b2b5aa83ed04741390f
         return
   }
   ; if !DllCall(&quot;MonitorFromWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, MONITOR_DEFAULTTONULL, &quot;ptr&quot;)   ; test if window is shown on any monitor. alt-tab shows any window even if window is out of monitor.
   ;   return
   WinGet, exStyles, ExStyle, ahk_id %hWnd%
   if (exStyles &amp; WS_EX_APPWINDOW)
   {
      if DllCall(&quot;GetProp&quot;, &quot;uptr&quot;, hWnd, &quot;str&quot;, &quot;ITaskList_Deleted&quot;, &quot;ptr&quot;)
         return
      if !VirtualDesktopExist or (VirtualDesktopAltTabFilter = 0) or IsWindowOnCurrentVirtualDesktop(hwnd)
         return true
      else
         return
   }
   if (exStyles &amp; WS_EX_TOOLWINDOW) or (exStyles &amp; WS_EX_NOACTIVATE)
      return
   loop
   {
      hwndPrev := hwnd
      hwnd := DllCall(&quot;GetWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GW_OWNER, &quot;ptr&quot;)
      if !hwnd
      {
         if DllCall(&quot;GetProp&quot;, &quot;uptr&quot;, hwndPrev, &quot;str&quot;, &quot;ITaskList_Deleted&quot;, &quot;ptr&quot;)
            return
         if !VirtualDesktopExist or (VirtualDesktopAltTabFilter = 0) or IsWindowOnCurrentVirtualDesktop(hwndPrev)
            return true
         else
            return
      }
      if DllCall(&quot;IsWindowVisible&quot;, &quot;uptr&quot;, hwnd)
         return
      WinGet, exStyles, ExStyle, ahk_id %hwnd%
      if ((exStyles &amp; WS_EX_TOOLWINDOW) or (exStyles &amp; WS_EX_NOACTIVATE)) and !(exStyles &amp; WS_EX_APPWINDOW)
         return
   }
}

GetLastActivePopup(hwnd)
{
   static GA_ROOTOWNER := 3
   hwnd := DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_ROOTOWNER, &quot;ptr&quot;)
   hwnd := DllCall(&quot;GetLastActivePopup&quot;, &quot;uptr&quot;, hwnd, &quot;ptr&quot;)
   return hwnd
}

IsWindowOnCurrentVirtualDesktop(hwnd)
{
   static IVirtualDesktopManager
   if !IVirtualDesktopManager
      IVirtualDesktopManager := ComObjCreate(CLSID_VirtualDesktopManager := &quot;{AA509086-5CA9-4C25-8F95-589D3C07B48A}&quot;, IID_IVirtualDesktopManager := &quot;{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}&quot;)
   DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 3*A_PtrSize), &quot;ptr&quot;, IVirtualDesktopManager, &quot;uptr&quot;, hwnd, &quot;int*&quot;, onCurrentDesktop)   ; IsWindowOnCurrentVirtualDesktop
   return onCurrentDesktop
}

GetWindowDesktopId(hwnd)
{
   static IVirtualDesktopManager, Guid_Empty
   if !IVirtualDesktopManager
   {
      IVirtualDesktopManager := ComObjCreate(CLSID_VirtualDesktopManager := &quot;{AA509086-5CA9-4C25-8F95-589D3C07B48A}&quot;, IID_IVirtualDesktopManager := &quot;{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}&quot;)
      VarSetCapacity(Guid_Empty, 16)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, &quot;{00000000-0000-0000-0000-000000000000}&quot;, &quot;ptr&quot;, &amp;Guid_Empty)
   }
   VarSetCapacity(desktopId, 16, 0)
   hr := DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 4*A_PtrSize), &quot;ptr&quot;, IVirtualDesktopManager, &quot;uptr&quot;, hwnd, &quot;ptr&quot;, &amp;desktopID)   ; GetWindowDesktopId
   if (hr != 0)   ; Unknown
      return
   if DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;ptr&quot;, &amp;desktopId, &quot;ptr&quot;, &amp;Guid_Empty)   ; Not Assigned
      return
   return true
}

PropEnumProcEx(hWnd, lpszString, hData, dwData)
{
   if (strget(lpszString, &quot;UTF-16&quot;) = &quot;ApplicationViewCloakType&quot;)
   {
      numput(hData, dwData+0, 0, &quot;int&quot;)
      return false
   }
   return true
}

realHwnd(hwnd)
{
   varsetcapacity(var, 8, 0)
   numput(hwnd, var, 0, &quot;uint64&quot;)
   return numget(var, 0, &quot;uint&quot;)
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Sun, 01 Sep 2024 12:11:31 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=161547#p161547</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=161464#p161464</link>
			<description><![CDATA[<p>Спасибо, забыл про неё, стало лучше! <br />С winapi пробовал варианты, намного хуже получалось.<br />И не подумал что зачем то может быть нужна тут задержка, ещё и по умолчанию.)</p>]]></description>
			<author><![CDATA[null@example.com (serzh82saratov)]]></author>
			<pubDate>Thu, 22 Aug 2024 14:26:13 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=161464#p161464</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=161463#p161463</link>
			<description><![CDATA[<p>Setwindelay?</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Thu, 22 Aug 2024 13:53:11 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=161463#p161463</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=161462#p161462</link>
			<description><![CDATA[<div class="quotebox"><cite>serzh82saratov пишет:</cite><blockquote><p>Судя по первым тестам работает как надо. Проходит список окон программы в соответствии использования.</p></blockquote></div><p>Кто нибудь пробовал? Как то немного долго окна активируются, не знаю как лечить.</p>]]></description>
			<author><![CDATA[null@example.com (serzh82saratov)]]></author>
			<pubDate>Thu, 22 Aug 2024 13:46:58 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=161462#p161462</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=161449#p161449</link>
			<description><![CDATA[<div class="quotebox"><cite>serzh82saratov пишет:</cite><blockquote><p>Взял твою IsAltTabWindow, не знаю вроде и без неё работает также</p></blockquote></div><p>IsAltTabWindow нужна.</p>]]></description>
			<author><![CDATA[null@example.com (serzh82saratov)]]></author>
			<pubDate>Tue, 20 Aug 2024 08:35:51 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=161449#p161449</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=161447#p161447</link>
			<description><![CDATA[<div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>С этим</p></blockquote></div><p>У меня оба кода обновляют порядок использования окон, только после перезагрузки скрипта. #62.</p><br /><p>Взял твою IsAltTabWindow, не знаю вроде и без неё работает также, на всякий случай пока.<br />Судя по первым тестам работает как надо. Проходит список окон программы в соответствии использования.</p><div class="codebox"><pre><code>
1::ParseAltTab(&quot;Prev&quot;)
2::ParseAltTab(&quot;Next&quot;)
3::PrevAltTab()

ParseAltTab(dir) {  
	AltTabList := []
	source := WinExist(&quot;A&quot;)
	WinGetClass, sClass, ahk_id %source%
	WinGet, sProcess, ProcessName, ahk_id %source% 
	Winget, List, List, ahk_class %sClass% ahk_exe %sProcess%
	Loop % List
	{  
		hwnd := List%A_Index%   
		If (IsAltTabWindow(hWnd) &amp;&amp; source != hwnd) {
			AltTabList.Push(hwnd)   
		}
	}  
	If (dir = &quot;Prev&quot;)  { 
		hwnd := AltTabList[1]    
	} Else  { 
		hwnd := AltTabList[AltTabList.Count()] 
	}
	WinShow ahk_id %hwnd%
	WinActivate ahk_id %hwnd%  
	If (AltTabList.Count() &gt; 1)
		; https://learn.microsoft.com/ru-ru/windows/win32/api/winuser/nf-winuser-setwindowpos
		DllCall(&quot;SetWindowPos&quot;, &quot;Ptr&quot;, source, &quot;Ptr&quot;, AltTabList[AltTabList.Count()]
			, &quot;Int&quot;, 0, &quot;Int&quot;, 0, &quot;Int&quot;, 0, &quot;Int&quot;, 0, &quot;UInt&quot;, 0x0002|0x0001|0x0010)   
}

PrevAltTab() {   
	source := WinExist(&quot;A&quot;)
	WinGetClass, sClass, ahk_id %source%
	WinGet, sProcess, ProcessName, ahk_id %source% 
	Winget, List, List, ahk_class %sClass% ahk_exe %sProcess%
	Loop % List
	{  
		hwnd := % List%A_Index%   
		If (IsAltTabWindow(hWnd) &amp;&amp; source != hwnd) {  
			WinShow ahk_id %hwnd%
			WinActivate ahk_id %hwnd% 
			Break
		} 
	} 
}
Return
4::

; MouseGetPos
source := WinExist(&quot;A&quot;)
DetectHiddenWindows On
arr := EnumerateAltTabWindows()
for k, v in arr
{
   WinGetClass, winClass, ahk_id %v%
   WinGetTitle, title, ahk_id %v%
   altTabWindows .= A_Index &quot;`nTitle: &quot; title &quot;`nClass: &quot; winClass &quot;`nhWnd: &quot; v &quot;`nLastActivePopup: &quot; format(&quot;0x{:x}&quot;, GetLastActivePopup(v)) &quot;`n`n&quot;
}
MsgBox, % altTabWindows
Return

EnumerateAltTabWindows()
{
   AltTabList := []
   WinGet, list, List
   Loop % list
   {
      if IsAltTabWindow(list%A_Index%)
         AltTabList.Push(list%A_Index%)
   }
   Return AltTabList
}

IsAltTabWindow(hWnd)
{
   static WS_EX_APPWINDOW := 0x40000, WS_EX_TOOLWINDOW := 0x80, DWMWA_CLOAKED := 14, DWM_CLOAKED_SHELL := 2, WS_EX_NOACTIVATE := 0x8000000, GA_PARENT := 1, GW_OWNER := 4, MONITOR_DEFAULTTONULL := 0, VirtualDesktopExist, PropEnumProcEx := RegisterCallback(&quot;PropEnumProcEx&quot;, &quot;Fast&quot;, 4)
   if (VirtualDesktopExist = &quot;&quot;)
   {
      OSbuildNumber := StrSplit(A_OSVersion, &quot;.&quot;)[3]
      if (OSbuildNumber &lt; 14393)
         VirtualDesktopExist := 0
      else
         VirtualDesktopExist := 1
   }
   if !DllCall(&quot;IsWindowVisible&quot;, &quot;uptr&quot;, hWnd)
      return
   DllCall(&quot;DwmApi\DwmGetWindowAttribute&quot;, &quot;uptr&quot;, hWnd, &quot;uint&quot;, DWMWA_CLOAKED, &quot;uint*&quot;, cloaked, &quot;uint&quot;, 4)
   if (cloaked = DWM_CLOAKED_SHELL)
      return
   if (realHwnd(DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_PARENT, &quot;ptr&quot;)) != realHwnd(DllCall(&quot;GetDesktopWindow&quot;, &quot;ptr&quot;)))
      return
   WinGetClass, winClass, ahk_id %hWnd%
   if (winClass = &quot;Windows.UI.Core.CoreWindow&quot;)
      return
   if (winClass = &quot;ApplicationFrameWindow&quot;)
   {
      varsetcapacity(ApplicationViewCloakType, 4, 0)
      DllCall(&quot;EnumPropsEx&quot;, &quot;uptr&quot;, hWnd, &quot;ptr&quot;, PropEnumProcEx, &quot;ptr&quot;, &amp;ApplicationViewCloakType)
      if (numget(ApplicationViewCloakType, 0, &quot;int&quot;) = 1)   ; https://github.com/kvakulo/Switcheroo/commit/fa526606d52d5ba066ba0b2b5aa83ed04741390f
         return
   }
   ; if !DllCall(&quot;MonitorFromWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, MONITOR_DEFAULTTONULL, &quot;ptr&quot;)   ; test if window is shown on any monitor. alt-tab shows any window even if window is out of monitor.
   ;   return
   WinGet, exStyles, ExStyle, ahk_id %hWnd%
   if (exStyles &amp; WS_EX_APPWINDOW)
   {
      if DllCall(&quot;GetProp&quot;, &quot;uptr&quot;, hWnd, &quot;str&quot;, &quot;ITaskList_Deleted&quot;, &quot;ptr&quot;)
         return
      if (VirtualDesktopExist = 0) or IsWindowOnCurrentVirtualDesktop(hwnd)
         return true
      else
         return
   }
   if (exStyles &amp; WS_EX_TOOLWINDOW) or (exStyles &amp; WS_EX_NOACTIVATE)
      return
   loop
   {
      hwndPrev := hwnd
      hwnd := DllCall(&quot;GetWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GW_OWNER, &quot;ptr&quot;)
      if !hwnd
      {
         if DllCall(&quot;GetProp&quot;, &quot;uptr&quot;, hwndPrev, &quot;str&quot;, &quot;ITaskList_Deleted&quot;, &quot;ptr&quot;)
            return
         if (VirtualDesktopExist = 0) or IsWindowOnCurrentVirtualDesktop(hwndPrev)
            return true
         else
            return
      }
      if DllCall(&quot;IsWindowVisible&quot;, &quot;uptr&quot;, hwnd)
         return
      WinGet, exStyles, ExStyle, ahk_id %hwnd%
      if ((exStyles &amp; WS_EX_TOOLWINDOW) or (exStyles &amp; WS_EX_NOACTIVATE)) and !(exStyles &amp; WS_EX_APPWINDOW)
         return
   }
}

GetLastActivePopup(hwnd)
{
   static GA_ROOTOWNER := 3
   hwnd := DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_ROOTOWNER, &quot;ptr&quot;)
   hwnd := DllCall(&quot;GetLastActivePopup&quot;, &quot;uptr&quot;, hwnd, &quot;ptr&quot;)
   return hwnd
}

IsWindowOnCurrentVirtualDesktop(hwnd)
{
   static IVirtualDesktopManager
   if !IVirtualDesktopManager
      IVirtualDesktopManager := ComObjCreate(CLSID_VirtualDesktopManager := &quot;{AA509086-5CA9-4C25-8F95-589D3C07B48A}&quot;, IID_IVirtualDesktopManager := &quot;{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}&quot;)
   DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 3*A_PtrSize), &quot;ptr&quot;, IVirtualDesktopManager, &quot;uptr&quot;, hwnd, &quot;int*&quot;, onCurrentDesktop)   ; IsWindowOnCurrentVirtualDesktop
   return onCurrentDesktop
}

PropEnumProcEx(hWnd, lpszString, hData, dwData)
{
   if (strget(lpszString, &quot;UTF-16&quot;) = &quot;ApplicationViewCloakType&quot;)
   {
      numput(hData, dwData+0, 0, &quot;int&quot;)
      return false
   }
   return true
}

realHwnd(hwnd)
{
   varsetcapacity(var, 8, 0)
   numput(hwnd, var, 0, &quot;uint64&quot;)
   return numget(var, 0, &quot;uint&quot;)
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (serzh82saratov)]]></author>
			<pubDate>Tue, 20 Aug 2024 06:42:07 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=161447#p161447</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159366#p159366</link>
			<description><![CDATA[<p>Поправил. Без недокументированных функций я так и не обнаружил возможность определить из-за чего наложен cloak shell - из-за того, что окно бекграундное/системное или из-за того, что оно находится на другом виртуальном дисплее.</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Tue, 17 Oct 2023 01:06:19 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159366#p159366</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159365#p159365</link>
			<description><![CDATA[<p>Только в таком варианте до того, как выдаст сообщение &quot;Your %A_OSVersion% can not handle virtual desktops&quot;, выскочит ошибка из строки<br /></p><div class="codebox"><pre><code>static IVirtualDesktopManager := ComObjCreate ...</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Mon, 16 Oct 2023 22:39:53 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159365#p159365</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159364#p159364</link>
			<description><![CDATA[<p>С этим апи также приходится использовать исключения.<br /></p><div class="codebox"><pre><code>DetectHiddenWindows On
arr := EnumerateAltTabWindows()
for k, v in arr
{
   WinGetClass, winClass, ahk_id %v%
   WinGetTitle, title, ahk_id %v%
   altTabWindows .= A_Index &quot;`nTitle: &quot; title &quot;`nClass: &quot; winClass &quot;`nhWnd: &quot; v &quot;`nLastActivePopup: &quot; format(&quot;0x{:x}&quot;, GetLastActivePopup(v)) &quot;`n`n&quot;
}
MsgBox, % altTabWindows


EnumerateAltTabWindows()
{
   AltTabList := []
   WinGet, list, List
   Loop % list
   {
      if IsAltTabWindow(list%A_Index%)
         AltTabList.Push(list%A_Index%)
   }
   Return AltTabList
}

IsAltTabWindow(hwnd)
{
   static ImmersiveShell, IApplicationViewCollection, MONITOR_DEFAULTTONULL := 0, VirtualDesktopAltTabFilter := &quot;null&quot;, PropEnumProcEx := RegisterCallback(&quot;PropEnumProcEx&quot;, &quot;Fast&quot;, 4)
   if (VirtualDesktopAltTabFilter = &quot;null&quot;)
   {
      RegRead, VirtualDesktopAltTabFilter, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, VirtualDesktopAltTabFilter
      OSbuildNumber := StrSplit(A_OSVersion, &quot;.&quot;)[3]
      if (OSbuildNumber &lt; 14393)
      {
         msgbox Your %A_OSVersion% can not handle virtual desktops
         exitapp
      }
      else if (OSbuildNumber &lt;= 17134)   ; Windows 10 1607 to 1803 and Windows Server 2016
         IID_IApplicationViewCollection := &quot;{2C08ADF0-A386-4B35-9250-0FE183476FCC}&quot;
      else
         IID_IApplicationViewCollection := &quot;{1841C6D7-4F9D-42C0-AF41-8747538F10E5}&quot;
      if !(ImmersiveShell := ComObjCreate(CLSID_ImmersiveShell := &quot;{C2F03A33-21F5-47FA-B4BB-156362A2F239}&quot;, IID_IUnknown := &quot;{00000000-0000-0000-C000-000000000046}&quot;))
      {
         MsgBox ImmersiveShell not supported.
         ExitApp
      }
      if !(IApplicationViewCollection := ComObjQuery(ImmersiveShell, IID_IApplicationViewCollection, IID_IApplicationViewCollection))
      {
         MsgBox IApplicationViewCollection interface not supported.
         ExitApp	
      }
   }
   WinGetClass, winClass, ahk_id %hWnd%
   if (winClass = &quot;Windows.UI.Core.CoreWindow&quot;)
      return
   if (winClass = &quot;ApplicationFrameWindow&quot;)
   {
      varsetcapacity(ApplicationViewCloakType, 4, 0)
      DllCall(&quot;EnumPropsEx&quot;, &quot;uptr&quot;, hWnd, &quot;ptr&quot;, PropEnumProcEx, &quot;ptr&quot;, &amp;ApplicationViewCloakType)
      if (numget(ApplicationViewCloakType, 0, &quot;int&quot;) = 1)   ; https://github.com/kvakulo/Switcheroo/commit/fa526606d52d5ba066ba0b2b5aa83ed04741390f
         return
   }
   ; if !DllCall(&quot;MonitorFromWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, MONITOR_DEFAULTTONULL, &quot;ptr&quot;)   ; test if window is shown on any monitor. alt-tab shows any window even if window is out of monitor.
   ;   return
   DllCall(NumGet(NumGet(IApplicationViewCollection+0)+6*A_PtrSize), &quot;ptr&quot;, IApplicationViewCollection, &quot;uptr&quot;, hwnd, &quot;ptr*&quot;, pView)   ; GetViewForHwnd
   if pView
   {
      DllCall(NumGet(NumGet(pView+0)+27*A_PtrSize), &quot;ptr&quot;, pView, &quot;int*&quot;, ShowInSwitchers)   ; GetShowInSwitchers
      ObjRelease(pView)
   }
   if ShowInSwitchers and ((VirtualDesktopAltTabFilter = 0) or IsWindowOnCurrentVirtualDesktop(hwnd))
      return true
   return
}

GetLastActivePopup(hwnd)
{
   static GA_ROOTOWNER := 3
   hwnd := DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_ROOTOWNER, &quot;ptr&quot;)
   hwnd := DllCall(&quot;GetLastActivePopup&quot;, &quot;uptr&quot;, hwnd, &quot;ptr&quot;)
   return hwnd
}

IsWindowOnCurrentVirtualDesktop(hwnd)
{
   static IVirtualDesktopManager
   if !IVirtualDesktopManager
      IVirtualDesktopManager := ComObjCreate(CLSID_VirtualDesktopManager := &quot;{AA509086-5CA9-4C25-8F95-589D3C07B48A}&quot;, IID_IVirtualDesktopManager := &quot;{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}&quot;)
   DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 3*A_PtrSize), &quot;ptr&quot;, IVirtualDesktopManager, &quot;uptr&quot;, hwnd, &quot;int*&quot;, onCurrentDesktop)   ; IsWindowOnCurrentVirtualDesktop
   return onCurrentDesktop
}

PropEnumProcEx(hWnd, lpszString, hData, dwData)
{
   if (strget(lpszString, &quot;UTF-16&quot;) = &quot;ApplicationViewCloakType&quot;)
   {
      numput(hData, dwData+0, 0, &quot;int&quot;)
      return false
   }
   return true
}</code></pre></div><p>Вариант без использования недокументированных функций (получаем окна только на активном virtual display):<br /></p><div class="codebox"><pre><code>DetectHiddenWindows On
arr := EnumerateAltTabWindows()
for k, v in arr
{
   WinGetClass, winClass, ahk_id %v%
   WinGetTitle, title, ahk_id %v%
   altTabWindows .= A_Index &quot;`nTitle: &quot; title &quot;`nClass: &quot; winClass &quot;`nhWnd: &quot; v &quot;`nLastActivePopup: &quot; format(&quot;0x{:x}&quot;, GetLastActivePopup(v)) &quot;`n`n&quot;
}
MsgBox, % altTabWindows


EnumerateAltTabWindows()
{
   AltTabList := []
   WinGet, list, List
   Loop % list
   {
      if IsAltTabWindow(list%A_Index%)
         AltTabList.Push(list%A_Index%)
   }
   Return AltTabList
}

IsAltTabWindow(hWnd)
{
   static WS_EX_APPWINDOW := 0x40000, WS_EX_TOOLWINDOW := 0x80, DWMWA_CLOAKED := 14, DWM_CLOAKED_SHELL := 2, WS_EX_NOACTIVATE := 0x8000000, GA_PARENT := 1, GW_OWNER := 4, MONITOR_DEFAULTTONULL := 0, VirtualDesktopExist, PropEnumProcEx := RegisterCallback(&quot;PropEnumProcEx&quot;, &quot;Fast&quot;, 4)
   if (VirtualDesktopExist = &quot;&quot;)
   {
      OSbuildNumber := StrSplit(A_OSVersion, &quot;.&quot;)[3]
      if (OSbuildNumber &lt; 14393)
         VirtualDesktopExist := 0
      else
         VirtualDesktopExist := 1
   }
   if !DllCall(&quot;IsWindowVisible&quot;, &quot;uptr&quot;, hWnd)
      return
   DllCall(&quot;DwmApi\DwmGetWindowAttribute&quot;, &quot;uptr&quot;, hWnd, &quot;uint&quot;, DWMWA_CLOAKED, &quot;uint*&quot;, cloaked, &quot;uint&quot;, 4)
   if (cloaked = DWM_CLOAKED_SHELL)
      return
   if (realHwnd(DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_PARENT, &quot;ptr&quot;)) != realHwnd(DllCall(&quot;GetDesktopWindow&quot;, &quot;ptr&quot;)))
      return
   WinGetClass, winClass, ahk_id %hWnd%
   if (winClass = &quot;Windows.UI.Core.CoreWindow&quot;)
      return
   if (winClass = &quot;ApplicationFrameWindow&quot;)
   {
      varsetcapacity(ApplicationViewCloakType, 4, 0)
      DllCall(&quot;EnumPropsEx&quot;, &quot;uptr&quot;, hWnd, &quot;ptr&quot;, PropEnumProcEx, &quot;ptr&quot;, &amp;ApplicationViewCloakType)
      if (numget(ApplicationViewCloakType, 0, &quot;int&quot;) = 1)   ; https://github.com/kvakulo/Switcheroo/commit/fa526606d52d5ba066ba0b2b5aa83ed04741390f
         return
   }
   ; if !DllCall(&quot;MonitorFromWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, MONITOR_DEFAULTTONULL, &quot;ptr&quot;)   ; test if window is shown on any monitor. alt-tab shows any window even if window is out of monitor.
   ;   return
   WinGet, exStyles, ExStyle, ahk_id %hWnd%
   if (exStyles &amp; WS_EX_APPWINDOW)
   {
      if DllCall(&quot;GetProp&quot;, &quot;uptr&quot;, hWnd, &quot;str&quot;, &quot;ITaskList_Deleted&quot;, &quot;ptr&quot;)
         return
      if (VirtualDesktopExist = 0) or IsWindowOnCurrentVirtualDesktop(hwnd)
         return true
      else
         return
   }
   if (exStyles &amp; WS_EX_TOOLWINDOW) or (exStyles &amp; WS_EX_NOACTIVATE)
      return
   loop
   {
      hwndPrev := hwnd
      hwnd := DllCall(&quot;GetWindow&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GW_OWNER, &quot;ptr&quot;)
      if !hwnd
      {
         if DllCall(&quot;GetProp&quot;, &quot;uptr&quot;, hwndPrev, &quot;str&quot;, &quot;ITaskList_Deleted&quot;, &quot;ptr&quot;)
            return
         if (VirtualDesktopExist = 0) or IsWindowOnCurrentVirtualDesktop(hwndPrev)
            return true
         else
            return
      }
      if DllCall(&quot;IsWindowVisible&quot;, &quot;uptr&quot;, hwnd)
         return
      WinGet, exStyles, ExStyle, ahk_id %hwnd%
      if ((exStyles &amp; WS_EX_TOOLWINDOW) or (exStyles &amp; WS_EX_NOACTIVATE)) and !(exStyles &amp; WS_EX_APPWINDOW)
         return
   }
}

GetLastActivePopup(hwnd)
{
   static GA_ROOTOWNER := 3
   hwnd := DllCall(&quot;GetAncestor&quot;, &quot;uptr&quot;, hwnd, &quot;uint&quot;, GA_ROOTOWNER, &quot;ptr&quot;)
   hwnd := DllCall(&quot;GetLastActivePopup&quot;, &quot;uptr&quot;, hwnd, &quot;ptr&quot;)
   return hwnd
}

IsWindowOnCurrentVirtualDesktop(hwnd)
{
   static IVirtualDesktopManager
   if !IVirtualDesktopManager
      IVirtualDesktopManager := ComObjCreate(CLSID_VirtualDesktopManager := &quot;{AA509086-5CA9-4C25-8F95-589D3C07B48A}&quot;, IID_IVirtualDesktopManager := &quot;{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}&quot;)
   DllCall(NumGet(NumGet(IVirtualDesktopManager+0), 3*A_PtrSize), &quot;ptr&quot;, IVirtualDesktopManager, &quot;uptr&quot;, hwnd, &quot;int*&quot;, onCurrentDesktop)   ; IsWindowOnCurrentVirtualDesktop
   return onCurrentDesktop
}

PropEnumProcEx(hWnd, lpszString, hData, dwData)
{
   if (strget(lpszString, &quot;UTF-16&quot;) = &quot;ApplicationViewCloakType&quot;)
   {
      numput(hData, dwData+0, 0, &quot;int&quot;)
      return false
   }
   return true
}

realHwnd(hwnd)
{
   varsetcapacity(var, 8, 0)
   numput(hwnd, var, 0, &quot;uint64&quot;)
   return numget(var, 0, &quot;uint&quot;)
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 16 Oct 2023 22:26:13 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159364#p159364</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159359#p159359</link>
			<description><![CDATA[<p>Да, отличная находка.<br />Спасибо!<br />Кстати, сами майкрософтцы его не используют, а используют исключения:<br /></p><div class="codebox"><pre><code>newWindow.ClassName != &quot;Windows.UI.Core.CoreWindow&quot;</code></pre></div><p><a href="https://github.com/microsoft/PowerToys/blob/main/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs#L116">https://github.com/microsoft/PowerToys/ … ws.cs#L116</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 16 Oct 2023 19:55:51 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159359#p159359</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159358#p159358</link>
			<description><![CDATA[<p>Ну мы в начале топика говорили о получении окон в порядке активации.<br /></p><div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>А вот GetShowInSwitchers, это не то, что надо для определения AltTab?</p></blockquote></div><p>Похоже оно самое.</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 16 Oct 2023 19:35:27 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159358#p159358</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159357#p159357</link>
			<description><![CDATA[<div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>не показать точное время активации скрипта, а сравнить это время с другими окнами</p></blockquote></div><p>В смысле, активации окна? Ну, если нужно сравнивать, то подойдёт, если точное время, тогда нет, зависит от задачи.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Mon, 16 Oct 2023 18:49:32 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159357#p159357</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159356#p159356</link>
			<description><![CDATA[<p>Например для того, чтобы не держать время активаций в скрипте.<br />Но я тут не совсем тебя понимаю, у нас же цель не показать точное время активации скрипта, а сравнить это время с другими окнами.</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Mon, 16 Oct 2023 18:46:57 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159356#p159356</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159355#p159355</link>
			<description><![CDATA[<p>А вот GetShowInSwitchers, это не то, что надо для определения AltTab?</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Mon, 16 Oct 2023 18:45:16 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159355#p159355</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: аналог altTab для окон определенной программы]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=159354#p159354</link>
			<description><![CDATA[<p>Ну это уж совсем костыль. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /> Если отслеживать время активаций, то зачем нужен этот метод.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Mon, 16 Oct 2023 18:39:44 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=159354#p159354</guid>
		</item>
	</channel>
</rss>
