我正在开发一个需要将击键发送到其他(未聚焦的)窗口的程序。
对于 Windows,我使用 WinAPI 中的以下本机函数:
SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
Run Code Online (Sandbox Code Playgroud)
hWnd是目标窗口句柄,Msg设置为按键按下/按键事件代码,wParam用于指定按键代码。
Mac OS API 中是否有与此等效的功能?或任何其他方式来实现相同的效果,而不必将目标窗口带到前台?我正在寻找可以使用以下语言之一实现的解决方案:Java、C++、C、AppleScript。
进度更新:
我在 CoreGraphics API 中找到了函数CGEventTapCreateForPSN(...),根据文档,它应该完全按照我想要的方式执行。但我不知道如何从 Java 程序访问它。据我所知,CoreGraphics API 只能从 Objective-C 和 Swift 访问,我不知道如何将这两者集成到 Java 程序中。我可以使用 JNI 执行 C 和 C++ 代码,并通过执行osascript进程来执行 AppleScript。我对这 3 种语言不是很熟悉,所以我不知道是否有办法以某种方式从它们(也不是从 Java)执行 Objective-C 或 Swift 代码,非常感谢任何帮助。
我正在考虑创建 Swift 或 Objective-C 程序的选项,对其进行编译并将其存储在 Java 程序的 .jar 文件中,然后将其提取到临时文件夹中,并在需要发送击键事件时执行它。我想它会起作用,但如果有一个更优雅的解决方案,不需要每次我想发送击键时都执行第二个程序,我真的很喜欢它。
演示中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
Run Code Online (Sandbox Code Playgroud)
简单的示例代码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]) );
}
Run Code Online (Sandbox Code Playgroud)
运行代码后:(swift sendspace.swift从终端)具有定义的 PID 的所有 3 个进程都将获得按键space,而终端仍然是前台应用程序。
| 归档时间: |
|
| 查看次数: |
2996 次 |
| 最近记录: |