1

I want to get the text which is in textbox of other application. It may be a textbox of gtalk client or a soap UI screen.

Based on my research most of the forums suggested winapi is the concept that I've to use to achieve this. I didn't get any good examples to implement this.

Bharath
  • 195
  • 1
  • 1
  • 19
  • Getting text from windows is different depending on what you are trying to get text from. Getting all the text from a winforms application, for example, can be done though the Windows API using EnumChildWindows and GetWindowCaption/GetWindowText. Whereas, getting text from a webpage or application written in another GUI tool kit is a whole other story. There is no universal text grabber that I am aware of. – Francis MacDonald Jul 12 '13 at 13:39

3 Answers3

12

Here is an example of how to grab all the text from a window by it's window title.

Please see the comments for an explanation on how this works.

public class GetWindowTextExample
{
    // Example usage.
    public static void Main()
    {
        var allText = GetAllTextFromWindowByTitle("Untitled - Notepad");
        Console.WriteLine(allText);
        Console.ReadLine();
    }

    // Delegate we use to call methods when enumerating child windows.
    private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    private static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, [Out] StringBuilder lParam);

    // Callback method used to collect a list of child windows we need to capture text from.
    private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer)
    {
        // Creates a managed GCHandle object from the pointer representing a handle to the list created in GetChildWindows.
        var gcHandle = GCHandle.FromIntPtr(pointer);

        // Casts the handle back back to a List<IntPtr>
        var list = gcHandle.Target as List<IntPtr>;

        if (list == null)
        {
            throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
        }

        // Adds the handle to the list.
        list.Add(handle);

        return true;
    }

    // Returns an IEnumerable<IntPtr> containing the handles of all child windows of the parent window.
    private static IEnumerable<IntPtr> GetChildWindows(IntPtr parent)
    {
        // Create list to store child window handles.
        var result = new List<IntPtr>();

        // Allocate list handle to pass to EnumChildWindows.
        var listHandle = GCHandle.Alloc(result);

        try
        {
            // Enumerates though all the child windows of the parent represented by IntPtr parent, executing EnumChildWindowsCallback for each. 
            EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle));
        }
        finally
        {
            // Free the list handle.
            if (listHandle.IsAllocated)
                listHandle.Free();
        }

        // Return the list of child window handles.
        return result;
    }

    // Gets text text from a control by it's handle.
    private static string GetText(IntPtr handle)
    {
        const uint WM_GETTEXTLENGTH = 0x000E;
        const uint WM_GETTEXT = 0x000D;

        // Gets the text length.
        var length = (int)SendMessage(handle, WM_GETTEXTLENGTH, IntPtr.Zero, null);

        // Init the string builder to hold the text.
        var sb = new StringBuilder(length + 1);

        // Writes the text from the handle into the StringBuilder
        SendMessage(handle, WM_GETTEXT, (IntPtr)sb.Capacity, sb);

        // Return the text as a string.
        return sb.ToString();
    }

    // Wraps everything together. Will accept a window title and return all text in the window that matches that window title.
    private static string GetAllTextFromWindowByTitle(string windowTitle)
    {
        var sb = new StringBuilder();

        try
        {
            // Find the main window's handle by the title.
            var windowHWnd = FindWindowByCaption(IntPtr.Zero, windowTitle);

            // Loop though the child windows, and execute the EnumChildWindowsCallback method
            var childWindows = GetChildWindows(windowHWnd);

            // For each child handle, run GetText
            foreach (var childWindowText in childWindows.Select(GetText))
            {
                // Append the text to the string builder.
                sb.Append(childWindowText);
            }

            // Return the windows full text.
            return sb.ToString();
        }
        catch (Exception e)
        {
            Console.Write(e.Message);
        }

        return string.Empty;
    }
}
  • Hi, Sir, Your solution so great. How to get text by type in any program, not only notepad? – Neo Aug 20 '15 at 09:35
0

You are correct. You will need to use the Windows API. For example:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

But first, you'll probably need to use FindWindow or FindWindowEx(?) recursively from the desktop down to where the text box is in the window hieracrchy to get the right window handle.

It looks like http://www.pinvoke.net/ has a good database of Win API's.

Hope that helps.

James R.
  • 822
  • 8
  • 17
  • Thanks for your response james. I used find window to get the handle. i gave the class and window of the application which was found using SPY++.I am having textbox in that applciation screen. But i am not getting that textbox handle in Spy++. – Bharath Jul 12 '13 at 13:00
  • can you please clarify me what GetWindowText does? – Bharath Jul 12 '13 at 13:00
  • Perhaps the text box is not a standard Windows "Text Box". Otherwise, it should have a window handle. You may be out of luck :( – James R. Jul 12 '13 at 13:02
  • [GetWindowText](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633520(v=vs.85).aspx) – James R. Jul 12 '13 at 13:03
0

One option would be to use TestStack.White, a UI automation framework. It's based on project white, and the original documentation is here.

devdigital
  • 34,151
  • 9
  • 98
  • 120