C# 如何获取当前聚焦窗口的选定文本?

C# 如何获取当前聚焦窗口的选定文本?,c#,focus,selection,C#,Focus,Selection,因此,我尝试制作一个应用程序,它可以执行以下操作: 侦听键盘快捷键(使用) 点击快捷方式时,检索当前选定文本的内容,然后 处理文本 我使用了()的最新编辑共享的方法将我的应用程序附加到聚焦控件,但是该方法中的GetText函数不能满足我的需要 我也看到了,但这只是给出了如何在双击时获得聚焦窗口的详细步骤,这不是我需要的。它确实链接到了我尝试WM_KEYDOWN方法(如下所示)的链接,但这也不起作用 到目前为止,我已经尝试了这些GetText方法(都在那篇MSDN文章的上下文中): (我还不在乎保

因此,我尝试制作一个应用程序,它可以执行以下操作:

  • 侦听键盘快捷键(使用)
  • 点击快捷方式时,检索当前选定文本的内容,然后
  • 处理文本
  • 我使用了()的最新编辑共享的方法将我的应用程序附加到聚焦控件,但是该方法中的
    GetText
    函数不能满足我的需要

    我也看到了,但这只是给出了如何在双击时获得聚焦窗口的详细步骤,这不是我需要的。它确实链接到了我尝试
    WM_KEYDOWN
    方法(如下所示)的链接,但这也不起作用

    到目前为止,我已经尝试了这些
    GetText
    方法(都在那篇MSDN文章的上下文中):

    (我还不在乎保留剪贴板。)


    如何一致地获取当前关注的应用程序的选定文本?不要篡改剪贴板,但使用剪贴板也可以。从Vista开始,应用程序应避免使用p-invoke或WM_GETTEXT来窥探其他应用程序,因为Windows进程可能会被阻止。取而代之的是考虑使用微软UI自动化。尽管可以说它是一个测试框架,但它还是一种与另一个GUI应用程序进行远程交互的有用方法

    MSDN:

    Microsoft UI Automation是Microsoft Windows的新辅助功能框架。它通过提供对用户界面(UI)信息的编程访问来满足辅助技术产品和自动化测试框架的需求。此外,UI自动化使控件和应用程序开发人员能够访问他们的产品

    下面的代码将查找正在运行的进程记事本并抓取任何文本选择确保事先运行记事本,输入一些文本并选择一两个单词

    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Windows.Automation;
    
    namespace UiaTest
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                var p = Process.GetProcessesByName("notepad").FirstOrDefault();       
                var root = AutomationElement.FromHandle(p.MainWindowHandle);
    
                var documentControl = new                                 
                        PropertyCondition(AutomationElement.ControlTypeProperty, 
                                          ControlType.Document);
    
                var textPatternAvailable = new PropertyCondition(AutomationElement.IsTextPatternAvailableProperty, true);
    
                var findControl = new AndCondition(documentControl, textPatternAvailable);
    
                var targetDocument = root.FindFirst(TreeScope.Descendants, findControl);    
                var textPattern = targetDocument.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
    
                foreach (var selection in textPattern.GetSelection())
                {
                    Console.WriteLine($"Selection: \"{selection.GetText(255)}\"");
                }    
            }
        }
    }
    
    编辑:

    如何一致地获取当前聚焦的应用程序的选定文本

    现在,在您的情况下,从聚焦窗口开始工作,而不是:

    var p = Process.GetProcessesByName("notepad").FirstOrDefault();     
    
    …执行以下操作:

    IntPtr handle = GetForegroundWindow();
    var root = AutomationElement.FromHandle(handle);
    
    …其中
    GetForegroundWindow
    定义为:

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();
    
    另见

    查看Microsoft用户界面Automation@MickyD如果你发布一个答案来说明如何使用它,这会有所帮助。WM_COPY和WM_GETTEXT它们并不总是像MSDN文档中对这些消息所述的那样工作。所以,问题是模拟或收听ctrl+c?@γηράσκω'αείπολάΔιΔασκόμε如果WMάCOPY和WMάGETTEXT不总是按规定工作,那么我猜问题是模拟ctrl+c(不收听)@MickyD你能解释一下MS UI自动化是如何用于这个目的的吗?谢谢你的回答!您能告诉我如何获取当前焦点窗口(实际问题)的选定文本,而不是按名称获取特定窗口的文本吗?这会有很大帮助。嗯,这种方法适用于记事本,但当我尝试在Chrome中使用所选文本(甚至是文本区域)时,
    targetDocument
    结果是
    null
    ,我得到了一个null引用异常,其中显示
    targetDocument.GetCurrentPattern
    。“我错过了什么?”肯希尔顿,这是个新问题。您需要枚举元素以找到适当的控件。这个答案足以让你开始了解。如果是那样的话,我会接受这个答案,谢谢你的帮助!
    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();