简体   繁体   English

将鼠标和键盘钩在拉撒路

[英]Hooking the mouse and keyboard in Lazarus

I am trying to hook mouse and keyboard events and log them to the Memo1 (for mouse) and Memo2 (for keyboard). 我试图挂钩鼠标和键盘事件,并将它们记录到Memo1(对于鼠标)和Memo2(对于键盘)中。 The code i am trying to compile to: 我试图编译的代码:

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.

But it returns these errors: 但它返回以下错误:

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>"

I can't understand what is "LongInt of object" and how to fix this. 我不明白什么是“对象的LongInt”以及如何解决此问题。

The of object indicates that you have supplied a method pointer . of object表示您已提供了方法指针 That is an instance or a class method. 那是一个实例或一个类方法。 In your case you are passing an instance method where a plain procedure is required. 在您的情况下,您正在传递需要简单过程的实例方法。

Solve the problem by using procedures rather than methods. 通过使用过程而不是方法来解决问题。 You'll need to get hold of the form by a means other than the Self pointer, but then the code in the question wasn't using Self anyway. 您需要通过Self指针以外的其他方式来获取表单,但是问题中的代码无论如何都没有使用Self As an aside, that in itself is a bad move. 顺便说一句,这本身就是一个不好的举动。 Always use Self rather than a global variable that happens to have the same value as Self . 始终使用Self而不是恰好具有与Self值相同的全局变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM