<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Работа с треем]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=5748&amp;type=atom" />
	<updated>2011-04-27T20:46:25Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=5748</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47881#p47881" />
			<content type="html"><![CDATA[<p>Различную информацию об иконках системного трея можно получить, отправляя им сообщение <a href="http://msdn.microsoft.com/en-us/library/bb787319%28VS.85%29.aspx"><strong>TB_GETBUTTON</strong></a>, и считывая данные из структуры <a href="http://msdn.microsoft.com/en-us/library/bb760476%28VS.85%29.aspx"><strong>TBBUTTON</strong></a>. (Чтобы считать данные из удалённого процесса (explorer.exe), нужно выделить буфер в его адресном пространстве, считать данные в него, а затем скопировать их в буфер из адресного пространства вызывающего процесса.) В составе этой структуры есть член <em>dwData</em>, описанный в MSDN как &quot;application-defined value&quot;. Порыскав по просторам интернета, я, наконец, <a href="http://winjade.net/wp-content/uploads/2008/06/systray-tutorial.pdf">нашёл</a> (pdf) его более подробное описание:<br /></p><div class="quotebox"><blockquote><p>The dwData member of the TBBUTTON structure gives us a pointer to the TRAYDATA structure for the button.</p></blockquote></div><div class="quotebox"><blockquote><p>public struct TRAYDATA<br />{<br />public IntPtr hwnd;<br />public uint uID;<br />public uint uCallbackMessage;<br />private uint Reserved;<br />private uint Reserved2;<br />public IntPtr hIcon;<br />}</p></blockquote></div><p>Возвращаясь к поставленной задаче — удалить &quot;зависшие&quot; иконки убитых приложений и обновить трей — можно получить хэндл родительского окна иконки (первый член структуры <strong>TRAYDATA</strong>) и проверить, существует ли его процесс (вариант с проверкой существования окна почему-то не срабатывает), затем удалить ненужную иконку, отправив ей <a href="http://msdn.microsoft.com/en-us/library/bb787309%28VS.85%29.aspx"><strong>TB_DELETEBUTTON</strong></a>. После этого нужно обновить трей с помощью <a href="http://msdn.microsoft.com/en-us/library/ms725497%28VS.85%29.aspx"><strong>WM_SETTINGCHANGE</strong></a>, иначе в области уведомлений останется пустое место.<br /></p><div class="codebox"><pre><code>#NoTrayIcon
SetBatchLines, -1

PROCESS_VM_OPERATION := (0x8)
PROCESS_VM_READ := (0x10)
PROCESS_QUERY_INFORMATION := (0x400)
SizeOfTBBUTTON := 20, SizeOfTRAYDATA := 24
MEM_COMMIT := 0x1000
MEM_RELEASE := 0x8000
PAGE_READWRITE := 0x4
WM_USER := 0x400
TB_BUTTONCOUNT := (WM_USER + 24)
TB_GETBUTTON := (WM_USER + 23)
WM_WININICHANGE := 0x1A
TB_DELETEBUTTON := (WM_USER + 22)
WM_SETTINGCHANGE := WM_WININICHANGE

; нам нужно найти хэндл окна класса ToolbarWindow32, которое является дочерним окна
; с классом SysPager, которое является дочерним окна с классом TrayNotifyWnd, которое,
; в свою очередь, является дочерним окна с классом Shell_TrayWnd (панели задач)
hShell_TrayWnd := WinExist(&quot;ahk_class Shell_TrayWnd&quot;)
ChildClasses = TrayNotifyWnd|SysPager|ToolbarWindow32  ; классы окон в порядке вложенности
Loop, parse, ChildClasses, |
   hChild := DllCall(&quot;FindWindowEx&quot;, UInt, A_Index = 1 ? hShell_TrayWnd : hChild
                                   , UInt, 0, Str, A_LoopField, UInt, 0)
; последнее вложенное — искомое окно — ToolbarWindow32 делаем последним найденным
WinWait, ahk_id %hChild%
WinGet, PID, PID
hProcess := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, UInt, 0, UInt, PID)
lpData := DllCall(&quot;VirtualAllocEx&quot;, UInt, hProcess, UInt, 0
                                  , UInt, SizeOfTBBUTTON
                                  , UInt, MEM_COMMIT
                                  , UInt, PAGE_READWRITE)
DetectHiddenWindows, On
VarSetCapacity(TBBUTTON, SizeOfTBBUTTON)
VarSetCapacity(TRAYDATA, SizeOfTRAYDATA)
VarSetCapacity(FilePath, A_IsUnicode ? 600 : 300)
Index = 0
SendMessage, TB_BUTTONCOUNT
Loop % IconCount := ErrorLevel
{
   SendMessage, TB_GETBUTTON, Index, lpData
   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, lpData
                              , UInt, &amp;TBBUTTON
                              , UInt, SizeOfTBBUTTON, UInt, 0)

   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, NumGet(TBBUTTON, 12)
                              , UInt, &amp;TRAYDATA
                              , UInt, SizeOfTRAYDATA, UInt, 0)

   WinGet, PID, PID, % &quot;ahk_id &quot; NumGet(TRAYDATA)
   if !PID
      SendMessage, TB_DELETEBUTTON, Index--  ; в случае удаления индексы уменьшаются на 1
   Index++
}

if (Index &lt; IconCount)
   SendMessage, WM_SETTINGCHANGE,,,, ahk_class Shell_TrayWnd  ; иначе останется пустое место

DllCall(&quot;VirtualFreeEx&quot;, UInt, hProcess , UInt, lpData, UInt, 0, UInt, MEM_RELEASE)
DllCall(&quot;CloseHandle&quot;, UInt, hProcess)</code></pre></div><p>(Чёрт, подсветку доделать никак руки не доходят!)<br />И напоследок, код определяющий исполнимые файлы процессов, создавших иконки в трее (нужно учитывать, что часть иконок скрыта).<br /></p><div class="codebox"><pre><code>#NoTrayIcon
SetBatchLines, -1

PROCESS_VM_OPERATION := (0x8)
PROCESS_VM_READ := (0x10)
PROCESS_QUERY_INFORMATION := (0x400)
SizeOfTBBUTTON := 20, SizeOfTRAYDATA := 24
MEM_COMMIT := 0x1000
MEM_RELEASE := 0x8000
PAGE_READWRITE := 0x4
WM_USER := 0x400
TB_BUTTONCOUNT := (WM_USER + 24)
TB_GETBUTTON := (WM_USER + 23)
WM_WININICHANGE := 0x1A
TB_DELETEBUTTON := (WM_USER + 22)
WM_SETTINGCHANGE := WM_WININICHANGE

hShell_TrayWnd := WinExist(&quot;ahk_class Shell_TrayWnd&quot;)
ChildClasses = TrayNotifyWnd|SysPager|ToolbarWindow32  ; классы окон в порядке вложенности
Loop, parse, ChildClasses, |
   hChild := DllCall(&quot;FindWindowEx&quot;, UInt, A_Index = 1 ? hShell_TrayWnd : hChild
                                   , UInt, 0, Str, A_LoopField, UInt, 0)
; последнее вложенное — искомое окно — ToolbarWindow32 делаем последним найденным
WinWait, ahk_id %hChild%
WinGet, PID, PID
hProcess := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, UInt, 0, UInt, PID)
lpData := DllCall(&quot;VirtualAllocEx&quot;, UInt, hProcess, UInt, 0
                                  , UInt, SizeOfTBBUTTON
                                  , UInt, MEM_COMMIT
                                  , UInt, PAGE_READWRITE)
DetectHiddenWindows, On
VarSetCapacity(TBBUTTON, SizeOfTBBUTTON)
VarSetCapacity(TRAYDATA, SizeOfTRAYDATA)
VarSetCapacity(FilePath, A_IsUnicode ? 600 : 300)
Index := 0
SendMessage, TB_BUTTONCOUNT
Loop % IconCount := ErrorLevel
{
   SendMessage, TB_GETBUTTON, Index, lpData
   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, lpData
                              , UInt, &amp;TBBUTTON
                              , UInt, SizeOfTBBUTTON, UInt, 0)

   DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess, UInt, NumGet(TBBUTTON, 12)
                              , UInt, &amp;TRAYDATA
                              , UInt, SizeOfTRAYDATA, UInt, 0)

   WinGet, PID, PID, % &quot;ahk_id &quot; NumGet(TRAYDATA)
   if !PID
      SendMessage, TB_DELETEBUTTON, Index--  ; в случае удаления индексы уменьшаются на 1
   Else
   {
      hProc := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_QUERY_INFORMATION, UInt, 0, UInt, PID)
      if !DllCall(&quot;GetProcessImageFileName&quot; . (A_IsUnicode ? &quot;W&quot; : &quot;A&quot;)
                                                , UInt, hProc
                                                , Str, FilePath, UInt, 300)
         DllCall(&quot;Psapi\GetProcessImageFileName&quot; . (A_IsUnicode ? &quot;W&quot; : &quot;A&quot;)
                                                   , UInt, hProc
                                                   , Str, FilePath, UInt, 300)
      FilePaths .= FilePath . &quot;`n&quot;
      DllCall(&quot;CloseHandle&quot;, UInt, hProc)
   }
   Index++
}

if (Index &lt; IconCount)
   SendMessage, WM_SETTINGCHANGE,,,, ahk_class Shell_TrayWnd

DllCall(&quot;VirtualFreeEx&quot;, UInt, hProcess , UInt, lpData, UInt, 0, UInt, MEM_RELEASE)
DllCall(&quot;CloseHandle&quot;, UInt, hProcess)

MsgBox, % SubStr(FilePaths, 1, -1)</code></pre></div><p>Оба варианта кода рассчитаны на 32-разрядную версию Windows.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-04-27T20:46:25Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47881#p47881</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47852#p47852" />
			<content type="html"><![CDATA[<p><strong>WUT</strong>, спасибо! Возможно, на этой основе можно будет сделать перевод и на AHK (послушаем коллег).</p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2011-04-26T18:53:18Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47852#p47852</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47850#p47850" />
			<content type="html"><![CDATA[<p><a href="http://www.forum.script-coding.com/viewtopic.php?pid=47849#p47849">http://www.forum.script-coding.com/view … 849#p47849</a></p>]]></content>
			<author>
				<name><![CDATA[WUT]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25947</uri>
			</author>
			<updated>2011-04-26T17:54:02Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47850#p47850</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47847#p47847" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>BasyAlex пишет:</cite><blockquote><p>А можно ссылочку...</p></blockquote></div><p>Сейчас размещу в соответствующем разделе оба кода</p>]]></content>
			<author>
				<name><![CDATA[WUT]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25947</uri>
			</author>
			<updated>2011-04-26T17:22:55Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47847#p47847</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47846#p47846" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>WUT пишет:</cite><blockquote><p>А обязательно AHK? На Autoit эти вопросы решаются без проблем <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p></blockquote></div><p>А можно ссылочку...</p>]]></content>
			<author>
				<name><![CDATA[BasyAlex]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26918</uri>
			</author>
			<updated>2011-04-26T17:18:42Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47846#p47846</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47845#p47845" />
			<content type="html"><![CDATA[<p>А обязательно AHK? На Autoit эти вопросы решаются без проблем <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[WUT]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=25947</uri>
			</author>
			<updated>2011-04-26T17:04:24Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47845#p47845</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47841#p47841" />
			<content type="html"><![CDATA[<p><a href="http://www.autohotkey.com/forum/viewtopic.php?t=19766">Скрипт</a> для определения констант.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-04-26T14:05:04Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47841#p47841</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47840#p47840" />
			<content type="html"><![CDATA[<p>Пошатался по форумам и пришла идея попробовать использовать <em>TB_-сообщения</em>. Вот толко я не нашел их hex-кодов для подстановки в <em>SendMessage/PostMessage</em></p>]]></content>
			<author>
				<name><![CDATA[BasyAlex]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26918</uri>
			</author>
			<updated>2011-04-26T13:51:34Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47840#p47840</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47835#p47835" />
			<content type="html"><![CDATA[<p>У меня та же проблема. Я и говорю, кривой способ. <img src="//forum.script-coding.com/img/smilies/big_smile.png" width="15" height="15" /> Насколько я вижу, Google ничего другого не предлагает.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-04-26T10:29:13Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47835#p47835</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47831#p47831" />
			<content type="html"><![CDATA[<div class="quotebox"><blockquote><p>Вот так можно попробовать, хотя способ довольно кривой</p></blockquote></div><p>Помогает, но&nbsp; DrWeb выдаёт свой <em>TrayTip</em> прямо у курсора мыши.</p>]]></content>
			<author>
				<name><![CDATA[BasyAlex]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26918</uri>
			</author>
			<updated>2011-04-26T08:53:05Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47831#p47831</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47827#p47827" />
			<content type="html"><![CDATA[<p>Вот так можно попробовать, хотя способ довольно кривой:<br /></p><div class="codebox"><pre><code>WinWait, ahk_class Shell_TrayWnd
ControlGetPos,,, W, H, ToolbarWindow321
Loop % W
   PostMessage, WM_MOUSEMOVE := 0x200,, (A_Index - 1)|((H/2)&lt;&lt;16), ToolbarWindow321</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-04-26T07:59:16Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47827#p47827</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47824#p47824" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>alexii пишет:</cite><blockquote><p>Попробовать сделать наподобие такого: Re: Очистка трея.</p></blockquote></div><p>Попробовал использовать wm_mousemove через PostMessage, но возникли сложности:<br /><strong>1</strong><br />При посылании <em>PostMessage,0x200,,,, ahk_class ToolbarWindow32</em> исчезает иконка неработающей проги только если она расположена крайняя-слева, а она может находиться в любом месте трея. Другими словами - у <em>PostMessage</em> необходимо указать координаты <span class="bbu">откуда-куда</span> двигаться мышке. Как это сделать?</p><p><strong>2</strong><br />Возникает проблема с определением <em>ahk_class ToolbarWindow32</em> - их там несколько этого типа окон (все принадлежат <em>explorer.exe</em>). Поэтому приходиться использовать <em>ahk_id</em> и смотреть его через WInspector, что не годится, конечно же.</p>]]></content>
			<author>
				<name><![CDATA[BasyAlex]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26918</uri>
			</author>
			<updated>2011-04-25T23:39:14Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47824#p47824</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47822#p47822" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>BasyAlex пишет:</cite><blockquote><p>Как заставиить трей обновить своё содержимое? Пробовал поискать какое сообщение должно ему передаваться при наведении курсора мыши на иконку неработающей проги для её исчезновения в трее через WInspector, но так и не нашел.</p></blockquote></div><p>Попробовать сделать наподобие такого: <a href="http://www.automate-my-tasks.com:8080/ru/viewtopic.php?f=2&amp;t=955&amp;p=3524#p3531">Re: Очистка трея</a>.</p><p><span style="color: Green"><strong>wodyanoi</strong>, что это за флуд?!</span></p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2011-04-25T19:50:28Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47822#p47822</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47821#p47821" />
			<content type="html"><![CDATA[<p>угу гулять с девочкой!!! солныфко светит, а мы цалуемса!!!)</p>]]></content>
			<author>
				<name><![CDATA[wodyanoi]]></name>
			</author>
			<updated>2011-04-25T19:41:15Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47821#p47821</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Работа с треем]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=47801#p47801" />
			<content type="html"><![CDATA[<p>Всем привет!</p><p><strong>Вопрос 1</strong><br />При некорректном завершении программ, частенько в трее остаются их иконки (к примеру Alcohol120%). Как заставиить трей обновить своё содержимое?</p><p>Пробовал поискать какое сообщение должно ему передаваться при наведении курсора мыши на иконку неработающей проги для её исчезновения в трее через WInspector, но так и не нашел. <br />Кстати, бывает и обратная ситуация - при крахе Explorer-а половина иконок просто исчезает из трея и приходиться перезапускать некоторые приложения дабы они там проявились.:mad:</p><p><strong>Вопрос 2</strong> (Следeт из первого)<br />Как получить список работающих прог висящих у меня в трее? Надобность возникла из-за того, что прога создаёт тьму окон одинакового класса (без имён и какого-либа текста) и только одно из них отвечает за клики в трее.</p><p><em>Стоит прога WallPaper Calendar v3.0.2 build 86 от zepsoft-a для смены обоев на рабочем столе выбираем через трей &quot;Change Wallpaper Image&quot; и меняем обои.<br />В скрипте это выглядит так - перебираем из полутора десятка одинаковых окон &quot;ahk_class TPUtilWindow&quot; выбираем необходимое (метотом тупого перебора через цикл) и посылаем ему PostMessage:<br /></em></p><div class="codebox"><pre><code>Process,Exist,WallCal3.exe
MyProgPID:=ErrorLevel
MyVar:=2
WinGet,ClassIDVar,List,ahk_class TPUtilWindow,,
While (MyVar&gt;0)
{
    MyProgID:=ClassIDVar%A_Index%
    WinGet,MyProgPIDVar,PID,ahk_id %MyProgID%,,
    if MyProgPIDVar=%MyProgPID%
    {
        OutputVar:=ClassIDVar%A_Index%
        MyVar-=1
    }
}
PostMessage,0x111,30,0,,ahk_id %OutputVar%</code></pre></div>]]></content>
			<author>
				<name><![CDATA[BasyAlex]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26918</uri>
			</author>
			<updated>2011-04-25T12:10:29Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=47801#p47801</id>
		</entry>
</feed>
