Форум: "Начинающим";
Текущий архив: 2010.01.10;
Скачать: [xml.tar.bz2];
ВнизПолучение сообщения о нажатии клавищи Найти похожие ветки
← →
ℓoℓ (2009-11-17 20:24) [0]Здравствуйте уважаемы мастера, возникла необходимость, что бы созданное моей программой окно получало сообщения о нажатии клавиш. Тут я видел ссылку на какой-то пример, тем не менее, нашел другой, работающий по тому же принципу, а именно - добавление hook (по русски хз) на клавиатуру. Вот код основной части
library KeyHook;
uses
SysUtils, Classes, Windows, Messages, Forms;
const
{пользовательские сообщения}
WM_Key = WM_User + 133;
var
SaveExitProc: Pointer;
HookHandle: hHook = 0;
Form: Pointer = nil;
{собственно ловушка}
function KeyboardHook(Code: integer; wParam: word;
lParam: Longint): Longint; stdcall; export;
var h, h2: HWnd;
begin
Result := 0;
{если Code>=0, то ловушка может обработать событие}
if (Code >= 0) and (lParam and $40000000 = 0) then
begin
h := FindWindow("TForm1", "Form1");
{h2 := TForm(Form).Handle;
if h <> h2
then
MessageBox(0, "Дискриптор найденного по имени окна" + #13 +
"не совпадает в дискрипотром заданного окна", "wtf?", mb_Ok);}
SendMessage(h, WM_Key, wParam, lParam);
{если 0, то система должна дальше обработать это событие}
{если 1 - нет}
Result := 0;
end
else if Code < 0 {если Code<0, то нужно вызвать следующую ловушку} then
Result := CallNextHookEx(HookHandle, Code, wParam, lParam);
end;
{при выгрузке DLL надо снять ловушку}
procedure LocalExitProc; far;
begin
if HookHandle <> 0 then
begin
UnhookWindowsHookEx(HookHandle);
ExitProc := SaveExitProc;
end;
end;
function TargetWindow: Pointer; export;
begin
Result := @Form;
end;
exports KeyboardHook, TargetWindow;
{инициализация DLL при загрузке ее в память}
begin
HookHandle := SetWindowsHookEx(wh_Keyboard, @KeyboardHook,
hInstance, 0);
if HookHandle = 0 then
MessageBox(0, "Unable to set hook!", "Error", mb_Ok)
else
begin
SaveExitProc := ExitProc;
ExitProc := @LocalExitProc;
end;
end.
Столкнулся с рядом проблем:
1. Работа с dll неудобна.
2. Все мои попытки передать дескриптор окна моей программы приводили к отсутствию всяких сообщений (в лучшем случае, работало когда мое окно было активно), т.е. приходиться искать окно по названию.
3. Код построен на основе чьего-то примера (я мало что изменил), автор предусмотрел удаление hook"a из очереди (или т.п.), но, после завершения exe программы, dll файл оказывается открытым (наблюдал через UnLocker) программой explorer.exe (Проводник), как следствие, dll файл не доступен к изменению. При удалении этой связи, иногда, перестают частично работать WM_... всех окон (не работает повтор символов при нажатой клавише и если нажать на кнопке (TButton) пробел - она так и останется нажатой), хотя, это было только при первом эксперименте и после перезагрузки ЭВМ повторно не проявлялось (вероятно я допустил тогда ошибку в коде).
Как я понял, причиной проблем является защита в ОС от сбоев (логично, ведь если эта dll окажется связанной с моей программой и я вызову ее отладку, то получится... не знаю что, но интересно, ведь тогда отладчик будет отлаживать системные hooks).
← →
Leonid Troyanovsky © (2009-11-17 21:46) [1]
> ℓoℓ (17.11.09 20:24)
> - добавление hook (по русски хз) на клавиатуру. Вот код
По-русски - это крючок, ну, или, хук (справа).
http://groups.google.com/group/fido7.ru.delphi.chainik/msg/ba088c4f6ad9649f
--
Regards, LVT.
← →
KilkennyCat © (2009-11-17 22:43) [2]
> 1. Работа с dll неудобна.
работать всегда неудобно.
> приходиться искать окно по названию
в этом нет ничего позорного
> 3. Код построен...
Да пофиг, что он так построен, это все-таки программирование, а не картины рисовать. Однозначно решаемая задача как правило, будет иметь похожие решения.
А вопрос в чем, я не понял.
← →
Юрий Зотов © (2009-11-17 22:56) [3]> Как я понял, причиной проблем является защита в ОС от сбоев
В 99% случаев причиной проблем является кривой код. Ваш случай - не исключение.
Вы нашли в Инете чей-то пример и скатали его один-в-один. А Вы его изучили, этот пример? Вы поняли, как он работает? Вы разобрались в нем досконально, до каждой буквы и запятой?
Спорю, что нет. Потому что иначе Вы не обошлись бы без изучения документации. А Вы ее и не смотрели, потому что wParam: word.
← →
котэ (2009-11-17 23:47) [4]
> Leonid Troyanovsky
спс за пример, буду разбираться
> KilkennyCat
вопрос задан как бы косвенно: как сделать global hotkey по людски.
> Юрий Зотов
обычно (из моего опыта) ошибки с неверным размером переменных (если они возникают) заканчиваются типа fatal exception и access violation.
> Вы нашли в Инете чей-то пример и скатали его один-в-один.
> А Вы его изучили, этот пример? Вы поняли, как он работает?
> Вы разобрались в нем досконально, до каждой буквы и запятой?
...если бы я это сделал, то писал бы в конкретной теме, а не в «Начинающим».
Большую часть этого кода я понимаю. Не понимаю, что такое ExitProc и почему, если убрать с этого комментатор {}, программа перестает работать (у меня):{h2 := TForm(Form).Handle;
if h <> h2
then
MessageBox(0, "Дискриптор найденного по имени окна" + #13 +
"не совпадает в дискрипотром заданного окна", "wtf?", mb_Ok);}
← →
котэ (2009-11-17 23:49) [5]у меня просто есть определенная проблема, она для меня большая, я пытаюсь возле нее пригреться так сказать
← →
Юрий Зотов © (2009-11-18 00:02) [6]> котэ
http://sources.ru/delphi/dll/hooks_aspects.shtml
http://social.msdn.microsoft.com/Search/ru-RU?query=SetWindowsHookEx&ac=3
← →
Дмитрий Белькевич (2009-11-18 00:08) [7]Рекомендую скачать архивы конференции и натравить на них Яндекс - персональный поиск:
персональный поиск - CallNextHookEx - Документы 956.
Уже тысячу раз обсуждалось.
← →
Дмитрий Белькевич (2009-11-18 00:09) [8]Ну или на ксаямовский сайт: http://xayam.kilkennycat.ru/
← →
Cobalt © (2009-11-18 14:19) [9]> вопрос задан как бы косвенно: как сделать global hotkey
> по людски.
Тогда может тебе поможет
The WM_HOTKEY message is posted when the user presses a hot key registered by the RegisterHotKey function. The message is placed at the top of the message queue associated with the thread that registered the hot key.
← →
котэ (2009-11-18 20:57) [10]
> Cobalt
просто хотелось бы на все клавиши, а так придется по одной делать.
В общем-то, сделал через хуки, спасибо за статьи, исходники и ссылку на поисковик. К сожалению, немного плаваю в этой теме, поэтому трудно искать.
Только я не нашел информации о том, что будет если моя программа вырубится (например я в диспетчере задач процесс закрою) когда она "зацеплена" за клаву?
← →
Leonid Troyanovsky © (2009-11-19 11:36) [11]
> котэ (18.11.09 20:57) [10]
> Только я не нашел информации о том, что будет если моя программа
> вырубится
Хук - собственность потока, его установившего.
Т.е., он умрет вместе с потоком.
Если хук был в длл, то она будет выгружаться из зацепленных
процессов при очередном отлавливаемом событии.
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.01.10;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.005 c