I got how to SendMessage to another process. Now I am trying to understand how to receive the message on my other process. I know how to extract my items from de COPYDATASTRUCTURE but what is the method that is called on my other process. I found a lot of stuff on how to read the received data but never how to implement it. So basically, what function/event is called when an application receives a message from SendMessage()? You must know here that I have full control on both process.
The send message from another process is exactly like any send message received from the same process: Specifically the window procedure for the window the message is sent to is called with the message as parameters just as you would receive a WM_PAINT or any other op-sys message.
Consider reading this blog post, containing sample code:
Using WM_COPYDATA to marshal message parameters since the window manager otherwise doesn't know how
(You simply handle WM_COPYDATA in the receiver WndProc.)
Related
I'm asking as the title says. Is it possible?
Since a MSG already contains all the things I need for a self-made event handler, I figured maybe I could make one. I'm asking this mostly to get rid of interpreted casting so I can use internal functions and classes inside my window class for performance. I also want to know if its possible to just get the MSG alone and do whatever I want with it.
Basically is there another way to get the window message, and then process it not similar to the general loops found in this thread?
EDIT:
Currently I'm using GetMessage() function to get the MSG struct and use that in my own event handler, however I am not getting all the messages that I want with this. Is there anything else I should do?
Thank you in advanced.
Currently I'm using GetMessage() function to get the MSG struct
Which is the problem, GetMessage() only retrieves messages that were posted to the message queue. It does not detect messages that were sent with SendMessage(). Which bypasses the message queue and calls the window procedure directly.
You therefore must use WndProc to see all the messages for a window.
The subset of posted messages that go into the queue and thus returned by GetMessage() is a small one. In a nutshell, the input notification messages for mouse and keyboard and the low-priority messages (WM_PAINT, WM_TIMER, WM_QUIT). WM_ACTIVATE is always sent.
Replacing the WndProc of a window is certainly a common technique, it is called "sub-classing the window". Any C++ class library wrapper uses it to map messages to C++ methods. Best to not re-invent that wheel.
I have a VC++ code that uses PostMessage to trigger a function call. Although the function gets called eventually, I see that the function does not get called right after PostMessage is executed. It does not even get called after the function containing the PostMessage command completes execution. I noticed that a few more functions got called before the desired function was called.
I would like to know what determines when exactly the callback for a message gets called.
The message is a WM_USER message.
The Windows event-driven model in a nutshell (with many important details simplified away):
There is a "message pump," which is a loop that, on each iteration, pulls a message out of a queue and "dispatches" it by calling the "window procedure" associated with the specific window, passing it the details from the message.
If you're using a framework, it's likely that the message pump and the window procedure are provided for you and that the provided window procedure calls your handler functions in response to the messages it receives.
When a message is posted, it's added to the queue, and nothing else happens to it until the message pump gets to it. There may be messages ahead of it in the queue, and/or a bunch of other code may run before execution returns to the message pump.
When a message is sent, the message is not added to the queue. Instead, the sending code will call the window procedure directly. (Caveat: this is an oversimplification. Things are more complicated when sending a message to another thread.)
So if other functions are being called before the one you expect from your posted message, here are some possibilities:
Other messages were already in the queue when you posted your message.
Other messages are being sent rather than posted, so they're handled immediately, and only when they're done and the message pump eventually runs again will your posted message be handled.
The message pump decided that other messages, which were posted after yours, are more important and therefore should be handled first. (This is not actually common. Certain types of messages, like WM_PAINT, are very low priority and are only generated when there's nothing in the queue, but I can't think of a case where a message takes priority over one that's already in the queue.)
You're posting your message during initialization before the message pump even starts. For example, if you create a window, post a message to it, and then start the message pump, it's possible that there will be a series of messages in the queue related to the window creation ahead of your posted message.
Not all messages are equal. PostMessage doesn't simply add it to a queue data structure; the OS will do a lot of manipulation and prioritizing. Different messages get different priorities, and some messages like WM_PAINT, cannot be sent like this at all.
So there's no way to generalize "when will PostMessage invoke the message handler?" It depends on which message you're sending, how busy the target message queue is, and how the target message loop behaves.
I don't think there is any concise list of how messages are prioritized.
My code will receive xml data from server, the data quite huge.
after finishing receiving the xml data from sever, my code want to continue to parse the xml data, however, I have no idea why the thread focus on the dialog to receive message from system to paint or do something else... NO WAY TO go back to the parsing code.
however, if i close the dialog, it will go back the parsing code automatically?
what is the problem? please help me.....
while fetching data from internet your onpaint message of dialog is pending in message loop.Becose as you said its big data, So it hangs your application.All other messages placed in message queue.As soon as your applicationr return back from hang condition all messages that present in queque started execution.Finally dialog's WM_PAINT message is also pending which execute after hange condition finish and before reading of xmle file.
You will need to perform the "receive and parse xml data" in a separate thread if you need the dialog to be responsive during that time.
Use CreateThread() to start a thread, you can check if the thread has terminated (and get the exit code of the thread) using GetExitCodeThread().
Alternatively, you can use the MFC CWinThread class to do the same thing.
I have a multiple dialog MFC client app that i am working on. This client can receive a lot of messaging (>10Hz) to the main dialog, which often performs some small function, then forwards that message onto the another dialog for processing.
In my specific case, the main dialog receives messages relating to a vehicle location, updates a couple fields on that GUI, then passes it on vi a PostMessage to a window that displays all the vehicle information.
So basically, my question is this: what is the difference b/w posting the message, or just calling the dialog.update (which is a function i created)?
Well, since we don't know what your dialog.update() does, how are we to know what the difference is?
If you are doing another PostMessage, I'm not sure what the point of that is. Your program has to wait for another iteration of the message loop to retrieve your newly posted message and possibly another message could be received before that one is posted. Instead of PostMessage, you could use SendMessage which will send the message straight to the WndProc without having to iterate the message loop for another message.
I am thinking that if you are multi-threaded, then sending or posting messages will be a little more thread safe since Windows should switch contexts automatically. If you are single threaded, then it probably shouldn't matter.
I believe your application is multithreaded, and one of the thread is receivng the data, and is different than GUI thread. You should use PostMessage only from other thread to this dialog, and not SendMessage or direct call.
If you are receiving too many messages, you should buffer them - either by count (say 5000), or by some timeout. You may keep the messages into vector, list or any other collection you like. Later, when sending, post the address of this collection as WPARAM (or LPARAM) to the dialog. Dialog will get it, in a single bunch and would process it. This approach may not be correct as I am not aware about other design perspetives of your application.
You would need to trial-and-error approach, see where you get the actual performance and stability benefits.
I am debugging GUI app on windows and I want to find out who is the sender of some message. On linux, I can run app in synchronized mode and find the sender in call stack. Is there any equivalent mode in windows?
AFAIK there's no built-in ability to do this.
But let's first investigate the problem. You want to know who's the sender of the message. You should know however that windows message processing can be classified by the following criterias:
Posted vs Sent messages (PostMessage vs SendMessage).
Messages sent to the window belonging to another thread vs sender thread.
Messages posted to a thread (not bound to a specific window, hence not processed by the window procedure).
You may trace directly the sender only when the message is sent (not posted) to a window, whereas the call to the SendMessage (or similar) was issued in the thread to which the window belongs. In such you will see the sender in the call stack.
In case the message was sent from another thread - you will not see it in the call stack. Simply because the call stack shows the call chain that belongs to the current thread only. When a message is sent from another thread the system performs the following:
Suspends the caller thread.
Puts this message to the queue of the thread that owns the window.
When that thread calls GetMessage (or similar) - the message is dispatched to the window.
Finally the OS resumes the caller thread. The SendMessage returns with the result that was returned by the window procedure.
In such a case you may try to identify the caller indirectly. Interrupt your program with the breakpoint, and try to search for suspended threads, which are blocked in a call to SendMessage or similar.
Finally, messages that are posted are impossible to trace by the above method. You may try to put a conditional breakpoint on a call to PostMessage, but if the caller belongs to another problem - this will be more complex.
valdo is correct. Calls to SendMessage call your applications wndproc directly. Calls to PostMessage posts the message to the message que and your application then recives the message via the message pump (the loop, getmessage, translatemessage, dispatchmessage). So , like he said, if the messages were sent via a SendMessage then the callee of the function will show in the call stack. If it was sent via PostMessage , it will not.