ANSHIT KALAR
ANSHIT KALAR

Reputation: 181

Breaking a while loop in a called Function

On clicking the start button the function RunB() executes the while loop . I need to break the while loop execution midway using the Stop Button .

switch (msg)
{

case WM_CREATE:
    CreateWindow(TEXT("button"), TEXT("Browser"),
        WS_VISIBLE | WS_CHILD,
        30, 100, 80, 25,
        hwnd, (HMENU)1, NULL, NULL);
    CreateWindow(TEXT("button"), TEXT("Stop"),
        WS_VISIBLE | WS_CHILD,
        30, 200, 80, 25,
        hwnd, (HMENU)2, NULL, NULL);
    break;

case WM_COMMAND:
    if (LOWORD(wParam) == 1) {
        Obj.RunB();
    }
    break;
    if (LOWORD(wParam) == 2) {
        //Code to break the while loop

    }
    break;

Code for the Called Function RunB:

void RunB(){
    while(n<15){
    //Some statements here:
    }

How do I break the while loop using the Stop Button ?

Upvotes: 1

Views: 133

Answers (2)

Chris Becke
Chris Becke

Reputation: 36016

If you find you have some modal action that is going to take a long time to complete and you absolutely can't break it up, then you need to periodically process messages from within your modal action.

For example:

while(n<15){
  DoAPieceOfWork(n);
  FlushPendingMessages();
}

And FlushPendingMessages would be implemented something like:

void FlushPendingMessages(){
  MSG msg;
  while(PeekMessage(&msg,0,0,0,PM_REMOVE)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
}

This will keep your application mostly responsive. Normaly you would also display a modeless dialog at the same time, so that people know your application is busy and cannot be interacted with.

To be more correct, before calling TranslateMessage/DispatchMessage you must also check for WM_QUIT and repost it to terminate your app, and you can also explicitly check for WM_APP+x messages- using code something like this:

#define WM_APP_QUITLOOP  (WM_APP+1)

// use this from anywhere to tell your processing loop to quit
PostMessage(NULL,WM_APP_QUITLOOP,0,0L);

BOOL FlushPendingMessages(){
  MSG msg;
  while(PeekMessage(&msg,0,0,0,PM_REMOVE)){
    switch(msg.message){
    case WM_APP_QUITLOOP:
      return FALSE;
    case WM_QUIT:
      PostQuitMessage(msg.wParam);
      return FALSE;
    default:
      TranslateMessage(&msg);
      DispatchMessage(&msg);   
    }
  }
  return TRUE;
}

Your processing loop would need to check the return value from FlushPendingMessages and abort if its FALSE of course.


Edit: as per @IInspectable's comment.

Upvotes: 1

Cosmo
Cosmo

Reputation: 41

The event driven action (i.e. pressing a button), shouldn't engage a looping or business logic.... Otherwise the whole windows will be halt until it gets the synchronous response.

Upvotes: 1

Related Questions