Destroying child window without parent WIN32 APi - winapi

I have one problem . I am trying to destroy child window ,but it also destroys parent window, so application closes.
I have such code.
HWND cloneWin =FindWindowEx(hWnd, 0, szChildWin, 0);
if (cloneWin) {
MessageBox(NULL,"You are trying to create more than one child window\n Current child window will be destroyed", "Message", MB_OK|MB_ICONINFORMATION);
DestroyWindow(cloneWin);
}
What is wrong ?
THx in advance !

The documentation says:
A thread cannot use DestroyWindow to destroy a window created by a different thread.
Since you are trying to find these windows using FindWindowEx, it seems pretty obvious that the windows were created in a different process, never mind a different thread. In other words, your call to DestroyWindow can never succeed. Hard to know why this is bringing the other application down, but since you are not obeying the rules then I suppose it is reasonable that anything can happen.
It's plausible I suppose that you could send the window a WM_CLOSE message and hope that it will respond by calling DestroyWindow. That would be a valid call to DestroyWindow because it would be made on the thread that created the window. But it all depends on how that other window responds to WM_CLOSE.

Related

Is it possible to get the origin of a call to SetWindowPos?

We've had an issue reported about our application "freezing". After investigation, what happens is, our main form ends up WS_EX_TOPMOST, so when a modal form is shown, it ends up being shown behind our main form which then appears to be frozen.
Considering we've never set our form as TOPMOST, our working assumption at the moment is that another application is, mistakenly or not, setting our application's mainform as TOPMOST through:
SetWindowPos(OurFormHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE)
So how would one identify the guilty party?
I'll post the method I came up with, just wondering if there is something more reliable...
From what I can tell, a call to SetWindowPos doesn't returns until the process owning the target window's process the WM_WindowPosChanging and WM_WindowPosChanged message.
During the WM_WindowPosChanging, it doesn't seem possible to know if the form will become topmost, much less prevent it (hwndInsertAfter isn't HWND_TOPMOST anymore, and doesn't even refer a TOPMOST window). So there isn't much we can do here as we don't know if we're in trouble.
However, when WM_WindowPosChanged is processed, the WS_EX_TOPMOST style has been applied to the window's style. So by that point, you know you've been set topmost.
So now... How could we make a "guilty process" stand out of the crowd? Well, I did mention SetWindowPos doesn't return until WM_WindowPosChanged is done processing. So, if we were to, lets say, sleep for 10 seconds while processing WM_WindowPosChanged, the calling process would become unresponsive!
At that point, we can EnumWindowsand test if they are IsHungAppWindow and retrieve the name of the applications they belong to.
Oh... and we'll still collect a callstack, in case this is actually the result of some wild side-effect in our code and not a "rogue application".
Limitations
Obviously, if SetWindowPos is called from a windowless thread, that technique won't work. It might also have a few false positive.
Some of this is most likely working "by implementation" rather than "by design".

Winapi: window is "sent to back" when using EnableWindow() function

To prevent users from clicking in my main_window when a MessageBox appears I have used:
EnableWindow(main_window,FALSE);
I got a sample MessageBox:
EnableWindow(main_window,FALSE);
MessageBox(NULL,"some text here","About me",MB_ICONASTERISK);
EnableWindow(main_window,TRUE);
The problem is that when I press "OK" on my MessageBox it closes and my main_window is send to back of all other system windows. Why this is happening?
I tried to put:
SetFocus(main_window);
SetActiveWindow(main_window);
after and before : EnableWindow(main_window,TRUE) the result was strange: it worked 50/50. Guess I do it the way it shouldn't be.
Btw.
Is there a better solution to BLOCK mouse click's on specific window than:
EnableWindow(main_window,FALSE);
Displaying modal UI requires that the modal child is enabled and the owner is disabled. When the modal child is finished the procedure has to be reversed. The code you posted looks like a straight forward way to implement this.
Except, it isn't.
The problem is in between the calls to MessageBox and EnableWindow, code that you did not write. MessageBox returns after the modal child (the message box) has been destroyed. Since this is the window with foreground activiation the window manager then tries to find a new window to activate. There is no owning window, so it starts searching from the top of the Z-order. The first window it finds is yours, but it is still disabled. So the window manager skips it and looks for another window, one that is not disabled. By the time the call to EnableWindow is executed it is too late - the window manager has already concluded that another window should be activated.
The correct order would be to enable the owner prior to destroying the modal UI.
This, however, is only necessary if you have a reason to implement modality yourself. The system provides a standard implementation for modal UI. To make use of it pass a handle to the owning window to calls like MessageBox or CreateDialog (*), and the window manager will do all the heavy lifting for you.
(*): The formal parameter to CreateDialog is unfortunately misnamed as hWndParent. Parent-child and owner-owned relationships are very different (see About Windows).

How to subclass Windows Explorer's window

I want to change color of listview of explorer.exe like this
I got the handle of listview window by GetTopWindow function and his family.
To subclass listview window of explorer.exe, I injected my dll code to explorer by following code.
SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll,
dwExplorerListviewThreadId);
My dll is loaed by explorer.exe well.
And I subclassed the window procedure by SetClassLongPtr(for global subclass) in injected code.
SetClassLongPtr returns success but my subclass function(SubclassProc) receives only WM_CREATE WM_DESTROY and WM_MOVE messages. What's wrong? I expected to get WM_NOTIFY and NM_CUSTOMDRAW.
The problem is that this is not a ListView in the first place; it's instead using Microsoft's internal "DirectlUI" framework, which is used in several places in explorer. It doesn't use any of the Common Control messages such as NM_CUSTOMDRAW. There's pretty much no reasonable way to change the colors it uses.
(Also, generally it's best to use SetWindowLongPtr instead of SetClassLongPtr for subclassing a HWND: SetClassLong only changes the underlying template that is used for creating new windows, but may not end up changing any instances that were based on that. And you should not be using the same function - GetMsgProc - for both the hook callback and the subclass proc; they need to handle the message in different ways, the hook callback needs to call CallNextHookEx while the subclass proc needs to call CallWindowProc with the original wndproc. But none of this really matters since the control isn't a ListView in the first place...)
I think and suppose that the OS has special protections for the explorer.exe process, because otherwise it would be an easy target for malicious code or just applications that think they are more important than they actually are (if some people insist on putting back a shortcut on their desktop every time you start the application, imagine what they would do when they had this sort of access to explorer.exe - everything in the shell).
EDIT: I was intrigued by the question and did some more research, I think there is a more mundane reason, see http://blogs.msdn.com/b/oldnewthing/archive/2005/09/07/461912.aspx. (basically: explorer.exe is the window manager so doesn't know about message routing yet when it receives certain messages, which is why they can't be intercepted with message hooks).

Win32 , WndProc, and parent-child windows

I'm developing in C code that uses the Win32 Api to create multiple windows.
I used createWindow twice - to create parent and child windows.
I have a message loop
while ( GetMssage (&msg, NULL,0,0)){
.
translate
dispatch
.
}
But I only get the WND_Proc function called once, instead of twice for each of the windows.
What am I doing wrong?
If I'm understanding your question correctly, you should expect your WndProc to receive a single WM_CREATE message for each window created of the window class for which the WndProc is registered.
Your WndProc will not receive a WM_CREATE for a window you create of a different class (like the standard Windows UI controls, for example), even if it is a direct child of a window of the WndProc's class. If you gave us some more specifics on what you are trying to accomplish we could provide suggestions or workarounds.
This question may also shed some more light on your situation.

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).

Resources