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

Вниз

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

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

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

Наверх





Память: 0.48 MB
Время: 0.045 c
14-1093947617
Delirium
2004-08-31 14:20
2004.09.19
Теперь, посылая кого-нибудь, вы точно знаете куда он пойдёт :)


3-1093348596
Snip
2004-08-24 15:56
2004.09.19
InterBase и Remote Connect


3-1093068104
ZSerg
2004-08-21 10:01
2004.09.19
Слишком мало параметров. Требуется 1.


14-1093976300
kaif
2004-08-31 22:18
2004.09.19
Была тут ветка про Шнура


14-1093420906
Alx2
2004-08-25 12:01
2004.09.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
Английский Французский Немецкий Итальянский Португальский Русский Испанский