<プログラム環境>
Windows XP
VC++6.0
MFC AppWizard(exe)
ダイアログベース
<目的>
1.ダイアログにボタン1を配置する
2.処理A(無限ループ)を開始する
3.処理Aの先頭でボタン1が押されたか判断する
4.ボタン1が押された場合処理Aを終了し、処理Bを行う
というプログラムを作成する。
<質問>
目的のプログラムを作成するには、ボタン1が押された事を検知する
必要があると思うのですが、その方法が分かりません。
ボタンが押された事を検知するにはどうしたら良いのでしょうか?
宜しければご指摘お願い致します。
No.5
- 回答日時:
> ボタン2を押して無限ループを実行している最中にダイアログの
> ボタン1を押すと、砂時計のアイコンが出て、フリーズしました。
当然でしょう
ループで待っている部分にメッセージポンプが無いからです
WaitForSingleObjectの返り値が時間切れの場合に
MSG msg;
while( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) {
AfxGetApp()->PumpMessage();
}
といった具合でメッセージポンプを組みましょう
MFCアプリで CreateThradなど使うのは避けたほうがいいようです
MFCでマルチスレッドをしたいなら CWinThreadクラスを使いましょう
この回答への補足
redfox63様、有難うございます。
ご指摘頂いた通りに、コーディングしたのですが、
症状に変化はありませんでした・・。
データをPCに送信する機器の故障が無い限り、
データは延々と連続して送られてくるので、
WaitForSingleObjectの戻り値はWAIT_OBJECT_0になります。
もしくは、ReadFileの戻り値が0以外となって、受信成功です。
(この場合はWaitForSingleObjectは実行されない)
WaitForSingleObjectの戻り値が時間切れになる事は、まず無いので、
MSG msg;
while( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) {
AfxGetApp()->PumpMessage();
}
という処理には入らないと思います。
シングルスレッドでは不可能なのでしょうか?
宜しければ、ご指摘お願い致します。
No.4
- 回答日時:
うーん、申し訳ありません。
チョッと判りませんが、こんな感じ?//グローバルハンドル
static HANDLE g_hEvent = 0;
//スレッド関数
DWORD WINAPI ThreadProcA(void* p)
{
HANDLE hCom;//COMポートのハンドル
unsigned char Buf[4];//受信バッファ
DWORD dwOldTime = ::timeGetTime();
for( ; ; )
{
//一秒経過
if(::timeGetTime() - dwOldTime > 1000)
{
dwOldTime = 0;
return;
}
if(::ReadFile(hCom,Buf,1,NULL,&old) == 0)
{
return;
}
}
}
void ボタン1関数()
{
//スレッドは既に停止していた
if(g_hEvent == 0)return;
//スレッドの停止
::CloseHandle(g_hEvent);
g_hEvent = 0;
//B処理
}
void 起点()
{
DWORD dw;
g_hEvent = ::CreateThread(NULL, 0, &::ThreadProcA, NULL, 0, &dw);
}
この回答への補足
machongola様、有難うございます。
スレッド関数を使った事が無いので良く理解できていないのですが、
void 起点()
というのが、ボタン2関数の事ですよね?
g_hEvent = ::CreateThread(NULL, 0, &::ThreadProcA, NULL, 0, &dw);
というコードで、スレッド関数が実行されるということですか?
スレッド関数のコードでは
1秒経過すると受信が終わってしまうのではないでしょうか?
延々と受信を行い、任意にボタン1を押して、そのタイミングで
受信を止めたいと考えております。
if(::ReadFile(hCom,Buf,1,NULL,&old) == 0)
{
return;
}
というのは、受信が失敗した場合にスレッドを終了する、という
事ですよね?
データがPCに送られてくるのが遅れて、
少し(数ms)待たないと受信完了しない場合があるので、
ReadFileの戻り値が0の場合でも、WaitForSingleObjectなどで
受信完了まで少し待った方がいいと思うのですが、いかがでしょうか?
宜しければご指摘お願い致します。
No.3
- 回答日時:
挙げられたソースだけではなんとも判断できませんが、
・処理Bは無限ループ?それともAに戻ってくる?
Aに戻ってこないなら、Bの中でもイベント処理をしないと応答無しになってしまいます。
・Flagは0に戻してますか?
無限ループ処理内で Flag==1であることを関知したら、Flag=0に戻しましょう。
そうしないと、一度クリックしたら、いつまでもクリック時の処理を行うことになっていしまいます。
この回答への補足
mtaka2様、有難うございます。
ソースが未完全で申し訳ありませんでした。
処理Bは
Flag = 0;
break;
です。
よってAには戻りません。
Bの中でもイベント処理をする必要があるとの事ですが、
どのようにコーディングしてイベント処理をするのでしょうか?
宜しければご指摘お願い致します。
No.2
- 回答日時:
マルチスレッドにして、通常のメッセージループと無限ループ処理を別スレッドにするのがいいと思います。
あとは、「ボタン1がクリックされたかどうか」を表す変数を用意しておいて、
ボタン1のクリックイベントで変数に代入
無限ループ処理内では、その変数の内容チェック
を行えばいいでしょう。
あるいは、シングルスレッドでも、
無限ループ内でメッセージ処理してもいいでしょう。
http://msdn.microsoft.com/ja-jp/library/3dy7kd92 …
シングルスレッド方式の場合、無限ループ処理内で定期的にメッセージ処理を行う必要があります。
変数を介してクリック情報を取得するのは同じ。
この回答への補足
mtaka2様、有難うございます。
マルチスレッドの知識がまだ無いので、シングルスレッド方式で
メッセージ処理するようにコーディングしました。
ボタン2を押すと無限ループの処理(ボタン2関数)に入ります。
ボタン2関数では延々とデータを受信するように
なっています。(簡略に記述してます)
BYTE Flag = 0;//グローバル変数
ボタン2関数(){
HANDLE hCom;//COMポートのハンドル
unsigned char Buf[4];//受信バッファ
OVERLAPPED old;//オーバーラップ構造体
int i =0;
old.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
while(i != 1){//無限ループ
if(Flag == 1)処理B;
if(ReadFile(hCom,Buf,1,NULL,&old) == 0){
if(WaitForSingleObject(old.hEvent,1000) == WAIT_TIMEOUT){
return;
} } } }
ボタン1関数(){
Flag = 1;
}
ボタン2を押して無限ループを実行している最中にダイアログの
ボタン1を押すと、砂時計のアイコンが出て、フリーズしました。
なぜでしょうか?
宜しければご指摘お願い致します。
No.1
- 回答日時:
Windowsプログラミングするのであれば 無限ループによる処理は避けましょう
待ちを期待する処理ならWaitForSingleObjectなど使ってメッセージポンプを止めないような処理が必要です
無限ループなどの処理をした場合 コントロールで起きたイベントは
独自のメッセージポンプを実装しない限り 永遠に取得できません
ボタンが押された場合は BN_CLICKEDメッセージを処理するようにします
ダイアログエディタで ボタンをダブルクリックすればイベントハンドラを作成してくれます
この回答への補足
redfox63様、有難うございます。
無限ループはご指摘頂いた通りWaitForSingleObjectを使っています。
非同期でCOMポートからデータ受信を行い、1秒でタイムアウトする
設定です。タイムアウトしない限り延々とデータを受信します。
ダイアログエディタでイベントハンドラを作成すると、
Onから始まる名前の関数が作成されますが、
この関数では何も処理を行わないつもりです。
BN_CLICKEDメッセージを処理したいのですが、どのようにコーディング
するのでしょうか?
if(BN_CLICKED == TRUE){
処理
}
という感じでしょうか?
また、BN_CLICKEDだけでは、どのボタンが押されたか分からないのでは
ないでしょうか?
宜しければご指摘お願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- Excel(エクセル) マクロで謎の現象が起きていて困ってます。 エクセルで作ったボタンを押すとマクロが動いて処理をしてくれ 3 2023/06/22 17:28
- その他(プログラミング・Web制作) uwscとWinShotを使いスクリーンショットを撮る 1 2022/06/30 21:15
- Windows Vista・XP 電源ボタンでスリープするように設定の場合の強制終了方法 3 2022/06/21 14:00
- Excel(エクセル) excelvbaでスライドショーを作りたい 2 2023/04/20 14:32
- JavaScript HTMLでJavaScriptを使用してプログラムを作ります。 入力されたパスワードを取得して、パス 2 2022/10/18 01:05
- Visual Basic(VBA) 【ExcelVBA】動的にボタン、ボタン名を生成できますか? 7 2022/04/08 12:54
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Visual Basic(VBA) 動かなくなってしまった古いVBAを動くようにしたい 8 2022/09/20 13:57
- その他(趣味・アウトドア・車) Arudino nanoが正常に動作しない原因 1 2022/10/30 18:29
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教える店舗&オフィスのセキュリティ対策術
中・小規模の店舗やオフィスのセキュリティセキュリティ対策について、プロにどう対策すべきか 何を注意すべきかを教えていただきました!
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
ビジュアルC++でボタンの有効/無効
C言語・C++・C#
-
c言語 ボタン入力のプログラムについて
C言語・C++・C#
-
-
4
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
5
ボタンが押された時にループから抜けるには
C言語・C++・C#
-
6
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
7
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
8
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
9
iniファイルに追記がしたいです。
Visual Basic(VBA)
-
10
ループからの抜け出し方
C言語・C++・C#
-
11
charからLPTSTRへの変換方法
C言語・C++・C#
-
12
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
13
ラジオボタンの値の取得について(C++)
C言語・C++・C#
-
14
C# WindowsForm Button押下判定
その他(プログラミング・Web制作)
-
15
switch の範囲指定
C言語・C++・C#
-
16
C++でのCRLFについて
C言語・C++・C#
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excel(VBA)シート上のコマンド...
-
メッセージボックスのボタン名変更
-
C#で処理中画面を表示したい。
-
スロットゲームのプログラミング
-
エクセルVBAでクリップボード内...
-
VBSの処理中一旦処理を止めて再...
-
Macターミナルで実行中のプログ...
-
緯度、経度の 10進法と 60進法...
-
マイコンからプログラムを読み...
-
DoEvents関数って何?
-
forkについて
-
誤ってプロセスの終了をしてし...
-
WindowsAPIのCreateFile関数ま...
-
4分木の探索プログラミングにつ...
-
C言語primeについて
-
C言語における再帰呼び出しの...
-
ExcelのVBAでX=0〜1の定積分を...
-
【C言語】再帰が時間がかかる...
-
MACで動く実行ファイルをWindow...
-
VBSでのPostMessageについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
ACCESS側からEXCELの書式を設定...
-
VBSで応答不要のメッセージボッ...
-
VBA kernel32 の意味
-
エクセルVBAでクリップボード内...
-
【C#】 あるイベントから別イ...
-
Excel VBA で処理中断(DoEvents...
-
VBA メッセージボックスを自動...
-
Application.ScreenUpdating=Fa...
-
Excel VBA 自動的に閉じるMsgBox
-
ASP.NETでのメッセージ画面を出...
-
メッセージBOXの「はい」「いい...
-
「キャンセル」ボタン付きの処...
-
B列に特定の文字列が入っている...
-
シャットダウン時のExcel強制終...
-
ASP VBScriptでスクリプト実行...
-
起動後直に実行するコードはど...
-
MFCのメニューバーのイベント取得
-
アクセスでのキー送信について
おすすめ情報