29#if ! defined(_WIN32_WCE)
30 #if defined(__AFX_H__)
32 inline HANDLE il_CreateThread(LPVOID pAddr, LPVOID pParam, DWORD* pThreadId)
34 CWinThread* P = ::AfxBeginThread(
static_cast<AFX_THREADPROC
>(pAddr), pParam, 0, 0, CREATE_SUSPENDED, NULL);
37 *pThreadId = P->m_nThreadID;
42 inline void il_ExitThread(DWORD dwResult)
44 ::AfxEndThread(dwResult);
46 inline void il_CloseThreadHandle(HANDLE h)
51 inline HANDLE il_CreateThread(LPVOID pAddr, LPVOID pParam, DWORD* pThreadId)
54 typedef unsigned(__stdcall* P_FUNC)(LPVOID);
55 INT_PTR dw = ::_beginthreadex(NULL, 0 ,
static_cast<P_FUNC
>(pAddr), pParam, CREATE_SUSPENDED, &uId);
57 return reinterpret_cast<HANDLE
>(dw);
59 inline void il_ExitThread(DWORD dwResult)
61 ::_endthreadex(dwResult);
63 inline void il_CloseThreadHandle(HANDLE h)
69 inline HANDLE il_CreateThread(LPVOID pAddr, LPVOID pParam, DWORD* pThreadId)
71 return ::CreateThread(NULL, 0,
static_cast<LPTHREAD_START_ROUTINE
>(pAddr), pParam, CREATE_SUSPENDED, pThreadId);
73 inline void il_ExitThread(DWORD dwResult)
75 ::ExitThread(dwResult);
77 inline void il_CloseThreadHandle(HANDLE h)
84 inline HANDLE il_CreateThread(LPVOID pAddr, LPVOID pParam, DWORD* pThreadId)
86 return ::CreateThread(NULL, 0,
static_cast<LPTHREAD_START_ROUTINE
>(pAddr), pParam, CREATE_SUSPENDED, pThreadId);
88 inline void il_ExitThread(DWORD dwResult)
90 ::ExitThread(dwResult);
92 inline void il_CloseThreadHandle(HANDLE h)
101 #define TNB_THREADNAMEFRM1 "スレッド 0x%X"
102 #define TNB_THREADNAMEFRM2 "スレッド 0x%X [%s]"
103 #define TNB_THREADTRACETYPE "スレッド 0x%X [%s] %s。\n"
105 #define TNB_THREADNAMEFRM1 "スレッド 'Win32 スレッド' (0x%x)"
106 #define TNB_THREADNAMEFRM2 "スレッド 'Win32 スレッド' (0x%x) [%s]"
107 #define TNB_THREADTRACETYPE "スレッド 'Win32 スレッド' (0x%x) [%s] %s。\n"
145 operator HANDLE(
void)
const
221 if ( ::SetThreadPriority(
m_hThread, priority) )
225 _GetLastError(
"SetThreadPriority");
238 bool PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
const
240 bool r = !! ::PostThreadMessage(
GetId(), message, wParam, lParam);
243 _GetLastError(
"PostThreadMessage");
257 DWORD_PTR r = ::SetThreadAffinityMask(
m_hThread, affinityMask);
260 _GetLastError(
"SetThreadAffinityMask");
346 IRunner(
void) : m_canRunnable(true), m_isOnDemandSuspend(false)
357 if ( m_isOnDemandSuspend )
359 m_isOnDemandSuspend =
false;
360 ::SuspendThread(::GetCurrentThread());
362 return m_canRunnable;
374 virtual DWORD
Run(
void) = 0;
389 volatile bool m_canRunnable;
390 mutable bool m_isOnDemandSuspend;
400 CThread(
void) : m_pRunner(NULL), m_lastResult(0)
441 _super::SetOwnerHwnd(hOwner);
463 BOOL r = ::TerminateThread(
m_hThread, result);
464 _GetLastError(
"TerminateThread");
480 if (
IsAlive() && m_pRunner->m_canRunnable )
483 if ( ! m_threadName.
IsEmpty() )
485 TRACE3( TNB_THREADTRACETYPE,
m_threadId, m_threadName.
Ref(), _T(
"停止要求") );
491 m_pRunner->m_canRunnable =
false;
505 bool Stop(DWORD dwWait = 15000)
509 ASSERT0(
false,
"CThread::Stop()",
"リスナースレッド処理内で Stop() は使用できません。" );
516 if ( ! ::GetExitCodeThread(
m_hThread, &dwExitCode) )
520 else if ( dwExitCode != STILL_ACTIVE )
523 if ( ! m_threadName.
IsEmpty() )
525 TRACE3( TNB_THREADTRACETYPE,
m_threadId, m_threadName.
Ref(), _T(
"既に停止...") );
534 if ( ! m_threadName.
IsEmpty() )
536 TRACE3( TNB_THREADTRACETYPE,
m_threadId, m_threadName.
Ref(), _T(
"停止要求") );
538 #if ( _WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400 )
539 if ( ::IsDebuggerPresent() )
548 m_pRunner->m_canRunnable =
false;
559 for ( DWORD i = 0; i < dwWait; i++ )
561 m_pRunner->m_canRunnable =
false;
567 if ( ::GetExitCodeThread(
m_hThread, &dwExitCode) )
569 if ( dwExitCode != STILL_ACTIVE )
585 _GetLastError(
"TerminateThread");
587 TRACE0(
"ThreadをTerminateしました\n");
590 if ( ! m_threadName.
IsEmpty() )
592 STRLIB::PrintF(str, 1024, _T(
"指定時間内に、") _T(TNB_THREADNAMEFRM2) _T(
"が終了しませんでした。\n 強制終了させました。")
597 STRLIB::PrintF(str, 1024, _T(
"指定時間内に、") _T(TNB_THREADNAMEFRM1) _T(
"が終了しませんでした。\n 強制終了させました。")
600 ASSERT1(
false,
"CThread::Stop()",
"%s", str.
Ref() );
620 if ( m_pRunner == NULL ||
IsAlive() )
625 m_threadName = lpszName;
636 ASSERT(
ToInt(r) != -1 );
638 m_pRunner->m_excThreadReady.
Exchange(0);
649 if ( m_pRunner != NULL )
651 m_pRunner->m_isOnDemandSuspend =
true;
678 while ( ::PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE) )
680 if ( ! ::GetMessage(&msg, hWnd, 0, 0) )
684 bool r = (WM_KEYFIRST <= msg.message && msg.message <= WM_IME_KEYLAST);
685 r |= (WM_MOUSEFIRST <= msg.message && msg.message <= WM_MOUSELAST);
688 TRACE1(
"Drop Message = %d\n", msg.message);
692 ::TranslateMessage(&msg);
693 ::DispatchMessage(&msg);
709 static DWORD WINAPI ms_ThreadMain(LPVOID lpPoint)
712 ASSERTLIB(P->
m_threadId == ::GetCurrentThreadId());
713 P->m_pRunner->m_canRunnable =
true;
715 P->m_pRunner->m_excThreadReady.
Exchange(0);
717 if ( ! P->m_threadName.
IsEmpty() )
719 TRACE3( TNB_THREADTRACETYPE, P->
m_threadId, P->m_threadName.
Ref(), _T(
"開始"));
722 P->m_lastResult = P->m_pRunner->
Run();
724 if ( ! P->m_threadName.
IsEmpty() )
726 TRACE3( TNB_THREADTRACETYPE, P->
m_threadId, P->m_threadName.
Ref(), _T(
"終了"));
733 il_ExitThread(P->m_lastResult);
734 return P->m_lastResult;
798 virtual void Run(LPARAM lParam) = 0;
810 static bool Start(LPARAM lParam,
IRunner* piRunner,
bool withDelete =
true,
int priority = THREAD_PRIORITY_NORMAL)
813 P->m_pRunner = piRunner;
814 P->m_lParam = lParam;
815 P->m_withDelete = withDelete;
818 HANDLE hThread = il_CreateThread(ms_ThreadMain, P, &dwThreadId);
819 if ( hThread == NULL )
823 if ( P->m_withDelete )
830 ::SetThreadPriority(hThread, priority);
831 DWORD r = ::ResumeThread(hThread);
832 ASSERT(
ToInt(r) != -1);
834 il_CloseThreadHandle(hThread);
851 static DWORD WINAPI ms_ThreadMain(LPVOID lpPoint)
855 P->m_pRunner->
Run(P->m_lParam);
857 if ( P->m_withDelete )
893 : m_hThread(::GetCurrentThread())
926 if ( m_hThread != NULL )
928 ::SetThreadPriority(m_hThread, m_priority);
936 m_priority = ::GetThreadPriority(m_hThread);
937 ::SetThreadPriority(m_hThread, p);
938 ASSERT( ::GetThreadPriority(m_hThread) == p );
TYP Exchange(const TYP &t)
[取得] 値交換.
bool IsEmpty(void) const
[確認] 空チェック
LPCTSTR Ref(void) const
[取得] 文字列参照
CTemporarilyThreadPriority(int priority=THREAD_PRIORITY_TIME_CRITICAL)
コンストラクタ.
void Restore(void)
[処理] リストア.
CTemporarilyThreadPriority(HANDLE hThread, int priority=THREAD_PRIORITY_TIME_CRITICAL)
コンストラクタ.
~CTemporarilyThreadPriority(void)
デストラクタ.
bool PostMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0) const
[実行] PostThreadメッセージ
HWND m_hOwnerWnd
オーナーウィンドウ
HANDLE GetHandle(void) const
[取得] スレッドのハンドル取得
void SetOwnerHwnd(HWND hWnd)
[設定] 関連ウィンドウハンドル設定.
CThreadStatus(void)
コンストラクタ.
bool IsAlive(void) const
[確認] スレッドが生きているか
DWORD GetId(void) const
[取得] スレッドのID取得
bool SetPriority(int priority=THREAD_PRIORITY_NORMAL)
[設定] 優先度設定
HANDLE m_hThread
スレッドのハンドル
DWORD_PTR SetAffinityMask(DWORD_PTR affinityMask)
[設定] プロセッサアフィニティマスク設定.
virtual ~CThreadStatus(void)
デストラクタ
int GetPriority(void) const
[取得] 優先度取得
bool Terminate(DWORD result=0)
[設定] スレッド中断
void Suspend(void)
[実行] サスペンド.
bool SetRunner(IRunner *pRunner)
[設定] ランナー、設定
bool Stop(DWORD dwWait=15000)
[設定] スレッド停止 スレッドに対して停止要求します。
bool Start(LPCTSTR lpszName=NULL)
[設定] スレッド開始
bool Resume(void)
[実行] レジューム.
DWORD GetThreadResult(void) const
[取得] スレッド終了値
virtual ~CThread(void)
デストラクタ
void SetOwnerHwnd(HWND hOwner)
[設定] 関連ウィンドウハンドル設定.
static void PumpMessage(HWND hWnd)
[処理] メッセージポンプ.
void StopRequest(void)
[設定] スレッド停止要求.
static bool Start(LPARAM lParam, IRunner *piRunner, bool withDelete=true, int priority=THREAD_PRIORITY_NORMAL)
[設定] スレッド開始
const TYP * Ref(void) const
[取得] ポインタ取得
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
void IgnoreUnusedValue(const T &value)
[宣言] 参照しない値宣言.
bool PrintF(LPSTR _pWork, size_t iLen, LPCSTR lpFmt,...)
[作成] 書式付き文字列作成(ASCII/SJIS用)
virtual void OnExitThread(void)
[通知] スレッド終了通知.
bool IsRunnable(void) const
[確認] 実行可能か否か
virtual void OnSetupThread(void)
[通知] スレッド開始前通知.
virtual ~IRunner(void)
デストラクタ
virtual DWORD Run(void)=0
[動作] スレッド処理本体
virtual void Run(LPARAM lParam)=0
[通知] スレッド処理部
virtual ~IRunner(void)
デストラクタ