I have a thread that calls ::PostMessage(hWnd, [...]); to send a message to the main thread alerting it to the results of an async operation.
However, I'm concerned that if the thread takes a particularly long time to finish its operation, the hWnd may not exist when the PostMessage is called (the user may have closed the window).
The MSDN Documentation doesn't say anything about the results if hWnd is invalid.
Do you know from experience, or other documentation, about what I can expect if hWnd is invalid?
Raymond Chen wrote about this:
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/16/3885472.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
Some choice excerpts:
It so happens that boatloads of programs (and "boatloads" is a technical term) contain bugs where they use window handles after the window has been destroyed. When a window handle is re-used, that program sends a message to the window it thinks is still there, but instead it sends the message to a completely unrelated window. This doesn't bode well for the program, and it usually doesn't bode well for the new window that received the message by mistake either.
We left off our story last time by raising the problem of programs that send messages to windows that have already been destroyed and how window handle re-use exacerbates the problem. Although this is clearly a bug in the programs that use window handles after destroying the window, the problem is so widespread that the window manager folks in Windows NT decided to take a more proactive approach.
As others have pointed out, Ramond Chen explained what happens if the HWND gets re-used by a new window. PostMessage() will succeed, it will just go to the wrong window. However, in cases where the HWND does not get re-used, PostMessage() will fail with an ERROR_INVALID_WINDOW_HANDLE (1400) error code.
Related
MSDN at this link states that there is a flag
CMIC_MASK_FLAG_NO_UI
The system is prevented from displaying user interface elements (for example, error messages) while carrying out a command.
However, it also indicates that the structure has
nShow
Type: int
A set of SW_ values to pass to the ShowWindow function if the command displays a window or starts an application.
which I think contradicts each other as there is no indication I can set the latter parameter to 0 and there is no SW_NOSHOW parameter in the ShowWindow documentation.
Is it even possible to suppress that window? If yes - how?
TIA!!
There is some ambiguity about which UI we are talking about here.
There are UI things related to invoking the command (asking for network share password, error message on failure etc.) and CMIC_MASK_FLAG_NO_UI certainly applies here. I don't know how relevant nShow is though. The caller does not know which UI might be displayed and it makes zero sense for the callee to allow its error MessageBox to be maximized etc. Respecting SW_HIDE might end up stuck waiting for the user to interact with a window they can't see.
The other UI is actually the thing that is executed. In the cases where a new process is started we are looking at a ShellExecuteEx call. CMIC_MASK_FLAG_NO_UI is passed on as SEE_MASK_FLAG_NO_UI (same integral value) and MSDN just says "Do not display an error message box if an error occurs" for this flag. Here however, nShow is relevant and can trickle all the way down to CreateProcess.
This is how I personally deal with this situation:
Set CMIC_MASK_FLAG_NO_UI if you are going to display your own error UI in case of failures or if you are running in a silent/automated mode of execution.
Only set nShow to something other than SW_SHOW when you control the action being executed. For example, you know cmd.exe is getting called and you need to hide the console window with SW_HIDE.
It is important to remember that CMINVOKECOMMANDINFO is parsed by the default IContextMenu shell32 implementations for various shell objects (files, control panel etc.) and by 3rd-party context menu handlers. You cannot assume that they are going to respect your wishes.
This may seem to be a duplicate question for Is KillTimer necessary?, but i would like to confirm this with credible source.
Does destroying window really free the resource allocated by the OS for the timer? (does DestroyWindowsTimers really get called let alone if such function actually exists? if so, where?)
No, it is not necessary. From the documentation of DestroyWindow (with emphasis added):
The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
Doing a google search the only actual real looking reference to it looked to be some Win2k source code. The url ended with /Censorship/win2k_sources/private/.../timers.c, I'm assuming from the source code leak a while back. I did not look at the code, nor will I post a link here.
That function most likely exist - something like that almost has to exist for timers linked to window handles - since the timer message is delivered to a specific window handle.
I can't see anywhere in the documentation that states that you don't have to call KillTimer to get rid of a timer. So based on the documented contract, you need to call KillTimer. In practice Windows will probably clean it up for you, but since that is undocumented behavior you should write your code to follow the documented behavior and call KillTimer on all your timers.
This is somewhat of a general question regarding Windows programming:
Are Window messages "reliable"?
For example (these are just examples):
Can you be certain that a WM_MOUSEMOVE will happen before a cursor enters your screen?
Can you be certain that you will get a WM_DEVICECHANGE message if a device is inserted?
Can you be certain that you will receive a WM_KILLFOCUS message if your window loses focus?
Or, in other words: Can you be certain that you'll get the appropriate message at the appropriate times, or do you always have to code defensively in case that, somehow, you might miss a message for no apparently documented reason?
Example:
It is guaranteed (AFAIK) that a file system filter driver will not "miss" a file operation or change notification.
By contrast, it is not guaranteed that ReadDirectoryChangesW will not miss a notification. In fact, it can miss quite a few if its buffer overflows.
Note:
I am not talking about a situation against an adversary (e.g. someone hijacking your window procedure or installing a hook/filter); that would pretty much invalidate any guarantee. I'm only asking about obscure situations that could really happen even if no one meant anything bad intentionally, like if some random buffer overflows, if someone uses SendInput, etc., assuming you have control of your own code.
No you cannot be certain that a given message will be delivered in a specific order. Here are a couple of reasons why not
Messages can be sent progamatically and this can be used to simulate "impossible" scenarios like a WM_KEYUP followed by a WM_KEYDOWN.
Another routine could sub-class your window and selectively intercept messages and not send them on to your WNDPROC
It's best to code defensively around any scenarios where ordering is important
The SetParent function takes a child and new parent window handle.
This also seems to work when the child window is in a different Windows process.
I have seen a post that claims this is not officially supported, but the current docs don't mention this any more. Is this a flaw in the current docs, or did this behavior change?
HWND WINAPI SetParent(
__in HWND hWndChild,
__in_opt HWND hWndNewParent
);
You can have a parent-child relationship with the windows in different processes. It's tricky to get it to work right in all cases. You may have to debug various strange symptoms.
Normally, windows in separate processes would get their messages from separate input queues using separate message pumps. When you use SendMessage to a window in another process, it's actually posted to the other window's queue, processed there, and the return is effectively marshaled back to the original process. So if one of the processes stops handling messages, you can effectively lock up the other as well. (That's true even within a process when the windows are created on different threads and the thread queues haven't been attached.)
But when you set up the parent/child relationship among windows in different threads, Windows attaches those input queues together, forcing the message processing to be synchronous. You're no longer in the normal case, but you face the same kinds of problems: a hang in the processing for one window effectively hangs the other process.
Watch out for messages that pass pointers in the params. The pointers will not be valid in the receiving process. (There are a couple of exceptions, like WM_COPYDATA, which recreates the data in the receiving process for you. But even those have limitations.)
You have to be especially careful when the windows are being destroyed. If possible, disconnect the parent-child relationship before destroying either window. If it's not possible, then it's probably best to manually destroy the child window before the parent is destroyed. Normally, destroying a parent will cause the children to be destroyed automatically, but it's easy to get hangs when the child is in another process (or un-attached thread).
In newer versions of Windows (Vista+), you can also hit some security speedbumps if the processes run at different integrity levels.
Thanks to IInspectable who pointed out an error in my earlier answer.
Just remove WS_CHILDWINDOW from the child window. It avoid locks.
Sorry, that has not been helped
This may be the simplest win32 program ever ..
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int show)
{
MessageBox(0, "Hello world..", "Salutations!", MB_OK);
return 0;
}
.. which makes no calls whatsoever to the usual GetMessage() call. My question is this: if my program doesn't process any window messages, can the OS cope with that? I.e., does it cause memory leaks? Or some other resource that wouldn't be apparent unless I ran it 16K times?
In a broader sense, exactly how 'dependent' is Win32 on applications taking care of their messages? I would hope that when the compiler links the executable as a windows program, that the run-time would be capable of cleaning up any kind of message queue, be it emptied or not.
Just a technicality, but you do have a window, and you do have a message loop, just not in your code.
The call to MessageBox() creates a window (of class #32770) and runs a local message loop, not returning to your code till the message loop drops out, presumably when WM_NCDESTROY is sent. I think it's the same message loop that runs in response to DialogBox().
But you could substitute your call to MessageBox() with anything else that really doesn't create a message loop, and you'll still be fine. Windows doesn't care if you have a message loop, although some functionality (primarily UI related) is difficult or impossible to use without it. In fact, you don't have to link to user32 at all, and some apps that have no user interface don't.
Now if you create a window and don't process messages for it in some way, Windows XP and up will replace your window with a "ghost" window that has a white client area and Task Manager will tell the user that the application is not responding.
Although it seems so at first, the message loop is not magic or a strictly required part of Windows boilerplate. It is highly ingrained as a standard in most Windows applications, though, because it's the best way to handle the dispatching of window messages. The "event-driven" nature of most Windows applications makes us forget sometimes that Windows applications were originally designed to be single-threaded, and in this model, it is code running within that single thread, not some unseen force within the operating system, that must make every function call within our code. The addition of multithreading changed that somewhat, but the basic model still remains the same.
EDIT
A note about message queues:
As is mentioned elsewhere, a message queue is only created (and on a per-thread basis) when a window is created by that thread. Your example program, upon creating a message box, does create a message queue. But this queue need not be empty when your application exits. This queue is just a memory structure. It's a block of memory that can hold a certain number of message objects (specifying destination hWnd, message id, wParam, lParam, system time when message was posted, mouse position when message was posted, and some data that allows the derivation of keyboard and mouse button state when the message was posted), along with pointers to the head and tail of the queue (I assume it's a circular queue). When the application exits, this memory, like all memory belonging to the process, is summarily freed.
There are, of course, other things that must be cleaned up outside your process. The OS must keep a table of all existing windows, for example, along with the thread and process that created them. Of course, these are all cleaned up automatically as well.
Since you don't have a window, you don't need a message loop. In Win32 the messages are sent to windows, not to applications.
You do have a message loop - MessageBox is a modal dialog and therefore contains a message loop within.
You don't have to create windows. But still, there are some kind of messages, like
WM_TIMER
WM_TIMECHANGE
WM_CLIPBOARDUPDATE
WM_COPYDATA
WM_POWER
that you may need. So, a ghost window hanging around wouldn't be bad.
If you don't have a window, then that is fine, but if you do then you need to make sure that you pump messages for it. Otherwise the system can hang on broadcast messages waiting for you to respond. This is important for things like COM which create hidden windows for message processing. If your main thread does not pump messages (e.g., by calling WaitForSingleObject) then calls to your COM objects will not be processed, and any programs which send broadcasts will appear to hang.
I have read somewhere (and can't find the reference) is that Windows will create a message queue on demand. If you never call a function that looks for a message queue, one will never be created. And this occurs on a per-thread basis.