使用 CoreGraphics 方法发送自动重复键 (Mac OS X Snow Leopard)
我已经成功地发送击键,以便自动化我使用的用于绘图的特定软件包。该软件依赖于很多键盘快捷键,因此我编写了一些可以调用其中一些键盘快捷键的东西,以简化我的工作流程。正如我所说,这已经取得了很好的效果。
我的库是一个 Cocoa 库,它作为插件加载到软件包中。这是我用来发送击键的代码片段。
CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef eventDown = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, true);
CGEventRef eventUp = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, false);
//setting the process number somewhere else
CGEventPostToPSN(&number, eventDown);
CGEventPostToPSN(&number, eventUp);
对于绘图包中的某些程序,如果继续按住 Shift 键,则会激活特殊工具。我一直无法模拟这个。我以为我可以发送 Shift 键并说我希望它自动重复,但这似乎不起作用。我一直在使用以下代码来设置自动重复:
//This is done before sending the key
CGEventSetIntegerValueField(eventDown, kCGKeyboardEventAutorepeat, 1);
在我的测试中,我无法使任何键自动重复。它只需发送一次密钥即可。
有人使用上述方法成功地自动重复按键吗?我在互联网上搜索了答案,但我发现的只是 2008 年一些未解答的问题......非常感谢任何帮助。
谢谢,
莫贝
I have been successful sending keystrokes in order to automate a particular software package for drawing that I use. This software relies a lot of keyboard shortcuts so I wrote something that could call some of these keyboard shortcuts in order to streamline my workflow. As I said, this has worked out good.
My library is a Cocoa library that is loaded as a plugin to the software package. Here is a snippet of code that I have been using for sending my keystrokes.
CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef eventDown = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, true);
CGEventRef eventUp = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, false);
//setting the process number somewhere else
CGEventPostToPSN(&number, eventDown);
CGEventPostToPSN(&number, eventUp);
For some procedures in the drawing package if you continue to hold the Shift key then you activate a special tool. I have been unable to simulate this. I thought I could send the Shift key and say that I wanted it to auto-repeat but that doesn't seem to work. I have been using the following code to set the auto-repeat:
//This is done before sending the key
CGEventSetIntegerValueField(eventDown, kCGKeyboardEventAutorepeat, 1);
In my testing I have been unable to make any key auto-repeat. It just send the key once and that is it.
Is there anyone that have been successful autorepeating a key using the above method? I have searched the Internet for answers but all I have found are some unanswered questions from 2008... Any help is greatly appreciated.
Thanks,
mobbe
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
OP最终想出的解决问题的代码(从其他答案下的评论转移到这里):
131330
是一个常量,表示Shift键;它与NSShiftKeyMask
和kCGEventFlagMaskShift
相关,即131072
(0x00020000
)。131330 - 256 - 2 == 131072
。The code that OP finally came up with to solve the problem (transferred here from a comment under other answer):
131330
is a constant indicating the Shift key; it is related toNSShiftKeyMask
andkCGEventFlagMaskShift
, which are131072
(0x00020000
).131330 - 256 - 2 == 131072
.更新:根据 Events.h,Shift 键的代码不是
56
:(编辑:当然,那些关注的人(我没有)意识到 HEX 38 == DEC 56 .)
我还意识到如何获得修饰键按下:
flagsChanged:
。因此,使用这个键码,我可以在flagsChanged:
中捕捉 Shift 键按下的情况,并且重复工作正常;我还可以毫无困难地在keyDown:
和keyUp:
中获得“普通”键的重复按键事件。听起来您可能无权访问/想要更改事件处理代码(添加
flagsChanged:
),所以如果该键代码不适合您,我会很困惑并且可以只说“祝你好运!”我相信您设置的字段用于指示系统不应重复该事件,而是指示该事件是先前事件的自动重复事件。您仍然需要自己生成每个事件。像(编辑使用计时器而不是循环):
我不确定您是否可以使用更改的字段重用第一个事件,或者您需要生成一个新事件以在重复时使用。
UPDATE: the Shift key's code isn't
56
, according to Events.h:(EDIT: of course those of you who are paying attention (I wasn't) realize that HEX 38 == DEC 56.)
I also realized how to get modifier key presses:
flagsChanged:
. So using this keycode, I can catch Shift key presses inflagsChanged:
, and the repeat works fine; I also get repeated key events for "normal" keys inkeyDown:
andkeyUp:
without difficulty.It sounds like you may not have access to/want to change the event-handling code (to add
flagsChanged:
) though, so if that keycode doesn't work for you, I'm stumped and can only say "Good luck!"I believe that the field you're setting is used to indicate not that the event should be repeated by the system, but that an event is an auto-repeat of a previous event. You still have to generate each event yourself. Something like (EDITED to use a timer instead of a loop):
I'm not certain whether you can reuse the first event with a changed field or you'll need to generate a new event to use when repeating.