HOME     メール  

Links:

最近の投稿

カテゴリー

広告

サイト内検索

外部リンク

アーカイブ

広告

お知らせ

class CResizablePropertySheet

これはプロパティーシートをリサイズ可能にするMFCの派生クラスです。既存のCPropertySheetをCResizablePropertySheetに変えるだけでリサイズ可能になります。
中のコントロールのレイアウトはクラス内で最適な位置に移動し、リサイズします。

ダウンロードはここから

正直、MFCでこのような機能が存在していれば、こんなものを作らなくていいのですから、やりたくはなかった。
ある程度出来た後、Webで調べたら、なんと、ダイアログはリサイズできると判明したので、「しまった!」と思ったのですが、やっぱりプロパティシートはリサイズできないので作る意味はあった。
でも、それでもMFCのダイアログで出来てしまのなら、プロパティシートに対応するのは大したことはでありません。(やっぱり骨折り損のくたびれ儲けか?)

私はこのコードを作るのに一週間以上はかかってしまった。やめようかと何度も思ったぐらい訳が分からない挙動に悩まされてしまった。
Windowsのリサイズできるファイルダイアログの動きを見れば、アルゴリズムは大したことないと思ったのに、実際は数多くの場合分けが必要で、頭がこんがらがってしまってばかり。

でもMFCのダイアログのリサイズは、指定が柔軟過ぎて、設定が面倒です。つまり、ダイアログ内のコントロール(ボタンやエディットボックスなどの事)ごとに、移動やリサイズの指定をいちいち設定しなくてはならないのです。(VisualStudioのコントロールのプロパティで「動的レイアウト」という項目をいじれば出来てしまう!。知らなかった。こういう拡張の仕方は気づきにくいよ…)

しかもその指定が実際の使用上、あり得ない動きを指定できるので、ライブラリの設計として良いとは思えません。加えて、この指定はリソースファイルに書かれるのですが、MFCでしか解釈できない情報となるので、移植はほぼ無理だと思われます。一方私が今回作成したCResizablePropertySheetは、レイアウトは自動でクラス内で完結しており、他の高級言語でも比較的容易に移植ができるでしょう。コードの中身はMFCの部分は少なく、あえてWin32APIで記述してあるので、理解は容易だと思われます。(移植する人はいるのかは知らないが)
CDialogなどに対応した奴も作ろうかと思いましたが、移植は簡単で、それにMFCで既にできているのでやめました。

他、機能としては
1.マウス左ボタンをタイトルバー上でダブルクリックすると、全画面表示なる。もう一回ダブルクリックすると元通りになる。
2.幅の変更だけ行えるオプションがある.(メンバ変数OnlyWidthをTRUEにする)
3.周りのサイズだけ変更するオプションがある(メンバ変数OnlyAroundをTRUEにする)。つまり、コントロールの移動やリサイズはMFCの機能を使う
4.起動時にサイズを指定できる(メンバ変数current_sizeにスクリーン座標の矩形を入力)

その他注意点
1.タイトルバー上部のリサイズアイコン表示時にダブルクリックして高さだけ最大限になるWindows10の機能は削除してある
2.VisualStudioやMFCで動的レイアウト項目を有効にしないでください。仮に有効にした場合の動作は私はチェックしていません。それをしたい場合、OnlyAroundをTRUEにしてください。
3.最初のプロパティーシートのサイズより小さいサイズにはリサイズできません。無理にそうすると中のコントロールの配置がおかしくなります。
 ですので、小さいサイズでの使用も考えた場合、最初のプロパティページのサイズは小さくしてください

簡単なアルゴリズムの説明
ダイアログを4つに区切って、(田んぼの田をイメージ)、各コントロールがその4つの四角のどの位置に乗っているかで、リサイズするか、移動するかを決めています。
複数の四角にまたがっているコントロールはリサイズされます。4つの四角にまたがっているコントロールは縦横ともリサイズされます。2つの場合、縦長もしくは横長になります。
4つの四角のいずれかに収まっているコントロールはリサイズしません。つまり、リサイズしたくないコントロールは4隅に置いてください。

ファイル一覧
ResizablePropertySheet.cpp (本体)
ResizablePropertySheet.h (ヘッダ)

(当然ながら使用にはMFCが必須です。)

サンプルは以下のサイトにあったリサイズダイアログのサンプルプロジェクトに付け加えたものになります。
https://mariusbancila.ro/blog/2015/07/27/dynamic-dialog-layout-for-mfc-in-visual-c-2015/

最初に出てくるダイアログの右上に「PropertySheet」というボタン部分を押せば、このクラス上で動く、プロパティシートが現れます。

最後に

このクラスは自由に使って構いません。


(追記2/4)

ウイザード形式だと初期リリースではうまくいかないことが分かりました。次のページに変わる時、勝手にそのページの枠のサイズを元に戻してしまうのです。当初の目的がウイザード形式対応だったので、本当に腹立たしいのですが、後で時間差を置いて元通りにするように改変しました。非常にセコいやり方ですが、サイズ変更を直前で阻止する方法を知りません。プロパティーシートのウィンドウクラスをサブクラス化してやればできるかもしれませんが…

また、この問題を発見時、SDKのヘッダファイルを見て分かったのですが、WindowsはAeroウイザード形式( PSH_AEROWIZARD )だとリサイズ指定( PSH_RESIZABLE )が正式に対応していることが分かりました。SDKヘッダファイルは実際は実装されていないシンボルなどがあるのですが、これは違いました。しかも腹立たしい事に、それが分かったのは個人のホームページであり、Microsoftのドキュメントでは見つけられないのです。MFCのソースコードを見ると、プロパティシート関連のコード内にダイアログコントロールの動的レイアウトに関連するコードがたくさん記述されているのに、実際は極めて限定的な指定しか使えないのはいい加減な実装としか言いようがありません。

この Aeroウイザード 形式を指定すると、見た目が大幅に変わってしまい、戻るに相当するボタンが上についていて、既に作ったものと統一感が無くなるので、最初このオプションで済まそうかと思いましたが、やめました。

ちなみに PSH_AEROWIZARD を指定すると、このクラスは全く機能しません。この指定に PSH_RESIZABLE を追加指定し、ダイアログの各コントロールの動的レイアウト項目を操作する事で初めてウイザード形式でリサイズできます。Windowsで正式にリサイズできるプロパティーシートは知っている限りこの指定だけです)(追記2/4終わり)

追記2/13

最大化処理の振る舞いをWindowsの基本的な振る舞いにした。最大化時、タスクバーのサイズ分がかぶっていた問題を修正