Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.11.19;
Скачать: [xml.tar.bz2];

Вниз

Вопрос про установку глобального хука   Найти похожие ветки 

 
leonidus ©   (2006-07-03 21:30) [0]

Уважаемые мастера подскажите пожалуйста как мне поставить такой глобальный хук: хук ставится на щелчок правой клавиши мыши, после этого если пользователь нажимает скажем Ctrl и щелкает правой клавишей мыши, то хук срабатывает отсылая моему окну некое сообщение и при этом не дает отобразиться контекстному меню которое как правило во всех приложениях отображается по щелчку правой клавиши мыши. В остальных случаях (когда щелчок правой клавишей мыши произведен но Ctrl не нажат) все работает в обычном режиме, т.е. щелчки правой клавишей в любом приложении вызывают появление контекстного меню данного приложения.
 
Я делаю так, создаю dll`ку в которой есть функция получающая управления при перехвати действий мыши:

function Mouse_SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
var H: HWND;
begin
if (Code=HC_ACTION) then
 begin
  H := FindWindow("TForm1", "XXX");

//тут проверяю факт нажатия правой клавиши мыши и Ctrl`а
if (wParam = WM_RBUTTONDOWN) AND (HiWord(GetAsyncKeyState(VK_LCONTROL))<>0)    then
   SendMessage(H, wm_RightMouse_Event, 0, 0);
 end;

 Result:= CallNextHookEx(Mouse_SysHook, Code, wParam, lParam);
end;

Этот код позволяет мне узнать что нажата правая клавиша мыши и Ctrl, но не позволяет предотвратить появление контекстного меню. Как мне это сделать?


 
Leonid Troyanovsky ©   (2006-07-03 22:58) [1]


> leonidus ©   (03.07.06 21:30)  

> if (wParam = WM_RBUTTONDOWN) AND (HiWord(GetAsyncKeyState>  


Почему, собс-но, GetAsyncKeyState?
IMHO, этот вопрос уже задавался.
Ну, а про остальные вопросы можно и после.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-07-03 23:05) [2]


> leonidus ©   (03.07.06 21:30)  

> Уважаемые мастера подскажите пожалуйста как мне поставить
> такой глобальный хук: хук ставится на щелчок правой клавиши
> мыши, после этого если пользователь нажимает


WH_MOUSE_LL, этот ответ (LL), IMHO, уже давался.
Т.е., даже без dll.

--
Regards, LVT.


 
leonidus ©   (2006-07-03 23:13) [3]

Леонид, а чем вам не нравится GetAsyncKeyState, чем его можно заменить? Разве в данном случае это вообще принципиально, ведь как раз определение факта нажатия Ctrl срабатывает нормально? И потом как вы предлагаете установить глобальный хук без dll? Простите что столько вопросов, я просто совсем не понял ваших ответов...


 
Leonid Troyanovsky ©   (2006-07-03 23:26) [4]


> leonidus ©   (03.07.06 23:13) [3]

> Леонид, а чем вам не нравится GetAsyncKeyState, чем его
> можно заменить? Разве в данном случае это вообще принципиально,
>  ведь как раз определение факта нажатия Ctrl срабатывает
> нормально? И потом как вы предлагаете установить глобальный
> хук без dll? Простите что столько вопросов, я просто совсем


GetKeyboardState vs GetAsyncKeyState.
WM_MOUSE vs  WM_MOUSE_LL

Все это можно почерпнуть из http://msdn.microsoft.com

--
Regards, LVT.


 
Lamer@fools.ua ©   (2006-07-03 23:31) [5]

>function Mouse_SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;

[OFFTOPIC] Уже устал спрашивать: откуда многие этот бред берут?


 
leonidus ©   (2006-07-04 08:54) [6]

Леонид, подскажите пожалуйста как с WM_MOUSE_LL работать? Искал на MSDN "WM_MOUSE_LL" но не нашел, Яндекс вообще молчит, поясните пожалуйста хотябы как вы видите решение этой проблемы.


 
второе явление Чапаева народу   (2006-07-04 09:57) [7]


> >function Mouse_SysMsgProc(code : integer; wParam : word;
>  lParam : longint) : longint; stdcall;
>
> [OFFTOPIC] Уже устал спрашивать: откуда многие этот бред
> берут?

Из Win16, где WPARAM <=> Word...


> Леонид, подскажите пожалуйста как с WM_MOUSE_LL работать?
>  Искал на MSDN "WM_MOUSE_LL" но не нашел

Дядя пошутил. Имелось в виду SetWindowsHookEx()+WH_MOUSE_LL.


 
leonidus ©   (2006-07-04 10:40) [8]

Ок, я понял что нужно глобальный хук, я просто не нашел сообщение WH_MOUSE_LL, поясните поажлуйста как оно работает.


 
Ketmar ©   (2006-07-04 11:30) [9]

странно. а я нашёл. что я сделал неправильно?

LL -- это "низкоуровневый" хук. работает по всей системе, не требует DLL. если упрощённо, то вызывается сразу после того, как драйвер сгенерировал событие, но до того, как это событие будет проинтерпретировано.


 
второе явление Чапаева народу   (2006-07-04 11:38) [10]


> я просто не нашел сообщение WH_MOUSE_LL

Логично. Потому как такого сообщения ещё не придумали.


 
Ketmar ©   (2006-07-04 11:56) [11]

более того, LL-констант нет в заголовочных файлах Delphi. %-)


 
leonidus ©   (2006-07-04 11:56) [12]

Ок, делаю в самой программе без использования dll так:

 
var
Mouse_SysHook:HHook = 0;

implementation
{$R *.dfm}

function tform1.Mouse_SysMsgProc(code : integer; wParam : word; lParam : longint) : longint;
var H: HWND;
begin
if (Code=HC_ACTION) then
 begin
  if wParam = WM_RBUTTONDOWN then form1.Label1.Caption:="wm_RightMouse_Event";
 end;
 Result:= CallNextHookEx(Mouse_SysHook, Code, wParam, lParam);
end;

procedure tform1.hook(switch : Boolean);
begin
 if switch=true then
 begin
   Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);
   if Mouse_SysHook <> 0 then MessageBox(0, "Хук на мышь установлен", "", 0)
     else MessageBox(0, "Хук на мышь установить не удалось", "", 0);
 end
  else
   begin
    if UnhookWindowsHookEx(Mouse_SysHook) then MessageBox(0, "Хук на мышь снят", "", 0)
     else MessageBox(0, "Хук на мышь снят не удалось", "", 0);

    Mouse_SysHook := 0;
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//установить хук
hook(true);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
//снять хук при выходе из программы
hook(false);
end;


 
leonidus ©   (2006-07-04 11:58) [13]

но на строчку:     Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);
компилятор ругается на WH_Mouse_LL, что делать?


 
Игорь Шевченко ©   (2006-07-04 12:06) [14]


> WH_Mouse_LL


const
 WH_Mouse_LL = 14;


 
leonidus ©   (2006-07-04 13:07) [15]

Ни чего не понимаю, теперь в
   Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);

ругается на HInstance... может я уже туплю, но код скопировал прямо из dll`ки в которой все работало прекрасно


 
Игорь Шевченко ©   (2006-07-04 13:37) [16]


> ругается на HInstance


Дорогой друг, кроме фразы "ругается" желательно еще приаттачить скриншот экрана твоего монитора в момент ругани, а так же до ругани и после ругани.


 
leonidus ©   (2006-07-04 13:48) [17]

Компилятор выделяет строчку
Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);
ставит курсор на HInstance и пишет: "Variable required"


 
Ketmar ©   (2006-07-04 13:51) [18]

кстати, я тут заметил: а может, просто надо "съёдать" событие, когда оно не должно происходить? т.е. возвращать "не ноль" и не вызывать следующий хук при помощи CallNextHookEx()? а то мы тут уже полезли в LL-хуки... %-)


 
leonidus ©   (2006-07-04 14:07) [19]

я пробовал делать так:

if (wParam = WM_RBUTTONDOWN) and (HiWord(GetAsyncKeyState(VK_LCONTROL))<>0) then  
begin
 form1.Label1.Caption:="wm_RightMouse_Event";
end
 else
  Result:= CallNextHookEx(Mouse_SysHook, Code, wParam, lParam);

т.е. следующему хуку упраление передавалось только если нет одновременного нажатия на Ctrl и правую клавишу мыши, а если они нажаты одновременно то CallNextHookEx управление не передается, но после такого трюка система вообще перестает реагировать на клики мыши, поэтому пришлось от этого отказаться.


 
Ketmar ©   (2006-07-04 14:22) [20]

странно. %-)


 
leonidus ©   (2006-07-04 14:40) [21]

Я всеже не пойму почему на HInstance компилятор ругается, и в тоже время туже строчку в dll`ке компилирует нормально.


 
Игорь Шевченко ©   (2006-07-04 17:26) [22]


> function tform1.Mouse_SysMsgProc(code : integer; wParam
> : word; lParam : longint) : longint;


Убрать TForm1 из объявления


 
Игорь Шевченко ©   (2006-07-04 17:28) [23]

unit Unit1;

interface

uses
 Windows, Classes, Controls, Forms,
 StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 end;

var
 Form1: TForm1;

const
 WH_Mouse_LL = 14;

implementation

{$R *.DFM}

var
 Mouse_SysHook: HHOOK;

function Mouse_SysMsgProc(code: integer;
 wParam: longint; lParam : longint):longint; stdcall;
begin
 Result := CallNextHookEx(Mouse_SysHook, Code, wParam, LParam);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);
end;

end.

Не ругается


 
Gero ©   (2006-07-04 18:04) [24]

Только стоит принять во внимание, что WH_MOUSE_LL отсутствует в Windows 9x/Me.


 
Leonid Troyanovsky ©   (2006-07-04 18:30) [25]


> второе явление Чапаева народу   (04.07.06 09:57) [7]

> Дядя пошутил.


Не, просто, описАлся, чисто машинально.

Sorry.

--
Regards, LVT.


 
leonidus ©   (2006-07-04 20:07) [26]

Игорь, большое спасибо. Теперь вроде разобрался и вернулся к первому вопросу, как в случае если нажата "горячая клавиша" - скажем Ctrl, и произведен клик правой клавишей мыши не допустить появления контекстного меню в каком-либо приложении?

Пишу такой код:

const
WH_Mouse_LL = 14;

var
 Form1: TForm1;
 Mouse_SysHook: HHOOK;

implementation

{$R *.dfm}

function Mouse_SysMsgProc(code: integer;
wParam: longint; lParam : longint):longint; stdcall;
begin
if (Code=HC_ACTION) then
 if (wParam = WM_RBUTTONDOWN) and (HiWord(GetAsyncKeyState(VK_LCONTROL))<>0) then
  begin
   form1.Label1.Caption:="wm_RightMouse_Event";
   result:=1;
  end
  else
   begin
    form1.Label1.Caption:="";
    Result := CallNextHookEx(Mouse_SysHook, Code, wParam, LParam);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
UnhookWindowsHookEx(Mouse_SysHook);
end;

но после определения того что нажат Ctrl и правая клавиша мыши, контекстное меню всеравно благополучно появляется. Что я делаю не так?


 
leonidus ©   (2006-07-05 15:47) [27]

Господа подскажите пожалуйста


 
guav ©   (2006-07-05 18:15) [28]

к. меню появляется при отпускании мыни


 
leonidus ©   (2006-07-05 22:12) [29]

блин точно, сейчас попробую WM_RBUTTONUP


 
leonidus ©   (2006-07-06 07:58) [30]

В общем вот последняя редакция кода:

const
WH_Mouse_LL = 14;

var
 Form1: TForm1;
 Mouse_SysHook: HHOOK;

implementation

{$R *.dfm}

function Mouse_SysMsgProc(code: integer;
wParam: longint; lParam : longint):longint; stdcall;
begin
if (Code=HC_ACTION) then
 if (wParam = WM_RBUTTONUP) and (HiWord(GetAsyncKeyState(VK_LCONTROL))<>0) then
  begin
   form1.Label1.Caption:="wm_RightMouse_Event";
   result:=-1;
  end
  else
   begin
    form1.Label1.Caption:="";
    Result := CallNextHookEx(Mouse_SysHook, Code, wParam, LParam);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Mouse_SysHook := SetWindowsHookEx(WH_Mouse_LL, @Mouse_SysMsgProc, HInstance, 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if UnhookWindowsHookEx(Mouse_SysHook) then MessageBox(0, "Хук на мышь снят", "", 0)
end;

На этот раз все работае нормально, прекрасно перехватывается нажанием Ctrl и правый клик мыши  и предотвращается появление контекстного меню, но вот проблема в том, что сразу после этого мое приложение подвисает до того момента пока я не кликну еще раз правой клавишей и параллельно система престает реагировать на левый клик мыши. После одного рпавого клика, все становится на свои места.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.11.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.041 c
5-1143640846
Gaval
2006-03-29 18:00
2006.11.19
fastreport


2-1162635752
Savek
2006-11-04 13:22
2006.11.19
TQRCompositeReport, количество страниц


15-1162148722
Petr V.Abramov
2006-10-29 22:05
2006.11.19
сможет ли взлететь реактивный самолет


2-1162462779
pasha_golub
2006-11-02 13:19
2006.11.19
Как поймать сообщение посланное для Application.Handle?


1-1160321075
flaxe
2006-10-08 19:24
2006.11.19
Встраивание в другие программы





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский