フォントの設定について

[戻る]
べーちゃん 2002/04/25(木) 02:28:37
はじめまして、ベーちゃんと申します。
実は過去ログを見たのですがはっきりと理解できなかったのでフォントに関して
質問させてください。

今、フォームビューを継承した画面を作っております。リソースウィンドウの
ダイアログの項目でフォームに対してフォントを設定しております。

1.このときフォームのプロパティで設定できたのはフォントのポイントサイズと
  フォント名だけですが、フォントのボールド(太字)やイタリック(斜体)を
  プロパティで指定することはできないのでしょうか。

できないと仮定して、
2.フォントをCreateするとして、CreatePointFontではやはりサイズとフォント名
  だけしか指定できないので、CreatFont, CreateFontIndirectまたは
  CreatePointFontIndirectを使うことになると思いますが、いずれもパラメータが
  多すぎて困ってしまいます。指定したいのはサイズ、フォント名とボールド、
  イタリックの有無のみで後はデフォルトのままでいいのですが、この場合でも
  すべてのパラメータに対してちゃんとした値を調べてきて設定したほうが
  よいのでしょうか。

3.::OnInitialUpdate()にてGetDlgItem(IDC_STATIC)->SetFont(&m_bFont);として
  コントロールに対してフォントを設定するとアクセス違反が発生しますが、複数の
  コントロール(特にIDC_STATICで設定しているコントロール群に対して)の
  フォントを一括して設定することは可能でしょうか。それとも、やはり
  全コントロールを個別にフォントの設定を行わなければならないのでしょうか。

開発環境はWin2000 VC6.0SP5 MFCです。

どうかよろしくお願いします。

ワルツ 2002/04/25(木) 09:35:27
2.GetFontでCFontを取得し、GetLogFontでそのフォント情報を取得する。
    それをもとに必要な構造体(LOGFONT)のメンバを設定してやる。

3.そもそも、GetDlgItem(IDC_STATIC)では該当スタティックのポインタは
    取得できない。(NULLが戻ってくる)
    GetDlgItemで取得したいなら、そのIDを適当なものにかえる必要がある。

不良PG [E-Mail] 2002/04/25(木) 11:49:46
>1.このときフォームのプロパティで設定できたのはフォントのポイントサイズと
>  フォント名だけですが、フォントのボールド(太字)やイタリック(斜体)を
>  プロパティで指定することはできないのでしょうか。
ダイアログリソースの仕様上無理です

>2.
ワルツさんの発言通り

>3.::OnInitialUpdate()にて
OnInitialUpdate()というグローバル関数は、ありません

OnInitailUpdate()または、CView::OnInitialUpdate()と記述しましょう。

>GetDlgItem(IDC_STATIC)->SetFont(&m_bFont);として
>コントロールに対してフォントを設定するとアクセス違反が発生しますが、複数の
>コントロール(特にIDC_STATICで設定しているコントロール群に対して)の
>フォントを一括して設定することは可能でしょうか。それとも、やはり
>全コントロールを個別にフォントの設定を行わなければならないのでしょうか。

IDC_STATICは、値が-1で特殊なコントロールIDですので、
IDC_STATICは、コードからは、アクセスできません

どうでも良い話ですが・・
こういう書き方をする癖をつけたほうがよろしいかと・・
CWnd* pWnd = GetDlgItem(IDC_STATIC);
if( NULL != pWnd )
{
    pWnd->SetFont(&m_bFont);
}

べーちゃん 2002/04/26(金) 11:59:46
こんばんわ、べーちゃんです。

ワルツさん、不良PCさん。ありがとうございました。

>>1.このときフォームのプロパティで設定できたのはフォントのポイントサイズと
>>  フォント名だけですが、フォントのボールド(太字)やイタリック(斜体)を
>>  プロパティで指定することはできないのでしょうか。
>ダイアログリソースの仕様上無理です

やはり抜け道はないのですね。

>2.GetFontでCFontを取得し、GetLogFontでそのフォント情報を取得する。
>    それをもとに必要な構造体(LOGFONT)のメンバを設定してやる。

手順は一応わかりました。やってみます。

>IDC_STATICは、値が-1で特殊なコントロールIDですので、
>IDC_STATICは、コードからは、アクセスできません

はい、それはうすうす感じてましたが、やはり全コントロールを個別にフォントの設定を
行わなければならないみたいですね。

それと書き方の件ですが、確かにおっしゃる通りですね。今はまだVC++始めて2週間目
なんで動くコードに気を取られすぎてエラー処理とかまで気が回ってない状態でした。
すぐには治らないかもしれませんが今後気をつけるようにします。

申し訳ないのですが、もう一つ質問させてください。

フォームに設定したデフォルトのフォントを、コードを使ってボールド(太字)に
切り替えたり、他のフォントに設定することは可能でしょうか?

dairygoods 2002/04/26(金) 14:51:00
>>2.GetFontでCFontを取得し、GetLogFontでそのフォント情報を取得する。
>>    それをもとに必要な構造体(LOGFONT)のメンバを設定してやる。
>
>手順は一応わかりました。やってみます。

>フォームに設定したデフォルトのフォントを、コードを使ってボールド(太字)に
>切り替えたり、他のフォントに設定することは可能でしょうか?

まず、2を試してみれば、それが目的の方法であることがわかるでしょう。


>はい、それはうすうす感じてましたが、やはり全コントロールを個別にフォントの設定を
>行わなければならないみたいですね。


全てのコントロールのフォントをまとめて変更することはできます。
SetFontの代わりに次のようにします。

Viewクラス内:
  SendMessageToDescendants(WM_SETFONT,
     (WPARAM)(HFONT)m_bFont, MAKELPARAM(TRUE, 0));

べーちゃん 2002/04/27(土) 05:26:21
dairygoodsさん、ありがとうございました。べーちゃんです。

申し訳ないのですが、どうか今一度お付き合いください。

>まず、2を試してみれば、それが目的の方法であることがわかるでしょう。

そう考えてフォームからフォントを取ってきて、それを設定しなおして
やる方法を考え、以下のように記述したのですが、思いっきりAssertが
でて、死んでしまいます。

死んでしまうのはCreatePointFontIndirectの行です。
デバッガで追いかけたところlftTempには、私がリソースエディタで
設定したフォントが入っていたので問題ないと思ったのですが、

1.OnInitialUpdate()関数で記述しているのが悪いのかと思い
 OnCreate()関数で記述しなおすも、エラーはやはりでるので、
 現在は元に戻しました。

2.LOGFONTの扱いが悪いのかとも思いましたが、原因がさっぱり
 わかりません。

どうか、ヒントでも結構ですので何か教えていただけないでしょうか?

OnInitialUpdate()関数の内容は以下のとおりです。

    // TODO: Add extra initialization here
    LOGFONT        lftTemp;
    CFont*        pfntTemp;

    pfntTemp = this->GetFont();
    pfntTemp->GetLogFont(&lftTemp);
    lftTemp.lfWeight = FW_BOLD;
    lftTemp.lfHeight = 100;
    pfntTemp->CreatePointFontIndirect(&lftTemp);
    this->SetFont(pfntTemp);

追伸:
不良PGさん、ハンドル名を間違えてすいませんでした。

Bun 2002/04/27(土) 08:27:36
>1.OnInitialUpdate()関数で記述しているのが悪いのかと思い
> OnCreate()関数で記述しなおすも、エラーはやはりでるので、
> 現在は元に戻しました。

どっちでもいーかも知れませんね。初期化のところですから。

>2.LOGFONTの扱いが悪いのかとも思いましたが、原因がさっぱり
> わかりません。

多分、すでにあるものを再度Createしようとしているからでしょう。

エラーをなくすだけなら
pfntTemp->CreatePointFontIndirect(&lftTemp);
の直前に
pfntTemp->DeleteObject();
を入れれば良いかも知れませんね。
でも、これぢゃうまくいかないと思います。
この場合、フォントは一時オブジェクトではまずいと思います。

-------------------------------------------------
私なら、こんな感じかなぁ。(試していません)
m_Fontは CFont型のViewのメンバ変数

pfntTemp = GetFont();
pfntTemp->GetLogFont(&lftTemp);

// カスタマイズ (ご自由に)
lftTemp.lfWeight = FW_BOLD;
lftTemp.lfHeight = 100;

m_Font.DeleteObject();
m_Font.CreatePointFontIndirect(&lftTemp);
SetFont(&m_Font);

こう書いても、結局は
SendMessageToDescendants(WM_SETFONT)
しなきゃあかんのでわ?
要は子コントロールに変更した結果を反映せにゃあかんつーこってす。

-------------------------------------------------

#あとはノーガキ(笑)

>this->SetFont(pfntTemp);

Time is money.ですから、こーいう書き方はやめましょう。
省略できるものは、省略する。( "this->"の部分が省略可能であることはおわかりですよね )

べーちゃん 2002/04/27(土) 08:50:37
[[解決]]
ワルツさん、不良PGさん、dairygoodsさん、そしてBunさん。
みなさんどうもありがとうございました。べーちゃんです。

なんとか、解決しました。

>多分、すでにあるものを再度Createしようとしているからでしょう。

そうだったんですね。気が付きませんでした。

>こう書いても、結局は
>SendMessageToDescendants(WM_SETFONT)
>しなきゃあかんのでわ?

そのとおりでしたら動きました。

動いたOnInitialUpdate()関数のソースは以下のとおりです。
(m_fntStaticはビューのクラスのメンバ変数です)

LOGFONT        lftTemp;
CFont*        pfntTemp;

pfntTemp = GetFont();
pfntTemp->GetLogFont(&lftTemp);
lftTemp.lfWeight = FW_BOLD;
lftTemp.lfHeight = 100;
m_fntStatic.CreatePointFontIndirect(&lftTemp);
SetFont(&m_fntStatic);

SendMessageToDescendants(WM_SETFONT, (WPARAM)(HFONT)m_fntStatic, 
MAKELPARAM(TRUE, 0));

で無事望みどおりに動きました。

>#あとはノーガキ(笑)
>>this->SetFont(pfntTemp);
>Time is money.ですから、こーいう書き方はやめましょう。
>省略できるものは、省略する。( "this->"の部分が省略可能であることはおわかりです
よね )

すんません。きぃついてませんでした。

古いスレッドには追加発言できません。