代码之家  ›  专栏  ›  技术社区  ›  AbyxDev user411313

如何获取当前焦点窗口的选中文本?

  •  1
  • AbyxDev user411313  · 技术社区  · 6 年前

    因此,我正在尝试创建一个执行以下操作的应用程序:

    1. 监听键盘快捷键(使用 this library )
    2. 当快捷方式被点击时,检索当前所选文本的内容,以及
    3. 处理文本

    我使用的方法是 this answer ( this method )将我的应用程序附加到焦点控件,但是 GetText 那个方法中的函数不能满足我的需要。

    我见过 this answer 同样,但这只给出了如何使焦点窗口双击的详细步骤,这不是我需要的。它确实链接到 this question 这让我尝试 WM_KEYDOWN 方法(如下所示),但也不起作用。

    到目前为止我已经试过了 获得文本 方法(全部在该msdn post的上下文中):

    string GetText(IntPtr handle)
    {
        // works in Notepad, but not Chrome
        SendMessageW(handle, WM_COPY, 0, 0);
        string w = Clipboard.GetText();
        return w;
    
        // works in every app, but in Notepad gets the complete contents
        // and in Chrome gets the window title
        int maxLength = 160;
        IntPtr buffer = Marshal.AllocHGlobal((maxLength + 1) * 2);
        SendMessageW(handle, WM_GETTEXT, maxLength, buffer);
        string w = Marshal.PtrToStringUni(buffer);
        Marshal.FreeHGlobal(buffer);
        return w;
    
        // I would have thought these would work, but
        // they don't do anything for some reason. They
        // all simulate a Ctrl+C.
    
        SendKeys.SendWait("^c");
        // or
        // this is from the same library that listens for the keyboard shortcut
        KeyboardSimulator.SimulateStandardShortcut(StandardShortcut.Copy);
        // or
        SendMessageW(handle, WM_KEYDOWN, (ushort)Keys.LControlKey, 0);
        SendMessageW(handle, WM_KEYDOWN, (ushort)Keys.C, 0);
        SendMessageW(handle, WM_KEYUP, (ushort)Keys.C, 0);
        SendMessageW(handle, WM_KEYUP, (ushort)Keys.LControlKey, 0);
        // after any of those
        string w = Clipboard.GetText();
        return w;
    }
    

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

    如何始终获取当前关注的应用程序的选定文本?不篡改剪贴板的奖励积分,但使用它也是可以的。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Deleted    6 年前

    WM_GETTEXT

    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();