Reading text from an external applications textbox

Marco picture Marco · Sep 27, 2011 · Viewed 8.3k times · Source

I am trying to extend some features of a external programm that is not able to use plugins or something. So I have to write my own app that reads the text from a textbox from this external application and trigger some own actions.

By using the FindWindow API in user32.dll I allready catched up the handle for the external application. But now I am kind of stuck. By using Spy++ from the Visual Studio Tools I got the information that the class name from the control I would like to read from is "WindowsForms10.EDIT.app.0.218f99c", but there are several of them. Additionally every time the external app starts it creates a new control id for the textbox I want to read.

How can I get it managed to identify a certain textbox and read the value of it? Can anybody give me a hint or kind of advice?

Answer

Sander Wollaert picture Sander Wollaert · Jan 4, 2012

The Code in C#

public static class ModApi
{
    [DllImport("user32.dll", EntryPoint = "FindWindowA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

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

    [DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern uint SendMessageTimeoutText(IntPtr hWnd, int Msg, int countOfChars, StringBuilder text, uint flags, uint uTImeoutj, uint result);

    [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    static internal extern bool EnumChildWindows(IntPtr hWndParent, funcCallBackChild funcCallBack, IntPtr lParam);

    public delegate bool funcCallBackChild(IntPtr hWnd, IntPtr lParam);


    public static ArrayList TextBoxStrings = new ArrayList();
    public static void ParseWindowControls(string WindowTitle)
    {
        IntPtr hWnd = FindWindow(null, WindowTitle);
        TextBoxStrings.Clear();


        funcCallBackChild MyCallBack = EnumChildWindowsProc;
        EnumChildWindows(hWnd, MyCallBack, IntPtr.Zero);
    }

    private static bool EnumChildWindowsProc(IntPtr hWndParent, IntPtr lParam)
    {
        var buffer = new StringBuilder(256);
        long Retval = GetClassName(hWndParent, buffer, buffer.Capacity);
        if (buffer.ToString() == "Edit" || buffer.ToString() == "Static")
        {
            TextBoxStrings.Add(GetText(hWndParent));
        }

        return true;
    }

    private static string GetText(IntPtr hwnd)
    {
        var text = new StringBuilder(1024);
        if (SendMessageTimeoutText(hwnd, 0xd, 1024, text, 0x2, 1000, 0) != 0)
        {
            return text.ToString();
        }

        return "";
    }
}