![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как по хуку клавиатуры получить русские буквы? [D7, WinXP]
Aleksandr. © (2004-11-09 13:08:00)Попытался по-простому: сделал dllку с хуком на клавиатуру, все, что она делает - швыряет сообщение без изменений моему приложению, а то пересылает его обычному Memo, но уже с командой WM_KEYDOWN. И все зюквы, понятно, получаются латинскими. Соответственно, попробовал получать KeyBoardLayout приложения, в котором была нажата клавиша, чтобы включить соответствующую раскладку в приемнике, но вот нифига оно не получается:
function KeyboardProc(code: integer; wParam: longint; lp: longint): longint; stdcall;
var
H : HKL;
hw: HWND;
c : cardinal;
d : cardinal;
begin
Result:=0;
if code<0 then
Result:=CallNextHookEx(GlobalHook,Code,wParam,lP)
else begin
if Code IN [HC_ACTION, HC_NOREMOVE] then begin
if (LP shr 16) AND KF_UP=0 then begin
HW:=GetForeGroundWindow();
if (HW=0) OR (HW=ReceiveWnd) then
h:=GetKeyBoardLayout(0) AND $FFFF
else begin
d:=GetWindowThreadProcessID(HW,@c);
H:=GetKeyboardLayout(D) AND $FFFF;
end;
if h=$419 then
PostMessage(ReceiveWnd,WM_KEYHOOKRus,WParam,LP)
else
PostMessage(ReceiveWnd,WM_KEYHOOKEng,WParam,LP);
end
end
else
Result:=CallNextHookEx(GlobalHook, Code, wParam, lp)
end
end;
// код в приложении-приемнике:
procedure TKeyHooker.WndProc(var Message: TMessage);
begin
if Message.Msg=WM_KEYHOOKRus then begin
if GetLayout<>aglRus then
SetLayout(aglRus);
PostMessage(Memo.Handle,WM_KEYDOWN,Message.WParam,Message.LParam)
end
else if Message.Msg=WM_KEYHOOKEng then begin
if ri_utils.GetLayout<>aglEng then
ri_utils.SetLayout(aglEng);
PostMessage(Memo.Handle,WM_KEYDOWN,Message.WParam,Message.LParam)
end
else
Inherited
end;
Почему не удается получить локале приложения, получившего сообщение, или есть какой-то истчо способ получить реально нажатую клавишу? В Инете сотни страничек с описаниями хука, но все они повторяют три примера (один из которых истчо и с ошибкой - один упустил, а другие бездумно копировали), и ни один не описывает, как получить русскую зюкву.
Wiz@rd (2004-11-09 22:02:00) [1]Этот код из моего троя - прошёл огонь, воду, медные трубы и витую пару, и всё было ok
Aleksandr. (2004-11-09 20:24:00) [2]Wiz@rd :
А у себя вариант с вводом адреса в IE не пробовали?
Wiz@rd (2004-11-09 19:50:00) [3]Да какая разница какая структура, это у меня кейлог из длл в главное приложение данные посылал, просто там где нужно поставь свой wparam, lparam...
Aleksandr. (2004-11-09 19:48:00) [4]Wiz@rd :
Странно. Я попробовал счас повторить ситуацию через WM_CopyData по аналогии с Вашим кодом, опять повторил эксперимент: набрал адрес в эксплорере и нажал Enter, и опять та же AV вылетела. К слову сказать, все до единого самплы (и приведенный на этом сайте) в этой ситуации выдают AV. TWMHookStruct - это же Ваша структура?
Wiz@rd (2004-11-09 19:07:00) [5]Нет, никаких AV не было
Aleksandr. (2004-11-09 17:59:00) [6]Игорь Шевченко © :
Гы, дык если бы для энтого, я бы готовыми обошелся как-нить... Нетрудно прогнать два варианта - латинский и конвертнутый в русский. Я вообще начал с того, что нужно было кое-какие сообщения просмотреть в рабочем приложении, а потом решил - а чего бы тогда и универсальное не сделать, по галочке врубать нужные хуки... И резко приплыл на русских буквах. Теперь с ними управился, и пытаюсь понять природу AV для типов WH_KEYBOARD, WH_GetMessage...
Игорь Шевченко (2004-11-09 17:51:00) [7]
> только те, кого устраивали примерчики для хака паролей,
> все рисующие только большими латинскими буквами...
Ибо нефиг хакать пароли, написанные русскими буквами
Aleksandr. (2004-11-09 17:49:00) [8]2 Wiz@rd :
Круто! Скажите, а у Вас вышеупомянутые мной AV не вылетали?
Aleksandr. (2004-11-09 17:46:00) [9]Digitman © :
Спасибо за добрые и ласковые ответы... Что-то никаких примеров от Вас я не видел, так что кто тут гнет пальцы? Или посмотрите сами на самплы, в том числе присутствующие и на сем славном сайте.
С получением русских букв я разобрался, перенеся получение текущего HKL в WndProc приложения. Истчо бы понять, почему приложения типа ICQ или IE AV выкидывают в дллке при вводе адреса либо сообщения и нажатия Enter.
Wiz@rd (2004-11-09 17:40:00) [10]Вот как я делал (главное сюда передать wparam, lparam), думаю всё понятно:
procedure OnKeyHookEx (CDS: TCopyDataStruct);
var
S: String;
c: char;
ClassName: array [0..255] of Char;
Buffer: array [0..50] of Char;
Flags : Word;
NeedLog: Boolean;
ks: TKeyboardState;
kl: HKL;
shift: Boolean;
WMHookStruct: TWMHookStruct;
begin
if CDS.dwData <> CD_KEYMESSAGE then Exit;
WMHookStruct := PWMHookStruct (CDS.lpData)^;
NeedLog := False;
GetKeyNameText (WMHookStruct.lParam, @Buffer, SizeOf(Buffer));
GetKeyboardState (ks);
kl := GetKeyboardLayout (GetWindowThreadProcessId (GetForegroundWindow));
ToAsciiEx (WMHookStruct.wParam, MapVirtualKey(WMHookStruct.wParam, 0), ks, @c, 0, KL);
shift := GetKeyState (VK_SHIFT) <> 0;
if (Ord (c) in [Ord('A')..Ord('Z')]) or (Ord (c) in [Ord('a')..Ord('z')]) or
(Ord (c) in [Ord('А')..Ord('Я')]) or (Ord (c) in [Ord('а')..Ord('я')]) then
begin
S := c;
if Shift then
c := char(Ord(c) + 32);
end
else
if (Ord(c) in [32..64, 91..96, 123..191]) then
begin
s := c;
end;
Flags := WMHookStruct.lParam shr 16;
if (Flags and KF_UP) <> 0 then
begin
//S := S + ' down'
end
else
if (Flags and KF_REPEAT) <> 0 then
begin
//S := S + ' repeat'
end
else
begin
//S := S + ' up';
NeedLog := True;
//Beep(500, 100);
end;
//s - здеся результат
end;
Digitman (2004-11-09 17:27:00) [11]
> Aleksand
прежде чем гнуть пальцы разберись, что есть "буква", а что есть "код символа"
разберись так же в том, какое отношение KeyboardLayout имеет к CodePage
Aleksandr. (2004-11-09 14:36:00) [12]Мда. Похоже, в теории весь дельфийский инет силен, а на практике пользовались только те, кого устраивали примерчики для хака паролей, все рисующие только большими латинскими буквами...
Digitman (2004-11-09 13:24:00) [13]
> И все зюквы, понятно, получаются латинскими
"зюква" - этт-о чтот-то