わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。

スレッドにメッセージを送信する

スレッドにメッセージを送信するには、PostThreadMessage()関数を使用します。 スレッド側でメッセージを受信するには、PeekMessage()関数であらかじめメッセージキューを生成しておく必要があります。 PeekMessage()関数でメッセージキューを生成するまでは、メッセージを受信することができませんので、 イベントなどを利用して、メッセージキューが生成されたことを確認してから送信する必要があります。

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <process.h>
#include <windows.h>



/*
	スレッドメイン処理
*/
unsigned __stdcall ThreadMain
(
	void* vpArguments
)
{
	/*
		スレッドの起動引数に、初期化完了イベントをのせています
	*/
	HANDLE hThreadInitEvent = (HANDLE)vpArguments;

	// メッセージ
    MSG oMsg;

	// メッセージキューの作成
	::PeekMessage( &oMsg, NULL, 0, 0, PM_NOREMOVE );

	// スレッド初期化完了(メッセージキュー生成完了)
	::SetEvent( hThreadInitEvent );

	std::wcout << L"スレッド開始( 引数 = " << (int)vpArguments << L" )" << std::endl;


	/*
		スレッドメイン処理
			(GetMessageは、WM_QUIT以外を受信すると0以外の値が返ります)
	*/
	while( 0 != ::GetMessage( &oMsg, NULL, 0, 0 ) ) {
		switch( oMsg.message ) {
		case WM_USER + 0x100:
			{
				std::wcout << L"メッセージを受信しました(WM_USER + 0x100)。( " << oMsg.wParam << L" )" << std::endl;
			}
			break;


		case WM_USER + 0x101:
			{
				std::wcout << L"メッセージを受信しました(WM_USER + 0x101)。( " << oMsg.wParam << L" )" << std::endl;
			}
			break;
		}
	}


	/*
		スレッドの終了
			この値はGetExitCodeThread()で取得できる
	*/
	std::wcout << L"スレッド終了" << std::endl;
	::_endthreadex( 1234 );

	// 処理結果
	return( 0 );
}



/*
	スレッドの終了コードを取得する
*/
int _tmain
(
	  int argc
	, _TCHAR* argv[]
)
{
	/*
		std::wcoutのロケールを設定
		 これを設定するだけで、std::wcoutで日本語が表示される
		 ようになります。
	*/
	std::wcout.imbue( std::locale( "", std::locale::ctype ) );

	UINT nThreadId = 0;


	/*
		スレッド初期化完了イベントの生成
	*/
	HANDLE hThreadInitEvent = ::CreateEvent(
			  NULL		// SECURITY_ATTRIBUTES構造体
			, TRUE		// リセットのタイプ( TRUE: 自動 / FALSE: 手動 )
			, FALSE		// 初期状態( TRUE: シグナル状態 / FALSE: 非シグナル状態 )
			, NULL		// イベントオブジェクトの名前
		);


	/*
		スレッド起動
	*/
	HANDLE hThread = (HANDLE)::_beginthreadex(
			  NULL						// SECURITY_ATTRIBUTES構造体
			, 0							// スタックサイズ( 0は呼び出し側と同じサイズ )
			, &ThreadMain				// スレッド関数
			, (void*)hThreadInitEvent	// スレッド関数への引数
			, 0							// 作成オプション( 0 / CREATE_SUSPENDED )
			, &nThreadId				// スレッドId
		);
	std::wcout << L"スレッド起動 Id = " << nThreadId << std::endl;
    

	/*
		スレッドの初期化待ち(スレッドにメッセージキューが出来るまで待つ)
			→ メッセージキューが生成されないとメッセージが送れません
	*/
	::WaitForSingleObject( hThreadInitEvent, INFINITE );

	// スレッド初期化イベントの破棄
	::CloseHandle( hThreadInitEvent );


	/*
		スレッドへメッセージを送信する
	*/
	for ( UINT nI = 0; nI < 10; nI++ ) {

		// メッセージの送信
		::PostThreadMessage( nThreadId, WM_USER + 0x100, nI, 0 );

		// 待ち(待たなくても良い → 適当です)
		::Sleep( 1000 );

		// メッセージの送信
		::PostThreadMessage( nThreadId, WM_USER + 0x101, nI, 0 );

		// 待ち(待たなくても良い → 適当です)
		::Sleep( 1000 );
	}

	// スレッド終了メッセージの送信
	::PostThreadMessage( nThreadId, WM_QUIT, 0, 0 );


	/*
		スレッドの終了待ち
	*/
	::WaitForSingleObject( hThread, INFINITE );

	// スレッド終了コード
	DWORD dwExitCode = 0;

	// スレッドの終了コードを取得
	::GetExitCodeThread( hThread, &dwExitCode );

	std::wcout << L"スレッド終了コード( " << dwExitCode << L" )" << std::endl;

	// スレッドハンドルの解放
	::CloseHandle( hThread );

	// 処理結果
	return( 0 );
}



実行結果

スレッド起動 Id = 12864
スレッド開始( 引数 = 212 )
メッセージを受信しました(WM_USER + 0x100)。( 0 )
メッセージを受信しました(WM_USER + 0x101)。( 0 )
メッセージを受信しました(WM_USER + 0x100)。( 1 )
メッセージを受信しました(WM_USER + 0x101)。( 1 )
メッセージを受信しました(WM_USER + 0x100)。( 2 )
メッセージを受信しました(WM_USER + 0x101)。( 2 )
メッセージを受信しました(WM_USER + 0x100)。( 3 )
メッセージを受信しました(WM_USER + 0x101)。( 3 )
メッセージを受信しました(WM_USER + 0x100)。( 4 )
メッセージを受信しました(WM_USER + 0x101)。( 4 )
メッセージを受信しました(WM_USER + 0x100)。( 5 )
メッセージを受信しました(WM_USER + 0x101)。( 5 )
メッセージを受信しました(WM_USER + 0x100)。( 6 )
メッセージを受信しました(WM_USER + 0x101)。( 6 )
メッセージを受信しました(WM_USER + 0x100)。( 7 )
メッセージを受信しました(WM_USER + 0x101)。( 7 )
メッセージを受信しました(WM_USER + 0x100)。( 8 )
メッセージを受信しました(WM_USER + 0x101)。( 8 )
メッセージを受信しました(WM_USER + 0x100)。( 9 )
メッセージを受信しました(WM_USER + 0x101)。( 9 )
スレッド終了
スレッド終了コード( 1234 )






わびさびサンプルソース

WindowsやHTML5などのプログラムのサンプルコードやフリーソフトを提供します。