Access to WindowsFormsParkingWindow? - windows

I've been trying to obtain text from a panel that's part of a third-party application; I have the process ID. To do this, I've gone through the usual EnumProcessModulesEx / GetModuleBaseName / EnumWindows / EnumChildWindows steps. This code works when the panel is shown, but when it's hidden, the panel is no longer seen by my code or Spy++. I'd figured the panel must be destroyed and re-created as the user hides and shows the panel, but it turns out that the HWND of the panel is valid in both situations (GetWindow, GetTitle, etc. all return without errors, and with the same information, so the handle hasn't been re-used); the only difference is that its parent is different. When I trace the parent chain back to the root, the topmost parent's title is WindowsFormsParkingWindow, same process ID. I searched for WindowsFormsParkingWindow, and it seems to be a temporary place to "park" a HWND when you don't need it, so you won't have to re-create the window and its children. Does anyone know of an API for traversing the WindowsFormsParkingWindow hierarchy, or some other way of getting to this panel? Thanks for any advice.

WindowsFormsParkingWindow is a message-only window.
You can enumerate message-only windows by calling FindWindowEx with the special window handle HWND_MESSAGE.

Based on information from this blog:
Flashback: Windows Forms Parking Window
The Parking Window is just a generic parent window used for arbitrarily re-parenting child windows onto during parent window recreations. There is no API to query information from the Packing Window itself, such as the original parent window for any given parked child window. Only the original parent/control knows which child HWND(s) have been parked so they can be retrieved when needed.
The best you are likely to accomplish is to detect when the panel is visible, remember that HWND, and then just use that HWND when needed, even when the panel is not visible. Or at least enumerate the WindowsFormsParkingWindow to check if that HWWND is still a child of it, etc. But if the panel is losing its text while parked, then you are likely to be out of luck.

Related

On Windows, should my child window get a WM_WINDOWPOSCHANGED when its z-order changes relative to one of its siblings?

I am trying to insert a custom widget into the Internet Explorer 8 url bar, next to the stop and reload buttons. This is just a personal productivity enhancer for myself.
The "window model" for this part of the IE frame is an "address bar root" window that owns the windows which comprise the IE8 url bar: an edit box, a combo control, and the stop and reload buttons.
From another process, I create a new WS_CHILD window (with a custom class name) that is parented by IE's address bar root window, thus making it a sibling of the edit box and stop/reload. I call SetWindowPos with an hwndInsertAfter of HWND_TOP to make sure it appears "above" (i.e. "in") the urlbar. This works nicely, and I see my window painted initially inside the IE urlbar.
However, when I activate the IE window, the urlbar edit control jumps back in front of my window. I know this is happening because I still see my window painted behind the urlbar, and because when I print ->GetTopWindow() to the debug console on a timer, it becomes the HWND of the urlbar edit control.
If I update my message loop to call SetWindowPos with HWND_TOP on WM_PAINT, things are better -- now when I activate the IE window and move it around, my control properly stays planted above the edit control in the urlbar. However, as soon as I switch between IE tabs, which updates the text of IE's urlbar Edit control, my control shift backs behind the Edit control. (Note: This also happens when I maximize or restore the window.)
So my questions are:
1) Is it likely that IE is intentionally putting its urlbar edit control back on top of the z-order every time you click on a tab in IE, or is there a gap in my understanding of how Windows painting and z-ordering works? My understanding is that once you specify z-ordering of child windows (which are not manipulable by the end-user), that ordering should remain until programmatically changed. So even though IE is repainting its Edit control upon tab selection whereas I am not repainting or otherwise acting upon my window, my window should stil remain firmly on top.
2) Given that the z-order of my window is apparently changing, shouldn't it receive a WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED? If it did, I could at least respond to that event and keep myself on top of the Edit control. But even though I can see my window painting behind the urlbar Edit control when I click on a tab, and even though my debug window output confirms that the address bar root's GetTopWindow() becomes the HWND of the Edit control when I click on a tab, and even though I see WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED being sent to the Edit control with an hwndInsertAfter of HWND_TOP when I click on a tab, my own window receives no messages whatsoever that would allow me to keep the z-order constant. This seems wrong to me, and addressing it would force me to run in IE's process and hook all messages sent to its Edit control just to have an event to respond to :(
Thank you for your help!
It's quite likely that IE is juggling the Z-order of the controls when you change tabs. In IE9, the URL bar and the tabs have a common parent. When you select a new tab, it activates the URL bar (and activation usually brings the window to the top of its local Z order).
No. You get WM_WINDOWPOSCHANGED when a SetWindowPos function acts on your window. If some of the siblings have their z-orders changed, you don't get a message. Nobody called SetWindowPos on your window. You can see this by writing a test program that juggles the z-order of some child windows.
This makes sense because there might be an arbitrary number of sibling windows, and it could be an unbounded amount of overhead to notify all of them. It also would be nearly impossible to come up with a consistent set of rules for delivering these messages to all the siblings given that some of the siblings could react by further shuffling the z-order. Do the siblings that haven't yet received the first notification now have two pending notifications? Do they get posted or dispatched immediately? What if the queue grows and grows until it overflows?
This is different from WM_KILLFOCUS/WM_SETFOCUS notifications in that it affects, at most, two windows. That puts a reasonable bound on the number of notifications. Even if there's a runaway infinite loop because the losing control tries to steal the focus back, the queue won't overflow because there's only one SetFocus call for each WM_KILLFOCUS delivered.
Also, it's reasonable that windows might need to react to a loss of focus. It's much less likely that window C needs to know that B is now on top of A instead of the other way around, so why design the system to send a jillion unnecessary messages?
Hacking the UI of apps you don't control and that don't have well-defined APIs for doing the types of things you want to do is anywhere from hard to impossible, and it's always fragile. Groups that put out toolbars and browser customizations employee more people than you might expect, and they spend much of their day probing with Spy++ and experimenting. It is by nature hacking.

Real hwnd from the point

When we use WindowFromPoint winapi function we usually can get the case, when Point specifies to some control within a window. And in such cases WindowFromPoint returns handle to that control, not to the window that handles that control.
For example in my small test application if I point to the "body" of chrome browser I get the control with class = Chrome_RenderWidgetHostHWND and its hwnd.
But what I need is to get the "parent" window for that control (which is obviously should be the chrome window).
Traverse the parents using GetAncestor() passing GA_PARENT. This differs from calling GetParent() which will return the owner if the window is a top-level window.
Can't you just use GetParent? Keep traversing until you find the desktop window.

What are the Win32APIs corresponding to the "Parent" and "Owner" Window values displayed by MS Spy++?

I'd like to obtain the same values via code. However I'd like to obtain the top-most or root windows in the hierarchy
I seem to have got the Root Parent with
HWND rootWinHandle = GetAncestor(activatedWinHandle, GA_PARENT);
However I can't get the owner window correctly. Tried
HWND rootOwnerWinHandle = GetAncestor(activatedWinHandle, GA_ROOTOWNER);
For a particular modeless dialog, Spy++ returns the Main Exe window whereas the above line returns the input i.e. activatedWinHandle. Am I looking at the wrong api ?
I'd like to obtain this without MFC if possible... coz nothing else in my project requires it.
See the GW_OWNER flag for GetWindow.
The GetParent documentation states:
If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window.
Try GetParent(). I believe this will return the owner window of a window without the WS_CHILD style, and the parent window of a window with WS_CHILD.
Only bit of insight i can add it from Raymond Chen:
Remember that owner and parent are two
different things.
Modal dialogs disable their OWNERs.
All top-level windows have the desktop
as their PARENT.
From: What's so special about the desktop window?
Special demo (+src):
http://files.rsdn.ru/42164/parentowner.zip
screenshot: http://files.rsdn.ru/42164/parentowner.png
kero

How to Get the Active ChildWindow of an application?

I have this problem. I have an handler to the mainWindow of a certain application, and I want to simulate a keypress on that application...
I'm using sendMessage/postMessage api calls to do this. The reason why I don't use the .Net SendKeys function or the keybd_event of the win32 api, is that they simulate the keypress at a global level. In my case, I may have the application minimized and still want the keypress to be simulated.
The problem with sendMessage and postMessage is that you must pass the handler of the exact childwindow where you want the key to be pressed. For example, in notepad, if I send the key to the mainWindow, nothing happens, I have to send the key to the child window that basically consists of the white canvas where you can write.
With msPaint for example, if a user creates a new document, and opens a textbox in that drawing, and I want to simulate a keypress there, I have to get the childwindow of the childwindow of the mainwindow for it to works.
So I found a way that seemed to work for every situation, basically, I used getWindow with the parameter GW_CHILD, to get the child-window with the highest z-value. Then I do it again for the child window and continue doing it until a certain childWindow has no more childWindows..
And it seemed to work and I was very happy!
However... I found cases where this does not work. Firefox is one of them. Firefox has the mainWindow, and then has a childWindow that's pretty much the same as the mainWindow and then it has another childWindow which is the website area, ie, the area under the address bar and menus. If I am on www.google.com for example, and I want to simulate a keypress in the focused search box, it works, cause getting the child-window of the child-window gives me the correct childWindow. However, if the user clicks on the address bar for example, nothing changes in the way the getWindow works. It will still eventually get the childwindow that's under the address bar, doing nothing, instead of simulating the keypress on the address bar.
The thing is that I haven't found a way of getting the active child window of a certain application. I can only use the GetWindow method to get the child window of a certain window and do it until I find a child window with no childs. However, as you've seen in the firefox case, the active window is actually the parent of the child window that I get in the end.
I've tried other api calls like getTopWindow but I had no luck..
Anyone can put some light on this issue?
Thanks!
If the application violates the windowing rules of windows, you'll need an exception.
In Mozilla, it's like this (IIRC):
There's this 'god' window of the class MozillaUIWindowClass and with the "- Mozilla Firefox" string in its window text.
If you know the position of the address bar you can use the following function:
And provide it with the HWND of the 'god' window and the position of the address bar.
HWND ChildWindowFromPoint(HWND, POINT);
There is probably a better solution, I came up with this since I needed to automate mouse, which is position based.
For more information you might need to consult the sources of particular software, or spend whole day in Spy+. :>
You can use GetGUIThreadInfo to get info about the UI of a particular process.
If you have the main window you can call GetWindowThreadProcessId to obtain the process thread id. Then you can call GetGUIThreadInfo to get info about the active/focused windows, etc.
I also have to point that some applications only have one window and all its controls are windowsless (like Windows Live Messenger).

Win32 window Owner vs window Parent?

In Win32 programming, what is the difference between a window's parent and a window's owner? I thought I had it figured out, then I came across this code:
SetWindowLong(handle, GWL_HWNDPARENT, foo);
This actually sets the window's owner, not the parent - despite the GWL_HWNDPARENT being used. Are the terms parent/owner interchangeable, or is there actually a difference?
Ownership is a relationship between two top level windows while Parent is a relationship between a top level and a WS_CHILD, or a WS_CHILD and another WS_CHILD.
The parent of a button is the form it is on, while a message box is owned by the form that showed it.
Read this article from Microsoft Win32 Window Hierarchy and Styles to get a much clearer understanding of Ownership, Parenting, ZOrder, SetWindowLong, GetWindow and all the other nasty bits of the Win32 api for creating window relationships.
EDIT: Looks like Microsoft took down that content, here is another reasonable summary of Ownership / Parenting.
Owner is the Window* responsible for a control or dialog (for example, responsible for creating/destroying the window).
Parent is the next-senior window* to a control or dialog in the window chain, but isn't actually responsible for it (doesn't necessarily care about its lifecycle, etc). A window's parent can also be its owner.
*Window vs window: Window is an actual window displayed on the screen; window is any object with a HWND (includes buttons, panels, etc).
Chen's blog post is the one to read. The key point for me is that the WS_CHILD style must be used on the child window. You can attempt to create a child window and pass the parent handle in to CreateWindow( ), but if you don't have the WS_CHILD style set the two windows will have the owner relationship, not the parent/child relationship.
It's super easy: the code is wrong. End of story right here.
Yes, some windows may happen to react favorably to such a call - someone not knowing any better may have implemented support for it. Quoth documentation (and it's old documentation) - You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function.
So, all there's to it: you came upon buggy code, change it to SetParent or refactor to do something else, and keep going?

Resources