Reputation: 5040
I have one MFC based legacy application, in which I cannot do much modification as of now.
There is one functionality which involves Reading/Writing data from/to INI file. It was written keeping in mind that the settings in ini files will be very less in number. But now it has grown very huge.
So when executing this task, it takes about 30 minutes.
The problem is when user clicks on the application, the application get lock and window windows show it's not responding dialog, asking if the user need to wait for the application to respond or quit.
Now for me I can manage the time. But I don't want the window to show the "Not Responding" behavior.
I think the problem is, that the main thread get busy in this process and the UI hangs. I am not sure about this, as I am just guessing.
For handling this I created a Thread and calls this function inside it. But in this thread function I could not call the AfxGetMainWnd();
function, as it is returning NULL
.
It will be very helpful, if someone please let me know, how to handle such cases (leaving the ideal case of not happening this)?
Also any nice advice is welcome.
My another though is also to put this code on a progress bar dialog.---- Thought on this are welcome.
Thanks
Upvotes: 2
Views: 353
Reputation: 1
Here's a hack trick I've done for that kind of situation. I mainly create dialog-based apps for testing various electrical creations or processing data and the like. Simple stuff but one wants to do some kind of UI multitasking and just keep it simple. I add this function:
void CWhateverApp::doRepaints(void)
{
MSG msg;
while (PeekMessage(&msg,NULL,0,0xFFFFFFFF,PM_REMOVE))
DispatchMessage(&msg);
}
and call it periodically while I'm doing whatever the processing is. Calling it 10X a second is nice, but even once a second gives decent UI experience. An additional trick: have a "Cancel" button with a handler that sets a bool to true when clicked. (call the bool m_doCancel, say). Now when you begin your time-consuming task, do this:
m_doCancel= false;
Now do your task, calling doRepaints() pretty often, and after calling doRepaint() check that bool:
if (m_doCancel == true) { /* stop processing */ }
so this way you've got a way for the user to quit as well as handing repaints and the like.
FWIW!
J
Upvotes: 0
Reputation: 10425
Posting custom messages from the worker thread to the MFC main thread is explained here (see FAQ 12):
http://vcfaq.mvps.org/mfc/index.htm
You should do your file reading in the worker thread. If you want a progress dialog put that in the main thread and post messages to it to update the progress display.
Upvotes: 1
Reputation: 52689
the trick to using threads in a MFC app is to remember that only the main thread can access all the GUI elements. So, if you spin off a thread to do some work, you need to communicate updates and modifications back to the main thread in some way and let it do the GUI updating.
The easiest way to do this is to send yourself a message, the message pump is on the main thread, so it will always pick up the messages. Its really simply, once you know.
So, create a few WM_USER messages and send them from your thread when you need to and handle them as normal.
Upvotes: 2