简体   繁体   中英

How to get selected text from an active application, without using a clipboard

What am I doing:

My main intent is to enable user friendly text to speech for personal use on Win 7. Approach should work in Google Chrome, VS and Eclipse.

Code example:

Following code creates global keyboard hook for ctrl + alt + space , called hookEvent. If event fires, it starts/stops speaking clipboard contents ( that can be updated with ctrl + c ).

    /// <summary>
    /// KeyboardHook from: http://www.liensberger.it/web/blog/?p=207
    /// </summary>
    private readonly KeyboardHook hook = new KeyboardHook();
    private readonly SpeechSynthesizer speaker = //
        new SpeechSynthesizer { Rate = 3, Volume = 100 };

    private void doSpeaking(string text)
    {
        // starts / stops speaking, while not blocking UI
        if (speaker.State != SynthesizerState.Speaking)
            speaker.SpeakAsync(text);
        else
            speaker.SpeakAsyncCancelAll();
    }
    private void hookEvent(object sender, KeyPressedEventArgs e)
    {
        this.doSpeaking(Convert.ToString(Clipboard.GetText()));
    }
    public Form1()
    {
        InitializeComponent();
        hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hookEvent);
        hook.RegisterHotKey(ModifierKeysx.Control|ModifierKeysx.Alt, Keys.Space);
    }

Question:

I would prefer not using the clipboard. Or at least, restoring the value after, something like:

    [MethodImpl(MethodImplOptions.Synchronized)]
    private string getSelectedTextHACK()
    {
        object restorePoint = Clipboard.GetData(DataFormats.UnicodeText);
        SendKeys.SendWait("^c");
        string result = Convert.ToString(Clipboard.GetText());
        Clipboard.SetData(DataFormats.UnicodeText, restorePoint);

        return result;
    }

What are my options?

Edit:

To my surprise, I found that my clipboard reader is the best way to go. I created a notification area app, that responds to left click (speaking clipboard) and right click (menu opens up). In menu the user can chance speed, speak or create a audio file.

MS provide accessibility tools that do cover what you're trying to do. If you take a look at documents about screen scraping. In short, every component is accessible in some manner, if you use some of the windows debugging tools you can get to see the component names/structures within. You can then use that, however, its complicated as most times you would need to be very specific for each application you intend to scrape from.

If you manage to scrape you dont need to use the clipboard, as you can access the text property of the apps direct. Its not something I've had to do, hence, Ive no code to offer off the top of my head, but the term "screen scraping" should point you in the right direction.

If to expand a little on what Bugfinder said, Microsoft provider a UI Automation Framework to solve problems like the one you mentioned:

In particular you can use the TextSelectionChangedEvent of TextPattern :

The problem with this solution is that it only works on supported operating systems and applications - and not all support this.

Your clipboard solution is acceptable for applications that do not provide a good automation interface. But for many applications the UI Automation Framework will work well and will provide you with a far better solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM