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

Вниз

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

 
ikivio   (2004-01-26 16:25) [0]

Помогите, пожалуйста, разобраться !
Если делаю как в приведенном коде, то Hook, в других программах,
например Lingvo, не срабатывает.
А если вызываю CallNextHookEx в любом случае, то под Win98 дает ошибку.
Что я не так делаю ?

function PostKeyMess(Code:integer;wp:wParam;lp:lParam):integer; stdcall;
begin
Result:=0;
if Code<0 then Result:=CallNextHookEx(hh,Code,wp,lp) else
if rHookRec.MainWindow<>0 then PostMessage(rHookRec^.MainWindow,WM_USER+1714,wp,lp);
end;

function SetKeyBoardHook:Cardinal;stdcall;
begin
hh:=SetWindowsHookEx(WH_KEYBOARD,@PostKeyMess,HInstance,0);
Result:=hh;
end;


 
Digitman ©   (2004-01-26 16:31) [1]


> Lingvo, не срабатывает


сразу после SetWindowsHookEx вызови
sendmessage(HWND_BROADCAST, WM_NULL, 0, 0)


 
Юрий Зотов ©   (2004-01-26 16:38) [2]

> ikivio (26.01.04 16:25)

Что такое hh? Эта переменная должна быть глобальной на уровне всей системы. Если у Вас не так, то вот и причина ошибки.

И то же самое требование относится к rHookRec^.MainWindow


 
ikivio   (2004-01-26 16:40) [3]

>Digitman
>сразу после SetWindowsHookEx вызови
>sendmessage(HWND_BROADCAST, WM_NULL, 0, 0)
Не помогает.


 
Skier ©   (2004-01-26 16:42) [4]

http://www.delphimaster.ru/articles/hooks/index.html


 
Digitman ©   (2004-01-26 16:43) [5]


> ikivio


это - конкретно к вопросу о Lingvo и иже с ним приложений, "висящих в трее" ... это некоторая тонкость. практически не упоминающаяся ни в штатной док-ции ни в статьях на тему глоб.хуков

к вопросу же корректности прочего твоего кода это отношения не имеет

см. для начала [2]


 
ikivio   (2004-01-26 16:44) [6]

Вот весь код:
library HelpDll;

uses
// ShareMem,
Messages,
Windows;

type
PHookRec=^THookRec;
THookRec=record
MainWindow:Hwnd;
HookID:HHook;
end;

var
hh,hh1:THandle;
rHookRec:PHookRec=nil;
hMapObject:THandle;

function PostKeyMess(Code:integer;wp:wParam;lp:lParam):integer; stdcall;
begin
Result:=0;
if Code<0 then Result:=CallNextHookEx(hh,Code,wp,lp) else
if rHookRec.MainWindow<>0 then PostMessage(rHookRec^.MainWindow,WM_USER+1714,wp,lp);
end;

function PostMouseMess(Code:integer;wp:wParam;lp:lParam):integer; stdcall;
begin
Result:=0;
if Code<0 then Result:=CallNextHookEx(hh1,Code,wp,lp) else
if rHookRec.MainWindow<>0 then PostMessage(rHookRec^.MainWindow,WM_USER+1714,wp,lp);
end;

function SetKeyBoardHook:Cardinal;stdcall;
begin
hh:=SetWindowsHookEx(WH_KEYBOARD,@PostKeyMess,HInstance,0);
Result:=hh;
end;

function SetMouseHook:Cardinal;stdcall;
begin
hh1:=SetWindowsHookEx(WH_MOUSE,@PostMouseMess,HInstance,0);
SendMessage(HWND_BROADCAST,WM_NULL,0,0);
Result:=hh1;
end;

function UnHook(Hand:Cardinal):boolean;stdcall;
begin
Result:=UnhookWindowsHookEx(Hand);
end;

procedure GetHandle(FormHand:Hwnd);stdcall;
begin
rHookRec.MainWindow:=FormHand;
end;

procedure EntryPointProc(Reason:Integer);
begin
hMapObject:=0;
case reason of
DLL_PROCESS_ATTACH:
begin
hMapObject:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(THookRec),"_CALLWNDPROC");
rHookRec:=MapViewOfFile(hMapObject,FILE_MAP_WRITE,0,0,0);
end;
DLL_PROCESS_DETACH:
begin
try
UnMapViewOfFile(rHookRec);
CloseHandle(hMapObject);
except
end;
end;
DLL_THREAD_ATTACH:
begin
end;
DLL_THREAD_DETACH:
begin
end;
end;
end;

exports
SetKeyBoardHook,
SetMouseHook,
UnHook,
GetHandle;

begin
DllProc:=@EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end.


 
AKul ©   (2004-01-26 17:02) [7]

см. [2]: hh,hh1 должны быть объявлены внутри THookRec


 
ikivio   (2004-01-26 19:39) [8]

Все подправил в соответствии с советами
и статьей на www.delphimaster.ru/articles/hooks/index.html.
Но все равно:
Если вызываю CallNextHookEx при Code>=0, то под Win98 дает ошибку. А если нет, то Hook в др. программах (WinXP) не срабатывает.


 
Юрий Зотов ©   (2004-01-26 19:57) [9]

> ikivio (26.01.04 19:39) [8]

Значит, не так подправили. Вы разобрались, зачем нужна EntryPointProc, что она делает и как это потом используется?


 
ikivio   (2004-01-26 20:46) [10]

Вот переделанный код:
library HelpDll;

uses
// ShareMem,
Messages,
Windows;

type
PHookRec=^THookRec;
THookRec=record
MainWindow:Hwnd;
hh:HHook;
end;

var
rHookRec:PHookRec=nil;
hMapObject:THandle;

function PostKeyMess(Code:integer;wp:wParam;lp:lParam):integer; stdcall;
begin
if Code>=0 then
if rHookRec^.MainWindow<>0 then PostMessage(rHookRec^.MainWindow,WM_USER+1714,wp,lp)
Result:=CallNextHookEx(rHookRec^.hh,Code,wp,lp);
end;

function SetKeyBoardHook:Cardinal;stdcall;
begin
rHookRec^.hh:=SetWindowsHookEx(WH_KEYBOARD,@PostKeyMess,HInstance,0);
Result:=rHookRec^.hh;
end;

function UnHook(Hand:Cardinal):boolean;stdcall;
begin
Result:=UnhookWindowsHookEx(Hand);
end;

procedure GetHandle(FormHand:Hwnd);stdcall;
begin
rHookRec^.MainWindow:=FormHand;
end;

procedure EntryPointProc(Reason:Integer);
begin
hMapObject:=0;
case reason of
DLL_PROCESS_ATTACH:
begin
hMapObject:=CreateFileMapping(INVALID_HANDLE_VALUE,nil,PAGE_READWRITE,0,SizeOf(THookRec),"_HelpDll");
if hMapObject=0 then
begin
MessageBox(0,"Can""t create FileMapping","Message from HelpDll",0);
Exit;
end;
rHookRec:=MapViewOfFile(hMapObject,FILE_MAP_ALL_ACCESS,0,0,SizeOf(THookRec));
if rHookRec=nil then
begin
CloseHandle(hMapObject);
MessageBox(0,"Can""t make MapViewOfFile","Message from HelpDll",0);
Exit;
end;
end;
DLL_PROCESS_DETACH:
begin
try
UnMapViewOfFile(rHookRec);
CloseHandle(hMapObject);
except
end;
end;
DLL_THREAD_ATTACH:
begin
end;
DLL_THREAD_DETACH:
begin
end;
end;
end;

exports
SetKeyBoardHook,
SetMouseHook,
UnHook,
GetHandle;

begin
DllProc:=@EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end.
Примеры из статьи ( под WinXP ) иногда выдают следующее:
---------------------------
Explorer.EXE - Application Error
---------------------------
The instruction at "0xff6402a7" referenced memory at "0xff6402a7". The memory could not be "read".
Click on OK to terminate the program
Click on CANCEL to debug the program
---------------------------
Application Error
---------------------------
Exception EAccessViolation in module hook_dll1.dll at FF63F2A7. Access violation at address FF6402A7. Read of address FF6402A7.
---------------------------



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

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

Наверх




Память: 0.5 MB
Время: 0.019 c
6-16552
Паша Т
2003-12-02 21:42
2004.02.06
IdFTP


3-16080
Vemer
2004-01-07 21:34
2004.02.06
Вечная тема - транзакции InterBase.


1-16291
Serge
2004-01-28 14:24
2004.02.06
Количество символов в строке RichEdit-a ???


3-16106
Serge N
2004-01-09 16:00
2004.02.06
Проблема с ClientDataSet + Oracle (поле типа Date)


14-16637
Cerber
2004-01-13 15:55
2004.02.06
Хостинг