<?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>http://forum.script-coding.com/viewtopic.php?id=5697</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=5697&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Определение символов, посылаемых с клавиатуры».]]></description>
		<lastBuildDate>Mon, 30 Apr 2012 18:30:34 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Определение символов, посылаемых с клавиатуры]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=59856#p59856</link>
			<description><![CDATA[<p>Код исправлен для поддержки AHK_L x64.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Mon, 30 Apr 2012 18:30:34 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=59856#p59856</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Определение символов, посылаемых с клавиатуры]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=47396#p47396</link>
			<description><![CDATA[<p>Требует AHK_L.<br />Скрипт определяет символы, посылаемые с клавиатуры окнам других приложений и показывает их в своём окне.<br /></p><div class="codebox"><pre><code>   SetBatchLines, -1
   Gui, Add, Edit, x0 y0 w200 h100 ReadOnly hwndhEdit
   Gui, Show, w200 h100 NA
   OnExit, Exit
   hHookKeybd := DllCall(&quot;SetWindowsHookEx&quot; . (A_IsUnicode ? &quot;W&quot; : &quot;A&quot;)
      , Int, WH_KEYBOARD_LL := 13
      , Ptr, RegisterCallback(&quot;LowLevelKeyboardProc&quot;, &quot;Fast&quot;)
      , Ptr, DllCall(&quot;GetModuleHandle&quot;, UInt, 0, Ptr)
      , UInt, 0, Ptr)
   OnExit, Exit
   Return

GuiClose:
   ExitApp

Exit:
   DllCall(&quot;UnhookWindowsHookEx&quot;, Ptr, hHookKeybd)
   ExitApp

LowLevelKeyboardProc(nCode, wParam, lParam)
{
   global
   Critical

   if (wParam = 0x100)   ; WM_KEYDOWN = 0x100
   {
      vk := NumGet(lParam+0, &quot;UInt&quot;)
      sc := NumGet(lParam+0, 4, &quot;UInt&quot;)
      SetTimer, ShowChar, -10
   }
   Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)

ShowChar:
   Char := GetCharOfKey(vk, sc)
   Control, EditPaste, % Char,, ahk_id %hEdit%
   Return
}

GetCharOfKey(vk, sc)
{
   ThreadID := DllCall(&quot;GetWindowThreadProcessId&quot;, UInt, WinExist(&quot;A&quot;), UInt, 0)
   InputLocaleID := DllCall(&quot;GetKeyboardLayout&quot;, UInt, ThreadID)
   VarSetCapacity(KeyState, 256)

   DllCall(&quot;AttachThreadInput&quot;, UInt, ThreadID
                              , UInt, DllCall(&quot;GetCurrentThreadId&quot;)
                              , UInt, 1)

   DllCall(&quot;GetKeyboardState&quot;, UInt, &amp;KeyState)

   VarSetCapacity(Buffer, 2)
   A_IsUnicode ? DllCall(&quot;ToUnicodeEx&quot;
                  , UInt, vk, UInt, sc
                  , UInt, &amp;KeyState, Str, Buffer
                  , Int, 1, UInt, 0, UInt, InputLocaleID) : DllCall(&quot;ToAsciiEx&quot;
                                                               , UInt, vk, UInt, sc
                                                               , UInt, &amp;KeyState, Str, Buffer
                                                               , UInt, 0, UInt, InputLocaleID)
   Return Buffer
}</code></pre></div><p>Для перехвата клавиатурных событий скрипт устанавливает <a href="http://msdn.microsoft.com/en-us/library/ms644990%28VS.85%29.aspx">хук</a>, callback-функция которого (<a href="http://msdn.microsoft.com/en-us/library/ms644985%28VS.85%29.aspx">LowLevelKeyboardProc</a>) определяет виртуальный и скан-код нажатой клавиши. После этого мы выходим из обработчика событий, чтобы не создавать задержки, и остальные действия будем выполнять асинхронно в подпрограмме таймера.</p><p>Теперь для определения символа, посланного нажатой клавишей, нужно узнать текущую раскладку клавиатуры в активном окне (ф-ция <a href="http://msdn.microsoft.com/en-us/library/ms646296%28VS.85%29.aspx">GetKeyboardLayout</a>) и статусы клавиш Shift и Caps Lock. Ф-ция <a href="http://msdn.microsoft.com/en-us/library/ms646299%28VS.85%29.aspx">GetKeyboardState</a> делает снимок состояний всех виртуальных клавиш и помещает его в буфер. Чтобы иметь возможность сделать такой снимок для другого потока, нужно предварительно вызвать <a href="http://msdn.microsoft.com/en-us/library/ms681956%28VS.85%29.aspx">AttachThreadInput</a>.</p><p>Сейчас у нас есть все данные, нужные для определения символа. В Unicode-версии AHK это делается с помщью ф-ции <a href="http://msdn.microsoft.com/en-us/library/ms646322%28VS.85%29.aspx">ToUnicodeEx</a>, в ANSI-версии — посредством <a href="http://msdn.microsoft.com/en-us/library/ms646318%28VS.85%29.aspx">ToAsciiEx</a>. Скрипт сам определит нужный вариант по значению переменной <a href="http://www.autohotkey.net/~Lexikos/AutoHotkey_L/docs/#vars">A_IsUnicode</a>.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Tue, 05 Apr 2011 15:15:05 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=47396#p47396</guid>
		</item>
	</channel>
</rss>
