- ベストアンサー
MFC - ボタンの処理について
- MFCを用いてWebカメラからのキャプチャを行うソフトを作成しています。ダイアログ形式のソフトで、Captureボタンが押されたらWebカメラの映像を表示し、Stopボタンが押されたらキャプチャを終了します。
- 現在、Captureボタンのイベントハンドラ内でキャプチャ処理を実行しており、その間はCaptureボタンが押された状態になってしまい、Stopボタンを押すことができません。改善策として、オリジナルのメッセージを作成し、Captureボタンのイベントハンドラ内でメッセージを送信してキャプチャ処理を行うように変更しましたが、同じ問題が発生しています。
- キャプチャを行っている間でも、Captureボタンが押された状態にならず、Stopボタンを押すことができません。この問題を解決するためにはどのようなプログラムの組み方が必要でしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
afx_msg void myThreadExit( WPARAM wParam, LPARAM lParam ) は LRESULT myThreadExit( WPARAM wParam, LPARAM lParam ) でした ・・・ 関数を抜ける時には return S_OK; など リザルトコードを返してください
その他の回答 (2)
- redfox63
- ベストアンサー率71% (1325/1856)
スレッドプロシージャは 外部関数にしたほうがいいでしょう クラスのメンバーでやるなら static関数にしないとまずいです … お勧めはしませんが AfxBeginThread( Csample3::ImageCapture, this ); として呼び出し ヘッダーでの宣言は static UINT ImageCapture( LPVOID ); といった具合になります キャプチャー関数へ渡すのは thisポインターよりも 必要なデータの構造体のほうがいいでしょう 画面のキャプチャーサイズ 描画用のコントロールのハンドル 親ウィンドウのハンドル : Csample3Dlgのハンドル(m_hWnd) スレッドを抜けるためのフラグ スレッドが終了したことを知らせるメッセージ : RegisterWindowMessageなどで取得する 単純な外部関数として UINT ImageCapture( LPVOID lpparam ) { LPMYSTRUCT pmySTruct = (LPMYSTRUCT)lpParam; while( !pmyStruct->bDone ) { // キャプチャー処理 } PostMessage( pmyStruct->hParent, pmyStruct->uMsgExit, 0, 0 ); return 0; } といた具合のほうがいいように思います DLG側でスレッドの終了を感知する関数を追加 afx_msg void myThreadExit( WPARAM wParam, LPARAM lParam ) { //必要な後処理 // CWinThread変数の開放など } メッセージマップに ON_REGISTERED_MESSAGE( m_myREGMSG, myThreadExit ) を追加 メンバー変数として static UINT m_myREGMSG; を追加 CPPファイルに UINT CsampleDlg::m_myREGMSG = RegisterWindowMessage( _T("MyThread_Exit") ); といった具合でしょう
- redfox63
- ベストアンサー率71% (1325/1856)
普通はキャプチャーを別スレッドに仕立てて使うようにすると思いますよ メインスレッドの中でボタンのクリックイベントから抜けないなら CWinThreadクラスのPumpMessageメソッドを適当な頻度で呼びましょう ループ処理のをしていると思いますので適当なカウンタを設けて このカウンタが20回とかカウントしたら呼び出すとかして見ましょう if ( nCnt % 20 == 0 ) { AfxGetApp()->PumpMessage(); nCnt = 0; } nCnt++; といった具合です
お礼
返信ありがとうございました。 おっしゃられた通り、 AfxGetApp()->PumpMessage(); をループ文の中で実行した所、クリックイベントから抜け出し正常に終了することができました。ありがとうございます。 ですが、”普通はキャプチャーを別スレッドに仕立てて使うようにすると思いますよ” この一文も気になったので、スレッドを立ててキャプチャを行うようプログラムを組み替えました。 ですが、以下のような問題が生じてしまいました。 プロジェクト名は "Sample3" となっているため、それぞれのヘッダファイルやソースファイルはこのプロジェクト名が記載されています。 そして CWinThread* m_pThread = AfxBeginThread(&Csample3Dlg::ImgCapture, (LPVOID)this); としてスレッドを立てました。ちなみにキャプチャスレッドはCsample3Dlgクラス内で、 UINT ImgCapture(LPVOID pParam); というように定義されています。 この手順で一応はスレッドが立ち上がると考えたのですが、コンパイルすると以下のようなエラーが出てしまいます。 エラー 2 error C2665: 'AfxBeginThread' : 2 オーバーロードのどれも、すべての引数の型を変換できませんでした このエラーに対処すべく、色々と検索をかけて調べてみたところどうやら文字コードに依存して出てくるエラーだと分かり、文字コードを "マルチバイトコード" に変更したのですが、それでもこのエラーを取り除くことができませんでした。 何が問題なのでしょうか? 連続の質問で恐縮ですが、もしご理解いただけたらアドバイスをお願いしたいと思います。よろしくお願いいたします。
お礼
返信が遅れてしまい申し訳ありませんでした。 とても分かりやすいアドバイスをありがとうございます。 無事実装が完了し、正常に動作させることができました。 本当にいろいろとありがとうございました。