ダイアログを消去する

[戻る]
hanabi 2003/09/02(火) 19:43:10
いつもお世話になっています。
開発環境はwindows2000 VC++6.0 MFC SDI です。

現在 http://www.net24.ne.jp/~kenji/s_swin/swin.html のページを参考にし、
ダイアログを表示し、ボタンを押すとウインドウを表示するというプログラムを組んでい
ます。
今回、ウインドウを表示すると同時に、ダイアログを消去したいと考えたのですが
どうにもうまくいきません。
EndDialog関数を使用してみたりしたのですが、
それですと作成したウインドウごと消去してしまいます。


また、平行して質問させていただきたいのですが、
上のページのようにして作成したウインドウにViewを持たせることはできるのでしょうか?

稚拙な質問だとは思いますが、よろしくお願いいたします。

Daisuke 2003/09/02(火) 20:12:30
そのプロジェクトの**App.cppを良く眺めてみましょう。
Appがどうやってダイアログを表示させているのかがわかります。
(インスタンスができると何もしないで終了しているんですね。)

また、SDIのプロジェクトを作って同様の部分を見てみると、
SDI画面をどうやって表示しているのかもわかります。

それらと同じ事をやればいいんです。

どちらかというと、SDIプロジェクトのInitInstanceでダイアログを
DoModalさせた方が手っ取り早いですね。

hanabi 2003/09/02(火) 22:11:01
Daisukeさんありがとうございます。

なるほど。
普段主にViewやDocumentなどしか見ないのでAppでの処理はチェックしていませんでした。
ここでやってるんですね。
もっとくわしく見てみます。

Daisuke 2003/09/02(火) 23:33:39
SDIでドキュメントビューアーキテクチャのサポートをはずしたスケルトンを作って見ると
わかりやすいかもしれません。
AppのInitInstanceでCMainFrameをnewしてCreateしてShowWindowしている
だけですね。

そしてCMainFrameの中で、View、ToolBar、StatusBarをCreateしています。
(ViewはCViewの派生ではなく、単なるCWnd派生です。)
もしToolBarやStatusBarが要らなければ、メンバにしなければいいだけの話です。
他に必要なものがあれば(例えばCDialogBarとか)、メンバにしてあげればいいん
ですよね。
CMainFrameとCDialogの両方を切り替えて使いたいのでしたら、
両方をもCreateして
ShowWindow(SW_SHOW)
ShowWindow(SW_HIDE)
をAppにコントロールさせる(Appに独自の関数を追加する)ことで実現できます。

hanabi 2003/09/04(木) 10:25:14
返事が遅くなり申し訳ありません。
Daisukeさんアドバイスありがとうございます。
説明がとてもわかりやすく、大変参考になりました。

>CMainFrameとCDialogの両方を切り替えて使いたいのでしたら
というのは、前の方で質問した「ダイアログの消去」の方法なのでしょうか?
ShowWindow(SW_HIDE)はウインドウを非表示にする関数だと書いてありましたが、
消去というのは非表示にするだけでいいのですか?
イメージ的には作ったものはちゃんと消さないと、と考えてしまったので(^_^;

質問ばかりで申し訳ありませんが、よろしくお願いいたします。

Daisuke 2003/09/04(木) 11:17:12
>イメージ的には作ったものはちゃんと消さないと、と考えてしまったので(^_^;
作ったものはちゃんと消してください。(^^ゞ
(もっともスコープを外れる時にデストラクタで消えるでしょうから消す作業を
明記する必要はありませんが)

"後からもう一回このダイアログ出したい、そしてMainFrameはその時隠したい"
とかいう場合には...と思ったまでです。

Daisuke 2003/09/04(木) 12:03:44
ダイアログは一回しか表示しないのであれば、

1.後から表示したいウィンドウのプロジェクトを作る。
2.ダイアログクラスを追加する。
3.AppのInitInstance内の、CMainFrameを作る記述の前で、ダイアログを実体化し、
  DoModalする。

で実現できます。つまりダイアログが破棄されて(DoModalが終了して)はじめて、
"本来のウィンドウを作る作業が始まる"ということになります。

hanabi 2003/09/05(金) 17:09:09
Daisukeさんありがとうございます。

ふと思ったのですが、毎回AppのInitInstance内で処理を追加してますが、
そこ以外のとこに処理を書いても実行できるのでしょうか?

例えばメニューからダイアログを開き、ボタンを押すとウインドウが出る
というプログラムの場合も同じようにAppのInitInstance内に処理を書けばいいのですか?

Daisuke 2003/09/05(金) 23:02:45
試しにやってみたらいかがですか。
InitInstanceで作るのは、メインのウィンドウだけです。唯一のウィンドウとして
使用される様でしたので、そうしたほうがいいかなと思いました。

モードレスのウィンドウなら任意の場所で出せますよ。(モーダルは自分で実装する必要が
あります。)

但し、hanabiさんの書かれている
>例えばメニューからダイアログを開き、ボタンを押すとウインドウが出る

という場合には、親子関係をきちんと処理しないと思った通りの動きにならないかも
しれません。
親をメインウィンドウの方にするか、ダイアログにするかで、動作が違います。
ダイアログが閉じてもそのウィンドウが閉じてほしくないのでしたら、親をメインウィンドウ
にする必要がありますね。(そしてポインタも保存しておく必要があります。)
親をNULLにするとメインウィンドウと兄弟関係になります。この際の動きもビミョーで
しょうね。
while文でまわしてシステムダウンさせる様なウィルスまがいのプログラムは
くれぐれも作らないように。(^^ゞ

hanabi 2003/09/09(火) 11:15:37
[[解決]]
Daisukeさん、長々とお付き合いいただいてどうもありがとうございました。

今回大変勉強になりました。
ためしにやってみたのですが、まだまだよくわかってないところが多く、
どこがどう処理しているのか理解できてないところが多いですが、
もっと勉強して、理解できるようにがんばっていきます。

古いスレッドには追加発言できません。