locked
Capture Highlighted Text from any window using C#

    Question

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

     I tried this way:

            [DllImport("user32.dll")]
            static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
            [DllImport("user32.dll")]
            static extern IntPtr GetForegroundWindow();
            [DllImport("user32.dll", SetLastError = true)]
            static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
            [DllImport("kernel32.dll")]
            static extern uint GetCurrentThreadId();
            [DllImport("user32.dll")]
            static extern bool AttachThreadInput(uint idAttach, uint idAttachTo,bool fAttach);
            [DllImport("user32.dll")]
            static extern IntPtr GetFocus();
            [DllImport("user32.dll")]
            static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
            // second overload of SendMessage
            [DllImport("user32.dll")]
            static extern int SendMessage(IntPtr hWnd, uint Msg, out int wParam, out int lParam);
           
            const uint WM_GETTEXT = 0x0D;
            const uint WM_GETTEXTLENGTH = 0x0E;
            const uint EM_GETSEL = 0xB0;

            function string GetSelectedText()

            {

                   IntPtr hWnd = GetForegroundWindow();

                    uint processId;

                    uint activeThreadId = GetWindowThreadProcessId(hWnd, out processId);
                    uint currentThreadId = GetCurrentThreadId();
                    AttachThreadInput(activeThreadId, currentThreadId, true);
                    IntPtr focusedHandle = GetFocus();
                    AttachThreadInput(activeThreadId, currentThreadId, true);
                    StringBuilder sb1 = new StringBuilder();
                    int len = SendMessage(focusedHandle, WM_GETTEXTLENGTH, 0,sb1);

                    StringBuilder sb = new StringBuilder(len);
                    int numChars = SendMessage(focusedHandle, WM_GETTEXT, len + 1, sb);
                    int start, next;
                    SendMessage(focusedHandle, EM_GETSEL, out start, out next);
                    string selectedText = "";
                    if (sb.ToString() != "")
                        selectedText = sb.ToString().Substring(start, next - start);

                    return selectedText;

               }

     

    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?

    Thanks & Regards,

    Dev

    Tuesday, February 22, 2011 9:04 AM

Answers

  • If you look at the WM_GETTEXT documentation on MSDN it appears it only pulls text from edit, text, combo box, and button controls. 

    I'm not sure you will be able to use this approach with web browsers because of this statement in the remarks section:

    "Sending a WM_GETTEXT message to a non-text static control, such as a static bitmap or static icon control, does not return a string value. Instead, it returns zero."

    Tuesday, February 22, 2011 1:54 PM
  • Matt is right!

    We need to pass the correct Window handle when sending WM_GETTEXT messages.  For some Win32 controls like textbox, combobox and etc, we can use WM_GETTEXT message to retrieve the text inside.   However, some apps has their own controls, some of them even have not Window handles.  So, it's really hard to get the text of every apps unless each of them export some APIs for us to use.  :)

    Have a nice weekend!


    Michael Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, February 25, 2011 5:05 AM
    Moderator

All replies

  • If you look at the WM_GETTEXT documentation on MSDN it appears it only pulls text from edit, text, combo box, and button controls. 

    I'm not sure you will be able to use this approach with web browsers because of this statement in the remarks section:

    "Sending a WM_GETTEXT message to a non-text static control, such as a static bitmap or static icon control, does not return a string value. Instead, it returns zero."

    Tuesday, February 22, 2011 1:54 PM
  • Matt is right!

    We need to pass the correct Window handle when sending WM_GETTEXT messages.  For some Win32 controls like textbox, combobox and etc, we can use WM_GETTEXT message to retrieve the text inside.   However, some apps has their own controls, some of them even have not Window handles.  So, it's really hard to get the text of every apps unless each of them export some APIs for us to use.  :)

    Have a nice weekend!


    Michael Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, February 25, 2011 5:05 AM
    Moderator
  • Really? so how applications like Translation Client ( http://translateclient.com/ ) can do that? It's get text from any process.

    Alexsandro_xpt

    Sunday, November 11, 2012 8:33 PM