Форум: "WinAPI";
Текущий архив: 2004.12.26;
Скачать: [xml.tar.bz2];
ВнизКак по хуку клавиатуры получить русские буквы? Найти похожие ветки
← →
Aleksandr. (2004-11-09 13:08) [0]Попытался по-простому: сделал 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;
Почему не удается получить локале приложения, получившего сообщение, или есть какой-то истчо способ получить реально нажатую клавишу? В Инете сотни страничек с описаниями хука, но все они повторяют три примера (один из которых истчо и с ошибкой - один упустил, а другие бездумно копировали), и ни один не описывает, как получить русскую зюкву.
← →
Digitman © (2004-11-09 13:24) [1]
> И все зюквы, понятно, получаются латинскими
"зюква" - этт-о чтот-то
← →
Aleksandr. (2004-11-09 14:36) [2]Мда. Похоже, в теории весь дельфийский инет силен, а на практике пользовались только те, кого устраивали примерчики для хака паролей, все рисующие только большими латинскими буквами...
← →
Digitman © (2004-11-09 17:27) [3]
> Aleksand
прежде чем гнуть пальцы разберись, что есть "буква", а что есть "код символа"
разберись так же в том, какое отношение KeyboardLayout имеет к CodePage
← →
Wiz@rd (2004-11-09 17:40) [4]Вот как я делал (главное сюда передать 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;
← →
Aleksandr. (2004-11-09 17:46) [5]Digitman © :
Спасибо за добрые и ласковые ответы... Что-то никаких примеров от Вас я не видел, так что кто тут гнет пальцы? Или посмотрите сами на самплы, в том числе присутствующие и на сем славном сайте.
С получением русских букв я разобрался, перенеся получение текущего HKL в WndProc приложения. Истчо бы понять, почему приложения типа ICQ или IE AV выкидывают в дллке при вводе адреса либо сообщения и нажатия Enter.
← →
Aleksandr. (2004-11-09 17:49) [6]2 Wiz@rd :
Круто! Скажите, а у Вас вышеупомянутые мной AV не вылетали?
← →
Игорь Шевченко © (2004-11-09 17:51) [7]
> только те, кого устраивали примерчики для хака паролей,
> все рисующие только большими латинскими буквами...
Ибо нефиг хакать пароли, написанные русскими буквами
← →
Aleksandr. (2004-11-09 17:59) [8]Игорь Шевченко © :
Гы, дык если бы для энтого, я бы готовыми обошелся как-нить... Нетрудно прогнать два варианта - латинский и конвертнутый в русский. Я вообще начал с того, что нужно было кое-какие сообщения просмотреть в рабочем приложении, а потом решил - а чего бы тогда и универсальное не сделать, по галочке врубать нужные хуки... И резко приплыл на русских буквах. Теперь с ними управился, и пытаюсь понять природу AV для типов WH_KEYBOARD, WH_GetMessage...
← →
Wiz@rd (2004-11-09 19:07) [9]Нет, никаких AV не было
← →
Aleksandr. (2004-11-09 19:48) [10]Wiz@rd :
Странно. Я попробовал счас повторить ситуацию через WM_CopyData по аналогии с Вашим кодом, опять повторил эксперимент: набрал адрес в эксплорере и нажал Enter, и опять та же AV вылетела. К слову сказать, все до единого самплы (и приведенный на этом сайте) в этой ситуации выдают AV. TWMHookStruct - это же Ваша структура?
← →
Wiz@rd (2004-11-09 19:50) [11]Да какая разница какая структура, это у меня кейлог из длл в главное приложение данные посылал, просто там где нужно поставь свой wparam, lparam...
← →
Aleksandr. (2004-11-09 20:24) [12]Wiz@rd :
А у себя вариант с вводом адреса в IE не пробовали?
← →
Wiz@rd (2004-11-09 22:02) [13]Этот код из моего троя - прошёл огонь, воду, медные трубы и витую пару, и всё было ok
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.12.26;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.035 c