-PR-
解決
済み

キャンセルの方法

  • すぐに回答を!
  • 質問No.96951
  • 閲覧数210
  • ありがとう数3
  • 気になる数0
  • 回答数4
  • コメント数0

うらで何か動作しているとき、キャンセルボタンを押せるようにしたいのですが、
(例えば、Sleep()の間にキャンセルする)
イネーブルにしていても、ボタンが黒く表示されるだけで、押せません。
押せるようにするにはどうしたらいいのでしょうか。
OnTimer()を使っているのですが、それが原因なのでしょうか。
通報する
  • 回答数4
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.4
レベル12

ベストアンサー率 45% (210/459)

こんにちは。itohhといいます。

裏で動いているのは、サーバ通信になる予定なのですね。

わたしの勘違いでした、モーダレス・ダイアログでは、ちょっと対応できない
と思います。

なぜかというと、
モーダレス・ダイアログを使った場合、ダイアログボックスを呼び出す側で
ループによって、ダイアログボックスでボタンが押されたかを監視するのと
裏の処理を行うのを交互に行います。
この場合、裏の処理は、ある程度、細切れに処理を行います。
(例えば、10個のファイルをコピーするとき、1個コピーするたびに
ダイアログボックスのボタンが押下されたかをチェックします。)

今回の場合、サーバ通信は一定時間(Sleep関数のように)制御が
戻ってこないのですよね、同一スレッドでは、どうしてもサーバ通信を
呼び出したところで止まってしまいます。
(実際は、サーバ通信内で動いていますが)
このままだと、ダイアログボックスのボタンが押下することは出来ません。

対策としては、
1.toysmithさんが回答しているように、別スレッドにする。
2.サーバ通信内でたまに制御を戻すようにする。
です。

別スレッドにするメリットですが、中止するためのダイアログボックスと
実際の処理(裏で動いている)を完全に分離できるため制御が
シンプルになります。

対策2で行った場合、スレッドの制御はなくなりますが、
サーバ通信を一定間隔で呼び出し元に制御を戻さなくてはいけないため、
サーバ通信のロジックが難しくなります。

残念ながら、わたしの勘違いです、ごめんなさい。(モーダレス・ダイアログを使うこと)
王道は、対策1がベストだと思います。
お礼コメント
noname#794

早速試してみたのですが、(モーダレスの場合)
うまくいかなかったので、今、「別スレッドで立ち上げる」に挑戦中です。
回答ありがとうございました。
投稿日時 - 2001-07-02 14:48:13
-PR-
-PR-

その他の回答 (全3件)

  • 回答No.1

言語はCですか?C++ですか?それともVC++? VC++ならSleepExという関数があるのは知っていますが C++とかCとかだったらどうだったかな? #ご存じの方、フォローよろしく。 ではでは☆ ...続きを読む
言語はCですか?C++ですか?それともVC++?

VC++ならSleepExという関数があるのは知っていますが
C++とかCとかだったらどうだったかな?
#ご存じの方、フォローよろしく。

ではでは☆
お礼コメント
noname#794

VC++でした。
回答ありがとうございました。
投稿日時 - 2001-07-02 11:46:15


  • 回答No.2
レベル12

ベストアンサー率 45% (210/459)

こんにちは。itohhといいます。 ちょっと、状況があいまいなので。 1.裏で処理を行っている。(Sleep関数、なんのために??) 2.裏で行っている処理を途中で中断できるようにキャンセルボタン付きの   ダイアログボックスを表示している。 3.ダイアログボックスのキャンセルボタンが押下できない。 4.裏で処理といっても別プロセス、別スレッドではない。 5.ダイアログボックスを表示した ...続きを読む
こんにちは。itohhといいます。

ちょっと、状況があいまいなので。
1.裏で処理を行っている。(Sleep関数、なんのために??)
2.裏で行っている処理を途中で中断できるようにキャンセルボタン付きの
  ダイアログボックスを表示している。
3.ダイアログボックスのキャンセルボタンが押下できない。
4.裏で処理といっても別プロセス、別スレッドではない。
5.ダイアログボックスを表示したあと、裏の処理が動き出す。
  (OnInitDialog関数内で実行している)
6.MS VC++である。

状況は、これでよいでしょうか?違っていたら、補足願います。
とりあえず、これだと解釈して回答します。

ダイアログボックスの作成方法はどうしていますか?
CDialogクラスのDoModal関数を使っている場合、裏で処理を行っていると
ダイアログボックスの動きは止まりますよ。

基本は、モーダレスでダイアログボックスを作成してください。
そして、キャンセルボタンが押下されたら、裏の処理を中断するように
プログラムを作成してください。

モーダル・ダイアログボックス:CDialogクラスのDoModal関数
モーダレス・ダイアログボックス:CDialogクラスのCreate関数
補足コメント
noname#794

ありがとうございます。
Sleep関数の部分は本来ならば、サーバと通信の部分ですが、ダミーでSleepを使っているだけです。

他の部分はおっしゃる通りの状況です。
Create関数を使ってみたいと思うのですが、使い方がいまいちわかりません。
詳しく教えていただけませんでしょうか。
投稿日時 - 2001-07-02 11:32:57
  • 回答No.3
レベル13

ベストアンサー率 37% (570/1525)

「OnTimer()を使っている」というと… ・ダイアログでキャンセルボタン表示 ・OnTimer()で呼び出される関数で別の処理を行っている という状況でしょうか? この状況ならボタンは有効に動作するはずです(経験済み)。 より、実際的には 1.モーダルダイアログボックスでキャンセルボタンを表示 2.別スレッドで“裏”の処理を行う 3.キャンセルされたら“裏”処理のスレッド殺す ...続きを読む
「OnTimer()を使っている」というと…
・ダイアログでキャンセルボタン表示
・OnTimer()で呼び出される関数で別の処理を行っている
という状況でしょうか?

この状況ならボタンは有効に動作するはずです(経験済み)。

より、実際的には
1.モーダルダイアログボックスでキャンセルボタンを表示
2.別スレッドで“裏”の処理を行う
3.キャンセルされたら“裏”処理のスレッド殺す
という手順の方が確実に動作します。
補足コメント
noname#794

上記の通りです。
OnTimer()内で呼び出される関数が同クラス内にあっても、上記のように動くのでしょうか。
スレッドの使い方がわからないのと、時間がないことで、
スレッドを使わずに作りたいのですが、
補足などありましたらお願いします。
投稿日時 - 2001-07-02 11:46:34
お礼コメント
noname#794

別スレッドで裏の処理を行うようにしました。
結構、難しいでしたが、なんとか動くようになりました。
ありがとうございました。
投稿日時 - 2001-07-02 18:30:55
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ