c# - 如何获取当前焦点窗口的选定文本?

标签 c# focus selection

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

  1. 监听键盘快捷键(使用 this library )
  2. 当按下快捷键时,检索当前所选文本的内容,并且
  3. 处理文本

我使用了this answer最新编辑分享的方法( this method ) 将我的应用程序附加到焦点控件,但该方法中的 GetText 函数无法执行我需要的操作。

我见过this answer以及,但这只提供了如何通过双击获得焦点窗口的详细步骤,这不是我需要的。它确实链接到 this question这导致我尝试了 WM_KEYDOWN 方法(如下所示),但这也不起作用。

到目前为止,我已经尝试过这些 GetText 方法(全部在该 MSDN 帖子的上下文中):

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;
}

(我还不关心保留剪贴板。)

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

最佳答案

自 Vista 起,应用程序应避免使用 p-invoke 或 WM_GETTEXT 来窥探其他应用程序,因为 Windows 提升进程可能会阻塞。请考虑使用Microsoft UI Automation。虽然可以说是一个测试框架,但它也可作为与另一个 GUI 应用程序远程交互的手段。

MSDN:

Microsoft UI Automation is the new accessibility framework for Microsoft Windows. It addresses the needs of assistive technology products and automated test frameworks by providing programmatic access to information about the user interface (UI). In addition, UI Automation enables control and application developers to make their products accessible.

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

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)}\"");
            }    
        }
    }
}

编辑:

How can I consistently get the selected text of the currently focused application?

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

var p = Process.GetProcessesByName("notepad").FirstOrDefault();     

...执行:

IntPtr handle = GetForegroundWindow();
var root = AutomationElement.FromHandle(handle);

...其中 GetForegroundWindow 定义为:

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

另请参阅

关于c# - 如何获取当前焦点窗口的选定文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51557059/

相关文章:

c# - 如何输出字符串中的所有其他单词?

android - 如何检测和防止 Android 应用程序中的焦点窃取

c# - 受按钮影响的按键事件

Delphi:TRadioButton的TabStop问题

java - 使用小数组的选择排序算法

c# - 如何在 DotNetNuke 自定义模块中显示图像?

c# - 无法使用独立关联将可选外键设置为空

c# - 从 .NET HashSet 按索引选择元素

selection - Select UI/Vaadin 6.7.3 的 Property.valueChangeListener 的奇怪行为

cakephp - 在 cakephp 下拉菜单中添加默认选项 "Please Select"