I have a dialog where the user is able to enter information and then press the Go button. When they press this button I disable the form elements (buttons etc) and create a worker thread using AfxBeginThread( ... ). Once the worker thread has completed I want it to send a message to the UI thread so as to re-enable the form. I am using ::PostMessage( ... ) to send the message, but I can't find how to intercept these messages.
i've searched online (Link #1, Link #2, Link #3) but I can't find an understandable example of the code to implement my own message listener. In the header I can see some crazy define statements (started with DECLARE_MESSAGE_MAP()) which looks like it may have something to do with it, but I can't figure it out.
Any help is much appreciated. Thanks.
The message map is a table. For each message you are interested in it contains the message and a function pointer to the message handler function. To add a custom message to the map you add an ON_MESSAGE entry to the table. A tutorial example of doing this from a worker thread is here:
http://vcfaq.mvps.org/mfc/12.htm
Related
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 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.)
Generally, message boxes work like this:
if(ShowMessageBox("Title","Text",MB_YES_NO) == MB_YES)
{
//the user responded yes
}
However, I'm working on a game where I have made the gui system, and when a messagebox is shown, there is still animation happening in the background so I cannot simply block the thread, the animation would stop.
Right now, the way it works is to show the message box, an IMessageHandler* must be provided and it is called with the dialog result.
I'm wondering if I'm overlooking something. Is there a better way to do this that might resemble more how it is usually done. How might other games approach it?
Thanks
There are multiple options, e.g...
Create a View-Model class that the message box reads from (title, message, button text) and writes to (result prior to closing), pass the VM to your message box before displaying it, then read result from VM after close.
(A better technique would to use a command pattern or place an event on the message box instead of passing VM to message box, then within command/event handler update VM).
Use a command pattern or an event to pass result from message box (prior to close) directly to caller (or to view model).
Use a show dialog style call to message box (blocking), however, do that on a separate thread, then write results to a place where main thread can read from.
I have a non-MFC, non-ATL C++ app that routinely creates notification balloons on a system tray icon. If, on pre-Vista boxes, the user locks the screen - these newly created "balloons are queued", which creates a mess when the user finally logs back in. There could be dozens or hundreds of balloons waiting. The timeout set for each balloon does not apply until the user logs back in!!
So to solve this, I need to know either:
Is there a way to cancel any outstanding balloon I made, when a new balloon arrives?
Should I instead check for a "session lock" / "screen lock" and stop creating balloons in the user's absence?
Regarding option #2, what message do I listen for in the windows loop to capture an account lock / session lock? I tried the event WM_ENDSESSION, but my app acted like it didn't see it. Is that the right event? Do I need to register for it?
Of course if there is a simpler way to solve this, I'd love to know. Certainly for Vista and later, the NIF_REALTIME uFlags option solves the problem handily.
p.s. I'm appalled that I can't find a list of windows messages online with descriptions. All I found was a list without descriptions, and it isn't even hosted by Microsoft!!!
Regarding option (2) you need to register interest in 'SessionNotifications', using the function WTSRegisterSessionNotification:
WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags);
You pass in the handle to the window to receive the message WM_WTSSESSION_CHANGE, and use the flag NOTIFY_FOR_THIS_SESSION, which indicates you want to get messages when session events occur.
Session events you would be interested in are WTS_SESSION_LOCK and WTS_SESSION_UNLOCK. Please bear in mind that you must use the corresponding deregister function WTSUnRegisterSessionNotification:
WTSUnRegisterSessionNotification(HWND hWnd);
You need to keep track of the locked/unlocked/connected/disconnected state of the session, which allows you to decide when to schedule balloon messages.
I'm programming a very big software.
It has a lot of projects inside it.
One of my projects is a UI thread. I want to post messages to this UI thread, from the main project.
When I use PostThreadMessage (after getting the thread by GetCurrentThreadId() ), everything works fine, except the times when a MessageBox is open...
So I want to send messages from the main project by PostMessage. How exactly can I send messages in that way? how do I know which window to send the message to?
Thanks
If it is an UI thread then you must have a primary window created in that thread. Just post message to this window. That's it.
EDIT 1: If it is another process, then probably you can create a hidden window with some unique title with special characters and underscores and use FindWindow API to find that window or use EnumWindows to enumerate top level windows and match the title.