Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 611
  • Last Modified:

Hook in Delphi

I'm a newer in Experts-Exchange. So I haven't got a lot of points to evaluate this question. But I want to write a program that hook Window Mouse Messages. If it's anybody can help, please, show me how to do.
Thanks and best regards.
0
pvhoa
Asked:
pvhoa
  • 5
  • 3
  • 2
  • +4
1 Solution
 
MadshiCommented:
Do you want to hook messages in YOUR application or in another one?
If it's only your app, use Application.OnMessage, else use SetWindowsHookEx(WH_GETMESSAGE,...) or SetWindowsHookEx(WH_MOUSE,...).

Regards, Madshi.
0
 
pvhoaAuthor Commented:
Thanks,

But I need to have a global hook. And as I know, in C++ global hook need to be installed in a DLL. But I want to know there are any independent way in Delphi or not. Please, if any one can help.

VHOA
0
 
venksCommented:
There is a Hook component in RX Library Ver 2.5 availble from Torry's Delphi Pages (www.torry.ru).You can give it a try
regards
venks
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
ZifNabCommented:
Hi pvhoa,

here is code I've got from the web. I can't help you further if you don't give specific code. Maybe you can't, but then this example will help you further.

Can you elaborate more on how to use SetWindowsHookEx?  If possible,
>just enclosed a short piece of code.
OK, take the following and compile it into a dll.
When you call the SetHook function in the dll it sets a global
mouse hook - any mouse messages go to this hook first. If it's a
mousedown on the desktop there's a beep; whether it was a
mousedown on the desktop or not the HookProc calls the next
hook. When you call the UnHookHook function it unhooks the hook.
(I actually use the thing to pop up a menu when I
click on the desktop, if you're curious.)
You wanted a keyboard hook - it took me a while to
figure out how the mouse hook should go a while ago (then
another little while cleaning it up some just now; the original
was my very first Delphi project, what you see here is much
nicer.) If you look at the code below together with the
documentation for SetWindowsHookEx and MouseProc you
should be able to get a global keyboard hook going, I think maybe.
I just noticed that SetHook and UnHookHook are
functions that don't return anything in particular. So sue me.
(The idea is they'd return an error message or something.) The code:

library Hookdemo;
uses  Beeper in 'BEEPER.PAS';exports      

SetHook index 1,
UnHookHook index 2,      
HookProc index 3;

begin  
 HookedAlready:=False;
end.

{**************}
unit Beeper;
interface
uses Wintypes,Winprocs,Messages;
function SetHook:Boolean;export;
function UnHookHook:Boolean;export;
function HookProc(Code:integer; wParam: Word; lParam: Longint): Longint;export;

var HookedAlready:Boolean;
implementation
var  
 ourHook:HHook;  
 DeskTop:hwnd;

function SetHook:Boolean;
 begin
  if HookedAlready then exit;
  DeskTop:=GetDeskTopWindow;
  ourHook:=SetWindowsHookEx(WH_MOUSE,HookProc,HInstance,0);
  {I have smart callbacks turned on or this wouldn't quite work}
  HookedAlready:=True;
end;

function UnHookHook:Boolean;
begin
 UnHookWindowsHookEx(ourHook);
 HookedAlready:=False;
end;

function HookProc(Code:integer; wParam: Word; lParam: Longint): Longint;

begin
 if (wParam=WM_LBUTTONDOWN) and (PMouseHookStruct(lParam)^.hWnd=DeskTop)
     then MessageBeep(0);  
 result:=CallNextHookEx(ourHook,Code,wParam,lParam);
 {If you want to eat a message instead you simply
  leave out the CallNextHookEx part}
end;
end.

And in fact for this particular application subclassing
the desktop window (SetWindowLong) would probably make
more sense than using SetWindowsHookEx. But if you want a
global hook you need a hook, not a subclass.
Author: David Ullrich


Zif.

 
 
 

0
 
pvhoaAuthor Commented:
Thank mr.ZifNab for your answer. Cause there are some errors in this code, so if it's possible, please, help me more. I tried to correct these errors but no result now. For the first, in function SetWindowsHookEx(WH_MOUSE,HookProc,HInstance,0), we need put address of HookProc function, that means @HookProc instead. But after build all, when I tried to run program in Windows98, my machine is going to crash imediately after calling this function CallNextHookEx(ourHook,Code,wParam,lParam). And these parameters wParam and lParam, cause some unknown resons, don't match real Mouse Messages parameters at all.

Regard subclassing, I didn't try it. But I want to say again thanks to mr. ZifNab. If it's any progress from me, I will post comments imediately.

VHOA
0
 
MadshiCommented:
(1) HookProc has to be stdcall.
(2) You can't simply leave out CallNextHookEx, cause you MUST call it, when "code<0".
(3) Look at the documentation of SetWindowsHookEx. wParam is the identifier of the mouse message. lParam is a pointer to a mouseHookStruct.
(4) Subclassing works only for your own application. SetWindowLong doesn't work with windows that are created by other processes.

Regards, Madshi.
0
 
ZifNabCommented:
sorry pvhoa, that I couldn't answer you earlier. I'm just back from a trip. I've some work to do now... :-(. Soon I'll look at this q'n again. If problems still occur, let me know... first reject my answer, so that others can look at it too.
0
 
pvhoaAuthor Commented:
Adjusted points to 200
0
 
dwwangCommented:
This site contains a so-called Global mouse hook:
http://www.delphidevelopers.com/delphi/files/mousehook.zip
0
 
pvhoaAuthor Commented:
Mr. dwwang,

I test this program in Win98 env., and the same thing - Access violation in addr...

May be it's Win98 bug?

Please, try this in Windows 98 and tell me some more if it's possible.

Thanks.
0
 
ronit051397Commented:
pvhoa, post your EMail and I'll send you an example.
0
 
pvhoaAuthor Commented:
My E-mail: pvhoa@hotmail.com
0
 
ronit051397Commented:
pvhoa, did it helped you?
0
 
ZifNabCommented:
0
 
slautinCommented:
please, look my sample for keys hook.
Interception of all events is executed by means of calling the function SetWindowsHookEx. Given function registers in hook system for determined type of events/messages.
Main is that procedure must always be present in WINDOWS memories. So hook place in DLL and load this DLL from the program. While one program uses DLL, that can be not unloaded from the memory. In the example a hook intercepts a striking the keys "+" and "-", and will send a message to your form (caption 'XXX').
Certainly, example possible to remake under mouse!!!


library skey;

uses wintypes, winprocs, messages;

const

//user messages
wm_ns_Event = wm_user+133; //next event
wm_ps_Event = wm_user+134; //prev event
hookhandle : hHook = 0;

var
    saveEProc : pointer;

function key_hook (code: integer, wparam : word;
   lparam:longint) : longint; export;
var
  H : HWND;
begin
if code >- 0 then
  begin
  if ((wparam = VK_ADD) or (wparam = VK_SUBTRACT)) and
     (lparam and $40000000 = 0) then
     begin
     H := FindWindow('TForm1','XXX');
     if wparam=VK_ADD then
        SendMessage(H, wm_ns_Event,0,0)
     else
        SendMessage(H, wm_ps_Event,0,0);
     end;
     result := 0;
  end
else
  result := CallNextHookEx(hookhandle, code, wparam, lparam);
end;

//when unloading it is necessary to remove hook

procedure localexitproc : far;
begin
 if hookhadle <> 0 then
    begin
    UnhookWindowsHookEx(hookhandle);
    exitproc := SaveExitProc;
    end;
end;

// DLL initialization
begin

hookhandle := SetWindowsHookEx(wh_Keyboard, Key_Hook, hInstance, 0);
if hookhandle = 0 then
    MessageBox(0,'Error!', mb_Ok);
else
    begin
    saveEProc := ExitProc;
    ExitProc := @localexitproc;
    end;
end;

//------------------------

unit Unit1;

//user messages
const

//user messages
wm_ns_Event = wm_user+133; //next event
wm_ps_Event = wm_user+134; //prev event

type
   TForm1 = class (TForm)
   label1:TLabel;
private WM_NextMSG (var M : TMessage)
      message wm_ns_Event;
private WM_PrevMSG (var M : TMessage)
      message wm_ps_Event;
end;

var
 .....
 p : pointer;

implementation

function key_hook : longint; far; external 'skey';

procedure TForm1.WM_NextMSG (var M : TMessage)
begin
    label1.Caption := 'Next message';
end;

procedure TForm1.WM_PrevMSG (var M : TMessage)
begin
    label1.Caption := 'Prev message';
end;

procedure TForm1.FormCreate(sender : TObject)
begin
   p:= @key_hook;
end;

end.

0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 3
  • 2
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now