开发者

How to get selected text from ANY window (using UI Automation) - C#

I have a small tray application which registers a system-wide hotkey. When the user selects a text anywhere in any application and presses this hotkey I want to be able to capture the selected text. I'm currently doing this using AutomationEle开发者_JAVA技巧ments:

//Using FocusedElement (since the focused element should be the control with the selected text?)
AutomationElement ae = AutomationElement.FocusedElement;        
AutomationElement txtElement = ae.FindFirst(TreeScope.Subtree,Condition.TrueCondition);
if(txtElement == null)
    return;

TextPattern tp;

try
{
    tp = txtElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
}
catch(Exception ex)
{
    return;
}

TextPatternRange[] trs;

if (tp.SupportedTextSelection == SupportedTextSelection.None)
{
    return;
            }
else
{
    trs = tp.GetSelection();
    string selectedText = trs[0].GetText(-1);
    MessageBox.Show(selectedText );

}

This works for some apps (such as notepad, visual studios edit boxes and such) but not for all (such as Word, FireFox, Chrome, and so on.)

Anyone here with any ideas of how to be able to retreive the selected text in ANY application?


Unfortunately, there's no way to get the selected text from any arbitrary application. UI Automation works if the application supports UIA TextPattern; unfortunately, most do not. I wrote an application that tried to do this, and had a bunch of fallbacks.

I tried (pretty much in order):

  1. UIA.TextPattern
  2. Internet Explorer-specific (this had different implementations for IE 6,7,8,9)
  3. Adobe Reader-specific
  4. Clipboard

This covered 80-90% of the applications out there, but there were quite a few that still failed.

Note that restoring the clipboard has problems of its own; some applications (Office, etc.) put vendor-specific information into the clipboard that can have pointers into internal data; when you put your own info on the clipboard, the internal data gets released, and when you put the old data back, the clipboard now points to freed data, resulting in crashes. You could work around this somewhat by only saving/restoring known clipboard formats, but again, that results in odd behavior in that apps behave "wrong" instead of crashing.


UIA technology does not supported by all applications, you can try to use MSAA in some cases (like FF, Chrome, etc.) but you still will get many problems. The best way is to save current clipboard text, send "CTRL + C" keypress message via SendMessage WinAPI function, get clipboard text, and restore initial clipboard text as Rick said.


Is it possible to look at the clipboard and make your hotkey: CTRL+C ?

You won't be able to read selected text from any application. For example some PDF files have protected content that disallows copies.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜