【发布时间】:2018-03-28 22:49:50
【问题描述】:
我正在尝试从我的 Qt 应用程序中另一个应用程序的活动窗口中获取选定的文本。
在 Linux 上,我只在 Selection 模式下使用 QClipboard。
在 Windows 上,我正在尝试将 Ctrl + C 发送到系统:
INPUT copyText;
copyText.type = INPUT_KEYBOARD;
copyText.ki.wScan = 0;
copyText.ki.time = 0;
copyText.ki.dwExtraInfo = 0;
Sleep(200);
// Press the "Ctrl" key
copyText.ki.wVk = VK_CONTROL;
copyText.ki.dwFlags = 0; // 0 for key press
SendInput(1, ©Text, sizeof(INPUT));
// Press the "C" key
copyText.ki.wVk = 'C';
copyText.ki.dwFlags = 0; // 0 for key press
SendInput(1, ©Text, sizeof(INPUT));
Sleep(50);
// Release the "C" key
copyText.ki.wVk = 'C';
copyText.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, ©Text, sizeof(INPUT));
// Release the "Ctrl" key
copyText.ki.wVk = VK_CONTROL;
copyText.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, ©Text, sizeof(INPUT));
Sleep(50);
但是这个 hack 不能正常工作 - 有时我没有得到选择。我认为这可能是由使用此代码调用函数的热键引起的,并且在此代码运行时某些键仍被按下。如何检查 QKeySequenceEdit 中是否没有按下每个键?或者如何检查是否没有按下任何键? 或者有没有更简单的方法从 Windows 上的活动窗口中获取选定的文本?
【问题讨论】:
-
为什么不继续使用 QClipBoard for windows?
-
用
nInputs=1调用SendInput()是(几乎总是)一个错误。这违背了使用SendInput()而不是keybd_event()的目的。创建一个包含多个INPUTs 的数组,并将整个数组一次性传递给SendInput(),并将nInputs设置为数组中INPUTs 的数量。并摆脱Sleep()电话,它们不是必需的。如果您需要检查给定的密钥是否已经关闭,请使用GetAsyncKeyState()。或者,尝试使用GetGUIThreadInfo()获取当前具有输入焦点的HWND,然后向其发送WM_COPY消息。 -
或者,如果
HWND是标准的编辑控件,您可以使用EM_GETSEL和WM_GETTEXT的组合来提取选定的文本,而无需通过剪贴板。或者,如果HWND是标准RichEdit 控件,则使用EM_EXGETSEL和EM_GETSELTEXT的组合。或者,改用UI Automation。 -
@eyllanesc,因为 QClipboard 在选择模式下的 Windows 上不起作用。 @RemyLebeau,感谢您的解释!哪种解决方案更通用,可以从任何应用程序中获取选择,发送
Ctrl + C或发送WM_COPY消息? -
@ГенаЧерныщук 那么,为什么要使用 Qt 标签呢?