スレッドにメッセージを送信するには、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 )