在我的c#.Net应用程序中,我一直试图能够在当前关注的窗口中检索当前选定的文本。 (请注意,它可以是在窗口中打开的任何窗口,例如word或safari)。
我能够检索当前聚焦控件的句柄。 (使用对user32.dll和kernel32.dll的几个互操作调用)。
但是,我无法始终能够取回所选文字。
我尝试过使用SENDMESSAGE和GET_TEXT。然而,这似乎只适用于某些应用程序(适用于像wordpad这样的简单应用程序,不适用于更复杂的应用程序,如firefox或word)。
我尝试过使用SENDMESSAGE和WM_COPY。但是,这似乎只适用于某些控件。 (我认为WM_COPY会导致与手动按CTRL-C完全相同的行为,但事实并非如此)。
我尝试过使用SENDMESSAGE和WM_KEYUP + WM_KEYDOWN手动激发复制命令。这不是经常工作。 (可能与用户按下的实际热键重叠以调用我的应用程序)。
有关始终能够检索当前所选文本的任何想法吗? (在任何申请中)。
答案 0 :(得分:4)
我通过几个方面的组合来完成这项工作。所以:
发送控件+ c(使用此回答Trigger OS to copy (ctrl+c or Ctrl-x) programmatically)
bool stillHeld = true;
int timeSlept = 0;
do
{
// wait until our hotkey is released
if ((Keyboard.Modifiers & ModifierKeys.Control) > 0 ||
(Keyboard.Modifiers & ModifierKeys.Alt) > 0 ||
(Keyboard.Modifiers & ModifierKeys.Shift) > 0)
{
timeSlept += 50;
System.Threading.Thread.Sleep(timeSlept);
}
else
{
stillHeld = false;
}
} while (stillHeld && timeSlept < 1000);
Keyboard.SimulateKeyStroke('c', ctrl: true);
我正在使用WPF,因此Keyboard.Modifiers是System.Windows.Input.Keyboard,而Keyboard.SimulateKeyStroke来自Chris Schmick的答案。
注意,timeSlept是我继续快乐之前等待用户放开密钥的最长时间。
答案 1 :(得分:2)
我设法获得了wordpad / notepad以及任何支持UI自动化的文本。
以下代码在某些情况下可能适合您。我将开始使用Reflector来查看Windows如何为TextBoxBase.SelectedText属性中的文本框。
public static string SelectedText
{
get
{
AutomationElement focusedElement = AutomationElement.FocusedElement;
object currentPattern = null;
if (focusedElement.TryGetCurrentPattern(TextPattern.Pattern, out currentPattern))
{
TextPattern textPattern = (TextPattern)currentPattern;
TextPatternRange[] textPatternRanges = textPattern.GetSelection();
if (textPatternRanges.Length > 0)
{
string textSelection = textPatternRanges[0].GetText(-1);
return textSelection;
}
}
return string.Empty;
}
set
{
AutomationElement focusedElement = AutomationElement.FocusedElement;
IntPtr windowHandle = new IntPtr(focusedElement.Current.NativeWindowHandle);
NativeMethods.SendMessage(windowHandle, NativeMethods.EM_REPLACESEL, true, value);
}
}
答案 2 :(得分:1)
我不相信这是可能的,当前重点可能不包含任何选定的文本。 (它甚至可能根本不包含任何文本)。或者当前选择可以是图标或图像。
或许要求用户首先将所选文本复制到剪贴板可能是一种解决方案。
答案 3 :(得分:1)
我可能误解了这个问题,但你能不能发送Ctrl + c?如果您知道窗口总是最重要的并且选择了要复制的文本?
SendKeys.SendWait("^c");
复制到剪贴板后,it's not tricky以编程方式检索内容(您甚至可以检查它实际上是文本)。
答案 4 :(得分:0)
我认为创建剪贴板监视器是一个不错的选择。我建议您查看Klipper(KDE剪贴板模块),它会复制您在剪贴板列表中选择的所有内容,无论是内容是文件,文件夹还是某些文本。
可以找到更多详细信息here。
答案 5 :(得分:0)
SendKeys.SendWait(“^ c”)的最佳替代方案;我找到了这个:
http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=46203
但是,它仅适用于少数应用,例如记事本。对于Web浏览器,它只会崩溃。
谁有更好的东西?
答案 6 :(得分:0)
尝试使用其他方法不起作用的控件上的GetWindowText() API。