使用 C# 从任何窗口捕获突出显示的文本

发布于 2024-08-31 05:01:56 字数 2353 浏览 10 评论 0原文

如何使用 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 等其他应用程序捕获,它不会返回文本。

有人可以帮我吗,我哪里做错了?首先,我选择的方法正确吗?

How to read the highlighted/Selected Text from any window using c#.

i tried 2 approaches.

  1. Send "^c" whenever user selects some thing. But in this case my clipboard is flooded with lots of unnecessary data. Sometime it copied passwords also.

so i switched my approach to 2nd method, send message method.

see this sample code

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

this code working fine in Notepad. But if i try to capture from another applications like Mozilla firefox, or Visual Studio IDE, it's not returning the text.

Can anybody please help me, where i am doing wrong? First of all, i have chosen the right approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冧九 2024-09-07 05:01:56

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

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

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

That's because both Firefox and Visual Studio don't use the built-in Win32 controls for displaying/editing text.

It is not possible in general to be able to get the value of "any" selected text, because of the fact that programs can re-implement their own version of the Win32 controls any way they see fit, and your program cannot possibly expect to work with all of them.

However, you can use the UI Automation APIs which will allow you to interact with the majority of 3rd-party controls (at least, all the good ones - such as Visual Studio and Firefox - will likely work with the UI Automation APIs since it's a requirement for accessibility)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文