在C#中,有没有办法来始终能够获得当前焦点窗口选定的文本内容是什么?没有办法、文本、窗口、焦点

2023-09-03 02:15:25 作者:别吵醒、寂寞

在我的C#.NET应用程序中,我一直在试图能够检索中当前焦点窗口当前选定的文本。 (请注意,它可以在Windows中的任何窗口中打开,如Word,或Safari)。

In my c# .Net application, I've been trying to be able to retrieve the currently selected text in the currently focused window. (Note that it can be any window open in windows, such as word, or safari).

我能够检索句柄当前焦点的控制。 (使用一对夫妇互操作的调用user32.dll中,并KERNEL32.DLL)。

I'm able to retrieve the handle to the currently focused control. (Using a couple of interop calls to user32.dll, and kernel32.dll).

不过,我一直无法始终能够取回选定的文本。

However, I've been unable to consistently be able to get back the selected text.

我用SendMessage函数和GET_TEXT尝试。然而,这似乎只工作在某些应用(适用于简单的应用程序,如写字板,对于更复杂的应用,如Firefox或词不工作)。

I've tried using SENDMESSAGE and GET_TEXT. However this only seems to work for some applications (works for simple applications like wordpad, doesn't work for more complex applications like firefox, or word).

我用SendMessage函数和WM_COPY尝试。然而,这一次似乎只工作在一些控制。 (我认为WM_COPY,会导致完全一样的行为,手工pressing CTRL-C,但事实并非如此)。

I've tried using SENDMESSAGE and WM_COPY. However, again this only seems to work on some controls. (I would think that WM_COPY, would cause the exact same behaviour as manually pressing CTRL-C, but it doesn't).

我用SendMessage函数和WM_KEYUP + WM_KEYDOWN手动刺激复制命令尝试。但是,这并不经常工作之一。 (也许与由用户pssed调用我的实际应用的热键$ P $重叠的)。

I've tried using SENDMESSAGE and WM_KEYUP+WM_KEYDOWN to manually stimulate a copy command. BUt this doesn't constantly work either. (Perhaps of an overlap with the actual hotkey pressed by a user to invoke my applications).

这是一贯能够检索当前选定文本的任何想法? (在任何应用程序)。

Any ideas on consistently being able to retrieve the currently selected text ? (on any application).

推荐答案

我通过几件事情的组合得到了这个工作。所以:

I got this working by a combination of a couple of things. So:

在等待什么修改器目前按住释放。

发送控制+ C(使用这个答案trigger OS复制(Ctrl + C或按Ctrl-x)programicly )

        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是克里斯Schmick的答案。

I'm using WPF so Keyboard.Modifiers is System.Windows.Input.Keyboard, whereas Keyboard.SimulateKeyStroke is from Chris Schmick's answer.

请注意,timeSlept是我最大的时间来等待,让继续其快乐的方式去之前的关键用户。

Note, timeSlept is my max time to wait for the user to let go of the key before continuing on its merry way.