Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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]


> &#8467;o&#8467;   (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.004 c
1-1232969686
Валера
2009-01-26 14:34
2010.01.10
Как узнать версию Office?


15-1257793401
xtest
2009-11-09 22:03
2010.01.10
Не могу добавить СЮДА свой вопрос.


15-1257509410
Огненный_дракон
2009-11-06 15:10
2010.01.10
Удалённое включение компьютера


2-1258308164
&#8467;o&#8467;
2009-11-15 21:02
2010.01.10
Клавиатура в замену джостику


2-1258287355
sagitt
2009-11-15 15:15
2010.01.10
Не работает отладчик





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский