Solved

Refresh Issue with MFC Dialog

Posted on 2004-08-11
10
2,215 Views
Last Modified: 2013-11-20
I have an dialog application.  The problem is that the dialog class has functions which take a long time to complete -- thus, causing refresh problems with the dialog.

How do I refresh the dialog (with the OnPaint function) while those functions go off and do their things?  I need to do the refresh within the dialog cpp file and NOT in the functions that take a long time.
0
Comment
Question by:loneill2
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11779058
You have many alternatives, the cleanest in my opinion is to put your heavy processes in different threads, you can use CreateThead() for this. Another alternative is to call UpdateWindow() anywhere inside your processing funtions to make dialog repaint.
0
 

Author Comment

by:loneill2
ID: 11779780
An example using threads would be greatly appreciated.

UpdateWindow....I already have a Refresh ...what will UpdateWindow do for me differently?
0
 
LVL 86

Expert Comment

by:jkr
ID: 11779853
No need to use threads at all - you can just add a call to

void DrainMsgQueue () {

     MSG msg;

     while ( PeekMessage ( &msg, 0, 0, PM_REMOVE))
                DispatchMessage ( &msg);
}

every once in a while, e.g.

void OnSomeEvemt () {

    for (;;) {

        DoSomePartOfLengthyProcessing ();
        DrainMsgQueue ();
    }
}

That will help to keep your dialog up to date and running.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 44

Expert Comment

by:AndyAinscow
ID: 11780810
What you are experiencing is the WM_PAINT is of a low priority and your app is busy performing your processing.  Just calling UpdateWindow won't do anything.  You need to have a mechanism to allow any messages in the message queue to be processed.  jkr has given you a very useful piece of code to accomplish that.
I would also suggest in your for loop where you do your processing that you have a flag (bool member var, value modified in the OnClose of your dialog/window) and you only enter your DoSomePartOfLengthyProcessing when the flag has not been set.  This prevents silly things happening if the user is trying to close your dialog and you go back into the computationally intensive function and attempt to access a now non-existant window for example.
0
 

Author Comment

by:loneill2
ID: 11783880
I can't find info on DrainMsgQueue..can someone point me to some info or give some more info about it?
0
 
LVL 86

Expert Comment

by:jkr
ID: 11784280
>> I can't find info on DrainMsgQueue.

There is no info, that is a 'hand made' function:

void DrainMsgQueue () {

    MSG msg;

    while ( PeekMessage ( &msg, 0, 0, PM_REMOVE))
               DispatchMessage ( &msg);
}

The above is all you need, and it works. Just add it to your program.

0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 100 total points
ID: 11784431
What it does is remove any pending messages in the queue and pass them on for further processing.  When all of the messages have been removed the function will return.  This allows your app to appear responsive to user and other events such as repainting.

To use code from jkr

void OnSomeEvemt () {

    for (;;) {

        DoSomePartOfLengthyProcessing ();
        DrainMsgQueue ();
    }
}

You split the lengthy calculation into smaller parts - DoSomePartOfLengthyProcessing
After doing each part you call the function DrainMsgQueue which lets the app proess any pending messages such as repainting (and button presses, keyboard events ....).  When it has emptied the queue you go round the loop and perform the next computationally intensive part.

As I mentioned earlier you ought to have some way of stopping/handling the case of the user closing dialog and that is by having a member var to act as some flag that can be set in response to an event such as the WM_CLOSE message
0
 
LVL 86

Expert Comment

by:jkr
ID: 11784576
>>You split the lengthy calculation into smaller parts - DoSomePartOfLengthyProcessin

This should not even be necessary, since 'lengthy' processing in almost all 'real life' cases means that a loop of some kind is involved, so this function could just be called on every run of that loop.

BTW, VB has a similar mechanism for that, it is called 'DoEvents'
0
 

Author Comment

by:loneill2
ID: 11813061
The Visual C++ compiler is complaining that one parameter is missing from PeekMessage.

Would that be a call to this pointer as a handle to dialog?
0
 
LVL 86

Accepted Solution

by:
jkr earned 400 total points
ID: 11813103
Sorry, that should be

void DrainMsgQueue () {

    MSG msg;

    while ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE))
               DispatchMessage ( &msg);
}
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question