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

Din*_*esh 5 c# forms user32 sendmessage

如何使用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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

此代码在记事本中正常工作.但是,如果我尝试从其他应用程序捕获,如Mozilla firefox或Visual Studio IDE,它不会返回文本.

任何人都可以帮助我,我做错了吗?首先,我选择了正确的方法?

Dea*_*ing 3

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

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

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