<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Выбор пункта из меню в трее]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=13416</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=13416&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Выбор пункта из меню в трее».]]></description>
		<lastBuildDate>Fri, 23 Mar 2018 14:13:43 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124210#p124210</link>
			<description><![CDATA[<p>Для меню в трее много библиотек написано, вот вариант, кажется от <strong>teadrinker</strong> (пример для uTorrent, оба хоткея делают одно и тоже):<br /></p><div class="codebox"><pre><code>#SingleInstance Force
#NoEnv
DetectHiddenWindows On

Title := &quot;ahk_exe uTorrent.exe&quot;
1::
	Path := [&quot;Download Limit&quot;, [&quot;Неограниченно&quot;, &quot;150 kB/s&quot;]]
	MenuSelect(Path, Title)
	Return
2::
	Path := [&quot;6&amp;&quot;, [&quot;1&amp;&quot;, &quot;4&amp;&quot;]]
	MenuSelect(Path, Title)
	Return

Esc::ExitApp

MenuSelect(Path, Title) {
	WinGet, PID, PID, % &quot;ahk_id&quot; hWnd := WinExist(Title)
	PostMessage2TrayIconProcID(PID, WM_RBUTTONDOWN := 0x204, WM_RBUTTONUP := 0x205)
	WinWait, % &quot;ahk_class #32768 ahk_pid&quot; PID, , 0.5
	If ErrorLevel
		Return
	SendMessage, 0x1E1    ;  MN_GETHMENU
	If !(hMenu := ErrorLevel)
		Return
	DllCall(&quot;GetCursorPos&quot;, &quot;int64P&quot;, pt)
	X := pt &lt;&lt; 32 &gt;&gt; 32
	Y := pt &gt;&gt; 32
	MenuSelectPath(hMenu, hWnd, Path)
	DllCall(&quot;SetCursorPos&quot;, &quot;Uint&quot;, X, &quot;Uint&quot;, Y)
}

MenuSelectPath(hMenu, hWnd, Path, Key = 1) {
	Static MF_BYPOSITION := 0x400, MF_CHECKED := 0x00000008, MF_DISABLED := 0x00000002, MF_GRAYED := 0x00000001
		, MF_MENUBARBREAK := 0x00000020, MF_MENUBREAK := 0x00000040, MF_SEPARATOR := 0x00000800
	Item := Path[Key]
	If IsObject(Item)
		Item := Path[Key][1]
	If (Item ~= &quot;^\d+&amp;$&quot;)
		ItemNum := SubStr(Item, 1, -1) - 1
	Loop, % DllCall(&quot;GetMenuItemCount&quot;, &quot;Ptr&quot;, hMenu)
	{
		idx := A_Index - 1
		If (Item ~= &quot;^\d+&amp;$&quot;)
		{
			If (ItemNum != idx)
				Continue
			If (Key &lt; Path.MaxIndex())
			{
				MenuSetCursor(hMenu, hWnd, idx)
				Return MenuSelectPath(DllCall(&quot;GetSubMenu&quot;, &quot;Ptr&quot;, hMenu, &quot;Uint&quot;, idx), hWnd, Path, Key + 1)
			}
			Find := 1
			Break
		}
		Else
		{
			idn := DllCall(&quot;GetMenuItemID&quot;, &quot;Ptr&quot;, hMenu, &quot;int&quot;, idx)
			nSize++ := DllCall(&quot;GetMenuString&quot;, &quot;Ptr&quot;, hMenu, &quot;Uint&quot;, idx, &quot;Uint&quot;, 0, &quot;Uint&quot;, 0, &quot;Uint&quot;, MF_BYPOSITION)
			nSize := (nSize * (A_IsUnicode ? 2 : 1))
			VarSetCapacity(sString, nSize)
			DllCall(&quot;GetMenuString&quot;, &quot;Ptr&quot;, hMenu, &quot;Uint&quot;, idx, &quot;Str&quot;, sString, &quot;Uint&quot;, nSize, &quot;Uint&quot;, MF_BYPOSITION)   ; MF_BYPOSITION
			StringReplace, String, sString, &amp;, , 1
			If (Item != String)
				Continue
			If (Key &lt; Path.MaxIndex())
			{
				MenuSetCursor(hMenu, hWnd, idx)
				Return MenuSelectPath(DllCall(&quot;GetSubMenu&quot;, &quot;Ptr&quot;, hMenu, &quot;Uint&quot;, idx), hWnd, Path, Key + 1)
			}
			Find := 1
			Break
		}
	}
	If !Find
		Return 0
	If IsObject(Path[Key])
	{
		State := DllCall(&quot;GetMenuState&quot;, &quot;Ptr&quot;, hMenu, &quot;UInt&quot;, idx, &quot;UInt&quot;, MF_BYPOSITION)
		If (State &amp; MF_CHECKED || State &amp; MF_DISABLED || State &amp; MF_GRAYED || State &amp; MF_MENUBARBREAK || State &amp; MF_MENUBREAK || State &amp; MF_SEPARATOR)
			Return MenuSelectPath(hMenu, hWnd, [Path[Key][2]], 1)
	}
	MenuSetCursor(hMenu, hWnd, idx)
	Return 1
}

MenuSetCursor(hMenu, hWnd, idx) {
	VarSetCapacity(pt, 16, 0)
	DllCall(&quot;GetMenuItemRect&quot;
			 , &quot;Ptr&quot;, hWnd
			 , &quot;Ptr&quot;, hMenu
			 , &quot;UInt&quot;, idx
			 , &quot;UInt&quot;, &amp;pt)
	x := NumGet(pt, 0), y := NumGet(pt, 4)
	w := NumGet(pt, 8) - x, h := NumGet(pt, 12) - y
	DllCall(&quot;SetCursorPos&quot;, &quot;Uint&quot;, x + w // 2, &quot;Uint&quot;, y + h // 2)
	Click
	Sleep 100
}
Return



PostMessage2TrayIconProcID(ProcessPID, messages*)
{
/*
Структура TRAYDATA
typedef TRAYDATA
{
IntPtr hwnd;
uint uID;
uint uCallbackMessage;
uint Reserved;
uint Reserved2;
IntPtr hIcon;
}
*/
	Static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23
		, PtrSize := A_Is64bitOS ? 8 : 4, SizeOfTBBUTTON := 8 + PtrSize*3, SizeOfTRAYDATA := 16 + PtrSize*2
	DHW_Prev := A_DetectHiddenWindows
	DetectHiddenWindows, On

	Loop 2
	{
		ControlGet, hWnd, hwnd,, ToolbarWindow321, % &quot;ahk_class &quot; . (A_Index = 1 ? &quot;Shell_TrayWnd&quot; : &quot;NotifyIconOverflowWindow&quot;)
		WinExist(&quot;ahk_id&quot; hWnd)
		WinGet, PID, PID

		if (A_Index = 1 &amp;&amp; !IsObject(RemoteBuff := New RemoteBuffer(PID, SizeOfTRAYDATA))) {
			DetectHiddenWindows, %DHW_Prev%
			Return, 0, DllCall(&quot;MessageBox&quot;, Ptr, 0, Str, &quot;Не удалось создать удалённый буфер`nОшибка &quot; A_LastError, Str, &quot;&quot;, UInt, 0)
		}

		SendMessage, TB_BUTTONCOUNT
		Loop % ErrorLevel
		{
			SendMessage, TB_GETBUTTON, A_Index - 1, RemoteBuff.ptr
			if ! ( pTBBUTTON := RemoteBuff.Read(SizeOfTBBUTTON) )
				|| !pTRAYDATA := RemoteBuff.Read(SizeOfTRAYDATA, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr) {
				DetectHiddenWindows, %DHW_Prev%
				Return
			}

			WinGet, PID, PID, % &quot;ahk_id&quot; hWnd := NumGet(pTRAYDATA+0)
			if (PID = ProcessPID)
			{
				uID := NumGet(pTRAYDATA + PtrSize, &quot;UInt&quot;)
				uCallbackMessage := NumGet(pTRAYDATA + PtrSize + 4, &quot;UInt&quot;)
				; FocusTrayIcon(hWnd, uID)
				for i, message in messages
					PostMessage, uCallbackMessage, uID, message,, % &quot;ahk_id&quot; hWnd
				DetectHiddenWindows, %DHW_Prev%
				Return
			}
		}
	}
	DetectHiddenWindows, %DHW_Prev%
	MsgBox, % &quot;Иконка процесса &quot; . ProcessPID . &quot; не найдена&quot;
}

FocusTrayIcon(hWnd, uID)
{
	VarSetCapacity(NOTIFYICONDATA, size := A_PtrSize = 8 ? 848 : A_IsUnicode? 828 : 444, 0)
	NumPut(size, NOTIFYICONDATA, &quot;UInt&quot;)
	NumPut(hWnd, NOTIFYICONDATA, A_PtrSize)
	NumPut(uID, NOTIFYICONDATA, 2*A_PtrSize)
	DllCall(&quot;shell32\Shell_NotifyIcon&quot;, &quot;UInt&quot;, NIM_SETFOCUS := 0x00000003, Ptr, &amp;NOTIFYICONDATA)
	Return
}

Class RemoteBuffer
{
	__New(PID, size)
	{
		static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
			, MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4

		if !(this.hProc := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
			Return

		if !(this.ptr := DllCall(&quot;VirtualAllocEx&quot;, UInt, this.hProc, UInt, 0, UInt, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
			Return, &quot;&quot;, DllCall(&quot;CloseHandle&quot;, Ptr, this.hProc)
	}

	__Delete()
	{
		DllCall(&quot;VirtualFreeEx&quot;, Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
		DllCall(&quot;CloseHandle&quot;, Ptr, this.hProc)
	}

	Read(size, offset = 0)
	{
		static LocalBuff
		VarSetCapacity(LocalBuff, size, 0)
		if !DllCall(&quot;ReadProcessMemory&quot;, Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, &amp;LocalBuff, UInt, size, UInt, 0)
			Return, 0, DllCall(&quot;MessageBox&quot;, Ptr, 0, Str, &quot;Не удалось прочитать данные`nОшибка &quot; A_LastError, Str, &quot;&quot;, UInt, 0)

		VarSetCapacity(LocalBuff, -1)
		Return &amp;LocalBuff
	}

	Write(pLocalBuff, size, offset = 0)
	{
		res := DllCall(&quot;WriteProcessMemory&quot;, Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, pLocalBuff, UInt, size, UInt, 0)
		Return res ? res : 0, (!res) ? DllCall(&quot;MessageBox&quot;, Ptr, 0, Str, &quot;Не удалось записать данные`nОшибка &quot; A_LastError, Str, &quot;&quot;, UInt, 0)
	}
}
</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (stealzy)]]></author>
			<pubDate>Fri, 23 Mar 2018 14:13:43 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124210#p124210</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124207#p124207</link>
			<description><![CDATA[<p>Не могу понять в чем дело. PostMessage работает после, как вручную воспользуешься один раз этим меню, но когда запускаю приложение и не воспользовавшись меню, PostMessage не работает. Пробовал идентифицировать и прописывать ID, PID окна и прогресса, но результата не дало.</p>]]></description>
			<author><![CDATA[null@example.com (Vicoriyan)]]></author>
			<pubDate>Fri, 23 Mar 2018 09:19:18 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124207#p124207</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124206#p124206</link>
			<description><![CDATA[<p>Разобрался как найти это число. Спасибо.</p>]]></description>
			<author><![CDATA[null@example.com (Vicoriyan)]]></author>
			<pubDate>Fri, 23 Mar 2018 07:25:44 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124206#p124206</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124203#p124203</link>
			<description><![CDATA[<p>Spy++.</p>]]></description>
			<author><![CDATA[null@example.com (svoboden)]]></author>
			<pubDate>Thu, 22 Mar 2018 21:07:15 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124203#p124203</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124202#p124202</link>
			<description><![CDATA[<p>А как мне узнать, какое мне число нужно за месть 1005? Пробовал определить с помощью Winspector, ничего не вышло.</p>]]></description>
			<author><![CDATA[null@example.com (Vicoriyan)]]></author>
			<pubDate>Thu, 22 Mar 2018 20:36:21 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124202#p124202</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124201#p124201</link>
			<description><![CDATA[<div class="quotebox"><cite>Vicoriyan пишет:</cite><blockquote><p>Как активировать контекстное меню программы в трее и выбрать нужный пункт?</p></blockquote></div><p> Зачем активировать? В большинстве случаев работает так:<br /></p><div class="codebox"><pre><code>DetectHiddenWindows, on
PostMessage, 0x111, 1005,,, Заголовок программы ; вместо 1005 отловить нужно сообщение.</code></pre></div><p>p.s. Заголовок программы нужно подобрать самому, т.е. оставить одно-два слова.<br />p.p.s. Проверено на опыте. <img src="//forum.script-coding.com/img/smilies/neutral.png" width="15" height="15" /></p>]]></description>
			<author><![CDATA[null@example.com (svoboden)]]></author>
			<pubDate>Thu, 22 Mar 2018 19:29:34 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124201#p124201</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124199#p124199</link>
			<description><![CDATA[<p>Присоединяюсь к <strong>svoboden</strong>.</p>]]></description>
			<author><![CDATA[null@example.com (ypppu)]]></author>
			<pubDate>Thu, 22 Mar 2018 14:24:08 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124199#p124199</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=124197#p124197</link>
			<description><![CDATA[<p>Интересует данный вопрос, тока не конкретно в этой программе в теме, а вообще. Как активировать контекстное меню программы в трее и выбрать нужный пункт?</p>]]></description>
			<author><![CDATA[null@example.com (Vicoriyan)]]></author>
			<pubDate>Thu, 22 Mar 2018 12:49:30 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=124197#p124197</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=123440#p123440</link>
			<description><![CDATA[<p>Зачем открывать? Через сообщения можно выбрать пункт меню.</p>]]></description>
			<author><![CDATA[null@example.com (svoboden)]]></author>
			<pubDate>Sat, 27 Jan 2018 21:14:00 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=123440#p123440</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Выбор пункта из меню в трее]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=123412#p123412</link>
			<description><![CDATA[<p>Вопрос, каким кодом можно открыть меню в трее этого приложения и выбрать пункт под стрелочкой?<br /><span class="postimg"><img src="https://pp.userapi.com/c840620/v840620673/4c537/U_6RWHpwwdU.jpg" alt="https://pp.userapi.com/c840620/v840620673/4c537/U_6RWHpwwdU.jpg" /></span></p><p>Скрипт должен отключать мой Мегафон можем и включать через меню мегафон модема в трее</p>]]></description>
			<author><![CDATA[null@example.com (bsmolz)]]></author>
			<pubDate>Fri, 26 Jan 2018 19:08:18 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=123412#p123412</guid>
		</item>
	</channel>
</rss>
