お世話になります。
現在MFCのダイアログベースアプリケーションを作成しており、ダイアログ上に大小さまざまフォントのスタティックテキストを貼り付けています。
さまざまフォントがあるということは、それだけスタティックテキストに割り当てるCFontも多数作らなければならないと思います。

そこで質問なのですが、
この大小さまざまな(約5種類ほど)のフォントのスタティックテキストを、複数のダイアログで貼り付けようと思っているのですが、その際にダイアログ毎にメンバ変数としてCFontを5種類定義するのと、5種類のサイズ用のCStaticのクラスを作成し、それらを複数のダイアログに貼り付けるのとどちらがよいでしょうか?

クラスをむやみに増やすのもプログラムが見づらくなる気もしますし、ダイアログ毎にその都度CFontをCreateFontするのも面倒かなと思い、質問させて頂きました。

ご意見をよろしくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (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()を乗っ取ったら、他の場所で何やっても無駄」って事で、フォントを削除しても描画には何の影響も出ません。
    • good
    • 0
この回答へのお礼

理解が間違っていたらすみません。
とういうことは、ダイアログのOnPaint()に描画の処理やらを書くのではなく、CStatic継承のオリジナルのクラスを作成し、そのオリジナルクラスのOnPaint()内にフォントの設定等を書けばよいということでしょうか?
それだと、フォントの種類が様々ある場合、それに対応した複数のクラスを作成するか、フォントのサイズ等を引数としてそのクラスに渡すような処理が必要となるということでしょうか?

お礼日時:2009/05/29 12:03

要は「リソースの保持期間が重要なのでは」と思います。



「リソースは必要な期間のみ保持すべき」と言う点から言えば

>ダイアログ毎にその都度CFontをCreateFontする

のと、ダイアログをクローズしたら作成したCFontを破棄する、と言うのを行うのが良いと思います。

処理が多少重くなりますが、1度使用したフォントはフォントキャッシュに残っているだろうし「激しく重い」までは行かない筈です。

ホントの事を言うと「WM_PAINTメッセージを受け取って描画を行う必要がある時のみFontリソースを確保して、描画が終わったらリソースを開放、そうじゃない時(単にダイアログが開かれている最中)はFontリソースは保持してない、と言う状態がベストなんだけど。

そうすれば、同一のダイアログを数百個同時に開いても「同時にFontリソースを保持するのはWM_PAINTメッセージ処理中の数個だけ」なので「同一ダイアログを同時に100個くらい開いたら、リソースが不足してアプリが落ちる」と言う危険も減ります(一番危険なのは「同時に開けるデバイスコンテキストの少なさ」なんだけど、それは別の話)
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。

>ホントの事を言うと「WM_PAINTメッセージを受け取って描画を行う必要がある時のみFontリソースを確保して、描画が終わったらリソースを開放、そうじゃない時(単にダイアログが開かれている最中)はFontリソースは保持してない、と言う状態がベストなんだけど。

確かにその方がCFontのリソースを保持している期間が短いので理想的ですよね。
しかしCPaint()内でCreateFontをして、CPaint()の最後にリソースの確保をしたCFontをDeleteObjectすると、そのフォントがダイアログに反映されないのではないでしょうか?
それともDeleteObjectではない別のコマンドを使うと、リソースの破棄ではなく解放のみが出来るのでしょうか?

お礼日時:2009/05/29 09:44

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q映画などの無料ダウンロード方法

映画などの無料ダウンロード方法
チャーリーとチョコレート工場などを無料でダウンロードしたいで無料ダウンロードできるサイトややり方を教えて下さい。
よろしくお願いします。m(__)m

Aベストアンサー

2010年の1月1日より、改正著作権法が施行されました。
これにより、音楽・動画などの著作物を権利者の許可無くアップロードしたものを
ダウンロードするだけで犯罪となります。
ただし、ストリーミングは対象外なので、動画サイトなどに違法アップロードされたものを
見ても大丈夫です…が、やはりきちんと買いましょう。

参考URL:http://d.hatena.ne.jp/nakakzs/20090518/1242657559

Qダイアログのボタンが押された時に、その「ボタン」のあるダイアログと、すでに表示されている他のダイアログを消したいです

Win2000/MFC/ダイアログベース
で作業しています。初心者です(^^;)

Aというダイアログで「あるボタンa」を押してDoModalでBというダイアログを表示させ、Bダイアログで「あるボタンb」を押してDoModalでCというダイアログを表示させ、Cダイアログで「あるボタンc」を押した時にBダイアログとCダイアログを閉じたい(消したい)のですが
EndDialogで消せません
DoModalの戻り値をret_b,ret_cとした場合
EndDialog(ret_c);
EndDialog(ret_b);
としたのですが。。。

やり方がおかしいのか、よくわかりません・・
初心者でもわかりやすいお返事お待ちしています(^^;)

Aベストアンサー

各ダイアログボックスを CDialog の派生クラスとして次のように定義したとします。

CDlgA --- A というダイアログボックス
CDlgB --- B というダイアログボックス
CDlgC --- C というダイアログボックス

CDlgA のあるメンバ関数から CDlgB::DoModal() でダイアログボックス B を表示させます。 CDlgB のあるメンバ関数で EndDialog() を実行すればダイアログボックス B を閉じることができます。ここで、 CDialog::EndDialog() は引数として INT 型の値をひとつ渡すことができますが、その値が先の CDlgB::DoModal() の戻り値となります。
戻り値がある特定の値だったとき、つまり、質問の例ではダイアログボックス B で EndDialog(ret_b) が実行されたことが特定できたときに CDlgA も EndDialog() を実行すれば連鎖してダイアログボックスを閉じることができます。
ダイアログボックス C についても同様です。

実際のコーディングでは次のようになると思います。
ただし、ダイアログボックス A もモードレスで表示されていると仮定しています。



#define ret_b (-1) // 特定の値
#define ret_c (-1) // ID_OK や ID_CANCEL と重ならないように注意

...

(CDlgA の実装)

void CDlgA::OnButtonA() // あるボタン a が押されたときの処理
{
CDlgB dlg; // ダイアログボックス B

if (dlg.DoModal() == ret_b) // モードレスで表示して、戻り値をチェック
EndDialog(-1); // ダイアログボックス A を閉じる
}

...

(CDlgB の実装)

void CDlgB::OnButtonB() // あるボタン b が押されたときの処理
{
CDlgC dlg; // ダイアログボックス C

if (dlg.DoModal() == ret_c) // モードレスで表示して、戻り値をチェック
EndDialog(ret_b); // ダイアログボックス B を閉じる
}

...

(CDlgC の実装)

void CDlgC::OnButtonC() // あるボタン c が押されたときの処理
{
EndDialog(ret_c); // ダイアログボックス C を閉じる
}

各ダイアログボックスを CDialog の派生クラスとして次のように定義したとします。

CDlgA --- A というダイアログボックス
CDlgB --- B というダイアログボックス
CDlgC --- C というダイアログボックス

CDlgA のあるメンバ関数から CDlgB::DoModal() でダイアログボックス B を表示させます。 CDlgB のあるメンバ関数で EndDialog() を実行すればダイアログボックス B を閉じることができます。ここで、 CDialog::EndDialog() は引数として INT 型の値をひとつ渡すことができますが、その値...続きを読む

Q音楽の無料ダウンロード

ナップスターなどから音楽の無料ダウンロードが出来ると聞きましたが、ネットから好きな音楽を検索し、無料ダウンロードする方法は今でもあるのでしょうか?

Aベストアンサー

ナップスターそのものに関しては今現在サービスはまだ続けているようですが、既に終わっている模様です。
その代わりナップスター互換のクローンツールが代わりに繁栄しています。
日本ではWinMXとか、海外ではまた別のソフトです。
ただこの手のソフトは身元がバレバレになってしまうので、逮捕も続出していますね。日本ではですが。

これとは別にグヌテラ互換のソフトが今後主流になっていくのではないかと言われています。

Qダイアログを継承したダイアログの作成について

お世話になります。
今回お聞きしたいことは、
オリジナルに作成したダイアログを継承したオリジナルのダイアログを作成した際に、オリジナルに作成した基底ダイアログのダイアログ上のコントロールや、そのコントロールの位置を継承することはできますでしょうか?
ということです。
何がしたいかといいますと、4つのダイアログをメインダイアログから呼び出すのですが、その4つのダイアログには共通するコントロールがあり、そのコントロールの動作もその位置も全く同じなのです。
そのため、いちいち4つのダイアログにコントロールの貼り付けや、処理を記入せずに、その共通のコントロールをもった基底ダイアログを作成して、その基底ダイアログの継承としてダイアログが作れたらなと思い、質問させて頂きました。
継承をすると、基底クラスの関数等を使うことができるというのはわかるのですが、ダイアログ上のコントロールの位置までは不可能なのかなと疑問に思いました。
ご回答を宜しくお願い致します。

開発環境は
Windows CE 6.0
Visual Studio 2005
です。

お世話になります。
今回お聞きしたいことは、
オリジナルに作成したダイアログを継承したオリジナルのダイアログを作成した際に、オリジナルに作成した基底ダイアログのダイアログ上のコントロールや、そのコントロールの位置を継承することはできますでしょうか?
ということです。
何がしたいかといいますと、4つのダイアログをメインダイアログから呼び出すのですが、その4つのダイアログには共通するコントロールがあり、そのコントロールの動作もその位置も全く同じなのです。
そのため、いちいち4つの...続きを読む

Aベストアンサー

私、CEの経験がないので厳密なところはわからないのですが、
一般的なMFCであれば、可能です。
ただし、条件により困難さが変わります

1)4つのダイアログが全て同じコントロールのみからなる場合
  コントロールは同じだが、ラベルのキャプションが違うとか
  リストボックスのデータが違うとかいう場合です。

  非常に単純です。普通の派生と全く同じ感じです
  OnInitDialog等適当な関数をオーバーライドするだけです。

2)共通のコントロール以外に独自のコントロールも持つ場合
  多少困難です
  いくつかアプローチが考えられます。
  a) ダイアログ・テンプレートを個別に持つ方法
    リソース内のダイアログ・テンプレートは(共通のコントロールも含め)
    コピー&ペーストなどで独自に作成します(4つ作ります)
それぞれを制御するクラスですが、
    ウィザードのサポートを受けられない
    (ウィザードではCDialog派生にされてしまう)
    ので、既存のCDialog派生クラスを参照して
    自力で希望のCDialog派生からさらに派生させるようにします

    リソースIDとクラスの結びつけ方法などは既存のクラスを
    参考にしてください

  b)リソースも完全に共通化する
    ちょっと難しいかもしれません。
    OnInitDialog等で自力でコントロールをCreateします。
    レイアウトが視覚的にできないので非常に困難ですが、
    隣接するコントロールの位置情報をもとに計算するなどしてください。

    ダイアログの大きさに余裕があり、
    追加するコントロールも小さなもの
    (1行のみのエディット等)であれば、
    最初から場所をstaticコントロールで場所を確保しておき
    非表示にしておいて、
    派生クラスで、そのstaticの位置を取得するとかなり楽ができます。

    派生クラスで、本格的にレイアウトが変わってしまう場合は、
    レイアウトを頭に入れながら、Createし、試行錯誤で
    完成させることになるでしょう。


以上の方法がCEでも通じるのかわかりませんが、
参考になれば幸いです。    

   

私、CEの経験がないので厳密なところはわからないのですが、
一般的なMFCであれば、可能です。
ただし、条件により困難さが変わります

1)4つのダイアログが全て同じコントロールのみからなる場合
  コントロールは同じだが、ラベルのキャプションが違うとか
  リストボックスのデータが違うとかいう場合です。

  非常に単純です。普通の派生と全く同じ感じです
  OnInitDialog等適当な関数をオーバーライドするだけです。

2)共通のコントロール以外に独自のコントロールも持つ場合
 ...続きを読む

Q無料ダウンロードの意味は

無料ダウンロードとあるので
explorer-construction1.9をダウンロードして使用してみました
http://explorer-construction.softonic.jp/
新版はシエアウエアだと認識していましたが、ここでは旧版のVer1.9のダウンロードです、
ところが使用を始めてみると「お金を払って」のメッセージがしつこくポップアップしてきます。
無料ダウンロードって何ですか?
何か詐欺まがいの気がしますが・・・・

Aベストアンサー

そこまでは無料にして体験してもらって、これ以降は有料との事で大嫌いな商売ですね。そうゆう商売の仕方を禁止にしてほしいですよ。

Q子ダイアログのデータを親ダイアログで取得するには

VC6.0にてMFCでダイアログベースアプリケーションを作成しています。

親ダイアログ(TestDlg.cpp)のメニューを選択すると、子ダイアログ(SetDlg.cpp)が開き、テキストボックスに文字を入力し、ボタン押下によりテキストボックスの入力数字を確定(グローバル変数(igStatu)に代入)しています。
子ウインドウで入力確定したデータを、親ダイアログにて使用したいのですが、データが受け渡されずに、親ダイアログ側にデータが入りません。
どのようにしたら、子ダイアログで設定したデータを親ダイアログで取得することができるのでしょうか?

C++、MFCともに全然わかっていませんがお願いします。

グローバル変数は、TestDlg.cpp、SetDlg.cppがインクルードしているTest.h内にstatic宣言しています。
static宣言しないとリンクエラー2005になってしまいます。

Aベストアンサー

Test.h内で
extern int igStatu;

TestDlg.cpp内で
int igStatu;

とすればいいのでは?
externについて調べてみてください。

参考URL:http://homepage3.nifty.com/mmgames/c_guide/20-02.html

QYouTubeから音楽無料ダウンロードについて

今パソコンにYouTubeから音楽を無料ダウンロードして、何年後か近い将来に、コンピューターが進化して、昔にYouTubeから音楽を無料ダウンロードした事がばれて、警察に逮捕される事ってありますか?

またコンピューターが人の脳を超えたら、YouTubeから音楽を無料ダウンロードした事が必ずばれて、何年後か近い将来に警察に逮捕される事ってありますか?

Aベストアンサー

 考え過ぎです。毎日1億回も視聴されているYouTubeを監視出来るわけがありません。違法ダウンロードが事件としてニュース報道された番組を見た事がありますか。そういうニュースは見掛けませんよね。

 違法ダウンロードを摘発するのは難しいのが実情です。現在の防止方法は、プロテクトをかけて、ダウンロード出来ないようにする方法ですが、それ以外の対策を取った例はほとんど無いだろうと思います。

 違法アップロードは警告を受けた後で削除され、アカウント停止で終わりのようです。違法ダウンロードを把握して訴追した事件は聞いた事が無いですね。よほど組織的にDVDやBDの違法アップロードとダウンロードを大量におこなった場合を除いて、警察の摘発までには至らないのではないでしょうか。

 そもそも現在の著作権法が前近代的で、著作権者の利益しか考えておらず、ユーザーの不利益に対する配慮に欠けているので、プロテクトを付け過ぎたBDレコーダーの販売不振などの弊害が出ているようです。

 YouTubeは基本的にダウンロードしても問題ありませんし、ダウンロード出来ない場合は違法だと判断すれば良いだけです。

 考え過ぎです。毎日1億回も視聴されているYouTubeを監視出来るわけがありません。違法ダウンロードが事件としてニュース報道された番組を見た事がありますか。そういうニュースは見掛けませんよね。

 違法ダウンロードを摘発するのは難しいのが実情です。現在の防止方法は、プロテクトをかけて、ダウンロード出来ないようにする方法ですが、それ以外の対策を取った例はほとんど無いだろうと思います。

 違法アップロードは警告を受けた後で削除され、アカウント停止で終わりのようです。違法ダウンロードを...続きを読む

QMFC・ダイアログベースで、ダイアログの変更内容が反映されない・・・

初めて質問させていただきます。よろしくお願いします。

当方、VisualStdio2005内のC++2005で、
ダイアログベースにてツールを開発していました。

ある日、ダイアログ上に多くのEditコントロールを作成(追加)することになり、
ダイアログリソースをVC内のリソースエディタにて、
テキスト形式でコントロールを追加していきました。

そのときは、テキストでの変更内容がダイアログにも反映されていたのですが、
その後はダイアログにツールボックスでのコントロールの追加やサイズ変更など、
見た目には反映されてもビルド後に反映されなくなってしまいました。

クリーン後のリビルドでも、問題は解決しません。

原因と対策をご存知の方、いらっしゃいましたらご教授いただけませんでしょうか。

よろしくお願いします。

Aベストアンサー

VC2005は初心者です。VC6.0は仕事で使っていました。

私はダイアログリソースをテキスト形式でコントロールを追加したことがないので、基本的にご期待に添える回答ではないと思いますが、ご参考までに。

回答する前に質問ですが、もっと詳しい問題の状況、状態を教えていただけませんか?「ビルド後に反映」とは?実行までおこなっていない、ということですか?

以下、回答です。

ダイアログリソースとダイアログのウィンドウの関連付けは正しいですか?ダイアログIDが間違って指定されていませんか?変更対象のダイアログとビルド後の実行したダイアログが違っているなんてことがあったりします。

上記のような間違いがなければ、Editコントロールを1つだけにしてビルド&実行してみてください。それで問題があれば、Editコントロールの書き方に問題があるかも?(いや、その場合はコンパイルでエラーになるはずだけど)。問題がなければ、Editコントロールを1つずつ増やしてビルド&実行する。ある程度増やしたら、思い切って半分くらい増やしてみたりしてもいいと思います。

VC2005は初心者です。VC6.0は仕事で使っていました。

私はダイアログリソースをテキスト形式でコントロールを追加したことがないので、基本的にご期待に添える回答ではないと思いますが、ご参考までに。

回答する前に質問ですが、もっと詳しい問題の状況、状態を教えていただけませんか?「ビルド後に反映」とは?実行までおこなっていない、ということですか?

以下、回答です。

ダイアログリソースとダイアログのウィンドウの関連付けは正しいですか?ダイアログIDが間違って指定されていませんか?...続きを読む

Qエクセル ワード の無料ダウンロード

エクセル ワード の無料ダウンロード

オフィス機能を無料ダウンロードできるところを探してます。
現在Win7なんですが、対応してるものを見つける事ができません。

仕事で使うわけではないので、最低限の機能で充分ですので何かご存知でしたら教えて下さい

Aベストアンサー

> トップのサイトは私も見つけてインストールしたのですが、ワードやエクセルの画面がどうも出ず、
  
WordやExcelはMicrosoft社の名称です。
「OpenOffice.org」のワープロソフトは「Writer」、表計算ソフトは「Calc」という名称です。
「スタート」ボタン→「すべてのプログラム」→「OpenOffice.org」→「Writer」または「Calc」の順にクリックしてみて下さい。

Q自分のプログラムで作成したダイアログのフォントサイズを知るには?

VC++ V6.00 でWindowsアプリを開発しているんですが、ひとつ悩んでいます。

あるダイアログのフォント情報を得るにはどうすればいいのでしょうか?

実はウィンドウにCFormView を使ってダイアログをそのまま表示しています。
そのウィンドウのある位置にダイアログと同じフォントで文字を表示したいのです。

Aベストアンサー

SDKなら
(HWND hDialogとして)
HFONT hFont;
LOGFONT logFont;
int nFontHeight;
hFont = SendMessage(hDialog, WM_GETFONT, 0, 0);
GetObject((HGDIOBJ)hFont, sizeof(LOGFONT), (LPVOID)&logFont);
nFontHeight = logFont.lfHeight;

MFCなら
(CDialog * pDialogとして)
LOGFONT logFont;
int nFontHeight;
pDialog->GetFont()->GetLogFont(&logFont);
nFontHeight = logFont.lfHeight;

初期化、NULLチェックなど省いてるので
適宜追加してくださいね。


人気Q&Aランキング

おすすめ情報