Index: sakura_core/macro/CWSH.cpp =================================================================== --- sakura_core/macro/CWSH.cpp (リビジョン 2860) +++ sakura_core/macro/CWSH.cpp (作業コピー) @@ -32,6 +32,7 @@ #include "util/window.h" // BlockingHook #include "dlg/CDlgCancel.h" #include "sakura_rc.h" +const HRESULT SCRIPT_E_REPORTED = 0x80020101; // 何を includeしたらいいかわからないので。 /* 2009.10.29 syat インタフェースオブジェクト部分をCWSHIfObj.hに分離 class CInterfaceObjectTypeInfo: public ImplementsIUnknown @@ -255,9 +256,7 @@ // AbortMacroProcのパラメータ構造体 typedef struct { - CRITICAL_SECTION cs; //同期用クリティカルセクション - bool bIsMacroRunning; //マクロ実行中フラグ - bool bIsAbortThreadRunning; //AbortMacroProc実行中フラグ + HANDLE heventMacroExited; //マクロ実行が終了すると励起される(自動キャンセルは無し)。 IActiveScript *pEngine; //ActiveScript HWND hwndDlgCancel; int nCancelTimer; @@ -269,20 +268,11 @@ { SAbortMacroParam* pParam = (SAbortMacroParam*) lpParameter; - //停止ダイアログ表示前に数秒待つ - int i; - for( i=0; i < pParam->nCancelTimer * 10; i++ ){ - ::EnterCriticalSection(&pParam->cs); - if( ! pParam->bIsMacroRunning ){ - ::LeaveCriticalSection(&pParam->cs); - break; - } - ::LeaveCriticalSection(&pParam->cs); - ::Sleep(100); - } + //停止ダイアログ表示前に指定秒待つ + DWORD dwMacroState = WaitForSingleObject(pParam->heventMacroExited, pParam->nCancelTimer/*sec*/ * 1000); //停止ダイアログ表示 - if( pParam->bIsMacroRunning ){ + if (dwMacroState != WAIT_OBJECT_0) { // マクロ実行が終了していなければ DEBUG_TRACE(_T("AbortMacro: Show Dialog\n")); MSG msg; @@ -307,21 +297,16 @@ DispatchMessage(&msg); } - ::EnterCriticalSection( &pParam->cs ); if( pcDlgCancel->IsCanceled() ){ - if( pParam->bIsMacroRunning ){ - DEBUG_TRACE(_T("AbortMacro: Try Interrupt\n")); - pParam->pEngine->InterruptScriptThread(SCRIPTTHREADID_BASE, NULL, 0); - DEBUG_TRACE(_T("AbortMacro: Done\n")); - } + DEBUG_TRACE(_T("AbortMacro: Try Interrupt\n")); + pParam->pEngine->InterruptScriptThread(SCRIPTTHREADID_BASE, NULL, 0); + DEBUG_TRACE(_T("AbortMacro: Done\n")); } pParam->hwndDlgCancel = NULL; - ::LeaveCriticalSection( &pParam->cs ); pcDlgCancel->DeleteAsync(); } DEBUG_TRACE(_T("AbortMacro: Exit\n")); - pParam->bIsAbortThreadRunning = false; return 0; } @@ -356,16 +341,14 @@ { //マクロ停止スレッドの起動 SAbortMacroParam sThreadParam; - ::InitializeCriticalSection(&sThreadParam.cs); - sThreadParam.bIsMacroRunning = true; - sThreadParam.bIsAbortThreadRunning = true; + sThreadParam.heventMacroExited = CreateEvent(NULL, TRUE, FALSE, NULL); // 手動リセット、初期値non-signaled、無名イベント sThreadParam.pEngine = m_Engine; sThreadParam.hwndDlgCancel = NULL; sThreadParam.nCancelTimer = GetDllShareData().m_Common.m_sMacro.m_nMacroCancelTimer; sThreadParam.view = (CEditView*)m_Data; unsigned int nThreadId; - /* HANDLE hThread = (HANDLE) */ _beginthreadex( NULL, 0, AbortMacroProc, (LPVOID)&sThreadParam, 0, &nThreadId ); + HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, AbortMacroProc, (LPVOID)&sThreadParam, 0, &nThreadId ); DEBUG_TRACE(_T("Start AbortMacroProc 0x%08x\n"), nThreadId); //マクロ実行 @@ -373,31 +356,33 @@ Error(L"状態変更エラー"); else { - if(Parser->ParseScriptText(AScript, 0, 0, 0, 0, 0, SCRIPTTEXT_ISVISIBLE, 0, 0) != S_OK) + HRESULT hr = Parser->ParseScriptText(AScript, 0, 0, 0, 0, 0, SCRIPTTEXT_ISVISIBLE, 0, 0); + if (hr == SCRIPT_E_REPORTED) { + /* + IActiveScriptSite->OnScriptErrorに通知済み。 + 中断メッセージが既に表示されてるはず。 + */ + } else if(hr != S_OK) { Error(L"実行に失敗しました"); + } } - ::EnterCriticalSection(&sThreadParam.cs); - sThreadParam.bIsMacroRunning = false; //マクロ実行中フラグを落とす + SetEvent(sThreadParam.heventMacroExited); // マクロ実行終了を通知。 //マクロ停止ダイアログが表示されていれば閉じる if ( sThreadParam.hwndDlgCancel ) { - ::SendMessage( sThreadParam.hwndDlgCancel, WM_CLOSE, 0, 0 ); + ::PostMessage( sThreadParam.hwndDlgCancel, WM_CLOSE, 0, 0 ); } - ::LeaveCriticalSection(&sThreadParam.cs); //マクロ停止スレッドの終了待ち DEBUG_TRACE(_T("Waiting for AbortMacroProc to finish\n")); - for (;;) { - ::EnterCriticalSection(&sThreadParam.cs); - if( ! sThreadParam.bIsAbortThreadRunning ){ - ::LeaveCriticalSection(&sThreadParam.cs); - sThreadParam.pEngine = NULL; - ::DeleteCriticalSection(&sThreadParam.cs); - break; - } - ::LeaveCriticalSection(&sThreadParam.cs); - ::Sleep(50); - } + WaitForSingleObject(hThread, 5000/*msec*/); + + // 後片付け。 + /* + TearminateThreadしておくべき?放置した方がまし? + */ + CloseHandle(hThread); + CloseHandle(sThreadParam.heventMacroExited); } } Parser->Release();