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;
....
LRESULT CALLBACK MainWndProc(HWND hwnd,
UINT umsg, WPARAM wParam, LPARAM lParam)
{
switch (umsg){
.....
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDC_LOOP:
{
bProgress=TRUE;
while(bProgress)
{
....
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:
- The generic programming for Win32 API,
- How to create & use some of the standard controls directly without resource editor.