我用两个按钮创建了一个简单的窗口, 第一个调用一个持续很长时间的函数, 第二个将变量“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()是正确的吗? (我是新手:))
谢谢!
答案 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()。
我在工作线程循环中使用它来保持响应。它很棒。