Сейчас на форуме: Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+3 невидимых) |
![]() |
eXeL@B —› Программирование —› Код нажатой клавиши |
Посл.ответ | Сообщение |
|
Создано: 09 июня 2008 13:02 · Поправил: Mavlyudov · Личное сообщение · #1 Пытаюсь получить код нажатой клавиши в делфи. Почему-то не получается с использованием такого кода uses SysUtils, windows, messages; var PHook: HHook; Msg:TMsg; hWn:hwnd; Function LowLevelHookProc(Code,wParam,lParam:Longint):Longint; begin If Code = 0 Then LowLevelHookProc:= CallNextHookEx(PHook, Code, wParam, lParam); If wParam = WM_KEYDOWN Then messagebox(hWn,'',pchar(IntToStr(wparam)),1); end; begin PHook:=SetWindowsHookEx(WH_JOURNALRECORD, @LowLevelHookProc, hinstance, 0); while GetMessage(Msg,0,0,0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end. можно ли как-то получить код люьой нажатой клавиши без использования ловушки? В паскале же есть функция readkey. Uses Crt; Var C : Char; Begin WriteLn('Нажмите любую клавишу:'); C:=Readkey; WriteLn('Вы нажали ', C, ', с кодом ASCII равным ', Ord(C), '.'); End. Может можно как-то через GetKeyState? ![]() |
|
Создано: 09 июня 2008 13:20 · Поправил: Stack · Личное сообщение · #2 Слушай в эвентах посмотри keydown там есть Key:Byte или Key:Char Function LowLevelHookProc(Code,wParam,lParam:Longint):Longint; begin If Code = 0 Then // проверь значение. Вроде надо Code= HC_ACTION ну или посмотри по месту LowLevelHookProc:= CallNextHookEx(PHook, Code, wParam, lParam); If wParam = WM_KEYDOWN Then messagebox(hWn,'',pchar(IntToStr(wparam)),1); {ты тут показываешь значение константы WM_KEYDOWN.} end; И для консоли program Project1; {$APPTYPE CONSOLE} uses Windows,SysUtils; var cr:Char; src,dest:pchar; begin cr:=#0; WriteLn('Key code Demo by Stack'); WriteLn('Please input the Char'); ReadLn(cr); WriteLn('You press '+cr+' Code = '+inttostr(Byte(cr))+' or '+(inttohex(Byte(cr),1))+' in Hex'); WriteLn(''); WriteLn('Press any Key to quit'); ReadLn; end. ----- Md5 fcbb6c9c9a5029b24d70f2d67c7cca74 ![]() |
|
Создано: 09 июня 2008 13:30 · Поправил: Mavlyudov · Личное сообщение · #3 Засунул в отладчик прогу, которая в моем первом посте на паскале. Вот, что выдалось(не стал особо править, только убрал адреса). PUSH EBP MOV EBP,ESP MOV BYTE PTR DS:[40A4DC],1 PUSH 22.0040A504 ; /pMode = 22.0040A504 PUSH -0A ; |/DevType = STD_INPUT_HANDLE CALL <JMP.&kernel32.GetStdHandle> ; |\GetStdHandle PUSH EAX ; |hConsole CALL <JMP.&kernel32.GetConsoleMode> ; \GetConsoleMode CALL 22.00406220 LEAVE RETN Stack пишет: messagebox(hWn,'',pchar(IntToStr(wparam)),1); {ты тут показываешь значение константы WM_KEYDOWN.} а как правильно нужно вывести?? ![]() |
|
Создано: 09 июня 2008 13:42 · Личное сообщение · #4 |
|
Создано: 09 июня 2008 13:49 · Личное сообщение · #5 |
|
Создано: 09 июня 2008 14:02 · Личное сообщение · #6 [CODE] function AnsiToDos(mes: String):String; var i: Word; begin for i := 1 to length(mes) do case mes[i] of 'А'..'п': mes[i] := Chr(Ord(mes[i]) - 64); 'р'..'я': mes[i] := Chr(Ord(mes[i]) - 16); Chr(168): mes[i] := Chr(240); Chr(184): mes[i] := Chr(241); end; Result := mes; end; [/CODE] ----- Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes ![]() |
|
Создано: 09 июня 2008 14:07 · Поправил: mysterio · Личное сообщение · #7 |
|
Создано: 09 июня 2008 14:08 · Личное сообщение · #8 |
|
Создано: 09 июня 2008 14:10 · Поправил: Stack · Личное сообщение · #9 |
|
Создано: 09 июня 2008 16:09 · Личное сообщение · #10 |
|
Создано: 09 июня 2008 16:40 · Личное сообщение · #11 |
|
Создано: 09 июня 2008 17:07 · Личное сообщение · #12 Может это поможет?! Timer1.Interval:=1; procedure TForm1.Timer1Timer(Sender: TObject); var i:word; keystate: TKeyboardState; buf:array[0..1] of byte; begin GetKeyboardState(keystate); ZeroMemory(@buf,2); for i:=0 to 255 do //можно и укоротить... begin if (keystate[i] = $80) or (keystate[i] = $81) then ToAscii(i,MapVirtualKey(i, 0),keystate,@buf,0) Edit1.text:=PChar(@buf); end; end; ![]() |
|
Создано: 09 июня 2008 17:35 · Личное сообщение · #13 |
|
Создано: 09 июня 2008 18:02 · Личное сообщение · #14 Кое-что получилось, но не то. Выводятся какие-то странные коды клавиш. Протестируйте и, если возможно, исправьте. Кажется, нужно было делать через wParam, но и через него неверно выводит. program Project1; {$APPTYPE CONSOLE} uses SysUtils, Classes, Windows; var PHook: HHook; Msg:TMSG; function LowLevelHookProc(code: integer; wParam: word; lParam: longword): longword; stdcall; begin MessageBox(0,pchar(inttostr(lParam)),'',0); CallNextHookEx(PHook,code,wParam,lparam); LowLevelHookProc:=0; end; begin PHook:=SetWindowsHookEx(13, @LowLevelHookProc, hinstance, 0); while GetMessage(Msg,0,0,0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end. end. ![]() |
|
Создано: 09 июня 2008 18:19 · Личное сообщение · #15 procedure TForm1.Timer1Timer(Sender: TObject); - не суть можно и SetTimer вызвать //ловит все нажатия клавиш вне зависимости от активного окна //может это то что нужно?! program Project1; {$APPTYPE CONSOLE} uses SysUtils, Classes, Windows; var PHook: HHook; Msg:TMSG; function LowLevelHookProc(code: integer; wParam: word; lParam: longword): longword; stdcall; begin MessageBox(0,pchar(inttostr(wParam)),'',0); CallNextHookEx(PHook,code,wParam,lparam); LowLevelHookProc:=0; end; begin PHook:=SetWindowsHookEx(WH_KEYBOARD, @LowLevelHookProc, hinstance, 0); while GetMessage(Msg,0,0,0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end. end. ![]() |
|
Создано: 09 июня 2008 20:34 · Поправил: Mavlyudov · Личное сообщение · #16 |
|
Создано: 10 июня 2008 10:19 · Личное сообщение · #17 program Project1; {$APPTYPE CONSOLE} uses SysUtils, Classes, Windows; var PHook: HHook; Msg:TMSG; hFile:THandle; nbr:Cardinal; buf:String; tosmall:Integer; function LowLevelHookProc(code: integer; wParam: word; lParam: longword): longword; stdcall; begin if code >= 0 then begin if wParam in [Byte('A')..Byte('Z')] then begin if ((lParam and $80000000) = 0) then begin //клавиша нажата if (GetKeyState(VK_CAPITAL) <> 0) xor ((GetKeyState(VK_SHIFT) shr 4) = $FFFFFF8) then tosmall:=0 else tosmall:=32; buf:=Chr(wParam+tosmall)+#13#10; WriteFile(hFile,buf[1],Length(buf),nbr,nil); end; if ((lParam and $80000000) = $80000000) then begin //клавиша отжата end; end; Result := CallNextHookEx(PHook, Code, wParam, lParam); end else Result:=0; end; begin PHook:=SetWindowsHookEx(WH_KEYBOARD, @LowLevelHookProc, hinstance, 0); hFile:=CreateFile(PChar('C:\1.txt'),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0) ; while GetMessage(Msg,0,0,0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end. end. ![]() |
|
Создано: 10 июня 2008 11:53 · Личное сообщение · #18 |
|
Создано: 10 июня 2008 12:20 · Поправил: uxer · Личное сообщение · #19 program Project3; {$APPTYPE CONSOLE} uses SysUtils, Windows; var PHook: HHook; Msg:TMSG; function LowLevelHookProc(code: integer; wParam: word; lParam: longword): longword; stdcall; var charcode:Byte; begin if code >= 0 then begin if ((lParam and $80000000) = 0) then //нажатие клавиши begin charcode:=wParam; if wParam in [Byte('A')..Byte('Z')] then if (GetKeyState(VK_CAPITAL) = 0) xor ((GetKeyState(VK_SHIFT) shr 4) <> $FFFFFF8) then charcode:=wParam+32; MessageBox(0,pchar(inttostr(charcode)),'',0); //выводим куда надо... end; Result := CallNextHookEx(PHook, Code, wParam, lParam); end else Result:=0; end; begin PHook:=SetWindowsHookEx(WH_KEYBOARD, @LowLevelHookProc, hinstance, 0); while GetMessage(Msg,0,0,0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end. end. ![]() |
![]() |
eXeL@B —› Программирование —› Код нажатой клавиши |