現在MFCを用いてWebカメラからのキャプチャを行うソフトを作成しています。
環境はVisual Studio 2005です。
ソフトウェアはダイアログ形式で、”Capture"と"停止"のボタン、そして1つPictureControlを配置し、"Capture"ボタンが押されたらWebカメラからの映像をPictureControlに表示し、"停止"ボタンが押されたらキャプチャを終了するというものです。
少し長くなってしまうのですがよろしくお願いします。
開発当初、ダイアログクラスのメンバ変数にbool型の Cap_Flag を追加し、コンストラクタにより初期値を false に設定するようプログラムを組みました。 そして "Capture"ボタンが押され、そのイベントハンドラが呼び出された時に、 Cap_Flag を true に設定しキャプチャを行う関数を実行するようにしました。
キャプチャを行う関数の中では、 Cap_Flag をチェックし true に設定されている間キャプチャを行うよう while( Cap_Flag == true ) としてキャプチャを行います。 その後 "停止"ボタン が押されれば、そのボタンに対するイベントハンドラ内で Cap_Flag に false を設定し、キャプチャを終了しようと考えました。
この設計では確かに "Capture"ボタンが押されればキャプチャが行われ、PictureControlに映像が表示されるのですが、これらのキャプチャ処理は "Capture"ボタン のイベントハンドラ内で実行しているため、キャプチャを行っている間、つまり while( Cap_Flag == true ) となっている間は永遠に実行状態になっているため "Capture"ボタン が押されっぱなしの状態になり、"停止"ボタンを押すことが出来なくなってしまいます。また無理に "停止"ボタン を押そうとすると固まってしまうため、うまく"Capture"と"停止"を行うことが出来ない状況です。
改善策として、オリジナルのメッセージを作成しメッセージマップでそのオリジナルの命令に対してキャプチャを行う関数が呼び出されるよう設定しました。よって、 "Capture"ボタンが押されたときに呼び出されるイベントハンドラ内で Cap_Flag を true に設定し、オリジナルのメッセージを送信して、そのメッセージに対応するキャプチャを行う関数を呼び出すようプログラムを組みなおしました。
このように組みなおした理由は、"Capture"ボタンが押されたときに呼び出されるイベントハンドラ内の処理は、Cap_Flag を true に設定することと、オリジナルのメッセージを送信することのみで、イベントハンドラ内ではキャプチャを行う関数は実行されず、 実際に "Capture"ボタン が押されたとしても、押された状態ではなくすぐに基の状態(表示)にもどるだろうと考えたためです。
ですが、このように変更しても "Capture"ボタンのイベントハンドラ内でキャプチャ処理を行っていることと同様に "Capture"ボタンが押されっぱなしの状態になり、"停止"ボタンを押すことが出来ません。
どのようにプログラムを組めば、実際にキャプチャを行っている間でも、"Capture"ボタンが押された状態にならず "停止"ボタン を押すことができるようになるでしょうか?
参考になるアドバイス、またはウェブページをご紹介いただけれたらと思います。
よろしくお願い致します。
No.3ベストアンサー
- 回答日時:
afx_msg void myThreadExit( WPARAM wParam, LPARAM lParam )
は
LRESULT myThreadExit( WPARAM wParam, LPARAM lParam )
でした ・・・
関数を抜ける時には
return S_OK;
など リザルトコードを返してください
返信が遅れてしまい申し訳ありませんでした。
とても分かりやすいアドバイスをありがとうございます。
無事実装が完了し、正常に動作させることができました。
本当にいろいろとありがとうございました。
No.2
- 回答日時:
スレッドプロシージャは 外部関数にしたほうがいいでしょう
クラスのメンバーでやるなら 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") );
といった具合でしょう
No.1
- 回答日時:
普通はキャプチャーを別スレッドに仕立てて使うようにすると思いますよ
メインスレッドの中でボタンのクリックイベントから抜けないなら
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);
というように定義されています。
この手順で一応はスレッドが立ち上がると考えたのですが、コンパイルすると以下のようなエラーが出てしまいます。
エラー2error C2665: 'AfxBeginThread' : 2 オーバーロードのどれも、すべての引数の型を変換できませんでした
このエラーに対処すべく、色々と検索をかけて調べてみたところどうやら文字コードに依存して出てくるエラーだと分かり、文字コードを "マルチバイトコード" に変更したのですが、それでもこのエラーを取り除くことができませんでした。
何が問題なのでしょうか?
連続の質問で恐縮ですが、もしご理解いただけたらアドバイスをお願いしたいと思います。よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- gooのスマホ スマホの通話切断について 2 2022/12/09 01:34
- Windows Vista・XP 電源ボタンでスリープするように設定の場合の強制終了方法 3 2022/06/21 14:00
- Visual Basic(VBA) visual basic初心者です。 visual studioで電卓を作成しています。 実行時にテ 1 2023/02/08 00:18
- ブルーレイ・プレーヤー・レコーダー シャープ BD-S520 録画中の一時停止画面 4 2022/10/13 17:59
- Android(アンドロイド) AQUOS sense6sの物理ボタン(アシスタントキー)に再生・一時停止を割り当てる方法 2 2022/08/09 00:37
- 債券・証券 SBI 証券でお金を入金 しているいるのですが 画像のように、入金サービスと住信 SBI ネット銀行 1 2022/06/06 21:59
- マウス・キーボード キーボード設定で困っています。長文です。 2 2022/12/10 12:44
- Android(アンドロイド) スマホ chromeの戻るボタンが機能しにくい スマホ(OPPO reno5A、Android12) 1 2022/09/11 20:39
- その他(パソコン・周辺機器) アイ・オー・データ ビデオキャプチャー GV-USB2で録画できない 0 2023/01/09 14:57
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA シートのボタン名を変更し...
-
VBA(エクセル)で自動的にボタン...
-
フォームの再読み込み
-
VBAのボタンの位置が変わって困...
-
ボタンをマウスで押し続けたと...
-
リストボックス 何も洗濯され...
-
Excel VBA Application.caller...
-
ボタン上にビットマップ、アイ...
-
タイマーがいきなり動き出すん...
-
VBA CommandButtonの文字ずれ
-
グラフィカルボタン
-
ExcelVBAでユーザーフォームで...
-
VB.NETでマウスクリックイベン...
-
VBS でユーザーからいくつかの...
-
VB2010 クリック数カウント
-
回数のカウント
-
見えないボタンを作って、押さ...
-
VBA でのボタンの移動について
-
プロシージャからイベントをコ...
-
[Excel VBA]コマンドボタンの入...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA シートのボタン名を変更し...
-
VBA(エクセル)で自動的にボタン...
-
フォームの再読み込み
-
ユーザーフォームに別シートか...
-
VBA CommandButtonの文字ずれ
-
セルをマクロのボタンにしたい。
-
Excel VBA Application.caller...
-
コマンドボタンやイメージにマ...
-
Access VBA でデータペーストを...
-
VBAのボタンの位置が変わって困...
-
ボタンをマウスで押し続けたと...
-
ボタン
-
C#プログラムで、ボタンをショ...
-
VBA でのボタンの移動について
-
閉じると「+」になり開くと「-...
-
ダウンロードダイアログをVB...
-
[Excel VBA]コマンドボタンの入...
-
ASP.Net ラベルの内容をすぐに...
-
プロシージャからイベントをコ...
-
CommandButtonのCaptionを変化...
おすすめ情報