
Windowsアプリで、ある時間のかかる処理を
キャンセルボタン付処理中ダイアログを表示し、途中で処理をキャンセル可能にしたいと考えています。
ここの過去ログから上記はマルチスレッドにする必要があると拝見しました。http://oshiete1.goo.ne.jp/kotaeru.php3?q=96951
<メイン画面の開始ボタン処理> ------------------
void C_SampleDlg::OnStart(){
CWinThread *cwt;
C_CancelDlg dlgCancel(this);
cwt = AfxBeginThread(Sample_Proc, &InputParams);
cwt->m_bAutoDelete = FALSE;
cwt->ResumeThread();
EnableWindow(FALSE);
dlgCancel.Create();
dlgCancel.ShowWindow(SW_SHOW);
while(TRUE){
if(dlgCancel.CheckCancel() == TRUE){
// キャンセルが押された時
EnableWindow(TRUE);
dRcd = WaitForSingleObject(cwt->m_hThread, INFINITE);
if(dRcd == WAIT_OBJECT_0)
return;
}
dRcd = WaitForSingleObject(cwt->m_hThread, 0);
if(dRcd == WAIT_OBJECT_0){
dlgCancel.DestroyWindow();
EnableWindow(TRUE);
break;
}
}
return;
}
<プロシージャ> ----------------------------------
UINT Sample_Proc(LPVOID pParam){
C_SampleDlg->やりたい処理関数呼び出し
::AfxEndThread(0);
return 0;
}
以降別ソース ==================================
<C_SampleDlg::やりたい処理関数>
↑ここでdlgCancel.CheckCancel() == TRUEかどうか
判定したい場合、グローバル関数を使うか、または呼出し元で作成したインスタンスをパラメタとして渡して使うべきなのでしょうか。文字数の関係で分かりにくいところもありますが、よろしくお願いします。
※dlgCancel.CheckCancel()はC_CancelDlgクラスのプロテクト変数を内部で操作しています。
No.1ベストアンサー
- 回答日時:
時間のかかる処理というのがループして実行するようなタイプの処理だと、マルチスレッド使わなくても以下のような方法で簡単にできます。
時間のかかる処理の中で、キャンセルボタンは普通押せません。それは1メッセージの処理の中で長~い処理を行っているからです。それならば、メッセージ処理中にも別のメッセージを処理できる仕組みを作ってやればいいのです。○ Before
for(int loop=0; loop < 1000000; loop ++) {
// ここで時間のかかる処理実行
}
この場合だとループがすべて終了するまで待たされます。
○ After
for(int loop=0; loop < 1000000; loop ++) {
// ここで時間のかかる処理
MSG msg;
while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
if(!AfxGetApp()->PumpMessage())
{
::PostQuitMessage(0);
break;
}
}
ループ1回に付きメッセージ処理を行うため、処理中であっても例えば中断ボタン操作などが普通に処理できます。
ご回答ありがとうございます。
上記のやり方を試したところ、上手く1つのスレッドで処理中の中断が実現できました。ありがとうございました。
ところで、1つのスレッドでキャンセルボタン付ダイアログの表示と処理を並行すると、PCのスペックにも依存すると思いますが、ダイアログのレスポンスがマルチスレッドに比べて遅い気がします。(処理中にダイアログボックスをドラッグ移動しようとすると、多少カクカクします)。もし、呼出し元で画面表示をするスレッドと処理をするスレッド間で、キャンセルボタンの押下判定をするには、スレッド間通信を行うしかないんですかねぇ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
ループからの抜け出し方
C言語・C++・C#
-
ボタンが押された時にループから抜けるには
C言語・C++・C#
-
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
-
4
処理をとめるキャンセルボタンのあるダイアログ作成
C言語・C++・C#
-
5
キャンセルの方法
C言語・C++・C#
-
6
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
7
画面を強制的に再描画させる方法
C言語・C++・C#
-
8
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
9
【MFC】キャンセルボタン処理が実装できない
C言語・C++・C#
-
10
CString型 全角半角を意識せずに「1文字」ずつ取り出す
C言語・C++・C#
-
11
別スレッドからメインダイアログのコントロールにアクセスする方法
C言語・C++・C#
-
12
エディットボックスの入力制限について
C言語・C++・C#
-
13
ビジュアルC++でボタンの有効/無効
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
ACCESS側からEXCELの書式を設定...
-
VBSで応答不要のメッセージボッ...
-
CreateCompatibleDCを初期化時...
-
Excel VBA で処理中断(DoEvents...
-
Excel(VBA)シート上のコマンド...
-
「キャンセル」ボタン付きの処...
-
MFCのワーカースレッドとUIスレ...
-
VBA、UserFormを前面に出力して...
-
VB6 コマンドボタン クリック...
-
ファンクションキーのキャンセ...
-
スロットゲームのプログラミング
-
thunderbirdのメッセージフィル...
-
VBA kernel32 の意味
-
Excel VBA 実行中に一瞬フリー...
-
Application.ScreenUpdating=Fa...
-
VB.NETで数秒間msgboxの...
-
【KeyDown】キーコードについて
-
PostMessageの連続送信
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
VBA kernel32 の意味
-
メッセージボックスのボタン名変更
-
ACCESS側からEXCELの書式を設定...
-
VBSで応答不要のメッセージボッ...
-
VBA、UserFormを前面に出力して...
-
【C#】 あるイベントから別イ...
-
Excel VBA で処理中断(DoEvents...
-
PostMessageの連続送信
-
ボタンが押された事を検知する...
-
Application.ScreenUpdating=Fa...
-
エクセルVBAでクリップボード内...
-
VB Loopを一時停止し再開あるい...
-
起動後直に実行するコードはど...
-
DirectX環境下での方向キー同時...
-
Excel VBA 実行中に一瞬フリー...
-
OSシャットダウン時の常駐アプ...
-
マウスのクリックを無視したい
-
エクセルVBAで
-
メッセージボックスの表示につ...
おすすめ情報