Главная страница
    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.49 MB
Время: 0.035 c
14-1094114473
maksim
2004-09-02 12:41
2004.09.19
удаление символов строки при нажатии кнопки


1-1093961128
DiMMoN
2004-08-31 18:05
2004.09.19
Взаимодействие с Excel


3-1093320603
Konrads
2004-08-24 08:10
2004.09.19
DbGrid


14-1094119262
Baron
2004-09-02 14:01
2004.09.19
Forums


4-1091314325
kulhacker
2004-08-01 02:52
2004.09.19
Своя кнопка в IE





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский