开发者

How to stop a process using a "Stop Button"

开发者 https://www.devze.com 2023-01-10 03:43 出处:网络
I created a simple wind开发者_Python百科ow with two buttons, the first one calls a function that lasts a long time,

I created a simple wind开发者_Python百科ow with two buttons, the first one calls a function that lasts a long time, the second one sets the value of a variable "stop" to TRUE, that was initially set to FALSE.

My intention is that, by pressing the first button it runs a long process, that controls if the stop variable is set to TRUE or FALSE for every loop, if the value is TRUE the function should return, so the process is stopped.

...

static BOOL stop = FALSE;   // My variable defined somewhere

...

int longProcess ()   // My function
{
    while(stop == FALSE) {
         // do something
    }
    return 0;
}

...

switch (msg)
{
    case WM_CREATE:
    {
                            ...

        Button1 = CreateWindowEx(0, 
                                         TEXT("BUTTON"),
                                         TEXT("Start"),
                                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                         100, 100, 100, 20,
                                         hWnd,
                             (HMENU)BUTTON_START,
                             NULL,
                                         NULL);

        Button2 = CreateWindowEx(0,
                           TEXT("BUTTON"),
                       TEXT("Stop"),
                       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                       200, 200, 100, 20,
                               hWnd,
                               (HMENU)BUTTON_STOP,
                               NULL,
                               NULL);
                             ...

    }
    break;

    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {

                        case BUTTON_START:
                            longProcess();   // Starts the process
                break;

                        case BUTTON_STOP:
                            stop = TRUE;  // Should stop the process
                break;

        }
    }
    break;

    ...

}

}

The problem is that when I press the first button the process starts normally, but when I press the second button in order to stop the process nothing happens, I noticed that the stop variable is set to TRUE only after the end of the process. I thought that probably in a problem related to the message queue...

What could be the best solution??? It is correct to call longProcess() there and in that way? (I'am a newbie :) )

Thanks!


You need to run the long process on a separate thread and your approach should work.

This is, instead of just calling longProcess function on Start Button Click, create a thread, and run the long process on it.

What's happening is that your long process is blocking your UI thread, which is responsible for handling UI events. So, Stop Button Click won't be handled until longProcess() finishes.


In Delphi we have Application.ProcessMessages() which basically processes all pending messages and returns. And you can put this line to cycle to make UI more responsive.

With function like that you could do this

while(stop == FALSE) {
     // do something
    ...

    ProcessPendingMessages();
}

EDIT: This applies if you don't want to split code to separate thread - quick'n'dirty workaround


How about using PeekMessage?

int longProcess ()   // My function
{
    while(stop == FALSE) 
    {
        // do something

        while (PeekMessage(&msg, hwnd,  0, 0, PM_NOREMOVE)) 
        { 
            // check for the stop button
            if ((msg.message == WM_COMMAND) && (LOWORD(wParam) == BUTTON_STOP))
                stop = TRUE;
            } 
        } 
    }
}


At the very minimum, you'll have to declare your variable with the volatile keyword. But the best way to do it is to use an event. CreateEvent() to initialize it, SetEvent() to signal the stop condition, WaitForSingleObject() with a 0 timeout to test it.


As a variation of AOI Karasu's answer, MFC has CWinThread::PumpMessage().

I use it in worker thread loops to keep them responsive. It works great.

0

精彩评论

暂无评论...
验证码 换一张
取 消