Простите, знаю, что тема избитая. Но моего случая пока не нашёл. Я делаю слухатель клавы через глобальный выньдовый хук. Библиотечку-слухач прилагаю. Задача стандартная: отслеживать все нажатия клавиш. Но в основной проге нет окна. Лишь основной тред. Ему сообщения надо слать с помощью PostThreadMessage. В основной проге в цикле вытаскиваю сообщения: Код (Text): invoke InstallHook,eax invoke CreateFile,offset szLogFile,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,0,0 mov hFile,eax invoke Listening,TRUE .while TRUE invoke GetMessage,addr msg,NULL,0,0 .break.if eax==0 .if msg.message==WM_KEYDOWN invoke MessageBox,0,CommandLine,offset AppName,MB_OK ; mov eax,msg.wParam ; .if eax>=VK_A && eax<=VK_Z ; invoke WriteFile,hFile,addr msg.wParam,1,addr dwWritten,0 ; .endif .endif .endw invoke CloseHandle,hFile invoke UninstallHook Но ни записи в файл ни даже Msb не получаю, а выходит замкнутый круг. Основная прога не получает сообщения WM_KEYDOWN, зато непрерывным потоком валятся какие-то левые сообщения и вся эта система виснет и круто тормозит машину. Не пойму в чём дело. Кто шлёт те сообщения? Номера сообщений: 184h и 18184h. 1876652513__KHL32.ZIP
Код (Text): KeyboardProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD .if nCode&80000000h invoke CallNextHookEx,hHook,nCode,wParam,lParam ret .endif invoke CallNextHookEx,hHook,nCode,wParam,lParam ; Зачем 1 раз вызывать по условию, а второй раз всегда? ;убери первый кусок ;а следующую часть надо вызывать когда у тебя nCode==HC_ACTION .if boolListening!=FALSE push eax ;here we do our part ; .if !(lParam&KEY_PRESSED) ; mov edx,WM_KEYDOWN ; .else ; mov edx,WM_KEYUP ; .endif mov edx,lParam shr edx,15 add edx,WM_KEYDOWN ;Что здесь происходит я не понял ;Но в edx у тебя не WM_KEYDOWN invoke PostThreadMessage,nOwnerThread,edx,wParam,lParam pop eax .endif @ret: xor eax,eax ret KeyboardProc endp
S_T_A_S_, ProgramMan Вообще-то в SDK говорится, что можно в треде насильно создать очередь сообщений с помощью процедур GetMessage или PeekMessage. Они создают очередь сообщений, если она отсутствует, а потом производят соответствующие действия с нею. А слать сообщения треду без окна можно как раз с помощью той процедуры PostThreadMessage, где вместо хэндла окна используется ID треда. Turkish Код (Text): ;here we do our part ; .if !(lParam&KEY_PRESSED) ; mov edx,WM_KEYDOWN ; .else ; mov edx,WM_KEYUP ; .endif mov edx,lParam shr edx,15 add edx,WM_KEYDOWN ;Что здесь происходит я не понял ;Но в edx у тебя не WM_KEYDOWN invoke PostThreadMessage,nOwnerThread,edx,wParam,lParam Здесь я беру lParam, в котором дополнительная информация о событии нажатой клавиши. Самый верхний бит (31) утановлен, если клавиша нажата, и сброшен, если клавишу отпустили. Ой, а что это я двигаю биты на 15? Надо же на 31! Сейчас исправлю. Ура, заработала!!! В аттаче высылаю тем, кто хочет эту DLL. Полный масмовский проект. Она отслеживает все события клавы во всех процессах и шлёт сообщения своему хозяину. Вместо WM_KEYDOWN я использовал WM_USER+WM_KEYDOWN, чтобы различать внутри цикла выборки сообщений хозяина откуда пришло клавишное событие: в рамках собственного потока или от библиотечного хука. Для активации хука нужно из хозяина вызвать следующее из того потока, который будет обрабатывать приходящие сообщения: Код (Text): InstallHook(GetCurrentThreadId()) Для снятия хука вызываем UninstallHook(). Но это можно делать в начале и в конце проги. А включать копию потока клавиатурных сочетаний себе можно с помощью Код (Text): Listening(TRUE) Для выключения соответственно высылаем в этой же функции FALSE. _1148334584__KHL32.ZIP