トップページ > 過去ログ > 記事閲覧
マルチスレッド化においてキー入力が取得できない
名前:minato 日時: 2010/03/23 01:35

タイトルの通りです。 スレッド内で、GetJoypadInputState( DX_INPUT_KEY_PAD1 )やGetHitKeyStateAllが正しく動作しないようなのです。 掲示板で検索をかけてDXライブラリでは全ての関数が排他になっているということが分かったので、 WinMain関数からはスレッドの終了を待つだけで何もしないようにしてみましたが、結果は同じでした。 ちなみにマルチスレッドで呼んでいるのは、 // 画面を消去 ClearDrawScreen(); // グラフィックのレンダリング DrawGraph( 0, 0, GraphHandle, FALSE ); InputState = GetJoypadInputState( DX_INPUT_KEY_PAD1 ); // キー取得 if( ( InputState & PAD_INPUT_START ) != 0 ) { exit(0); } // ESCキーが押されていれば終了処理へ ScreenFlip(); // バックバッファの内容をプライマリバッファに転送 if( ProcessMessage() == -1 ) { // メッセージループに代わる処理をする exit(-1); } これを一定回数ループしているだけの関数です。 画像を1枚表示し、その間にESCキーを押せば、終了するというものです。(画像は正常に描画されていますので、DrawGraphはきちんと動いているみたいです) マルチスレッドの処理にはboost::threadを使っております。 スレッドを外し、普通にWinMain関数内から呼ぶだけにしてやると、正常に動作しましたので、書いたコードに問題があるというわけでもなさそうです。 また、 SetMultiThreadFlag( TRUE ); や SetUseDirectInputFlag( FALSE ); も試してみましたが、全て上手くいきませんでした。 どのようにすれば、解決することができるでしょうか?

Page: 1 |

Re: マルチスレッド化においてキー入力が取得できない ( No.1 )
名前:いっち 日時:2010/03/23 18:36

私の環境で試してみましたが、うまく動作しているように見受けられます。 認識の違いや、ソースに誤りがあればご指摘下さい。 私の主な環境は以下の通りです。 Win XP Pro SP3 + DxLib 3.02 + VS2008EE //-- テストソース (Tex1.bmpを使用) #include <windows.h> #include <process.h> #include "DxLib.h" bool quit_thread; int GraphHandle; unsigned int WINAPI MyThread( void *p ) { int InputState; int i = 0; while ( 1 ) { ClearDrawScreen( ); DrawFormatString( 0, 0, GetColor( 255, 255, 255 ), "Thread Test : %d", i++ ); DrawGraph( 0, 20, GraphHandle, FALSE ); ScreenFlip( ); InputState = GetJoypadInputState( DX_INPUT_KEY_PAD1 ); if ( (InputState & PAD_INPUT_START) != 0 ) break; if ( ProcessMessage( ) != 0 ) break; if ( quit_thread ) break; } _endthreadex( 0 ); return 0; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); if ( DxLib_Init( ) < 0 ) return -1; SetDrawScreen( DX_SCREEN_BACK ); GraphHandle = LoadGraph( "Tex1.bmp" ); quit_thread = false; unsigned int thread_id; HANDLE thread_handle = (HANDLE)_beginthreadex( NULL, 0, MyThread, NULL, 0, &thread_id ); while ( 1 ) { //if ( ProcessMessage( ) != 0 ) // break; if ( WaitForSingleObject( thread_handle, 0 ) != WAIT_TIMEOUT ) break; } quit_thread = true; WaitForSingleObject( thread_handle, INFINITE ); CloseHandle( thread_handle ); DxLib_End( ); return 0; }
Re: マルチスレッド化においてキー入力が取得できない ( No.2 )
名前:minato 日時:2010/03/23 20:25

いっち様、ご回答ありがとうございます。 ご提示くださったソースコードをコピペして動かしてみたのですが、上手くいきませんでした。 (ESCキーを押してプログラムが終了すれば正常に動作していると解釈していますが、よろしいでしょうか?私の環境では画像と文字は表示されたものの、キーによって終了させることはできませんでした。) Windows Vista + DxLib 3.02 + VS2008StandardEditionです。
Re: マルチスレッド化においてキー入力が取得できない ( No.3 )
名前:いっち 日時:2010/03/23 21:02

> ESCキーを押してプログラムが終了すれば正常に動作していると解釈 その通りです。私の環境ではESCキー押下で終了します。 バイナリの問題ではないと思いますが、当方の環境で動作するモジュールをアップロードしました。 もし宜しければご確認下さい。 > ttp://www1.axfc.net/uploader/Sc/so/95620.zip "ProcessMessage"はメインスレッド内で呼ばなければならないようなので、( No.1 )のソースから若干改変しております。 具体的には子スレッド内の"ProcessMessage"をコメント化し、メインスレッド内の"ProcessMessage"をコメント解除しました。 (ソースを同梱しています)
Re: マルチスレッド化においてキー入力が取得できない ( No.4 )
名前:minato 日時:2010/03/23 21:20

いただきました実行ファイルを直接実行してみましたが、やはり結果は同じでした。 ESCキーを押下しても特に何も起こらないようです。 Vista環境下ではDirectInputに問題があるというような話を以前管理人さんが掲示板に書いていたのを記憶しておりますが、それが原因なのでしょうか……
Re: マルチスレッド化においてキー入力が取得できない ( No.5 )
名前:いっち 日時:2010/03/23 21:43

そのようですね。 DirectInput関連はXP以前とVista以降で切り分けているようです。 管理人さんの見解をお待ちになるのが良いかもしれません。
Re: マルチスレッド化においてキー入力が取得できない ( No.6 )
名前:管理人 日時:2010/03/29 06:39

Vista 以降はメインスレッドと別のスレッドでキーの押下状態を取得しても、キーを押していても 押していることにならないみたいです とりあえずメインスレッドで ProcessMessage が呼ばれた際にキーの押下状態情報を更新することで 対処しましたので、よろしければこちらをお試しになってみてください http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) ただ、メインスレッドで ProcessMessage を呼ばないと更新されませんので、申し訳ありませんが メインスレッドでは常に一定間隔で ProcessMessage を呼ぶようにしてください
Re: マルチスレッド化においてキー入力が取得できない ( No.7 )
名前:いっち 日時:2010/03/29 20:27

早速の対応ありがとうございます。 XPにて、前バージョンと変わらず動作することを確認しております。
Re: マルチスレッド化においてキー入力が取得できない ( No.8 )
名前:Masao 日時:2010/03/30 12:43

すいません。 マウス入力の対応もおねがいします。 以下、テストコードです。 #include <windows.h> #include <process.h> #include "DxLib.h" bool quit_thread; int GraphHandle; unsigned int WINAPI MyThread( void *p ) { int InputState; int i = 0; while ( 1 ) { ClearDrawScreen( ); DrawFormatString( 0, 0, GetColor( 255, 255, 255 ), "Thread Test : %d", i++ ); DrawGraph( 0, 20, GraphHandle, FALSE ); ScreenFlip( ); InputState = GetJoypadInputState( DX_INPUT_KEY_PAD1 ); if ( (InputState & PAD_INPUT_START) != 0 ) break; if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) break; if ( quit_thread ) break; } _endthreadex( 0 ); return 0; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); if ( DxLib_Init( ) < 0 ) return -1; SetDrawScreen( DX_SCREEN_BACK ); GraphHandle = LoadGraph( "brictest_M1.jpg" ); quit_thread = false; unsigned int thread_id; HANDLE thread_handle = (HANDLE)_beginthreadex( NULL, 0, MyThread, NULL, 0, &thread_id ); while ( 1 ) { if ( ProcessMessage( ) != 0 ) break; if ( WaitForSingleObject( thread_handle, 0 ) != WAIT_TIMEOUT ) break; } quit_thread = true; WaitForSingleObject( thread_handle, INFINITE ); CloseHandle( thread_handle ); DxLib_End( ); return 0; } ESCキーか、マウス左クリックで終了するとおもったのですが、 ESCキーしか反応しませんでした。 環境は、Windows7 64bit ライブラリは、比較的最新(3.02b)のものです。 あ、あと画像ファイル名は自由にかえてください。
Re: マルチスレッド化においてキー入力が取得できない ( No.9 )
名前:管理人 日時:2010/04/05 01:41

サンプルプログラムのお書き込みありがとうございます マウスも同じ手法で対応しましたので、よろしければお試し下さい http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
Re: マルチスレッド化においてキー入力が取得できない ( No.10 )
名前:Masao 日時:2010/04/05 03:31

修正を確認しました。 ありがとうございました。

Page: 1 |