Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 AutomationElements:

//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?

like image 552
nelshh Avatar asked Nov 22 '10 09:11

nelshh


3 Answers

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.

like image 151
Eric Brown Avatar answered Nov 12 '22 22:11

Eric Brown


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.

like image 24
Anton Avatar answered Nov 12 '22 23:11

Anton


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.

like image 1
Rick Avatar answered Nov 12 '22 21:11

Rick