Вниз
Скачать: CL | DM;

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

← →
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 вся ветка

Скачать: CL | DM;



Память: 0.53 MB
Время: 0.028 c
11-1139146742
Ganda1f
2006-02-05 16:39
2006.11.19
STL для дельфи (тестируем)


15-1162300387
Rule
2006-10-31 16:13
2006.11.19
Интересуюсь компонтой типа встроенного веб броузера


2-1162465442
dima_shapkin
2006-11-02 14:04
2006.11.19
Tform


2-1162458819
DVM
2006-11-02 12:13
2006.11.19
Как в SQL INSERT INTO указать правильное значение для счетчика?


15-1162444291
Slider007
2006-11-02 08:11
2006.11.19
С днем рождения ! 2 ноября




   Наверх