c# - 在C#中,有没有办法始终如一地获取当前焦点窗口的选定文本内容?

标签 c# .net winforms winapi

在我的 c# .Net 应用程序中,我一直在尝试能够在当前获得焦点的窗口中检索当前选定的文本。 (注意可以是windows中任意打开的窗口,比如word,或者safari)。

我能够检索到当前获得焦点的控件的句柄。 (使用对 user32.dll 和 kernel32.dll 的几个互操作调用)。

但是,我一直无法始终如一地取回所选文本。

我试过使用 SENDMESSAGE 和 GET_TEXT。然而,这似乎只适用于某些应用程序(适用于简单的应用程序,如写字板,不适用于更复杂的应用程序,如 firefox 或 word)。

我试过使用 SENDMESSAGE 和 WM_COPY。然而,这似乎只适用于某些控件。 (我认为 WM_COPY 会导致与手动按下 CTRL-C 完全相同的行为,但事实并非如此)。

我试过使用 SENDMESSAGE 和 WM_KEYUP+WM_KEYDOWN 手动激活复制命令。但这也不是一直有效。 (可能与用户为调用我的应用程序按下的实际热键重叠)。

关于始终能够检索当前选定文本的任何想法? (在任何应用程序上)。

最佳答案

我通过结合几件事来实现这一目标。所以:

  1. 等待当前按住的任何修饰符被释放。
  2. 发送 control+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 是我等待用户放开 key 的最大时间,然后才能继续其快乐的方式。

关于c# - 在C#中,有没有办法始终如一地获取当前焦点窗口的选定文本内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/653003/

相关文章:

c# - 有没有办法创建嵌套的开放泛型类型?

c# - 如何透视 IEnumerable<T>

.net - EventLog.WriteEntry 和 EventLog.WriteEvent 方法之间的区别

c# - 为什么我不能更改 String.Empty 的值?

c# - DPI 意识 - 在一个版本中没有意识到,在另一个版本中有系统意识

c# - 连接 Program.cs 和 Form.cs

c# - 如何在不显式指定主键的情况下使用 Dapper Extensions 将对象插入 PostGreSql?

c# - 路径不是合法的 C# 形式

c# - 带有提醒场景的 Toast 通知未停留在屏幕上

c# - 使用ANTLR用C#解析C++