In the debug version of the program, I create a visible window, and the WM_QUERYENDSESSION message is received by its WNDPROC. In the release version, the window is supposed to be message-only, so I specify HWND_MESSAGE as the hWndParent when calling CreateWindowEx(). Unfortunately, I then don't receive the WM_QUERYENDSESSION message anymore.
Is WM_QUERYENDSESSION one of those broadcast messages mentioned here?
A message-only window [...] does not receive broadcast messages.
MSDN gives a decent definition of a "message-only window":
A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
Relevant detail highlighted.
You use them to take advantage of the message dispatch mechanism in your own code. Most typically to get a worker thread to talk to the UI thread in a thread-safe way. A message loop is the universal solution to the producer-consumer problem. Apartment marshaling in COM is implemented with a message-only window for example. Clearly such a window should be hidden and only get the messages that are defined by the app.
Don't use HWND_MESSAGE as hWndParent when calling CreateWindowEx.
Replace HWND_MESSAGE with NULL for hWndParent and you should get the behavior you intend.
Per Raymond Chen's blog:
What kind of messages can a message-only window receive?
...
The point of a message-only window is that it receives only messages sent or posted specifically to it. You use it to set up a private channel between the sender and the window. After creating a message-only window, you can put messages in the window’s queue by calling PostMessage and passing that window handle, or you can send a non-queued message by calling SendMessage and passing that window handle.
What makes a message-only window interesting is that it doesn’t particpate in broadcast messages.
Many window messages are sent to all top-level windows. WM_QUERYENDSESSION, WM_SETTINGCHANGE, WM_DDE_INITIATE. and anything sent with HWND_BROADCAST. These messages don’t reach message-only windows.
Internally, message-only windows are treated as child windows of a system-managed common parent window called HWND_MESSAGE. This system-managed common parent window is permanently invisible, which results in message-only windows being permanently invisible. And that’s also how message-only windows are invisible to enumeration and broadcasts: Enumeration and broadcasting is done to top-level windows, but message-only windows are internally treated as child windows of HWND_MESSAGE and therefore are not considered top-level.
Related
Or how to determine if a given message was posted/sent programmatically by another thread or simply another process?
By post and send I mean functions PostMessage and SendMessage
The Windows API does not keep track of the originator of a message. So the only way to know where a message comes from would be to directly hook the (Post|Send)Message functions in every running process.
I have a program that shuts down another application when certain conditions are met. Now most of the time everything works out fine, but sometimes the app is writing to a file and leaves it in a half finished state and has no way of recovering it on restart. I thought that one could send soft close signals and escalate after certain timeouts to more aggressive close signals, going trough a list like this:
1. WM_CLOSE
2. WM_QUIT
3. WM_DESTROY
4. TerminateProcess().
Now I know that the program has no code to handle any signal it receives. Is there a possibility that certain FileHandler under Windows react gracefully on such soft signals or is there no use to sending those, if the app does not handle them explicitly?
This article says:
NOTE: A console application's response to WM_CLOSE depends on whether or not it has installed a control handler.
Does this mean if no control handler is installed sending 1-4 is just as good as sending 4 directly?
I would like to communicate between two processes running on the same machine.
I don not have luxury to use any sort of general IPC(e.g. shared memory, pipe, sockets etc.)
I can able to use window messages to communicate between both the process.
please advice will it be faster to use COM connection point rather than window messages.
Is COM connection point also based on window message queue.
Any help will be greatly appreciated.
Regards
Ashish
please advice will it be faster to use COM connection point rather
than window messages.
It largely depends on how you use Windows messages to communicate between processes.
For simple cases like calling a COM method without arguments, a synchronous inter-process call will not be faster than using SendMessage directly, because of the reason explained below.
Is COM connection point also based on window message queue.
It is not based on window message queue. COM connection point is just a convention for implementing outgoing COM interfaces. However, the COM inter-process marshaller does indeed use hidden windows and private messages to marshal calls, when it comes to making an out-of-proc call on a connection point interface.
This is not specific to connection points and applies to any COM proxy interface you may have cached. Normally, you need to have a functional message loop inside both client and server processes for this to work properly.
I've got no idea how window hooks work at the "system level". MSDN only touches what's going on very briefly:
A hook is a point in the system message-handling mechanism where an
application can install a subroutine to monitor the message traffic in
the system and process certain types of messages before they reach the
target window procedure.
My best guess is something like below:
Before each message is added to the message queue for a window, it'll first send the message to the global/local hooks, which may do something, depending on their hook procedures. After all global hooks and local hooks, the message is finally added to the window message queue.
However, MSDN says that for some of the types of hooks, it will monitor events, notifications etc.
An example is the WH_MOUSE_LL hook:
Installs a hook procedure that monitors low-level mouse
input events. For more information, see the LowLevelMouseProc hook
procedure.
When they say events, are we talking window messages, or do they mean something else?
Am I all wrong?
Yes, this is a mechanism for windows messages, you can process this data (messages) before they reach target window procedure (message loop).
If you want hook other process windows you can simply do this in DLL, and use DLL injection for inject your library to other process.
I am porting a library to Windows. In a function I need to block on the arrival of a WM_DEVICECHANGE message.
What options are available for doing this? As my code resides in a library I have little-to-no information on the current set-up (so if it is a Console application, a regular GUI application, if my code is being run in a spawned thread, and so on). Therefore what is the best way to wait for the arrival of a specific message?
Blocking and receiving Windows messages are mutually incompatible. You get messages by pumping a message loop. Since you cannot rely on the app pumping one, you'll need to do this yourself.
You will need to create a thread. Create a hidden window in that thread then run the standard message loop. The window procedure for that window can see the WM_DEVICECHANGE message. It can do what ever it needs to do, within the constraints of running inside a separate thread. Like setting an event to signal that a function should stop blocking.
The message is probably sent using BroadcastSystemMessage(). You could create a hidden top-level window and its window proc would probably get this message. I'm not sure; but that's what I'd try first.