【问题标题】:Capture Highlighted Text from any window using C#使用 C# 从任何窗口捕获突出显示的文本
【发布时间】:2023-03-10 08:28:01
【问题描述】:

如何使用 c# 从任何窗口读取突出显示/选定的文本。

我尝试了两种方法。

  1. 每当用户选择某些东西时发送“^c”。但在这种情况下,我的剪贴板中充斥着大量不必要的数据。有时它也会复制密码。

所以我将我的方法切换到第二种方法,发送消息方法。

查看此示例代码

 [DllImport("user32.dll")]
    static extern int GetFocus();

    [DllImport("user32.dll")]
    static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

    [DllImport("kernel32.dll")]
    static extern uint GetCurrentThreadId();

    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);    

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

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam);     

   // second overload of SendMessage

    [DllImport("user32.dll")]
    private static extern int SendMessage(IntPtr hWnd, uint Msg, out int wParam, out int lParam);

    const int WM_SETTEXT = 12;
    const int WM_GETTEXT = 13;     

private string PerformCopy()
    {
        try
        {
            //Wait 5 seconds to give us a chance to give focus to some edit window,
            //notepad for example
            System.Threading.Thread.Sleep(5000);
            StringBuilder builder = new StringBuilder(500);

            int foregroundWindowHandle = GetForegroundWindow();
            uint remoteThreadId = GetWindowThreadProcessId(foregroundWindowHandle, 0);
            uint currentThreadId = GetCurrentThreadId();

            //AttachTrheadInput is needed so we can get the handle of a focused window in another app
            AttachThreadInput(remoteThreadId, currentThreadId, true);
            //Get the handle of a focused window
            int focused = GetFocus();
            //Now detach since we got the focused handle
            AttachThreadInput(remoteThreadId, currentThreadId, false);

            //Get the text from the active window into the stringbuilder
            SendMessage(focused, WM_GETTEXT, builder.Capacity, builder);

            return builder.ToString();
        }
        catch (System.Exception oException)
        {
            throw oException;
        }
    }

此代码在记事本中运行良好。但是,如果我尝试从其他应用程序(如 Mozilla firefox 或 Visual Studio IDE)捕获,它不会返回文本。

谁能帮帮我,我哪里做错了?首先,我选择了正确的方法?

【问题讨论】:

    标签: c# forms sendmessage user32


    【解决方案1】:

    这是因为 Firefox 和 Visual Studio 都不使用内置的 Win32 控件来显示/编辑文本。

    一般不可能获得“任何”选定文本的值,因为程序可以以任何方式重新实现自己的 Win32 控件版本认为合适,您的程序不可能期望与所有这些都一起工作。

    但是,您可以使用UI Automation API,这将允许您与大多数 3rd 方控件进行交互(至少,所有好的控件 - 例如 Visual Studio 和 Firefox -可能会与 UI 自动化 API 一起使用,因为它是可访问性的要求)

    【讨论】:

    • Firefox没有实现UI自动化,我试过3.0版本还是不行,希望以后支持。
    • 我们可以做些什么来改进我的第一个方法。效果很好,除了不必要的复制............
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多