MFC

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ざこ

MFC

#1

投稿記事 by ざこ » 15年前

MFCのダイアログサイズの変更の仕方がわかりません。
プログラムのときには端っこドラッグして引っ張れば大きくなったら小さくなったりできますが
ビルド→実行してからだとサイズが変更できないです。ウィンドウの大きさにあわせてダイアログ内のアイテムの位置が変わるようにしたいのですが調べてもわかりません。教えて下さい。

Mist

Re:MFC

#2

投稿記事 by Mist » 15年前

ググる先生を有効活用しましょう。

http://7ujm.net/vc.html

の真ん中くらい。

ま~く

Re:MFC

#3

投稿記事 by ま~く » 15年前

ちょっと意味がわからないのですが、ダイアログのリソースでボーダーを「サイズ変更枠」にするのではなく、動的にサイズ変更可能にしたいのですか?

*リース作成時に変更可能とする場合
ダイアログのプロパティにボーダー属性があるので、それを「サイズ変更枠」にする

*動的に変更可能とする場合
ModifyStyle で WS_THICKFRAMEを指定
ただし、システムメニューに「サイズ変更」がない状態なので、必要であればメニューに
SC_SIZEを追加する。


ダイアログ内のコントロールを再配置する場合は、WM_SIZE等のメッセージハンドラ内で
コントロールを移動すればよいと思います。
MoveWindow、SetWindowPosなどで

ざこ

Re:MFC

#4

投稿記事 by ざこ » 15年前

まだその辺の単語うまく理解できてないんですが
ダイアログベースとかでプログラムを組みビルドして実行するとダイアログでてきますよね。
そのときにサイズ変更したいんです。プログラム内でサイズ変えるのではなくて実行してから画面の
端っこをひっぱりして変更したいのですができないのかな?もしかして。その可能性を考えてませんでした。
ModifyStyle で WS_THICKFRAMEはやってみたいんですけどどうもうまくいかなかったですね。
Mistさんの張られているHPも見たんですけどわからなかったです。

ま~く

Re:MFC

#5

投稿記事 by ま~く » 15年前

とりあえず、リソースで設定しておきたいと判断します^^;

ダイアログのリソース編集ってわかりますか?
ダイアログにコントロールをぺたぺた貼り付けられる画面のことです。
(VCの中に出てくるやつです)

あ・・VCのバージョンはいくつですか?

Mist

Re:MFC

#6

投稿記事 by Mist » 15年前

あ~、言いたいことが理解できた。

出来るダイアログボックスと、できないダイアログボックスがあるみたい。

http://www.relief.jp/itnote/archives/001030.php

試してないけど、やり方はこれかしら。

http://mcn.oops.jp/wiki/index.php?%B2%B ... A%EE%C0%AE(MFC)

Mist

Re:MFC

#7

投稿記事 by Mist » 15年前

あ、下のアドレスは(MFC)というところまでアドレスに含まれていないと表示できません。

ざこ

Re:MFC

#8

投稿記事 by ざこ » 15年前

多分mistさんのが正解だと思います。ちょっと試せる環境にないので明日試してみますね。
バージョンはVC++6.0です
そのペタペタのほうじゃなくて実際に動かしてみる時ですね。ペタペタはるときにダイアログを伸ばしたり
縮めたりするのはできるんですけどね。プログラムではなく手動です。
ありがとうございました。

ま~く

Re:MFC

#9

投稿記事 by ま~く » 15年前

うわ><まだ理解できない僕って・・・

Mistさんの提示したURLを確認したんですけど、コモンダイアログの事ですか?
下のURLは最初にぼくが説明した感じだし・・・

ざこ

Re:MFC

#10

投稿記事 by ざこ » 15年前

いや私の説明が悪いんです。御二方共わかりずらそうでしたのでそうだと思います。
ま~くさんに教えていただいたのとmistさんに教えていただいたのを検証して取り組んで見ます。
普通のダイアログの方かなとは思います。下の方のURLだったと思うのでま~くさんに説明していただいたとおりかな?まぁ明日試してわからなかったら最後質問させていただきます。

toyo

Re:MFC

#11

投稿記事 by toyo » 15年前

「サイズ枠変更」はこれのことですよ

ざこ

Re:MFC

#12

投稿記事 by ざこ » 15年前

上記のやり方でできました。ありがとうございました。
後はサイズ変更に伴ってボタンの位置も移動する方法ですがま~くさんの意見やmistさんに貼り付けていただいたサイトがまさにこれっぽいので試して見ます。

ざこ

Re:MFC

#13

投稿記事 by ざこ » 15年前

お二方の意見を参考にしてとあるhpに
フォームのリサイズと同じ比率でコントロールをリサイズします

bool flg = false;//起動時にイベントが発生してサイズを変えると落ちるため、回避のためのフラグ
void CtestDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	// TODO: この位置にメッセージ ハンドラ用のコードを追加してください

	if(flg) GetDlgItem(IDC_STATIC)->MoveWindow(cx/10,cy/10, cx/2,cy/2);//動的なサイズの変更
	flg = true;
}
とやり方が載ってました。これかなと思って試した結果サイズを変更しようと端をドラッグすると
問題が発生しました。作業を終了します
となります。やり方がおかしいのでしょうか?
※上記のソースはdialogのクラスでWM_SIZEのメッセージを使ってます。

ま~く

Re:MFC

#14

投稿記事 by ま~く » 15年前

できてよかったですね^^

問題はIDC_STATICにあると思います。
IDC_STATICではコントロールを特定できないので、
たとえば IDC_LABEL1 のように 別のIDをつけてみてください。

ちなみに flg による判定はうまくいくと思いますが、見た感じが微妙ですね^^;

ざこ

Re:MFC

#15

投稿記事 by ざこ » 15年前

とんでもないことに気づきました。そのままパクッて貼り付けたんですがSTATICをダイアログ内で使用してませんでした・・
それでif(flg) GetDlgItem(IDC_STATIC)->MoveWindow(cx/10,cy/10, cx/2,cy/2);//動的なサイズの変更を

if(flg) GetDlgItem(IDC_IDOK)->MoveWindow(cx/10,cy/10, cx/2,cy/2);//動的なサイズの変更
if(flg) GetDlgItem(IDC_CANCEL)->MoveWindow(cx/10,cy/10, cx/2,cy/2);//動的なサイズの変更
if(flg) GetDlgItem(IDC_LIST1)->MoveWindow(cx/10,cy/10, cx/2,cy/2);//動的なサイズの変更

にすると今度はドラッグする前、
詳しくは今SDIベースでメニューのとある欄を押すとダイアログが表示され、そのダイアログをいじくったりの作業を
今しています。それでメニューの所を押した時点で問題が発生しました。作業を終了します
とでます。何が問題なのかさっぱりです。

バグ

Re:MFC

#16

投稿記事 by バグ » 15年前

flg変数は、OnSize関数の中で毎回trueにしなくても、OnInitDialog関数の中で一度だけtrueにしてやればいいと思いますよ(^-^)

OnInitDialog関数の中でButtonやStaticなんかのコントロールの初期化を行っているようなので、この初期化が終了してしまわない内に、コントロールに対して何か操作しようとするとエラーが出るようです。

バグ

Re:MFC

#17

投稿記事 by バグ » 15年前

あ、追記です。
前述のflg変数ですが、Dialogクラスにメンバ変数として追加しておいた方がよいですよ。
グローバル変数でも構わないといえばそうなのですが、Dialog内でしか使わないものですから、Dialog内でしか使えないようにしておいた方が、可読性の向上を考えると良いと思います。

ざこ

Re:MFC

#18

投稿記事 by ざこ » 15年前

なんとかできました。最後の作業なんですが1度起動してダイアログのサイズを変更して終了します。
次また起動したときに終了したサイズで始める。というプログラム取り入れたいんです。最初は一定の値いれといて終了時にウィンドウのサイズをどっかに入れ次回起動時にそのサイズではじめる という感じかなとは思いますが
プログラムって1回終了したらデータ失われますよね。失われず続きからできるなら上記の作業いらないのかな
とは思います。お手数ですが教えて下さい。

バグ

Re:MFC

#19

投稿記事 by バグ » 15年前

ファイルにTop, Bottom, Left, Rightの値を保存しておくのがいいかと思います。
で、ダイアログを閉じる際のイベントハンドラ内(OnCloseとかOnDestroyかな?)で、値を更新保存する…というのでいけるんではないでしょうか?

ざこ

Re:MFC

#20

投稿記事 by ざこ » 15年前

どうやらレジストリというものを使うっぽいのでちょっと勉強してみます。

Mist

Re:MFC

#21

投稿記事 by Mist » 15年前

勉強のために作られているソフトだったらいいんですけど、完成後他の人に使ってもらうことを考えておられるのであればなるべくレジストリは使わないほうがいいと思います。
(テキストファイルやバイナリファイルで十分な気もします)

理由は
1.レジストリに設定を残す(=レジストリを汚す)ソフトは嫌われる傾向にある
  このソフトがレジストリを使用していることの銘記は必要になる
  よほどのことがない限り大丈夫と思いますが、レジストリを破壊するようなことがあるとOS再インストールということになる
2.アンインストール時に、レジストリから情報を消す手段が必要になる
  アンインストーラが必要になる
  レジストリを使用していなければ実行ファイルのフォルダ丸ごと削除だけですむ
3.他のPCで同じソフトを使用したい場合に設定を引き継がせにくい

特にVistaだとUACの影響でレジストリが使えなかったり、仮想化されてXPとは違う動きになったりしますしね。

ざこ

Re:MFC

#22

投稿記事 by ざこ » 15年前

.iniファイルに保存する形式にしました。まず初期サイズ作ってたんです。
DialongクラスにOnInitDailog関数作ってそこで
CRect WinRect;
WinRect.left=AfxGetApp()->GetProfileInt("memo","left",200);
WinRect.top=AfxGetApp()->GetProfileInt("memo","top",200);
WinRect.left=AfxGetApp()->GetProfileInt("memo","right",622);
WinRect.bottom=AfxGetApp()->GetProfileInt("memo","bottom",310);
MoveWindow(WinRect);
としてたんです。これで初期設定は出来ていました。

それでその後にです。ダイアログが閉じるときにそのサイズを保存しようとして
ダイアログのクラスにOnDestroy関数つくりそこに
CRect WinRect;
WinRect.left=AfxGetApp()->WriteProfileInt("memo","left",WinRect.left);
WinRect.top=AfxGetApp()->WriteProfileInt("memo","top",WinRect.top);
WinRect.left=AfxGetApp()->WriteProfileInt("memo","right",WinRect.right);
WinRect.bottom=AfxGetApp()->WriteProfileInt("memo","bottom",WinRect.bottom);
MoveWindow(WinRect);


としたんです。すると意味不明なことに
メニューから【ダイアログ】←※メニューからダイアログを呼びだす場所
押すとプログラムが動かなく閉じることもできなくなります。再起動してDestroy関数を消去しても同じ結果になり
InitDialogの方消せば動かなくなるのは止まりました。何が悪いのでしょうか?

バグ

Re:MFC

#23

投稿記事 by バグ » 15年前

ちなみに、WinRectに数値は入っているんですよね?

ざこ

Re:MFC

#24

投稿記事 by ざこ » 15年前

動かなくなるのは私のミスだと思います。ただ間違いはDestoy関数なはずなのに何故消去してもなるのかと・・
>>CRect WinRect;
WinRect.left=AfxGetApp()->WriteProfileInt("memo","left",WinRect.left);
WinRect.top=AfxGetApp()->WriteProfileInt("memo","top",WinRect.top);
WinRect.left=AfxGetApp()->WriteProfileInt("memo","right",WinRect.right);
WinRect.bottom=AfxGetApp()->WriteProfileInt("memo","bottom",WinRect.bottom);
MoveWindow(WinRect);

の部分を

CRect WinRect;
GetWindowRect(&WinRect);
AfxGetApp()->WriteProfileInt("memo","left",WinRect.left);
AfxGetApp()->WriteProfileInt("memo","top",WinRect.top);
AfxGetApp()->WriteProfileInt("memo","right",WinRect.right);
AfxGetApp()->WriteProfileInt("memo","bottom",WinRect.bottom);
にしました。するととりあえずおかしくなることはなくなりました。

>>WinRectに数値は入っているんですよね?
Destroyの中のWinRectの中を見るとちゃんとサイズ変更した値が入っていました。
ちゃんと起動しました。ありがとうございました。

バグ

Re:MFC

#25

投稿記事 by バグ » 15年前

ソースの全体を見ていないので推測ですが、OnDestroyの中でMoveWindowを呼び出していたのが原因ではないかと思います。既に破棄されたWindowに対して、なんらかの処理を行おうとしたために暴走してしまったのではないでしょうか?

バグ

Re:MFC

#26

投稿記事 by バグ » 15年前

あと1つ気になったんですが、iniファイルに書き込むのって、WriteProfileIntでいいんでしたっけ?
WritePrivateProfileStringじゃなかったっかな?違ってたらすみません(^_^;)

ざこ

Re:MFC

#27

投稿記事 by ざこ » 15年前

これは"新VisualC++6.0 入門シニア偏"に載っていました。
その方法でもできるかもしれませんね。ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る