Why "FindWindowEx" can't find RichTextBox component

408 views Asked by At

I'm doing an auto program (C#,not C++), and I need to get a RichTextBox in a form. I have used the Spy++ to get the title and class name, but FindWindowEx always does not find RichTextBox, and GetLastError gets the word 0. And then this is a simple example.

IntPtr parent = FindWindow(null, "Form1");
if (parent!=IntPtr.Zero) {
    //find test1 textbox
    IntPtr child = FindWindowEx(parent, 0,null,  "test1");
    if (child!=IntPtr.Zero) {
        SendMessage(child, 0x000c, 0, lParam:  "test");
    } else {
        Console.WriteLine("textbox can't be found");
    }
    //find test2 richtextbox
    IntPtr childRich = FindWindowEx(parent, 0, null, "test2");
    if (childRich != IntPtr.Zero) {
        SendMessage(child, 0x000c, 0, lParam: "test");
    } else {
        Console.WriteLine("richtextbox can't be found");
    }
} else {
    Console.WriteLine("Form1 can't be found");
}

https://i.stack.imgur.com/7eWil.png

But result is richtextbox can't find. Help me.

1

There are 1 answers

3
Diogo Neves On

I don't really think this is the best approach but it's something.

For this specific case you can search for all the handlers in the Form and then change the one you want.

var iHandle = Win32.FindWindow(null, "Form1");
var allItems = Win32.GetAllChildrenWindowHandles((IntPtr)iHandle, int.MaxValue);
Win32.SendMessage(allItems[1], 0x000c, 0, lParam: "Now you can change the text!");

I've tested and the allItems[1] will always be the same item, I think It's the way the items are ordered in the winForm top to bottom.

I'm using a second class for the Win Methods:

public class Win32
{
    public const int WM_SETTEXT = 0X000C;

    public static List<IntPtr> GetAllChildrenWindowHandles(IntPtr hParent, int maxCount)
    {
        var result = new List<IntPtr>();
        int ct = 0;
        IntPtr prevChild = IntPtr.Zero;
        IntPtr currChild = IntPtr.Zero;
        while (true && ct < maxCount)
        {
            currChild = FindWindowEx(hParent, prevChild, null, null);
            if (currChild == IntPtr.Zero) break;
            result.Add(currChild);
            prevChild = currChild;
            ++ct;
        }
        return result;
    }

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("User32.dll")]
    public static extern int FindWindow(string strClassName, string strWindowName);
}

Edit: Method to get all children windows handles taken from: https://jamesmccaffrey.wordpress.com/2013/02/03/getting-all-child-window-handles-using-c-pinvoke-findwindowex/