質問させてください!
例えば作成したアプリケーションのウインドウ上に、ボタンAとボタンBがあります。
そしてそのボタンAを押した時(イベントAが起きたとき)に、
for文が10000回ループするというプログラムがあるとします。
しかし、その10000回ループしている過程でウインドウ上のBボタンを押した時(イベントBが発生)すぐに、そのループを中断してイベントBが起きたときに起こる別のプログラムを流したいのです。
現実は、10000回ループし終えるまで、ボタンBを押してもイベントBは起きることはありません。
10000回ループし終えてから、ボタンBを押した時に発生するイベントBが発生します。
for文のループをボタンBを押した時実行途中でも終了して、イベントA用に書いたプログラムを中断させ、その直後イベントBが起きた時用に書いたプログラムを流すようにしたいのですが、
プログラム初心者なものでよくわかりません。
どなたかご教授お願いいただけないでしょうか?!
No.1ベストアンサー
- 回答日時:
★この場合はメッセージを処理します。
・for 文のループの中で『ボタンB』を押すと WM_COMMAND などのメッセージがキューに入ります。
・この情報を PeekMessage 関数で検査すれば for 文のループ途中でも強制終了可能な仕組みを組めます。
・下に実装例を載せますので読み取って下さい。
●実装例
static BOOL CALLBACK UserDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static BOOL swPushALoop; ←制御変数
switch ( uMsg ){
case WM_COMMAND:
switch ( LOWORD(wParam) ){
case IDC_PUSH_A: FuncPushA( hDlg, &swPushALoop ); break;
case IDC_PUSH_B: FuncPushB( hDlg, &swPushALoop ); break;
default:return( FALSE );
}
SetFocus( (HWND)lParam );
break;
default:return( FALSE );
}
return( TRUE );
}
VOID FuncPushA( HWND hDlg, LPBOOL swLoop )
{
MSG Msg;
INT i;
*swLoop = TRUE; ←初期化
for ( i = 0 ; (i < 10000) && *swLoop ; i++ ){
:
ループ処理
:
while ( PeekMessage(&Msg,hDlg,0,0,PM_REMOVE) ){ ←ここがポイント
if ( !IsDialogMessage(hDlg,&Msg) ){
TranslateMessage( &Msg );
DispatchMessage( &Msg );
}
}
}
}
VOID FuncPushB( HWND hDlg, LPBOOL swLoop )
{
*swLoop = FALSE; ←強制終了
Sleep( 0 ); ←念のため挿入(なくてもOKかもね)
:
ボタンBの処理
:
}
解説:
・『ボタンA』のループ(処理中)に『PeekMessage』で常にメッセージがキューに入っているかを監視します。
・そして、何かメッセージがあった場合は UserDialogProc プロシージャにそのメッセージを処理する指示を
『DispatchMessage』関数で送ります。
・こうすると『ボタンB』が押されたときに WM_COMMAND メッセージがキューという場所に格納されますから
『DispatchMessage』関数により UserDialogProc プロシージャが呼び出され、WM_COMMAND メッセージの
『IDC_PUSH_B』を即処理します。
・すると『FuncPushB』関数が実行されますが、この関数の最初で『swLoop』という変数に FALSE をセットする
ので、ループ処理中の『FuncPushA』関数の『*swLoop』が FALSE になるので for 文を抜けます。
・『IDC_PUSH_B』の先頭に『Sleep( 1 );』というウェイトを入れたのは『FuncPushB』関数が実行された後に
『FuncPushA』関数の for 文から抜けるまでの時間稼ぎで記述しなくても OK でしょう。
・もしも、ループ処理を抜ける前に『ボタンBの処理』を開始出来ないのならば、安全の為に入れておきましょう。
・以上。おわり。
参考URL:http://www.sm.rim.or.jp/~shishido/mainloop.html
お返事が遅れてしまい、大変申し訳ございません!
Oh-Orange様が教えていただいたことを、今までずっとあーでもない。こーでもないと私的に悪戦苦闘をしておりました。
そしてたった今・・・・、できることができましたぁ!!!
とても感謝しております。
ご丁寧に教えていただき、本当にありがとうございました!!
No.2
- 回答日時:
こんばんは。
他の方がC言語(?)で回答されているようなのでVBで回答してみます。
まず、for文の途中で他のイベントを受け取るには、
for文の処理中に一時的にWindowsに一瞬処理を返す必要があります。
これはDoEventsという命令をforループ内に追加することでできます。
次に処理を中断させる方法ですが、
グローバル変数で処理を抜けたかどうかを検査するための変数を用意し、
例えばこの変数がTrueの場合はBボタンがクリックされたとします。
コードは3つ追加する必要があります。
一つはforループ内(できれば最初の行)にこの変数の値をチェックする以下のような文を追加します。
(グローバル変数名をbolBClick(boolean)とします。)
If bolBClick Then Exit For
次にBボタンがクリックされたときのイベント処理コードの先頭に次のコードを追加します。
bolBClick = True
もうひとつ、同じイベント処理コードの最後に次のコードを追加します。
bolBClick = False
注意点として、各イベント処理のボリュームやタイミングによって若干処理が不安定になることも想定されるので、
シビアなタイミングを要求するような処理を実装されているのであればこの方法が使えないかもしれません。
必要であればループをDo文に変更してカウンタ変数を別途グローバル変数で用意し、
Bボタンクリック時の処理でカウンタを10000にしてしまうなどの工夫が必要かもしれません。
この回答への補足
迅速なご回答ありがとうございます!
それなのにお返事が送れてしまい、真に申し訳ございません!!!
私の投稿した質問に書くのを忘れてしまいましたが、私はAPIでのプログラミングをおこなっております(謝)
ですのでVBの方は・・・。
ですが、VBをやられている方たちは、kargon21様のご回答、絶対に役にたつとおもいます。
ご丁寧にご回答いただき、本当にありがとうございました!!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) uwscとWinShotを使いスクリーンショットを撮る 1 2022/06/30 21:15
- Excel(エクセル) excelvbaのenableeventsについて 3 2022/08/30 11:20
- Android(アンドロイド) xperiaを使うのですが再起動のループで繰り返しで起動しません。 電源ボタンと音量ボタン同時長押し 1 2022/10/31 07:55
- 教えて!goo 質問をして回答者さんにお礼文を書こうとしても、お礼のカウントを押すボタンだけは表示されて、それ以外の 1 2022/07/26 10:19
- その他(趣味・アウトドア・車) Arudino nanoが正常に動作しない原因 1 2022/10/30 18:29
- スピーカー・コンポ・ステレオ デンオン(現デノン)のプレーヤー、DP-3000の起動不良について。 7 2022/05/24 17:57
- Excel(エクセル) excelvbaでスライドショーを作りたい 2 2023/04/20 14:32
- 工学 1つのタクトスイッチで複数の並列回路を閉じ、アースにつなげることができるスイッチはありますか。 2 2022/08/06 10:38
- プリンタ・スキャナー キャノンmp490プリンター【エラー番号5400】で【プリンタートラブルが発生しました。電源を入れ直 2 2023/07/24 17:45
- JavaScript HTMLでJavaScriptを使用してプログラムを作ります。 入力されたパスワードを取得して、パス 2 2022/10/18 01:05
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
メッセージボックスのボタン名変更
-
VBSで応答不要のメッセージボッ...
-
VBSの処理中一旦処理を止めて再...
-
Excel(VBA)シート上のコマンド...
-
ACCESS側からEXCELの書式を設定...
-
エクセルが勝手に立ち上がる
-
【C#】 あるイベントから別イ...
-
Excel VBA で処理中断(DoEvents...
-
ASP.NETでのメッセージ画面を出...
-
Application.ScreenUpdating=Fa...
-
vb.netでバッチ処理
-
VbScriptでExcel操作待ちモード...
-
ボタンが押された事を検知する...
-
DoEvents(VBA)の質問です。
-
VBA メッセージボックスを自動...
-
VBA、UserFormを前面に出力して...
-
VB.NETのUsingキーワードの使い方
-
エクセルVBAでクリップボード内...
-
VCでウエイトをミリ秒でかけ...
-
メッセージBOXの「はい」「いい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
VBA kernel32 の意味
-
ACCESS側からEXCELの書式を設定...
-
VBSで応答不要のメッセージボッ...
-
エクセルVBAでクリップボード内...
-
Application.ScreenUpdating=Fa...
-
Excel VBA で処理中断(DoEvents...
-
VBA メッセージボックスを自動...
-
【C#】 あるイベントから別イ...
-
VBA、UserFormを前面に出力して...
-
ASP.NETでのメッセージ画面を出...
-
Excel VBA 自動的に閉じるMsgBox
-
スロットゲームのプログラミング
-
キーボード入力、マウス操作を...
-
<input type="file">タグで「キ...
-
Excelのワークシートに行を挿入...
-
ボタンが押された事を検知する...
-
VB6 コマンドボタン クリック...
-
VCでウエイトをミリ秒でかけ...
おすすめ情報