2016-07-07 30 views
1

Startボタンをクリックすると、関数RunB()がwhileループを実行します。停止ボタンを使用して途中でループ実行を中断する必要があります。呼び出された関数のRunBため呼び出された関数で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; 

コード:

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

完了までに時間がかかるモーダルアクションがあり、それを解消できない場合は、モーダルアクション内のメッセージを定期的に処理する必要があります。例えば

:これは主に応答してアプリケーションを維持します

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

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

そしてFlushPendingMessagesは次のように実施されます。通常、モードレスダイアログも同時に表示されるため、アプリケーションはビジー状態で、対話できません。

はまたあなたのアプリを終了させるためにWM_QUITをチェックし、それを再投稿しなければなりませんTranslateMessage/DispatchMessageをあなたを呼び出す前に、より正確であるために、あなたはまた、明示的に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

[.net]タグで無害なDoEvents関数を推奨するのではなく、[winapi]タグで独自のバージョンを実装することをお勧めします。私は、はい、これはうまくいく、と意味することがありますが、アドバイスは間違いなく注意する必要があります。このタイプの質問をする人々は、これを良い目的で使用する可能性が最も低いです。 –

+0

@ChrisBecke [スタート]ボタンをクリックすると、プログラムは機能しますが、[停止]ボタンをクリックすることはできません。アプリケーションは、アクション/クリックに応答しません。 –

関連する問題