Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.19;
Скачать: CL | DM;

Вниз

Хуки   Найти похожие ветки 

 
volser   (2004-08-03 17:55) [0]

Питаюсь перехватить сообщение дабл клик, но у меня ничего не получается. Что делаю не так? Вот код:

DLL:

type
 TMessageHookCallBack=procedure (Messag : CWPSTRUCT);

function SetMessageHook(Switch : Boolean; CallBack:TMessageHookCallBack):boolean export; stdcall;

implementation

var
 MessageHook: HHook;
 MH:TMessageHookCallBack;

function GetMsgProc(code : integer; wParam : wParam; lParam : lParam) : longint; stdcall;
begin
 if code=HC_ACTION then
 begin
    if PCWPStruct(Pointer(lParam))^.message=WM_LBUTTONDBLCLK then
      MH(PCWPStruct(Pointer(lParam))^);
 end;
 Result:= CallNextHookEx(MessageHook, Code, wParam, lParam);
end;

function SetMessageHook(Switch : Boolean; CallBack : TMessageHookCallBack):boolean export; stdcall;
begin
 if switch=true then
 begin
   MessageHook := SetWindowsHookEx(WH_CALLWNDPROC, @GetMsgProc, HInstance, 0);
   Result:=MessageHook<>0;
   MH:=CallBack;
 end
 else
 begin
   Result:=UnhookWindowsHookEx(MessageHook);
 end;
end;
end.


App:

...
function SetMessageHook(Switch : Boolean; CallBack : Pointer):boolean stdcall; external "ControlHooks.dll";...

procedure MessageHookCallBack(Messag : CWPSTRUCT);
begin
 ShowMessage("b");
end;
...

в FormCreate

SetMessageHook(True, @MessageHookCallBack);
в FormClose

SetMessageHook(False, nil);

С таким кодом вообще ничего не происходит.
Если перехватывать WM_PAINT, то вроде работает


 
Digitman ©   (2004-08-03 18:10) [1]


> MH:TMessageHookCallBack


грубая ошибка
эта переменная д.б. глобально доступной для всех экз-ров хук-модулей


 
volser   (2004-08-03 22:25) [2]

Все равно не понял что мне нужно поменять.
Для хука WH_MOUSE_LL я писал аналогичный код и он работал.

Вместо вызова функци MH(PCWPStruct(Pointer(lParam))^);
я пробовал посылать сообщение в мое приложение, но оно не посылалось, значит проблема не MH.


 
Digitman ©   (2004-08-04 08:30) [3]


> оно не посылалось, значит проблема не MH


замечательная причинно-следственная связь !

еще раз - это грубая ошибка, которая обязательно "выстрелит",


 
GrayFace ©   (2004-08-04 11:34) [4]

Поиск: hooks
Еще одна ошибка в том, что не всегда надо делать Result:= CallNextHookEx(MessageHook, Code, wParam, lParam);


 
Digitman ©   (2004-08-04 12:59) [5]


> GrayFace ©   (04.08.04 11:34) [4]


насчет того, что это ошибка - спорный момент

по соотв.инф-ции в MSDN этот вызов лишь настоятельно рекомендуется выполнять

цитата :

Calling CallNextHookEx is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.


 
Юрий Зотов ©   (2004-08-04 14:04) [6]

> GrayFace ©   (04.08.04 11:34) [4]

> Еще одна ошибка в том, что не всегда надо делать
> Result:= CallNextHookEx(MessageHook, Code, wParam, lParam);

Можно не всегда, а можно и всегда. Это не ошибка.

> volser   (03.08.04 17:55)  

Переменная MessageHook должна быть глобальной на уровне всей системы. Например, можно хранить ее в страничной памяти Windows
(CreateFileMapping + MapViewOfFile). Прочтите статью Алексея Павлова на этом сайте.


 
Digitman ©   (2004-08-05 09:09) [7]


> volser   (03.08.04 22:25) [2]


мало того, даже если MH сделать глобально-доступной (см. Юрий Зотов ©   (04.08.04 14:04) [6]), грубой ошибкой будет обращение по адресу, хранимому в этой переменной, с целью вызова процедуры, якобы находящейся по этому адресу .. только для процесса, устанавливающего ловушку, это будет работать безошибочно, для прочих же процессов это неминуемо приведет к AV


 
volser   (2004-08-05 18:28) [8]

Почитал статью и родил второй вариант, но он тоже почему то не работает:
DLL:


const
 MMFName: PChar = "_KeyMMF"; // имя объекта файлового отображения

 WM_APPKEYDOWN    =  WM_USER + 1;

type
 PGlobalDLLData = ^TGlobalDLLData;
 TGlobalDLLData = packed record
   SysHook: HWND;
   MyAppWnd: HWND;
 end;

var
 GlobalData: PGlobalDLLData;
 MMFHandle: THandle;

function WndProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
begin

 if code < 0 then
 begin
   Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
   Exit;
 end;

  Case PCWPStruct(Pointer(lParam))^.message of
    WM_KEYDOWN : begin
       PostMessage(GlobalData^.MyAppWnd, WM_APPKEYDOWN, wParam, lParam);
    end;
  end;

 CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
 Result:= 0;

end;

procedure hook(switch : Boolean; hMainProg: HWND) export; stdcall;
begin
 if switch=true then
 begin
   GlobalData^.SysHook := SetWindowsHookEx(WH_CALLWNDPROC, @WndProc, HInstance, 0);
   GlobalData^.MyAppWnd:= hMainProg;
 end else
 begin
   UnhookWindowsHookEx(GlobalData^.SysHook);
 end;
end;

procedure OpenGlobalData();
begin
 MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalDLLData), MMFName);
 GlobalData:= MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalDLLData));
end;

procedure CloseGlobalData();
begin
 UnmapViewOfFile(GlobalData);
 CloseHandle(MMFHandle);
end;

procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
 case dwReason of
   DLL_PROCESS_ATTACH: OpenGlobalData;
   DLL_PROCESS_DETACH: CloseGlobalData;
 end;
end;

exports hook;

begin
 DLLProc:= @DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


App:

procedure SetHook;
var
 Hook: procedure (switch : Boolean; hMainProg: HWND) stdcall;
begin
 @hook:= nil;
 hDLL:= LoadLibrary(PChar("hooks.dll"));
 if hDLL > HINSTANCE_ERROR then
 begin
   @hook:=GetProcAddress(Hdll, "hook");
   hook(true, frmMain.Handle);
 end else
 begin
   ShowMessage("Ошибка при загрузке DLL !");
   Exit;
 end;
end;

procedure UnSetHook;
var
 Hook: procedure (switch : Boolean; hMainProg: HWND) stdcall;
begin
 @hook:= nil;
 hDLL:= LoadLibrary(PChar("hooks.dll"));
 if hDLL > HINSTANCE_ERROR then
   begin
     @hook:=GetProcAddress(Hdll, "hook");
     hook(false, frmMain.Handle);
     if FreeLibrary(hDLL) then  sleep(1000);
   end
 else
 begin
   ShowMessage("Ошибка при загрузке DLL !");
   Exit;
 end;
end;

TfrmMain = class(TForm)
...
procedure AppKeyDown(var Message: TMessage); message WM_APPKEYDOWN;

...
procedure TfrmMain.AppKeyDown(var Message: TMessage);
begin
 Showmessage("cool");
end;



Но ничего не происходи. Где я туплю?


 
хук   (2004-08-05 19:11) [9]

http://www.delphimaster.ru/articles/hooks/index.html + Архив с примерами к статье: example.zip


 
volser   (2004-08-05 19:34) [10]

Вот я и сделал все по этой статье, но у меня почему то не работает с хуком WH_CALLWNDPROC.



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

Текущий архив: 2004.09.19;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.047 c
8-1088505767
sashok
2004-06-29 14:42
2004.09.19
Проигрывание видео на форме.


14-1093524695
hgd
2004-08-26 16:51
2004.09.19
Помогите с установка компонента


3-1092802109
Марат
2004-08-18 08:08
2004.09.19
Ошибка в DBGrid


1-1093714909
Агент Х-СОМ
2004-08-28 21:41
2004.09.19
Динамическая обработка событий меню


14-1093764725
Damatrion
2004-08-29 11:32
2004.09.19
WinApi