- ベストアンサー
ダイアログベースでの様々なフォントのスタティックテキストの貼り付け
- MFCのダイアログベースアプリケーションで、大小さまざまなフォントのスタティックテキストを貼り付ける方法について質問です。
- ダイアログ毎にメンバ変数としてCFontを5種類定義するのか、5種類のフォントサイズ用のCStaticのクラスを作成するのか、どちらが良いか悩んでいます。
- プログラムが見づらくならないように、効率的な方法をご教示いただけますか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>しかしCPaint()内でCreateFontをして、CPaint()の最後にリソースの確保をしたCFontをDeleteObjectすると、そのフォントがダイアログに反映されないのではないでしょうか? フォントがスタティックテキストに反映されるのは「スタティックテキストのCPaint()内で行った描画のみ」です。 なので、ダイアログのCPaint()を書き換えても、何の意味もありません。 つまり、 ・スタティックテキストのCPaint()をオーバーライドする ・そのCPaint()内で、CFontをCreateFontする ・スタティックテキストのDCをGetDCする。このDCは親から継承され、フォントや色などのプロパティは「スタティックテキストの親であるダイアログ」に設定されたプロパティと同じになっている筈 ・得たDCに作成したフォントを設定する ・フォントを変えたDCに対してCDC::DrawTextExで文字列を描画する←ここで行った「DCに対する描画」のみがダイアログに反映される。他の場所で描画しても、ウィンドゥが再描画された瞬間に消えてしまう。 ・GetDCしたDCをReleaseDCする←同時に使用できるDC数は非常に少ないので、これを忘れるとあっという間に破綻する ・CFontをDeleteObjectする と言う事です。 ダイアログベースでなくフォームデザイナを使ってアプリを書く場合、フォームデザイナでフォームにスタティックテキストを貼り付ける際に、Fontプロパティを「好みのフォント」にしておけば済むので、上記のような「面倒な事」は一切必要ありません。 スタティックテキストのCPaint()をオーバーライドしなかった場合、以下のようなデフォルトの描画処理が行われます。 ・スタティックテキストのDCがGetDCされる。このDCは親から継承され、フォントや色などのプロパティは「スタティックテキストの親であるダイアログ」に設定されたプロパティと同じになっている筈 ・そのDCに対してCDC::DrawTextExで文字列が描画される。つまり、スタティックテキストの親であるダイアログと同じフォントで描画される ・GetDCしたDCをReleaseDCされる 要は「CPaint()の中で描画した事がすべて」です。「そこでやったことだけ」がウィンドゥに反映され、「そこでやらなかったこと」はウィンドゥに反映されません。 CDC::DrawTextExでなく、CDC:FillRectやCDC::Polylineをやったって構いません。ともかく「そこでやった描画がすべて」です。 逆にいうと「CPaint()を乗っ取ったら、他の場所で何やっても無駄」って事で、フォントを削除しても描画には何の影響も出ません。
その他の回答 (1)
- chie65536(@chie65535)
- ベストアンサー率44% (8757/19871)
要は「リソースの保持期間が重要なのでは」と思います。 「リソースは必要な期間のみ保持すべき」と言う点から言えば >ダイアログ毎にその都度CFontをCreateFontする のと、ダイアログをクローズしたら作成したCFontを破棄する、と言うのを行うのが良いと思います。 処理が多少重くなりますが、1度使用したフォントはフォントキャッシュに残っているだろうし「激しく重い」までは行かない筈です。 ホントの事を言うと「WM_PAINTメッセージを受け取って描画を行う必要がある時のみFontリソースを確保して、描画が終わったらリソースを開放、そうじゃない時(単にダイアログが開かれている最中)はFontリソースは保持してない、と言う状態がベストなんだけど。 そうすれば、同一のダイアログを数百個同時に開いても「同時にFontリソースを保持するのはWM_PAINTメッセージ処理中の数個だけ」なので「同一ダイアログを同時に100個くらい開いたら、リソースが不足してアプリが落ちる」と言う危険も減ります(一番危険なのは「同時に開けるデバイスコンテキストの少なさ」なんだけど、それは別の話)
お礼
早速のご回答ありがとうございます。 >ホントの事を言うと「WM_PAINTメッセージを受け取って描画を行う必要がある時のみFontリソースを確保して、描画が終わったらリソースを開放、そうじゃない時(単にダイアログが開かれている最中)はFontリソースは保持してない、と言う状態がベストなんだけど。 確かにその方がCFontのリソースを保持している期間が短いので理想的ですよね。 しかしCPaint()内でCreateFontをして、CPaint()の最後にリソースの確保をしたCFontをDeleteObjectすると、そのフォントがダイアログに反映されないのではないでしょうか? それともDeleteObjectではない別のコマンドを使うと、リソースの破棄ではなく解放のみが出来るのでしょうか?
お礼
理解が間違っていたらすみません。 とういうことは、ダイアログのOnPaint()に描画の処理やらを書くのではなく、CStatic継承のオリジナルのクラスを作成し、そのオリジナルクラスのOnPaint()内にフォントの設定等を書けばよいということでしょうか? それだと、フォントの種類が様々ある場合、それに対応した複数のクラスを作成するか、フォントのサイズ等を引数としてそのクラスに渡すような処理が必要となるということでしょうか?