есть хук: Код (Text): unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); end; var Form1: TForm1; implementation var hHook: THandle; {$R *.dfm} function LowLevelKeyboardProc(nCode: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT stdcall; type PKbdDllHookStrukt = ^TKbdDllHookStrukt; _KBDLLHOOKSTRUCT = record vkCode: DWORD; scanCode: DWORD; flags: DWORD; time: DWORD; dwExtraInfo: PDWORD; end; TKbdDllHookStrukt = _KBDLLHOOKSTRUCT; const RPT_WPARAM_DATA = 'Keyboard message = %s '; RPT_LPARAM_DATA = 'scan code = %s [%d]'; var StrResult: String; begin StrResult := ''; if nCode = HC_ACTION then Result := CallNextHookEx(hHook, nCode, WParam, LParam); case WParam of WM_KEYDOWN: StrResult := Format(RPT_WPARAM_DATA, ['WM_KEYDOWN']); WM_KEYUP: StrResult := Format(RPT_WPARAM_DATA, ['WM_KEYUP']); WM_SYSKEYDOWN: StrResult := Format(RPT_WPARAM_DATA, ['WM_SYSKEYDOWN']); WM_SYSKEYUP: StrResult := Format(RPT_WPARAM_DATA, ['WM_SYSKEYUP']); end; StrResult := StrResult + Format(RPT_LPARAM_DATA, [ Chr(PKbdDllHookStrukt(LParam)^.vkCode), PKbdDllHookStrukt(LParam)^.vkCode]); Form1.Memo1.Lines.Add(StrResult); end; procedure TForm1.FormCreate(Sender: TObject); const WH_KEYBOARD_LL = 13; begin hHook := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0); if hHook = 0 then RaiseLastOSError; end; procedure TForm1.FormDestroy(Sender: TObject); begin if not UnhookWindowsHookEx(hHook) then RaiseLastOSError; end; end. и вот я не могу найти можно ли здесь перехватываемые коды клавиш менять на другие и посылать винде дальше? например в чужом приложении нажали A, а этому приложению пришло B.и еще вопрос: многие советуют глобальные хуки делать в dll. зачем это нужно и стоит ли переделывать этот в dll?
Нет нельзя. Можно только блокировать дальнейшую обработку клавиши (не вызывать следующий хук и вернуть TRUE), и сгенерировать нужнуй код с помощью kbd_event. Более правильно - фильтр драйвер на клавиатуру.
При использовании WH_KEYBOARD_LL делать процедуру-обработчик хуков в dll совсем не обязательно - обработчик хуков вызывается в контексте установившего хук процесса (msdn говорит, что вызов происходит посылкой оконного сообщения установившему потоку - т.е. поток должен иметь цикл обработки сообщений). katrus говорит, что менять код клавиши нельзя - видимо, копия структуры KBDLLHOOKSTRUCT в адресном пространство процесса, установившего хук, после использования просто отбрасывается. А вот, например, вызов SetWindowsHookEx с параметром WH_GETMESSAGE подразумевает загрузку кода хук-процедуры в адресное пространство других процессов. Именно поэтому в таком случае хук-процедура должна находится в dll - windows не будет грузить в процессы exe-файл. И, кстати, при использовании WH_GETMESSAGE данные можно подменять: Код (Text): LRESULT CALLBACK HookProc(int code, WPARAM wp, LPARAM lp) { static const wchar_t ValidText [] = L" desu"; static const wchar_t* pText = ValidText; if (code < 0 || wp == PM_NOREMOVE || ((MSG*)lp)->message != WM_CHAR) return CallNextHookEx(NULL, code, wp, lp); ((MSG*)lp)->wParam = (WPARAM)*pText++; if (!*pText) pText = ValidText; return CallNextHookEx(NULL, code, wp, lp); }