Форум: "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.039 c