在 MSWord、OOWriter 等中将选定的文本复制到剪贴板

Copy selected text to Clipboard in MSWord, OOWriter, etc

我在 Delphi 上有代码(但这不是主要的)

 hWindow := GetForegroundWindow;
 EditHandle := GetTopWindow(hWindow);
 SendMessage(EditHandle, WM_COPY, 0, 0);
 SClipboard := Clipboard.AsText;

如果此代码适用于记事本 - 一切都很好。如果另一个不是简单的编辑器,则所选文本不会复制到剪贴板。 我如何执行将文本复制到剪贴板? 我怀疑 SendMessage 不起作用。

首先,并非所有顶部windows都是编辑控件。所以,EditHandle是不可预测的。

然后,WM_COPY is only supported in edit control or combo box. The same goes for WM_GETTEXT,他们不支持全部windows。 除非您是 Windows 的所有者,否则您无法更改其消息处理机制。

但是,有一个解决方法——模拟 "Ctrl + C" 键盘输入到目标 window。

//SetForegroundWindow(hWindow); Since hWindow is already a Foreground Window
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);    // Ctrl down
keybd_event(ord('C'), MapVirtualKey(ord('C'), 0), 0, 0);        // C down
keybd_event(ord('C'), MapVirtualKey(ord('C'), 0), KEYEVENTF_KEYUP, 0);     // C up
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0); // Ctrl up

编辑:

由于 keybd_event 已被 SendInput 取代,这里是使用 SendInput 的 C++ 示例:

INPUT input[4] = {0};
input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;
input[0].ki.wVk = input[3].ki.wVk = VK_CONTROL;
input[0].ki.wScan = input[3].ki.wScan = MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC);
input[1].ki.wVk = input[2].ki.wVk = 'C';
input[1].ki.wScan = input[2].ki.wScan = MapVirtualKey('C', MAPVK_VK_TO_VSC);
input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP; // there is no KEYEVENTF_KEYDOWN
SendInput(4, input, sizeof(INPUT));