
現在、MFCで検索プログラムを作成しています。
始めはDoModalで作成していたのですが、ダイアログを閉じずに、ダイアログを複数並べて見たいという意見が出た為、モードレスで作成し直そうとしたところ、ダイアログが現れてくれません。
インターネットで見つけたソースを試してみたのですが、上手くいきません。
どなたか教えて頂けますか?
=ダイアログに移るボタンコードに=
CDlg1 dlg;
dlg.Create(IDD_DIALOG1, this);
dlg.ShowWindow(SW_SHOW);
(dlg.DestroyWindow();は他に記述)
1.
上記では、ShowWindowに0が返ってしまい、一瞬ダイアログが映って
消えてしまいます。Createは1が返ってるのでいいかと思いますが…。
2.
あと、違うソースで試したところ、ダイアログは表示できるものの、
一回消してしまうと、もう一度ボタンを押しても再度は表示されません。
しかも、Destroy()を設定したOKボタンでは強制終了となってしまいます。
モードレスで作成すると、一回そのダイアログを消してしまうと再度表示ができないのでしょうか?
モードレスってただ他の処理ができるというだけで、そのダイアログを何枚も表示させておくことはできないのでしょうか?
3.
このダイアログにjpegファイルを表示させているのですが、ダイアログベース・htmlView以外で表示させれる方法がありましたら教えて下さい。
よろしくお願いします。
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
もし作成したダイアログのポインタを削除する為だけにポインタ配列を用意する
のでしたら変わりにこんな方法もあります。
CMyDialog::PostNcDestroy()をオーバーライド
CMyDialog::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
}
こうすればモードレスダイアログが閉じられた時に自動でメモリも削除されるし
楽かなと思いますけど。
とりあえず参考まで...
No.5
- 回答日時:
こんにちは。
itohhといいます。その後、進展はありましたか?
もし、まだ悩んでいるようでしたら、子ダイアログのオブジェクトを配列で持つときの注意点を。
1.上限を決めたとき、それ以上はダイアログが表示されないようにする。
2.子ダイアログを閉じたとき、配列のどの位置のオブジェクトを削除するかわかるようにする。
3.親ウィンドウが終了するときには、子ダイアログはすべて閉じてオブジェクトもすべて
削除しなければいけない。
大まかに注意事項を上げるとするとこんなところでしょうか。
配列で管理する場合、配列の添字の管理が難しいと思います、配列の何番目がどの子ダイアログ
なのかとか、配列の空きはあるのかとかです。
配列の代わりとしてCObArrayクラスから派生させてコレクションにするという手もあります。
わからないところがあれば再度、補足をしてください、出来る範囲でお手伝いしますよ。
これからも頑張ってください。
No.4
- 回答日時:
> このやり方が一般的と考えていいのでしょうか?
newで実体を得る方法が一般的ですが、ポインタ変数をグローバル化してしまうのはお行儀が悪い気がします。
グローバル変数ではなく、親ウィンドウ(ダイアログ?)クラスのメンバ変数にしてしまうのがスマートではないかと思います(^_^;
> これは、グローバル変数のところで、dlg[10]のように枚数分設定しておくということなのでしょうか?
あらかじめ枚数が分かっているならそれでも良いと思います。その場合は、枚数の上限を超えて開かれないようにチェックしないといけませんね。
枚数が不定の場合にはリスト構造等でポインタ変数を動的に管理すれば可能だと思います。
要は作ったダイアログ(自分で確保したメモリ)全てを、終了時に確実に破棄できれば良いだけなので、自分で管理しやすいデータ構造を選べばいいと思いますよ。
返答ありがとうございます!
お礼が遅くなってしまって申し訳ありません。
>グローバル変数ではなく、親ウィンドウ(ダイアログ?)クラスのメンバ変数にして>しまうのがスマートではないかと思います(^_^;
すいません、ついついグローバル変数と書いてしまいました。(・・;
メンバ変数のことですよね。
ローカルにしたり、グローバルと言ったり…。
あまりに知らなくて申し訳ないのですが、
リスト構造、データ構造…今の私のレベルからだとかなり難しいことのように
思えます。
枚数を決めてみたものの、変数が登場する度に[]の中の数字をどうするのか
??です。[]の中にint型変数をいれて管理するのでしょうか??
No.3
- 回答日時:
こんにちは。
itohhといいます。動きましたか。良かったですね。(^_^)v
>表示の際のif文3つ{ return;}のところ、削除しました。
これのことでしょうか?
if(pDlgMless->GetSafeHwnd()) {
if(::IsWindow(pDlgMless->m_hWnd)) {
if(pDlgMless->IsWindowVisible()) {
//破棄部分pDlgMless->DestroyWindow();
return;
// returnで脱出しているのに注意。
}
}
}
これは一度、作成されている場合は再作成しないためです。
ですので、これを削除してしまうと、このあとにある
//生成部分
pDlgMless=new CDlgMless(this);
pDlgMless->ShowWindow(SW_SHOW);
で、一つの変数に2個、3個と上書きしていきますからメモリーリークを起こしますよ。
(deleteすることが出来なくなると言うことです。)
(注)関数はMSDNライブラリを参照しましょう。
返答ありがとうございます!
お礼が遅くなってしまって申し訳ありません。
一難去ってまた一難ってかんじです..。(;_;)
>で、一つの変数に2個、3個と上書きしていきますからメモリーリークを起こし>ますよ。
>(deleteすることが出来なくなると言うことです。)
この場合、どうしたらいいのでしょうか??
漠然とした質問で申し訳ありません…。
実はまだプログラムを始めたばかりで、何がどうなっているのか
解らない状態です。
ダイアログを作る度に、変数のアドレスが移動して、deleteできないっていう理解でいいのでしょうか?
今、子ダイアログのほうにdeleteが設定してあるのですが、どこにdeleteを設定していようと、変数が一つなら必ずメモリーリークが起きるということでしょうか?
No.2
- 回答日時:
こんにちは。
itohhといいます。モードレスで作成するのは、結構めんどくさいですよ。
(どのタイミングでWindowを作るのかとか、消す方法は?とか。)
サンプルを作成しようかとも思いましたが、
解説しているHPがありますので、そちらを参照してください。
URL:http://www2s.biglobe.ne.jp/%7Emaekawa/dev/vc/dia …
参考URL:http://www2s.biglobe.ne.jp/%7Emaekawa/dev/vc/dia …
早速の回答、ありがとうございます!!
教えて頂いたHPのソースで作ってみたら、上手くいきました!
解り易いHPですね!
ただ、同じダイアログを複数表示したかったので、
表示の際のif文3つ{ return;}のところ、削除しました。
今のところ問題は無さそうなのですが、このif文は何の為にあるのでしょうか?
No.1
- 回答日時:
ダイアログクラスの実体がローカル変数として宣言されているので、その関数を抜けた時点でウィンドウとメモリが破棄されているだけでは?
この場合はCDlg1型ポインタをメンバ変数で用意しておき、newでインスタンスを得るのが一般的だと思います。
(ダイアログが不要になった場合は、DestroyWindow()後、deleteで破棄します。)
モードレスダイアログを何枚も開く場合は、ポインタ変数の管理が必要ですね。
JPEGファイル表示のほうはネット上にライブラリやソースが落ちてるので、それを参考に自前で表示処理を書いてあげれば可能だと思います。
早速の回答ありがとうございます!!
仰る通り、ローカル変数が原因でした。
CDlg1* dlg; とグローバル変数にし、
dlg = new CDlg1(this);
dlg->ShowWindow(SW_SHOW); としたら上手くいきました!
このやり方が一般的と考えていいのでしょうか?
>モードレスダイアログを何枚も開く場合は、ポインタ変数の管理が必要ですね。
これは、グローバル変数のところで、dlg[10]のように枚数分設定しておくという
ことなのでしょうか?
ポインタがイマイチよく解っていないので、申し訳ありませんが教えて頂けますでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
UpdateData( FALSE); による文字列データの表示更新(VC++6.0)
C言語・C++・C#
-
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
-
4
ラベル(スタティックテキスト)内での改行。
C言語・C++・C#
-
5
ダイアログ表示時にチェックボックスにチェックされている状態にするには?
C言語・C++・C#
-
6
ボタンの配置を変更したい
C言語・C++・C#
-
7
MFC ダイアログ上のID取得について
C言語・C++・C#
-
8
エディットボックスの入力制限について
C言語・C++・C#
-
9
MFC モードレスDlgについて
C言語・C++・C#
-
10
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
11
メッセージハンドラ
C言語・C++・C#
-
12
リストビューのスクロールバーを非表示にしたい
C言語・C++・C#
-
13
MFCでコンボボックスを選択不可状態にしたい
C言語・C++・C#
-
14
デバッグ中のエラーのことで教えてください。
C言語・C++・C#
-
15
ビジュアルC++でボタンの有効/無効
C言語・C++・C#
-
16
起動時に何のダイアログも表示されない
C言語・C++・C#
-
17
エディットコントロールでEnter押した時の動作
C言語・C++・C#
-
18
CEdit の内容が変わった時にメッセージを表示させたい
C言語・C++・C#
-
19
MFCでOnPaintのタイミング
C言語・C++・C#
-
20
CString から LPCTSTRの型に変換
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
キーボードのキー配列について
-
【速いブラインドタッチ】手を...
-
先頭アドレスとは何ですか?
-
プログラムの作り方
-
EXCEL2000
-
メモリの初期値
-
次のプログラムが作れません…
-
[Fortran]VBでいうRedim Preserve
-
C# Listを使わずに2次元配列の...
-
C言語 少しの疑問
-
ポインタの配列のコンマについて
-
FORTRAN77の配列(除算)
-
LGノートPCグラムについて
-
プログラミングの課題で「5人分...
-
配列を使わずに、変数名を動的...
-
C++ vectorに配列をプッシュしたい
-
Functionの戻り値を2次元配列...
-
C言語初心者 構造体 課題について
-
C言語のプログラムで配列につい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
C# Listを使わずに2次元配列の...
-
配列を使わずに、変数名を動的...
-
配列で格納したものをmsgboxで...
-
【速いブラインドタッチ】手を...
-
配列をEraseしてもメモリが開放...
-
ExcelVBAで質問です。離れた二...
-
Redimした動的配列はEraseする...
-
C# 配列の変数宣言について。
-
複数の選択範囲の行番号を個別...
-
VBで構造体の配列を関数に渡す...
-
先頭アドレスとは何ですか?
-
配列の参照渡しで型が一致しま...
-
銀行ATMの数字キーの配列
-
配列を含む構造体の初期値について
-
C言語で特定列だけを抽出して配...
-
unsigned char配列への入力の仕方
-
VB.NET 構造体の配列の検索機能...
-
C++ vectorに配列をプッシュしたい
-
C言語初心者 構造体 課題について
おすすめ情報