user3655788
user3655788

Reputation: 135

Hook window messages

How can I hook windows messages for a particular window that gets created from my application. I've done this but I get an error saying E2036 Variable required.

type
  TSomeClass = class
  ...
  WndProc(code : integer; wParam: WPARAM; lParam: LPARAM ) : LResult;
  ...
  end;

var
  SomeClass: TSomeClass;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ...
  SomeClass := TSomeClass.Create;
  SetWindowsHookEx(WH_CALLWNDPROC, @SomeClass.WndProc, 0, GetCurrentThreadId);
  ...
end;

Upvotes: 0

Views: 2957

Answers (3)

Komarov Andrey
Komarov Andrey

Reputation: 11

If you want to use this method as class member, you can use static; modifier with class function like this (D2006):

type
  TSomeClass = class
  ...
  class function WndProc(code : integer; wParam: WPARAM; lParam: LPARAM ) : LResult; static; stdcall;
  ...
  end;

    var
      SomeClass: TSomeClass;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ...
      SomeClass := TSomeClass.Create;
      SetWindowsHookEx(WH_CALLWNDPROC, @TSomeClass.WndProc, 0, GetCurrentThreadId);
      ...
    end;

P.S. And don't remember stdcall; modifier for WinAPI func

Upvotes: 0

Pawel Piotrowski
Pawel Piotrowski

Reputation: 51

If you like to receive and process windows messages for any kind of window, not only such you created yourself, and be able to use your member-function you can use my unit:

http://www.maxlogic.eu/subclassing-hooking-windows-with-delphi/

And here is how to use it:

    uses maxWndSubClassing;




TSomeClass = class
public
    WindowHook: TWndSubClass;
    procedure myWindowProc(var Msg: Messages.TMessage; var PrevendDefaultHandler: boolean);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  ...
  SomeClass := TSomeClass.Create;


  SomeClass.WindowHook := TWndSubClass.Create(nil);
  SomeClass.WindowHook.OnMessage := SomeClass.MyMessageProc;
  // this line assigns the window handle that will be hooked. Depending on what you are hooking, pass something else instead of aHandle
  SomeClass.WindowHook.HookedWnd := aHandle;
end;

Obviously, it would be better to put this code into the constructor of TSomeClass. Do not forget to release the SubClass using:

SomeClass.WindowHook.free;

Anyway I hope this is helpful.

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 613461

If you want to hook window messages for a window that you create, you can set the WindowProc property of the control that wraps the window. If that is possible then it is the right way to go.

Your call to SetWindowHookEx fails because you are not passing a hook procedure. You are passing an instance method. Your hook procedure must be a non-member function declared like this:

function HookProc(nCode: Integer; wParam: WPARAM;
    lParam: LPARAM): LRESULT; stdcall;

You must also adhere to the documented instructions. Remember the HHOOK instance that you are given by SetWindowHookEx and make sure you call CallNextHookEx to respect the hook chain.

Upvotes: 5

Related Questions