- ベストアンサー
【VC2005(CLR)】モードレスで呼んだダイアログの閉じ方
VC2005初心者です。 現在CLRのプロジェクトでコーディングしてますが、 モードレスで呼んだダイアログの閉じ方が分かりません。 ご存知の方、よろしくお願いします。 ちなみに自分自身のダイアログを閉じるのは this->Close(); なので、以下のように書いたのですが、閉じてくれません。 ※showFlag = 0;を大域変数で宣言しておきます。 AAA^ formAAA = gcnew AAA(); if(showFlag ==0){ AAA^ formAAA = gcnew AAA(); formAAA->Show(this); showFlag = 1; } else{ formAAA->Close(); showFlag = 0; }
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
モーダルである場合、CloseでDispose処理が呼ばれるので、 deleteは不必要です。 (ShowDialogの場合は、Dispose処理が呼ばれないから、deleteが必要。) また、前述のとおり一度Disposeが呼ばれているためCloseすると再度Showできなくなるので、 再度gcnewを行う必要があります。 コードではこんな感じ。 ※全角空白で成形しています。そのままコピペしてもエラーになるので気をつけてください。 public: Form1(void) { InitializeComponent(); // //TODO: ここにコンストラクタ コードを追加します // this->childForm_ = nullptr; } ・ ・ ・ private: Form2^ childForm_; private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { if ((this->childForm_ != nullptr) && !this->childForm_->IsDisposed) { this->childForm_->Close(); //this->childForm_ = nullptr; } else { this->childForm_ = gcnew Form2(); this->childForm_->Show(this); } } 単に、表示非表示の切り替えで良いのであれば、CloseではなくHideを使います。 その場合は、1度だけgcnewすればいいです。 public: Form1(void) { InitializeComponent(); // //TODO: ここにコンストラクタ コードを追加します // this->childForm_ = gcnew Form2(); } ・ ・ ・ private: Form2^ childForm_; private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { if (this->childForm_->Visible) { this->childForm_->Hide(); } else { this->childForm_->Show(this); } }
その他の回答 (5)
- bluecampus
- ベストアンサー率66% (138/209)
if (条件式A && 条件式B) というif文があったとき、条件式Aが偽であるとき条件式Bを評価するまでもなく 結果が偽になります。 C言語ではそのケースのとき条件式Bを評価しないような仕組みになっています。 よって、「条件式Aが偽になる」点で効率が良くなるということです。 今回は 条件式A:this->childForm_ != nullptr 条件式B:!this->childForm_->IsDisposed ですので、nullptrを代入しておけば、条件式Aが偽になるので、 条件式Bを評価する必要がなくなる分効率が良くなるのです。 他にも if (条件式A || 条件式B) のときは条件式Aが真であれば、条件式Bは評価されません。
お礼
ご教授、ありがとうございます。 ご指摘頂いて、そういえばそうだった、と気付きました。 (すみません、私のレベルはその程度です。) this->childForm_->Close(); //this->childForm_ = nullptr; 上記の紹介頂いたソースは、コメントを除いて使用したいと思います。 ありがとうございました。
- bluecampus
- ベストアンサー率66% (138/209)
>this->childForm_->Close(); >//this->childForm_ = nullptr; 下のコメントになっているのはあってもなくても同じという意味です。 どちらかという意味ではありません。 >if ((this->childForm_ != nullptr) && > !this->childForm_->IsDisposed) nullptrを代入しておけば、この条件式が若干効率が良くなります。
補足
ご指摘ありがとうございます。 あまり質問し続けるのも恐縮してしまいますが、 nullptrを代入しておけば、この条件式が若干効率が良くなる とはどういうことなのでしょうか。
- bluecampus
- ベストアンサー率66% (138/209)
No.3です。 間違いがあったので訂正です。 >モーダルである場合、CloseでDispose処理が呼ばれるので、 モーダルではなくモードレスでした。
お礼
ご回答、ありがとうございます。 回答番号:No.3とまとめてお返事をさせて頂きます。 (返答遅れまして申し訳ございませんでした。) ご紹介頂いたコードでやりたい事が実現できました! ありがとうございました。 アドバイス頂いたとおりこの方法ですと、 ダイアログがあるかどうか判断するグローバル変数は 必要ないようですね。 this->childForm_->Close(); //this->childForm_ = nullptr; 途中で、上記の記述がございますが、この2つの記述には 何か違いがあるのでしょうか。
- chie65536(@chie65535)
- ベストアンサー率44% (8757/19871)
まずformAAAを「メインフォームのpublicなメンバ変数」として定義します。 そして、メインフォームのコンストラクタで「formAAA = gcnew AAA();」として、formAAAもコンストラクトして下さい。 formAAAは、メインフォームのコンストラクタで作成は行われますが、表示は行われません。 formAAAを表示する必要がでたら「formAAA->Show(this);」で表示します。これは、メインフォームのクラス内なら、どこで行っても構いません。 formAAAを閉じる必要がでたら「formAAA->Close();」で閉じます。これも、メインフォームのクラス内なら、どこで行っても構いません。 最後に、メインフォームのデクストラクタで「delete formAAA;」を行って、メインフォームの破棄と同時に子フォームも破棄してください。
補足
ご回答、ありがとうございます。 (返信おくれてすみませんでした。) 当初、私にはchie65535さんから頂いた説明では 難しく感じましたが、No3さんの具体的なコードを参照して 説明の内容はこういうことなのかな、と思いました。 (申し訳ございませんが、まだ十分に理解しきれていません。) また、chie65535さんの指摘で初めて、「デストラクタ」の言葉とか 「delete formAAA;」の文法を知りました。 いつも「this->Close();」という文法のみを使って ダイアログが消えたから安心していましたが、 「delete formAAA;」をしないと過去に開いたダイアログがメモリ上に 残り続けてしまうのでしょうか?
- bluecampus
- ベストアンサー率66% (138/209)
閉じようとしているものがShowしたものと別ということは理解していますか? gcnewで新しいフォームを作って、それに対してCloseを処理させようとしています。 開いたフォームを親フォームに覚えておくような仕組みにすればよいでしょう。 (そうすればフラグもいらなそう)
補足
ご回答、ありがとうございます。 >閉じようとしているものがShowしたものと別ということは理解していますか? すみません、まだ理解しておりません。 具体的にどのように、書けばよろしいでしょうか。 追記ですが、質問内容に、誤記がございました。 AAA^ formAAA = gcnew AAA();が2つ記載されておりますが、 1回目のAAA^ formAAA = gcnew AAA(); は削除して下さい。
補足
ご回答、ありがとうございます。 回答番号:No.4とまとめてお返事をさせて頂きます。