将按键发送到Mac上的特定窗口

时间:2019-01-24 00:09:51

标签: macos

我正在开发一个程序,该程序需要将击键发送到其他(未聚焦的)窗口。

对于Windows,我使用WinAPI中的以下本机函数:

SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

hWnd是目标窗口句柄,Msg设置为向下/向上键事件代码,wParam用于指定键代码。

Mac OS API中有与此等效的东西吗?或任何其他方法都可以实现相同的效果而不必将目标窗口置于前台?我正在寻找可以使用以下语言之一实现的解决方案:Java,C ++,C,AppleScript。

进度更新:

我在CoreGraphics API中找到了函数CGEventTapCreateForPSN(...),根据文档,它应该完全符合我的意愿。但是我不知道如何从Java程序访问它。据我所知,CoreGraphics API仅可从Objective-C和Swift访问,我都不知道如何将它们集成到Java程序中。我可以使用JNI和AppleScript通过执行osascript进程来执行C和C ++代码。我对这3种语言不是很熟悉,所以我不知道是否有某种方法可以从它们(而不是Java)中以某种方式执行Objective-C或Swift代码,

我正在考虑选择创建Swift或Objective-C程序,将其编译并存储在Java程序的.jar文件中,然后将其提取到temp文件夹中,并在需要发送按键事件时执行它。我想它会起作用,但是如果有一个更优雅的解决方案不需要每次发送按键时都执行第二个程序,我真的会喜欢它。

1 个答案:

答案 0 :(得分:1)

使用{p>中的swift中的演示

$ swift --version
Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)
Target: x86_64-apple-darwin17.7.0

简单的示例代码sendspace.swift

import Foundation

let src = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
    
let kspd = CGEvent(keyboardEventSource: src, virtualKey: 0x31, keyDown: true)   // space-down
let kspu = CGEvent(keyboardEventSource: src, virtualKey: 0x31, keyDown: false)  // space-up

let pids = [ 24834, 24894, 24915 ]; // real PID-s from command 'ps -ax' - e.g. for example 3 different processes
    
for i in 0 ..< pids.count {
    print("sending to pid: ", pids[i]);
    kspd?.postToPid( pid_t(pids[i]) ); // convert int to pid_t
    kspu?.postToPid( pid_t(pids[i]) );
}

运行代码:swift sendspace.swift(来自终端)后,所有3个具有已定义PID的进程将获得 space 按键,而终端仍是前台应用。