Can I always be sure of the hierarchical order of controls found via FindWindowEx?

c#, vb.net, vba, winapi, windows

Solution

Each child `HWND` has a property called `ID`. Use `GetWindowLongPtr( hWnd, GWLP_ID )` to get it. Depending on how the target application is coded, that `ID` may be a way to distinguish between child control. Knowing the `ID` you can get the child `HWND` with the `GetDlgItem` API (works fine when the parent is not a DialogBox, the API should have been called `GetChildByID`).

Beware: some target applications really use random/unreliable values for IDs.

It seems that there is a general consensus: Enumeration APIs rely on the Z-Order. See for example that SO answer (maybe making your question some sort of 'duplicate')

While some applications may "play" with the Z-Order of their child windows, in the standard case they won't, which means that the first created child window is at the top of the Z-order, and the last created one is at the bottom.

Problem

What am I doing? I am automating a 3rd party application. The login window looks like this Note: there is a background image embed within the form and both the `USERNAME` and `PASSWORD` are actually part of an image. Just in case anyone wonders why the below classes treeview from `Window Detective` doesn't have, possibly » `Label` controls. Where am I at? I don't have any problems getting handles of components. I mean, I can generally access each window/control using `FindWindowEx` function. I can implement a `GetWindowTextLength` and/or `GetWindowText` functions for buttons to distinguish which one I have got a handle of. While this approach works fine with `Button`s (.Caption) it would not benefit me when working with `Edit` controls. It seems that the `Edit` controls do not have any unique properties to distinguish which one is which. (correct me if I am wrong)... The problem Assume that I need to know at the compile stage which `Edit` control I am going to be handling, so I don't send a password to the username and other way around. There are only two but like I've said I'm not sure how to get the right one. I wouldn't mind figuring it out at run-time but I am unsure of how to distinguish the difference without sending a message and actually visually identify which one is which... Current solution I wouldn't really call this a solution but for now I am relying only on the fact that each time I run my code I always get a handle of the second (password) `Edit` control as the first handle returned. Question Can I be 100% sure the second `Edit` control will always be returned first in the hierarchy returned by the `FindWindowEx` function? If someone can confirm my idea than I'd already have had a solution BUT if I can't always expect the second `Edit` control to be returned then I would like to hear some insight on how to handle this situation. Note: I didn't think any code is actually required for my question but if anyone would like to see the code then please leave a comment and I will add it to the question. Thanks a lot for your time.

Original source

Related problems