Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Take user's action within "loop forever"

0.00/5 (No votes)
25 Dec 2002 1  
How to take user's action when your program is busy.

Introduction

One of the problems encountered by the programmer is how to consider the user action when activated (say, user pushed stop-button control) during continuous operation. In fact, this has been solved in the past by inserting the loop (as function) in the primary-message loop and replacing GetMessage() by PeekMessage() in WinMain(), as follows:

while(TRUE)
{
    if(PeekMessage(&msg,0,0,0,PM_REMOVE))
    {
        if(msg.message==WM_QUIT) break;
        DispatchMessage(&msg);
    }
    else LoopFun();
}

Also OnIdle() operates in the same manner. This function will be blocked if there are many messages sent to the app. Another way is to create a thread, but there you have to pay attention about thread safety, because your thread runs in a different context (thanks to jung-kreidler, CP member).

Best Solution

Consider you have a program doing continuous processing, and you want to permit the user to stop this process at any time he/she wishes. At first glance, this is impossible, because window messages are not posted when the program is busy. But inserting the DispatchMessage() API function within the loop can solve this problem as follows:

bool bProgress; //global var or volatile 

     //(Thanks to Andreas Saurwein,CP member) 

....
LRESULT CALLBACK MainWndProc(HWND hwnd, 
   UINT umsg, WPARAM wParam, LPARAM lParam)
{
    switch (umsg){
        .....
        case WM_COMMAND:
        switch (LOWORD(wParam)){
            case IDC_LOOP:
            {
       
                bProgress=TRUE;
                //loop around a time consuming process

                while(bProgress) 
                {
                    .... //process body

                    //check if user stop the process

                    while(PeekMessage(&msg,0,0,0,PM_REMOVE))
                        DispatchMessage(&msg);
                }
                break;
            }
            ....
            case IDC_STOP:
                bProgress=FALSE;
                break;
                ....

So, having secondary message loops is a common practice... this is how modal dialogs are done. Also, in many cases such as popup windows or tracking, secondary message loops are executed while capture remains set to the expected window (thanks to Tim Smith, CP member).

In addition to this technique, the beginner will learn from the complete code, the following things:

  1. The generic programming for Win32 API,
  2. How to create & use some of the standard controls directly without resource editor.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here