2016-07-07 58 views
1

单击开始按钮时,函数RunB()将执行while循环。我需要使用停止按钮中途中断while循环执行。在调用函数中打破一个while循环

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; 

代码调用的函数RunB:

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

如何打破使用停止按钮while循环?

+4

不会发生,直到您将头围绕基于事件的Windows应用程序模型。给自己一份Petzold的[ProgrammingWindows®](https://www.amazon.com/dp/157231995X)的副本。 – IInspectable

+3

为此,您必须在单独的线程中运行while循环。 –

+2

公平起见,通过在while循环中调用'PeekMessage',可能没有线程。但没有理想。 –

回答

1

事件驱动的动作(即按下按钮)不应该使用循环或业务逻辑....否则,整个窗口将暂停,直到它获得同步响应。

+0

是的,那是对的,但是如何确保窗口在循环运行时获得连续的同步响应,因为此循环不允许我单击任何其他按钮,直到循环完成。 –

1

如果您发现某些模态操作需要很长时间才能完成,而且您完全无法分解,那么您需要定期处理模态操作中的消息。

例如:

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

而且FlushPendingMessages将实施类似:

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

这将让您的应用程序大多响应。通常你也会同时显示一个无模式的对话框,这样人们就会知道你的应用程序很忙,不能与之交互。

更正确,调用的TranslateMessage/DispatchMessage函数,你还必须检查WM_QUIT并重新发布它终止您的应用程序之前,你也可以明确地检查WM_APP + X消息 - 使用代码是这样的:

#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; 
} 

您的处理循环将需要检查FlushPendingMessages的返回值,如果它的FALSE当然是中止。


编辑:根据@ IInspectable的评论。

+1

您的'PostQuitMessage'调用应该转发退出代码,即'PostQuitMessage(msg.wParam)'。 – IInspectable

+0

哦,太好了,现在我们推荐在[winapi]标签中实现我们自己的版本,而不是推荐[.net]标签中无害的'DoEvents'功能。我的意思是,这是行得通的,有时它是有道理的,但建议需要带有明确的警告。问这类问题的人最不可能用这种方式来达到好的效果。 –

+0

@ChrisBecke现在单击“开始”按钮程序可以工作,但我无法单击“停止”按钮。该应用程序不响应任何操作/点击。 –