0

これは、C++ コードの実装で私が抱えている問題です。

メイン スレッドで、子スレッドもスピンするキャンセル ボタンを含む静的テキストを表示するダイアログ ボックスを作成しました。

バックグラウンド スレッド (または子スレッド) でデータベースをチェックして、特定のステータス フィールドが更新されているかどうかを確認します。更新された場合は true を返し、それ以外の場合は定期的にデータベースをポーリングし続けます。

予想される動作 - キャンセル ボタンを含むダイアログ ボックスを表示し、イベントが子スレッドによって通知されるか、ユーザーがキャンセル ボタンを押すまで、ダイアログ ボックスを表示し続けます。

メイン スレッドで unsignalled 状態のイベントを作成しました。このイベント状態は子スレッドによって変更されます (ステータス フィールドが更新されたとき)。

問題は、バックグラウンド スレッドからの応答が得られるまでメイン スレッドをブロックすると、ユーザーがダイアログのキャンセル ボタンを押すことができず、常に砂時計の記号が表示されることです。

以下のコードの何が問題なのかわかりません。

HANDLE mainThread = NULL;
HANDLE ghWriteEvent; 

MainMethod()
{
mainThread = GetCurrentThread() ;
dlgCancelDialog dog // dialog with cancel button .

    ghWriteEvent = CreateEvent( NULL, TRUE,  FALSE,  TEXT("WriteEvent") ); 
HANDLE hThread = CreateThread(0,0, childThread, &threadData,0,NULL);
dlg.showDialog(); // Show dialog with cancel button .

    DWORD  dwWaitResult = WaitForSingleObject( ghWriteEvent, INFINITE); 
 //AT THIS POINT i WANT TO SAY WAIT FOR SIGNAL EVENT OR WAIT UNTIL CANCEL OPERATION IS HIT , BUT THE DIALOG IS SHOWN WITH HOURGLASS SYMBOL.
  switch (dwWaitResult) 
   {
    // Event object was signaled
    case WAIT_OBJECT_0: 
   break;
  }
dlg.hideDialog();

} //子スレッド コード。

childThread(LPVOID lpParam)
{
while(!databaseIsUpdated) // Check database.
{   
    Sleep(1000);

}
if (! SetEvent(ghWriteEvent) ) 
    {

        return 0;
    }
return 0;
}
4

2 に答える 2

0

MsgWaitForMultipleObjectsEx() を使用することもできます: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684245%28v=vs.85%29.aspx

于 2012-09-22T12:29:41.113 に答える
0

ダイアログ スレッドをブロックするため、INFINITE で待機しないでください。

したがって、私の提案は、SetTimer(hDlg, 500, 1, NULL) を使用してタイマーを作成し、DlgProc 内で次のように WM_TIMER を処理することです。

case WM_TIMER:
{
 DWORD  dwWaitResult = WaitForSingleObject( ghWriteEvent, 0);  //We will not wait

 if(dwWaitResult  == WAIT_OBJECT_0)  //We are signaled, exit now
    dlg.hideDialog();
}
break;

これにより、イベントの状態が 500 ミリ秒ごとにチェックされます。通知された場合はダイアログが終了し、通知されていない場合は続行します。

于 2012-09-22T07:55:45.410 に答える