如何使用“停止按钮”停止进程

时间:2010-08-05 12:35:12

标签: c++ c winapi

我用两个按钮创建了一个简单的窗口, 第一个调用一个持续很长时间的函数, 第二个将变量“stop”的值设置为TRUE, 最初设置为FALSE。

我的意图是,通过按下第一个按钮,它会运行一个很长的过程, 控制是否为每个循环将stop变量设置为TRUE或FALSE, 如果值为TRUE,则函数应该返回,因此进程停止。

...

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;

    ...

}

}

问题是当我按下第一个按钮时,过程正常启动, 但当我按下第二个按钮以停止该过程时没有任何反应, 我注意到只有在进程结束后才将stop变量设置为TRUE。 我认为可能是与消息队列有关的问题......

什么是最好的解决方案? 以这种方式调用longProcess()是正确的吗? (我是新手:))

谢谢!

5 个答案:

答案 0 :(得分:13)

您需要在单独的线程上运行长进程,并且您的方法应该有效。

这不是仅仅在启动按钮上调用longProcess函数单击,创建一个线程,并在其上运行长进程。

正在发生的事情是你的漫长过程正在阻止你的UI线程,它负责处理UI事件。因此,在longProcess()完成之前,停止按钮单击将不会被处理。

答案 1 :(得分:5)

在Delphi中,我们有Application.ProcessMessages(),它基本上处理所有挂起的消息并返回。您可以将此行循环以使UI 更多响应。

使用这样的功能你可以做到这一点

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

    ProcessPendingMessages();
}

编辑: 如果您不想将代码拆分为单独的线程 - quick'n'dirty解决方法

,则适用

答案 2 :(得分:3)

如何使用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;
            } 
        } 
    }
}

答案 3 :(得分:3)

至少,您必须使用 volatile 关键字声明您的变量。但最好的方法是使用一个事件。 CreateEvent()用来初始化它,SetEvent()表示停止条件,WaitForSingleObject()用0超时来测试它。

答案 4 :(得分:1)

作为AOI Karasu答案的变体,MFC有CWinThread :: PumpMessage()。

我在工作线程循环中使用它来保持响应。它很棒。