钩窗消息

时间:2014-05-25 10:57:46

标签: delphi delphi-xe5

如何为从我的应用程序创建的特定窗口挂钩窗口消息。我已经完成了此操作,但收到错误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;

3 个答案:

答案 0 :(得分:5)

如果要为您创建的窗口挂钩窗口消息,可以设置包装窗口的控件的WindowProc属性。如果可能,那么这是正确的方法。

您对SetWindowHookEx的调用失败,因为您没有通过挂钩程序。您正在传递实例方法。您的钩子过程必须是声明如下的非成员函数:

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

您还必须遵守文档化的说明。请记住HHOOK给出的SetWindowHookEx实例,并确保致电CallNextHookEx以尊重挂钩链。

答案 1 :(得分:1)

如果您希望接收和处理任何类型窗口的Windows消息,不仅仅是您自己创建的,并且能够使用您的成员函数,您可以使用我的单位:

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

以下是如何使用它:

    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;

显然,将此代码放入TSomeClass的构造函数中会更好。 不要忘记使用以下方法发布SubClass:

SomeClass.WindowHook.free;

无论如何,我希望这会有所帮助。

答案 2 :(得分:0)

如果要将此方法用作类成员,可以将 static; 修饰符与 类函数 像这样(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。并且不记得stdcall; WinAPI函数的修饰符