Сейчас на форуме: Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› Код нажатой клавиши
Посл.ответ Сообщение


Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 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?



Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 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





Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 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.}


а как правильно нужно вывести??



Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 09 июня 2008 13:42
· Личное сообщение · #4

Выше я пример привел на delphi.
Кстати никто незнает как в delphi по русски в консоли писать. CharToOem и AnsiToOem прогу вышибают в еррор.

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74





Ранг: 271.6 (наставник), 2thx
Активность: 0.30
Статус: Участник

Создано: 09 июня 2008 13:49
· Личное сообщение · #5

Stack
В делфеворлде есть модуль для русской консоли

-----
iNTERNATiONAL CoDE CReW





Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 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





Ранг: 307.9 (мудрец), 196thx
Активность: 0.180
Статус: Участник

Создано: 09 июня 2008 14:07 · Поправил: mysterio
· Личное сообщение · #7

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
Form1.KeyPreview := True; // Если не включили сразу включим здесь ;)
ShowMessage('Клавиша: ' + Key + ' Код: ' + IntToStr(Ord(Key)));
// ессно с сочетаниями клавиш не работает =)
end;

-----
Don_t hate the cracker - hate the code.




Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 09 июня 2008 14:08
· Личное сообщение · #8

Spirit пишет:
В делфеворлде есть модуль для русской консоли

Муть имхо. Для меня самые приемлимые варианты смены кодировки страницы и вариант coderess

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74




Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 09 июня 2008 14:10 · Поправил: Stack
· Личное сообщение · #9

mysterio я ему это сразу предложил только мну его код смутил.

А какая разница между ord() & Byte()

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74





Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 09 июня 2008 16:09
· Личное сообщение · #10

mysterio
мне нужно на winapi , а не через форму




Ранг: 260.9 (наставник)
Активность: 0.120
Статус: Участник
John Smith

Создано: 09 июня 2008 16:40
· Личное сообщение · #11

переопредели оконную функцию на свою(сабклась окно) и лови WM_XX, который тебя интересует

-----
Недостаточно только получить знания:надо найти им приложение




Ранг: 2.2 (гость)
Активность: 0=0
Статус: Участник

Создано: 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;



Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 09 июня 2008 17:35
· Личное сообщение · #13

uxer пишет:
procedure TForm1.Timer1Timer(Sender: TObject);

Говорят те на виапи чел пишет.

Mavlyudov лови WM_KEYDOWN в оконной процедуре

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74





Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 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.



Ранг: 2.2 (гость)
Активность: 0=0
Статус: Участник

Создано: 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.




Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 09 июня 2008 20:34 · Поправил: Mavlyudov
· Личное сообщение · #16

uxer
ну почти. твой вариант программы дает коды ТОЛЬКО для загавных клавиш.
Например, дает код для "B"=66, а для "b" (как мне нужно) он будет равен 98.

И сообщение выводится 2 раза, т.к. идет обработака WM_KEYDOWN и WM_KEYUP



Ранг: 2.2 (гость)
Активность: 0=0
Статус: Участник

Создано: 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.




Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 10 июня 2008 11:53
· Личное сообщение · #18

uxer
откуда такие извороты? и почему в файл вывод?
выводятся названия клавиш, а нужны коды



Ранг: 2.2 (гость)
Активность: 0=0
Статус: Участник

Создано: 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 —› Программирование —› Код нажатой клавиши
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати