如何在其他应用程序中可靠地调用剪贴板复制/粘贴操作而不扰乱输入队列
不久前,我编写了一个简单的应用程序,当用户按下某些热键时,它会用一些 unicode 符号包围任何应用程序中任何输入字段中的选定文本。基本上,应用程序的逻辑如下:
- 注册全局热键。
- 热键已触发,现在设置剪贴板监视器并调用剪贴板复制以查看是否选择了某些文本。
- 如果剪贴板已更改并且现在包含文本,请用符号包围所述文本,然后调用剪贴板粘贴,以便输入字段将使用修改后的文本进行更新。
问题是,我无法以可靠的方式从其他应用程序获取复制/粘贴功能。迄今为止我所尝试过的:
- 如果我发送 WM_COPY/WM_PASTE,它通常会被忽略,具体取决于应用程序。
- 如果我使用 SendInput、keybd_event 或任何其他键盘混乱的东西来按下/取消按下常用的剪贴板热键,它通常会篡改用户按下的键:复制/粘贴使用 control 或 shift,这对于所有通用热键来说也很流行应用程序,包括我的应用程序。
- 如果我使用 Journal Hook 直接将键盘消息注入系统输入队列,有时会正常工作,有时会出现奇怪的故障。另外,其他应用程序可能会自己使用 JournalHook,这会严重扰乱我的应用程序。更不用说默认的安全策略使日志挂钩难以使用。
- 我一直在尝试使用 Windows UI 自动化而不是剪贴板魔术来获取/设置输入字段中的文本,但它很少起作用。
因此,如果您知道使其他应用程序可靠地使用复制/粘贴功能的其他方法,或者甚至可以设计完全不同的方法,我真的很感激您告诉我:)
A while ago I wrote a simple app, which surrounds selected text in any input field in any application with some unicode symbols when user presses some hotkey. Basically, app's logic is as follows:
- Register global hotkey.
- Hotkey fired, now set clipboard monitor and invoke clipboard copy to see if some text was selected.
- If clipboard has changed and now contains text, surround said text with symbols and then invoke clipboard paste, so input field will be updated with modified text.
The problem is, I can't get copy/paste functionality from other apps in a reliable way. What I have tried to date:
- If I send WM_COPY/WM_PASTE, it's more often ignored than not, depending on the application.
- If I use SendInput, keybd_event or any other keyboard-messing stuff to press/unpress usual clipboard hotkeys, it will often tamper with user-pressed keys: copy/paste uses control or shift, which are also quite popular for all generic hotkeys in all apps, my app included.
- If I use Journal Hook to directly inject keyboard messages into system input queue, sometimes it will work fine, and sometimes weird glitches will occur. Also, other applications may be using JournalHook for themselves, and that will mess my app badly. Not to mention that default security policies make journal hook hard to use.
- I've been trying to get/set text in the input fields using Windows UI automation instead of clipboard magic, but it rarely works.
So, if you know other ways to make other applications reliably use copy/paste functionality, or can even devise entirely different approach, I'd really appreciate you telling me :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你的方法还不错,也许你可以从 WM_DRAWCLIPBOARD 开始,这样你就可以监视剪贴板。可以在此处找到一个很好的示例代码。
接下来我会看一下 SendKeys 类 - 注意:Flush、Buffer 等。使用它来发送 ctrl+c/v 而不是 Windows 消息!如果它有效,您应该会从监视器收到通知。
现在我将使用 Cliboard 类操作数据并将其粘贴回来。
I think your approach isn't that bad, maybe you can start with WM_DRAWCLIPBOARD so you can monitor the clipboard. A nice sample code can be found here.
Next I'd take a look at SendKeys class - Attention: Flush, Buffer, etc. Use this to send ctrl+c/v instead of a windows message! You should get a notification from your monitor if it worked.
Now I'd use the Cliboard class to maniplulate the Data and paste it back.
哦,看来我只能找到或多或少可靠的方法来调用没有 SendInput 或日志钩子的复制粘贴,但我必须处理它:-)所以这里是,以防有人发现它有用:
另外,每次执行 SetKeyboardState 时,请随后调用 SetForegroundWindow(focusedControlHandle) 和 SetFocus(focusedControlHandle) 。
Oh, it seems that I could only find more or less reliable way of invoking copy-paste without SendInput or journal hook, but I have to deal with it :-) So here it is, in case someone find it useful:
Also, every time you do SetKeyboardState, call SetForegroundWindow(focusedControlHandle) and SetFocus(focusedControlHandle) afterwards.