6

What am I doing?

I am automating a 3rd party application. The login window looks like this

enter image description here

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.

enter image description here

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 Buttons (.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.

Community
  • 1
  • 1
  • Unless the third party application changes ... have you any reason to think the order of controls will change? – Rob Feb 14 '14 at 10:24
  • Not answering, but 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. – manuell Feb 14 '14 at 10:28
  • @Rob for now the 3rd party application will be the same. If it changes I will obviously adjust my code. What I am actually asking is can I be sure that the `FindWindowEx` function always returns handles to windows/controls in the same order? –  Feb 14 '14 at 10:41
  • @manuell thanks for the tip. I would happy to accept your idea if you convert it to an answer. It turns out that the `GetWindowLongPtr()` function actually returns the ID of the controls (it seems to be constant each time I run my code). –  Feb 14 '14 at 11:00

1 Answers1

4

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.

Community
  • 1
  • 1
manuell
  • 7,528
  • 5
  • 31
  • 58
  • I have left a comment for you below my original post as it turns out the approach with `GetWindowLongPtr` works for me :) –  Feb 14 '14 at 11:01
  • @manuell, answers http://stackoverflow.com/a/296014/1374704 is very inaccurate, I just corrected, see ibid. – kero Feb 15 '14 at 10:14