使用 Lazarus / FreePascal 进行 OSX 键盘事件点击

问题描述 投票:0回答:2

我正在尝试使用 Lazarus / FreePascal 创建 OSX 键盘事件点击。 Lazarus 设置为安装时的默认值 - 32 位和 Carbon 小部件集。

设置水龙头的代码如下所示:

eventMask := (1 shl kCGEventKeyDown) or (1 shl kCGEventKeyUp);

KeyboardTap := CGEventTapCreate( KCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, @KeyboardEventTapCB, nil);
if KeyboardTap <> nil then
begin
   RunLoopSource := CFMachPortCreateRunLoopSource( kCFAllocatorDefault, KeyboardTap, 0);
   CFRunLoopAddSource(CFRunLoopGetCurrent(), RunLoopSource, kCFRunLoopCommonModes);
   CGEventTapEnable( KeyboardTap, 1);
   result := true;
end

回调看起来像:

function KeyboardEventTapCB(proxy: CGEventTapProxy; eType: CGEventType; e: CGEventRef; userInfo: UnivPtr): CGEventRef;
var
   keycode: CGKeyCode;
begin
   keycode := CGEventGetIntegerValueField( e, kCGKeyboardEventKeycode);
   result := nil;
end;

我有两个问题。

第一个是传递到回调中的 CGEventRef 看起来实际上是 CGEventType 值。也就是说,传递给 CGEventGetIntegerValue() 的“e”包含 eType 中应包含的值,即 CGEventType。

另一个是,如果我尝试在回调中返回事件,则会导致 AV。

所以问题是...我是否正确创建了水龙头(我对 OSX 的内部结构不是很熟悉),如果是这样,fpc 的 OSX 单元用于此功能是否正确?

macos lazarus freepascal
2个回答
1
投票

Pascal 和 C 有不同的调用约定。由于您将

KeyboardEventTapCB
传递到将使用 C 调用约定来调用它的函数中,因此您需要确保它被编译为符合 C 调用约定。

一些网络搜索建议您可以在函数声明的末尾添加

cdecl;
。如果不是这样,请尝试将
KeyboardEventTapCB
括起来:

${CALLING cdecl}

${CALLING default}

0
投票

你能让它发挥作用吗? 我想在 macOS 上拦截媒体键,你能给我一个示例代码吗?

谢谢你。

© www.soinside.com 2019 - 2024. All rights reserved.