在拉撒路挂钩鼠标和键盘

时间:2014-08-25 09:07:16

标签: delphi pascal freepascal lazarus

我正在尝试挂钩鼠标和键盘事件并将它们记录到Memo1(用于鼠标)和Memo2(用于键盘)。我试图编译的代码:

unit Unit1;

{$mode objfpc}{$H+}


interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, windows;

type

  { TForm1 }

  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    function LowLevelKeybdHookProc(nCode: LongInt; WPARAM: WPARAM; lParam : LPARAM) : LRESULT; stdcall;
    function LowLevelMouseHookProc(nCode: LongInt; WPARAM: WPARAM; lParam : LPARAM) : LRESULT; stdcall;
    { public declarations }
  end;
  KeybdLLHookStruct = record
    vkCode      : cardinal;
    scanCode    : cardinal;
    flags       : cardinal;
    time        : cardinal;
    dwExtraInfo : cardinal;
  end;
  MouseLLHookStruct = record
    pt          : TPoint;
    mouseData   : cardinal;
    flags       : cardinal;
    time        : cardinal;
    dwExtraInfo : cardinal;
  end;

var
  Form1: TForm1;
  mHook : cardinal;
  kHook : cardinal;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
UnhookWindowsHookEx(kHook);
UnhookWindowsHookEx(mHook);
end;

procedure TForm1.FormCreate(Sender: TObject);
const
  wh_keybd_ll = 13;
  wh_mouse_ll = 14;
begin
kHook := SetWindowsHookEx(wh_keybd_ll, @LowLevelKeybdHookProc, hInstance, 0);
mHook := SetWindowsHookEx(wh_mouse_ll, @LowLevelMouseHookProc, hInstance, 0);
end;


function TForm1.LowLevelKeybdHookProc(nCode: LongInt; WPARAM: WPARAM; lParam : LPARAM) : LRESULT; stdcall;
// possible wParam values: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP
var
  info : ^KeybdLLHookStruct absolute lParam;
  lpChar : word;
  kState : TKeyboardState;
begin
result := CallNextHookEx(kHook, nCode, wParam, lParam);
with info^ do
case wParam of
  wm_keydown : begin
    GetKeyboardState(kState);
    if ToAscii(vkCode, scanCode, kState, @lpChar, 0) > 0 then Form1.Memo2.Lines.Append(format('pressed key -- %s', [char(lpChar)]));
  end;
end;
end;

function TForm1.LowLevelMouseHookProc(nCode: LongInt; WPARAM: WPARAM; lParam : LPARAM) : LRESULT; stdcall;
// possible wParam values: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP
var
  info : ^MouseLLHookStruct absolute lParam;
begin
result := CallNextHookEx(mHook, nCode, wParam, lParam);
with info^ do
case wParam of
  wm_lbuttondown : Form1.Memo1.Lines.Append(format('pressed left button (%d, %d)'    , [pt.x, pt.y]));
  wm_lbuttonup   : Form1.Memo1.Lines.Append(format('released left button (%d, %d)'   , [pt.x, pt.y]));
  wm_mbuttondown : Form1.Memo1.Lines.Append(format('pressed middle button (%d, %d)'  , [pt.x, pt.y]));
  wm_mbuttonup   : Form1.Memo1.Lines.Append(format('released middle button (%d, %d)' , [pt.x, pt.y]));
  wm_rbuttondown : Form1.Memo1.Lines.Append(format('pressed right button (%d, %d)'   , [pt.x, pt.y]));
  wm_rbuttonup   : Form1.Memo1.Lines.Append(format('released right button (%d, %d)'  , [pt.x, pt.y]));
  wm_mousewheel  : begin
    if smallInt(mouseData shr 16) > 0
    then Form1.Memo1.Lines.Append('scrolled wheel (up)')
    else Form1.Memo1.Lines.Append('scrolled wheel (down)');
  end;
end;
end;

end.

但它会返回这些错误:

unit1.pas(64,62) Error: Incompatible type for arg no. 2: Got "<procedure variable type of function(LongInt,LongInt,LongInt):LongInt of object;StdCall>", expected "<procedure variable type of function(LongInt,LongInt,LongInt):LongInt;StdCall>"
unit1.pas(65,62) Error: Incompatible type for arg no. 2: Got "<procedure variable type of function(LongInt,LongInt,LongInt):LongInt of object;StdCall>", expected "<procedure variable type of function(LongInt,LongInt,LongInt):LongInt;StdCall>"

我无法理解什么是“LongInt of object”以及如何解决这个问题。

1 个答案:

答案 0 :(得分:3)

of object表示您提供了method pointer。这是一个实例或类方法。在您的情况下,您将传递一个实例方法,其中需要一个简单的过程。

通过使用过程而不是方法来解决问题。您需要通过Self指针以外的方式获取表单,但问题中的代码无论如何都不是Self。顺便说一句,这本身就是一个糟糕的举动。始终使用Self而不是与Self具有相同值的全局变量。