処理中のキャンセルを受け付けたい – プログラミング – Home

処理中のキャンセルを受け付けたい
 
通知
すべてクリア

[解決済] 処理中のキャンセルを受け付けたい


Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

Windowsの「コピー中」ダイアログのように、
ダイアログでの処理中に「キャンセル」を受け付けたいのですが、
キャンセルボタンが触れなくなってしまい、うまく動きません。
良い方法は無いでしょうか?

実現したい処理の内容は下記です。
1)ダイアログ出現
2)OKを押したら、繰り返し処理開始(ダイアログは閉じない)
3)途中でキャンセルを押したら処理内容を破棄してダイアログを閉じる

ソースは以下のようになっています。

void CTestDlg::OnOK()
{
PostMessage(START, ...);
// CDialog::OnOK();    /* ダイアログ閉じない */
}

void CTestDlg::OnCancel()
{
PostMessage(CANCELED, ...);
CDialog::OnCancel();
}

LRESULT CTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch(msg){
case START:
/* ここで初期化処理を行う */
PostMessage(CONTINUE, ...);
break;
case CONTINUE:
Shori1(); /* キャンセルが押されるまでこの処理を繰り返したい */
PostMessage(CONTINUE, ...);
break;
case CANCELED:
/* ここで終了処理を行う */
break;
}
return;
}

よろしくお願いいたします。


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

WindowProcには飛び込みますか?
Shori1()には飛び込みますか?
Shori1()での処理は十分に短い時間で完了しますか?


返信引用
Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

はい。
「CONTINUE」の処理が継続される状態です。


返信引用
Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

追記いたします。

>WindowProcには飛び込みますか?
>Shori1()には飛び込みますか?

はい。
WindowProc()にもShori1()にも飛び込みます。

>Shori1()での処理は十分に短い時間で完了しますか?

Shori1()は1回で約1秒程度かかる処理です。
現在は未実装のため、forループなどで仮処理を入れてあります。

実際に動作が始まると、処理は動いているのですが
画面に触っても「キャンセル」他に触れず、アクションが起きません。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

> 実際に動作が始まると、処理は動いているのですが
> 画面に触っても「キャンセル」他に触れず、アクションが起きません。

「触れない」とは? grayになるってことですか? クリックに反応しないってことですか?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

あれ? START/CONTINUE/CANCELED以外のメッセージはどうやって処理してるんでしょ?
CDialog::WindowProc()を呼んであげないかんのとちゃいますか?


返信引用
Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

たびたび記述不足で申し訳ありません。

>「触れない」とは? grayになるってことですか? クリックに反応しないってことです
か?

「クリックに反応しない」ということです。
全体が何も反応しなくなるため、
キャンセルボタンが凹んだりもしません。
grayにはなっていません。

>CDialog::WindowProc()を呼んであげないかんのとちゃいますか?

すみません、記述漏れです。
return CDialog::WindowProc(message, wParam, lParam);
は呼んであります。
(初期生成状態のままです。)


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

普通にShori1()よんだら、
スレッドでないから終るまでそこの状態になるのでは?

case CONTINUE:
Shori1(); /* キャンセルが押されるまでこの処理を繰り返したい */
// Shori1()から戻ってこないと次に進まないよ普通は
PostMessage(CONTINUE, ...);
break;


返信引用
Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

>普通にShori1()よんだら、
>スレッドでないから終るまでそこの状態になるのでは?
>
> case CONTINUE:
> Shori1(); /* キャンセルが押されるまでこの処理を繰り返したい */
>// Shori1()から戻ってこないと次に進まないよ普通は
> PostMessage(CONTINUE, ...);
> break;

本来であれば下記のような処理でよいのですが、
for(cnt = 0; cnt < 1000; cnt++){
shori1();
}
時間がかかるため、途中キャンセルも可能にしたいのです。
(Shori1()の途中で中断する必要はありません。)


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

> case CONTINUE:
> Shori1(); /* キャンセルが押されるまでこの処理を繰り返したい */
> PostMessage(CONTINUE, ...);

これだと、メッセージキューが絶対に空にならないので、
まずいような気がします。

タイマーを使った方がよいのでは。


返信引用
Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

>タイマーを使った方がよいのでは。

タイマーというものを使ったことがないのですが、
タイマーで指定時間経過毎にPostMessage(CONTINUE, ...)を
呼ぶようにするというイメージなのでしょうか?


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

SetTimerと言う関数を調べてください。
あと、WM_TIMERというウインドウメッセージも。
WM_TIMERの処理の中でShori1を呼んだ方がすっきりしそうです。
STARTでSetTimerしてその後は、WM_TIMERの方で処理が進みます。
CANCELEDでKillTimerすれば、処理の中断が出来ます。
Shori1の返却値か何かで処理が終了できるようにしておいて
処理そのものが終わった時もKillTimerと言う流れで良いと思います。
詳しい部分はご自分で考えてください。

長い処理をワーカースレッドで処理させて、メインスレッド側でGUIの制御を
行うようにし、キャンセルのオペレーションでワーカースレッドに中断を
通知すると言う手もあります。
今後、Windowsのプログラミングを続けていくのであれば、スレッドについても
勉強してみた方が良いと思います。


返信引用
Tony
 Tony
(@Tony)
ゲスト
結合: 19年前
投稿: 12
Topic starter  

タイマーを使用してみました。
なんとかうまく行きそうです!
επιστημηさん、
Blueさん、
dairygoodsさん、
PATIOさん、
どうもありがとうございました!


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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