1

I want to get the window handle of some controls to do some stuff with it (requiring a handle). The controls are in a different application.

Strangely enough; I found out that many controls don't have a windows handle, like the buttons in the toolbar (?) in Windows Explorer. Just try to get a handle to the Folder/Search/(etc) buttons. It just gives me 0.

So.. first question: how come that some controls have no windows handle? Aren't all controls windows, in their hearts? (Just talking about standard controls, like I would expect them in Windows Explorer, nothing customdrawn on a pane or the like.)

Which brings me to my second question: how to work with them (like using EnableWindow) if you cannot get their handle?

Many thanks for any inputs!

EDIT (ADDITIONAL INFORMATION):

Windows Explorer is just an example. I have the problem frequently - and in a different application (the one I am really interested in, a proprietary one). I have "physical" controls (since I can get an AutomationElement of those controls), but they have no windows handle. Also, I am trying to send a message (SendMessage) to get the button state, trying to find out whether it is pushed or not (it is a standard button that seems to exhibit that behaviour only through that message - at least as far as I have seen. Also, the pushed state can last a lot longer on that button than you would expect on a standard button, though the Windows Explorer buttons show a similar behaviour, acting like button-style checkboxes, though they are (push)buttons). SendMessage requires a window handle.

Does a ToolBar in some way change the behaviour of its child elements? Taking away their window handle or something similar? (Using parent handle/control id for identification??) But then how to use functions on those controls that require a windows handle?

Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104

3 Answers3

7

If they don't have a handle, they're not real controls, they're just drawn to look like controls.

But of course, the toolbar buttons in Windows Explorer do have window handles, they're part of a toolbar. Use the toolbar manipulation functions to interact with them, not EnableWindow.

Or, better yet, use the documented APIs for things like search. Reverse-engineering Windows Explorer has never ended well for anyone, least of all the poor Windows Shell team, saddled with years of backwards-compatibility hacks for certain developers who thought that APIs are for everyone else. Whatever you do manage to get to work is very likely to break on the next version of Windows.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • I tried to be generic and then give a specific example that actually has nothing to do with what I want to do - my fault, sorry. I actually have completely different buttons in a completely different application that also do not have a window handle. Or is that a specific feature of a Toolbar they are part of? Also, the function I want to use is something like int res = SendMessage(realHwnd, BM_GETSTATE, 0, 0); to find out whether the button is pushed or not. – Andreas Reiff Jun 15 '11 at 15:39
  • @Andreas: Yes, partially my fault, too. I've spent too long reading Raymond Chen's blog and answering questions on here, both of which have probably made me bitter about people trying to reverse engineer Windows. As far as what the other app's doing, it's hard to say. There are a lot of possible scenarios. If you have a copy of Visual Studio, you should have a little utility called Spy++. Use that to figure out what control actually houses those buttons. If it's indeed a toolbar (`ToolbarWindow32` or something like that), then you can use one of the toolbar manipulation functions. – Cody Gray - on strike Jun 15 '11 at 15:40
  • Specifically, you'll need to detect one of the toolbar button states, defined by the [`TBSTATE_*` values](http://msdn.microsoft.com/en-us/library/bb760437.aspx). A pushed (or checked) button will have the `TBSTATE_CHECKED` state flag set (you probably don't want `TBSTATE_PRESSED`, as that indicates the user is currently clicking the button). The [`TB_GETSTATE` message](http://msdn.microsoft.com/en-us/library/bb787348.aspx) is how you determine which state a particular button has. – Cody Gray - on strike Jun 15 '11 at 15:42
  • Thanks for your added info! (feels like a chat here ;) ) So the ToolBar really changes the behaviour of its "children", since the TB_GETSTATE message is different (taking command id as added parameter) to the BM_GETSTATE message. I might have to go back to my application - it only runs on dedicated hardware, so I have been examining Windows Explorer whenever I found a similarity, since it is so much easier to use - and available on my developer machine. Are there other controls, too, that have handle-less children, apart from the ToolBar? – Andreas Reiff Jun 15 '11 at 15:51
  • It seems like a control/(embedded)elements construct that I never thought about when creating GUIs myself. Now, using GUIs in this way, I am astonished how much more there is to know and learn (and also take into account). – Andreas Reiff Jun 15 '11 at 15:52
  • @Andreas: Yes, there are others, but it depends very much on the GUI toolset that you're using. There are a lot more of them in .NET WinForms, for example. In the straight Win32 API, probably only the ToolBar (and its brother like the ReBar) and the StatusBar are like that. But it's a fairly common general pattern to have the parent manage the state of child controls. Each control having its own handle starts to get expensive in terms of resources and such, so it was avoided, especially in the early days when the ToolBar was invented. You'll really have to see what control you're dealing with. – Cody Gray - on strike Jun 15 '11 at 16:07
3

The controls you are talking about are using the ToolbarWindow32 class. If you want to interact with them then you'll need to use the toolbar control APIs/message. For example for enabling buttons you'd want to use TB_ENABLEBUTTON.

Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
0

You can implement the controls yourself using GDI, OpenGL or DirectX. Try Window Detective on Mozilla Firefox and you will see that there is only one window. Controls in dialog boxes are not windows known to Windows.

user877329
  • 6,717
  • 8
  • 46
  • 88