ループ処理中止ダイアログについて – プログラミング – Home

ループ処理中止ダイアログについて
 
通知
すべてクリア

[解決済] ループ処理中止ダイアログについて


VC初心者
 VC初心者
(@VC初心者)
ゲスト
結合: 22年前
投稿: 21
Topic starter  

長いループ処理を開始した時に中止ダイアログを表示し、中止ボタンを押すとループ処
理を中止するプログラムを作成したいのですが、うまくいきません。
開発環境は、WinXP(SP2) VC++6.0 MFCです。

以下のような記述をしています。
ダイアログベース(CTestDlg)で作成しており、ボタンを押すとループ処理が始まると
同時に中止ダイアログ(Dialog1)が表示されます。
中止ダイアログの中止ボタン(Button2)を押すとループ処理が止まるようにしたいので
すが、Button2を押してもループ処理はとまらないし、中止ダイアログも閉じません。

根本的に間違っているようなのですが、行き詰っています。
どなたか、ご教授くださいますようお願いいたします。

TestDlg.hで
static BOOL bCancel;
を定義しています。

BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
bCancel = FALSE;
return TRUE;
}

void CTestDlg::OnButton1()
{
Dialog1* dlg1;
dlg1 = new(Dialog1);

  dlg1->Create(IDD_DIALOG1, this);
dlg1->ShowWindow(TRUE);
dlg1->UpdateWindow();

MSG msg;

while(1){
while(!bCancel && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(!dlg1->IsDialogMessage(&msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

// ループ処理

if(bCancel){
dlg->DestroyWindow();
delete [] dlg1;
break;
}
}
}

void Dialog1::OnButton2()
{
bCancel = TRUE;
 
}


引用未解決
トピックタグ
金魚ちゃん
 金魚ちゃん
(@金魚ちゃん)
ゲスト
結合: 16年前
投稿: 52
 

bCancelの判定位置がおかしいかな。

void CTestDlg::OnButton1()
{
 Dialog1* dlg1 = new(Dialog1);
 :
 for ( ; ; ){
  while ( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ){
   :
  }
  if ( bCancel ){
   dlg->DestroyWindow();
   delete[] dlg1;
   break;
  }
  else{
   // ループ処理
  }
 }
}
これでどう。


返信引用
VC初心者
 VC初心者
(@VC初心者)
ゲスト
結合: 22年前
投稿: 21
Topic starter  

金魚さん、ありがとうございます。
やってみましたが、ダメでした・・・

Dialog1のOnButton2では、bCancel=TRUEになっているのですが、CTestDlgの方で
bCancel=FALSEのままのようなんです。
bCancelの定義位置が違っているのでしょうか??


返信引用
金魚ちゃん
 金魚ちゃん
(@金魚ちゃん)
ゲスト
結合: 16年前
投稿: 52
 

PeekMessage関数の第2引数にダイアログのウインドウ・ハンドルを渡してないね。
ここを直したらどうなる?


返信引用
ryo
 ryo
(@ryo)
ゲスト
結合: 23年前
投稿: 252
 

>Dialog1のOnButton2では、bCancel=TRUEになっているのですが、CTestDlgの方で
>bCancel=FALSEのままのようなんです。
>bCancelの定義位置が違っているのでしょうか??
同名の別物になってる可能性が高そうですね

static BOOL bCancel;と同様の宣言は別にないか
bCancelはグローバルか、TestDlgのメンバ変数か
TestDlgとDialogの宣言・関数定義は、同一のファイルか、
それとも別ファイルか

このあたりどうでしょうか?


返信引用
VC初心者
 VC初心者
(@VC初心者)
ゲスト
結合: 22年前
投稿: 21
Topic starter  

金魚ちゃんさん、ryoさんありがとうございます。
返信がおそくなり、申し訳ありません。

①h_cancelwnd = dlg1->GetSafeHwnd();
 として、PeekMessageの第2引数にh_cancelwndとしてみましたが、同じでした。

②bCancelの宣言は、testDlg.hに宣言しており、
 Dialog1.cppの頭でtestDlg.hをインクルードしています。
 testDlg.cppの頭でDialog1.hをインクルードしています。

③TestDlgとDialogの宣言・関数定義は、別ファイルです。

bCancelの宣言は以下の通りです。
何度もすみませんが、ご指導お願いいたします。

// testDlg.h : ヘッダー ファイル
//

#if !defined(AFX_TESTDLG_H__17F2C46D_575C_46AE_8A76_E198F3669C84__INCLUDED_)
#define AFX_TESTDLG_H__17F2C46D_575C_46AE_8A76_E198F3669C84__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CTestDlg ダイアログ

static BOOL bCancel;

class CTestDlg : public CDialog
{
// 構築
public:
CTestDlg(CWnd* pParent = NULL); // 標準のコンストラクタ

---以下省略


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

以下の話からして、
> ②bCancelの宣言は、testDlg.hに宣言しており、
> Dialog1.cppの頭でtestDlg.hをインクルードしています。
> testDlg.cppの頭でDialog1.hをインクルードしています。

おそらく、
Dialog1.cpp から見た bCancel は、
testDlg.cpp から見た bCancel とは別物です。

同じものにするには、extern とか使いましょう。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

個人的には処理ループの中でメッセージループを回すのは
あまり好きでは無いので私だったら思い切ってマルチスレッドに
してしまいそうです。
メインスレッドとワーカースレッドのやり取りのやり方を
ちゃんと確立できれば、長い処理はワーカースレッド内で
完結して考えられるし、メインスレッドの方は普通にメッセージの
処理が出来るので整理はしやすいかなと。
マルチスレッドにすると複雑化すると言う事で避けるケースもある
見たいですけれど、私的には割りと簡単なケースでマルチスレッドに
慣れておくと応用しやすくなると思うので時間的に余裕があるなら
マルチスレッドにしてみるのも悪くないかもと思います。

マルチスレッドを強要するつもりは有りませんけれど、
こういう考え方もあるよと言う話です。


返信引用
VC初心者
 VC初心者
(@VC初心者)
ゲスト
結合: 22年前
投稿: 21
Topic starter  

bunさん、PATIOさん、ありがとうございます。
externを使って、できました。
基礎中の基礎ですね…すみません。勉強します。

マルチスレッドに関しては、まだ理解できていないのですが、
やり方としては、そちらの方がスムーズなんですよね。
今回は、何とか動きましたが、今後のためにネット等で調べてみます。

ありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました