Текущий архив: 2005.10.02;
Скачать: CL | DM;
Вниз
Проблемы с установкой глобального хука Найти похожие ветки
← →
SergP © (2005-09-10 19:57) [0]Нужно установить хук. Для начала решил поэкспериментировать. Но почему-то не работает так как нужно...
Мне не доводилось раньше устанавливать хуки, поэтому ногами не бейте...
Пользуясь примером, который есть на этом сайте, сделал так:
Вобщем устанавливаю хук, при возникновении какого-нить события вызывается PostMessage, а уже в проге я ловлю эту месагу и вывожу в memo1 хендл окна и сообщение, которые были отловлены в dll
Проблема в том, что если я (в выделеной жирным части кода) пытаюсь выделить все сообщения десктопу, например (if Wnd=0 then) то десктоп начинает глючить. Если все, кроме моей проги, (if Wnd<>MyHandle then) то глючить начинает все...
Что я не так делаю?
Код DLL
library hookdll;
uses
Windows, Messages,sysutils;
var
SysHook : HHook = 0;
Wnd : Hwnd = 0;
MyHandle:HWND;
MyMessage: Cardinal;
function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
begin
if code = HC_ACTION then
begin
Wnd:=TMsg(Pointer(lParam)^).hwnd;
if Wnd<>MyHandle { and TMsg(Pointer(lParam)^).message = WM_PAINT} then
PostMessage(MyHandle, MyMessage,wnd,TMsg(Pointer(lParam)^).message);
end;
Result:= CallNextHookEx(SysHook, Code, wParam, lParam);
end;
// Установка/снятие хука
procedure hook(switch : Boolean;MyHandle2:HWND;MyMessage2:Cardinal) export; stdcall;
begin
MyHandle:=MyHandle2;
MyMessage:=MyMessage2;
if switch then
begin
SysHook := SetWindowsHookEx(WH_GETMESSAGE, @SysMsgProc, HInstance, 0);
if SysHook <> 0
then MessageBox(0, "HOOK установлен !", "Message from Exampel1/Process1", 0)
else MessageBox(0, "HOOK установить не удалось !", "Message from Exampel1/Process1", 0);
end else begin
if UnhookWindowsHookEx(SysHook)
then MessageBox(0, "HOOK снят !", "Message from Exampel1/Process1", 0)
else MessageBox(0, "HOOK снять не удалось !", "Message from Exampel1/Process1", 0);
SysHook := 0;
end;
end;
exports hook;
begin
end.
Код проги:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
MyMessage=WM_USER+100;
type
MyProcType = procedure (flag : Boolean; MyHandle:HWND; MyMessage:cardinal); stdcall;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
procedure gMess(var M : TMessage); message MyMessage;
end;
var
Form1: TForm1;
Hdll : HWND;
implementation
{$R *.DFM}
procedure tform1.gMess(var M : TMessage);
begin
memo1.Lines.add(inttostr(m.WParam)+"=="+inttostr(m.LParam));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
hook: MyProcType;
begin
@hook:= nil;
Hdll:= LoadLibrary(PChar("hookdll.dll")); { загрузка DLL }
if Hdll > HINSTANCE_ERROR then { если всё без ошибок, то }
begin
@hook:=GetProcAddress(Hdll, "hook"); { получаем указатель на необходимую процедуру}
Button2.Enabled:=True;
Button1.Enabled:=False;
hook(true, handle, MyMessage);
end
else
ShowMessage("Ошибка при загрузке DLL !");
end;
procedure TForm1.Button2Click(Sender: TObject);
var
hook: MyProcType;
begin
@hook:= nil;
if Hdll > HINSTANCE_ERROR then
begin { если всё без ошибок, то }
@hook:=GetProcAddress(Hdll, "hook"); { получаем указатель на необходимую процедуру}
Button1.Enabled:=True;
Button2.Enabled:=False;
hook(false,handle,Mymessage); {вызываем нужную процедуру из DLL}
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeLibrary(Hdll); { при закрытии формы - освобождаем DLL }
end;
← →
Lamer@fools.ua © (2005-09-10 21:39) [1]>function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall
Ёлы-палы. Да откуда вы все это берёте?
>var
SysHook : HHook = 0;
Wnd : Hwnd = 0;
MyHandle:HWND;
MyMessage: Cardinal;
Так нельзя. Следует разместить такого рода данные, например, в File Mapping.
← →
Джо © (2005-09-10 21:49) [2]
> [1] Lamer@fools.ua © (10.09.05 21:39)
> >function SysMsgProc(code : integer; wParam : word; lParam
> : longint) : longint; stdcall
>
> Ёлы-палы. Да откуда вы все это берёте?
Места надо знать...
← →
SergP © (2005-09-10 22:34) [3]
> >function SysMsgProc(code : integer; wParam : word; lParam
> : longint) : longint; stdcall
>
> Ёлы-палы. Да откуда вы все это берёте?
Статья есть на этом сайте по этому поводу...
Ну исправил.... Ничего не поменялось...
> >var
> SysHook : HHook = 0;
> Wnd : Hwnd = 0;
> MyHandle:HWND;
> MyMessage: Cardinal;
>
> Так нельзя.
Почему?
> Следует разместить такого рода данные, например,
> в File Mapping.
1. Приведите пример если не трудно...
2. Это решит мою проблему?
← →
Lamer@fools.ua © (2005-09-11 09:57) [4]>>SergP © (10.09.05 22:34) [3]
Ну раз статья есть, так, может, стОит её всё-таки почитать? Там и про File Mapping и почему его нужно использовать написано. Более того, там и пример есть.
Сразу оговорюсь, что неправильно в примере:
1. Тип параметра wParam - word (то же, что и у Вас). Должно быть WPARAM (то есть Longint).
2. procedure DLLEntryPoint(dwReason: DWord); stdcall;
Никаких stdcall. Должно быть либо register, либо ничего (register - по умолчанию).
← →
SergP © (2005-09-11 12:25) [5]Ладно... С этим буду разбираться....
А вот еще такое:
Мне нужно отловить момент когда после того как винда послала нужному окну нужное сообщение и это окно уже прореагировало на это сообщение.
Как такое сделать?
← →
SergP © (2005-09-11 15:28) [6]Пока понял что нужно фильтр ставить WH_CALLWNDPROCRET
Но какое сообщение ловить? ( интересует окончание прорисовки десктопа).
WM_Paint - не проходит. Его просто нет.
Если ловлю все, то попадается и то что нужно. Но как его определить? так как в таком случае я получаю кучу сообщений, в том числе на перемещение мыши и пр...
Страницы: 1 вся ветка
Текущий архив: 2005.10.02;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.053 c