Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

подмена параметров в CallNextHookEx


Fdu4 ©   (2003-06-24 21:11:00) 

я делаю хук на клавиатуру ( WH_KEYBOARD). после выполнения моей процедуры я вызываю стандартную процедуру обработки нажатия с помощью ( ShareInf^.OldHookHandle, Code, ParamW, ParamL)

я делаю хук на клавиатуру ( WH_KEYBOARD). после выполнения моей процедуры я вызываю стандартную процедуру обработки нажатия с помощью

Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, ParamW, ParamL)

но почему ничего не меняет если я изменяю ParamW и ParamL ? Стандартная процедура никак не реагирует... я же хочу чтобы она подумала, будто была нажата другая клавиша... помогите пожалуйста!


Юрий Зотов   (2003-06-28 17:45:00) [1]

> Fdu4 © (28.06.03 15:56)

Только имейте в виду, что пример глобального хука в этой статье некорректен. Позже Алексей написал на эту тему другую статью, где подробно рассмотрел детали и пример переписал. Она тоже есть на сайте.

Еще один пример глобального хука см. здесь:
http://www.delphimaster.ru/cgi-bin/forum.pl?look=1&id=1056759260&n=5


Fdu4   (2003-06-28 15:56:00) [2]

:))) ВНИМАНИЕ!!!

Всем спасибо, я разобрался... понял вроде всё что хотел понять и сделал... всё пашет.... а нашёл я всё что мне надо в этом примере: http://www.delphimaster.ru/articles/dll_use/index.html

спсибо его создателю и всем вам! ...

до таких вещей как TMsg(Pointer(ParamL)^).я пока не в состоянии допирать сам :)

теперь осталось разобраться только в приколах кодировки... что-то там странное происходит :) ... ну если что, потом спрошусь отдельной темой...

всем исчо 1 раз спасибо! :)


Fdu4   (2003-06-28 14:02:00) [3]

> Юрий Зотов © (28.06.03 10:27)

спасибо огромное! это как раз то что мне нужно.... сегодня даже нашёл подтверждение вашим словам тут: <a href=" http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B33690"> http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B33690</a>

но из меня программер пока неважный, потому было б очень здорово, если бы Вы мне ответили на пару ключевых вопросов:

1. как мне определить что сообщение пришло от клавиатуры? (я понимаю, что надо анализировать LParam, и то что он является указателем на структуру типа MSG, но КАК ИМЕННО это сделать, не пойму...) (я бы хотел иметь дело именно с символами... то есть реагировать на WM_CHAR... или я несу бред?)

2. я бы хотел иметь дело именно с символами... означает ли это, что мне надо использовать TranslateMessage? Но почему-то, когда я пытаюсь скормить этой функции мой LParam, Delphi говорит мне про несовместимость типов... хотя в MSDN-описаниях написано, что как LParam, так и входной параметр этой функции имеют один тип, а именно "[in] Pointer to an MSG structure that contains details about the message." :(

помогите, пожалуйста! Спасибо Вам за внимание.


Юрий Зотов   (2003-06-28 10:27:00) [4]

> Fdu4 © (28.06.03 01:30)

Ну, положим, Ваша переменная будет глобальной только в рамках Вашей программы, а тут нужна глобальность на уровне всей системы. Так что забудьте об этом способе. А пример создания нужной переменной у Вас, похоже, уже есть - это OldHookHandle.

Только я бы, пожалуй, не боролся с зацикливанием, а изменил тип ловушки на WH_GETMESSAGE. Этот тип позволяет модифицировать параметры сообщения, чего не позволяют клавиатурные хуки. Думаю, такой способ будет проще.


Fdu4   (2003-06-28 01:30:00) [5]

я попробовал заменить мьютекс на глобальную переменную.... не помогло... я объявил её в отдельном юните:

unit Unit1;

interface
var
Leuft: boolean= true;

implementation

end.


в хуке в usesдобавилось Unit1 in "Unit1.pas";...

сам код хука переделал так:

if Leuft then
begin
If Chr(ParamW)="X" then
begin
Leuft:= false;
keybd_event( ParamW, 0, 0, 0 );
Result := 1;
Leuft:= true;
end
else
Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, ParamW, ParamL)
end
else
( ShareInf^.OldHookHandle, Code, ParamW, ParamL)

я попробовал заменить мьютекс на глобальную переменную.... не помогло... я объявил её в отдельном юните:

unit Unit1;

interface
var
Leuft: boolean= true;

implementation

end.


в хуке в usesдобавилось Unit1 in "Unit1.pas";...

сам код хука переделал так:

if Leuft then
begin
If Chr(ParamW)="X" then
begin
Leuft:= false;
keybd_event( ParamW, 0, 0, 0 );
Result := 1;
Leuft:= true;
end
else
Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, ParamW, ParamL)
end
else
Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, ParamW, ParamL);


но не смотря на глобальную переменную он всё равно входит в зацикл... где я напортачил? :((


Fdu4   (2003-06-27 16:09:00) [6]

спасибо Cobalt за идею... только боюсь мне её не реализовать в силу некоторой дельфи-неграмотности ... не мог бы Ты привести нужные мне для этого строчки (голые функции, процедуры и тд и тп)... с тем где устанавливать и где сбрасывать переменную думаю сам разобраться смогу... мне только средства нужны. или дай хотя бы ссылку где я про них прочесть могу... ибо сам ничего толкового не нашёл.

было б здорово. спасибо.


Cobalt   (2003-06-27 10:57:00) [7]

Имхо, тут нужен не мьютекс (ведь "владельцем мьютекса" может быть только конкретный поток, а "хук"), а достаточно прото глобальной переменной в мап-файле.
Перед тем, как посылать keybd_event устанавливаешь переменную (скажем, в 1).
При приеме проверяешь, если переменная устанвлена, значит не обрабатываем её. А саму переменную сбрасываешь.

Или сбрасывать надо после посылки сообщения? надо уточнить, что происходит позднее - возврат из keybd_event, или обработка события хуками.


Fdu4   (2003-06-26 23:24:00) [8]

попробовал мьютекс. не вышло. что я сделал не так?

ниже приведённый кусок кода из хука при нажатии "X" входит в зацикл... => мьютекс не выполнил миссию... или я не так проверку произвожу?

Mutex := CreateMutex(nil, False, "MyMutex");
if GetLastError <> ERROR_ALREADY_EXISTS then
begin
If Chr(ParamW)="X" then
begin
keybd_event( ParamW, 0, 0, 0 );
Result := 1;
end
else
Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, ParamW, ParamL)
end;
( Mutex)

попробовал мьютекс. не вышло. что я сделал не так?

ниже приведённый кусок кода из хука при нажатии "X" входит в зацикл... => мьютекс не выполнил миссию... или я не так проверку произвожу?

Mutex := CreateMutex(nil, False, "MyMutex");
if GetLastError <> ERROR_ALREADY_EXISTS then
begin
If Chr(ParamW)="X" then
begin
keybd_event( ParamW, 0, 0, 0 );
Result := 1;
end
else
Result := CallNextHookEx(ShareInf^.OldHookHandle, Code, ParamW, ParamL)
end;
CloseHandle(Mutex);



Aleksey Pavlov   (2003-06-26 11:32:00) [9]

Имитируешь нажатие - создаёшь мьютекс.
Принял сообщение о нажатии - проверяешь стоит ли мьютекс, если стоит, то не обрабатываешь, освобождаешь мьютекс.
Схема примерно такая.


Fdu4   (2003-06-25 18:53:00) [10]

мдя... окей.. опишу ситуацию подробнее.... мне нужно отлавливать сиволы, приходящие с клавиатуры и заменять изх на другие... для этого я и хотел подмениьт параметры.... то есть, например, я сижу в аське, жму на кнопку с буквой "ч" (при русской раскладке) ... и моя прога делает так, что в асе из-под курсора вылазит "4" ... и так далее... или вообще преобразовывает мою кириллицу в транслит... причём нужно мне это не только для аси, а для всей винды, глобально....
я всё сделаю сам... подскажите только, как можно (изящней всего) сделать эту "подмену"...

я пробовал блокировать нажатие и после этого иммитировать нажатие нужной мне клавиши.... но! после того как я программно нажимаю нужную клавишу, мой то это нажатие всё равно проходит через мой хук и получается зацикл... как указать моему хуку, что это всего лишь иммитация нажатия, причём сделанная им же, чтобы он не обрабатывал эту иммитацию? помогите пожалуйста!


Axis_of_Evil   (2003-06-25 11:09:00) [11]

Result или Code меняй.
RTFM


Song   (2003-06-25 08:39:00) [12]

WH_KEYBOARD не подходит для этой цели.


Suntechnic   (2003-06-25 01:55:00) [13]

Потому что хуки по своей природе ничего не меняют. Это средство мониторинга, а не хака. Если ты поменяешь значения wParam, lParam и вызовешь CallNextHookEx, то ты всего лишь "обманешь" следующий хук в цепочке хуков, но самим окнам от этого ни холодно и ни жарко.


Наверх

Титульная страница Поиск, карта сайта Написать письмо