フォントは変更されている?


まっち  2005-05-10 19:28:53  No: 57335

いつも勉強のため拝見させてもらってます(^−^)
CFontについて質問させてください。

Windows2000、MFC、VC++6.0  ダイアログベースで作成です。
ダイアログにボタンを1つ、リストボックスを2つはりました。
そして、CFontを使ってフォント変更を試みたところ、
いっぺん変わったように感じられたのですが
なんかおかしいのです。
ボタンがクリックされたときの処理で以下のように書きました

CFont m_Font;
m_Font.CreatePointFont(200, "MS ゴシック");
↑でMSゴシックに変更し、文字も200に設定しました。

CListBox* myList1 = (CListBox*)GetDlgItem(IDC_LIST1);
CListBox* myList2 = (CListBox*)GetDlgItem(IDC_LIST2);

myList2->AddString("1234567890");
myList2->AddString("PPPPP");

となり実行されると文字はでかくなりましたが
どうもMSゴシックになってないきがします。
なぜか?といいますと1234567890もPPPPPもどちらも
半角なので揃っていないとおかしいのですがズレてます。
これはフォント変更が反映されてないということなのでしょうか?
それともまた別の原因があるのでしょうか?

ご教授いただければ幸いですM(__)M


Blue  2005-05-10 19:39:28  No: 57336

SetFontはしてますか?

CreatePointFontのフォント名は"MS ゴシック"になっていますか?
(MSは全角 スペースは半角)


まっち  2005-05-10 19:44:17  No: 57337

>Blue様
失礼いたしました。記述もれがありました(汗)

void CxxxxxDlg::OnButton1() 
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください

//フォント作成
CFont m_Font;
m_Font.CreateFont(20,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,SHIFTJIS_CHARSET,        OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DRAFT_QUALITY,
DEFAULT_PITCH,"MS ゴシック");

//リストボックス使用
CListBox* myList2 = (CListBox*)GetDlgItem(IDC_LIST2);

//フォント設定をし、リストボックスに項目追加
myList2->SetFont(&m_Font);
myList2->AddString("1234567890");
myList2->AddString("PPPPP");

こんなソースです。
MSは全角、スペースは半角、ゴシックは全角となってます。
同じ半角同士(123とPP)なのに文字の横幅が違ってる感じがして
もしかしてフォント変更が有効になってない?と思ったのですが・・


Blue  2005-05-10 19:50:08  No: 57338

CreatePointFont()でフォントを作成していますがこのフォントは
ダイアログを破棄するまで必要なのでメンバ変数として宣言し保存しておく必要があります。

# m_ と変数名についていたのでてっきりメンバ変数かと。。。


まっち  2005-05-10 20:23:23  No: 57339

>Blue様

あぁーーなるほど。使いたい関数の中で
CFont m_Font;
ではなく、ヘッダーファイルで宣言するということでしょうか?

そう解釈し、
CFont m_Font;
をヘッダーファイルのprivate:に宣言したところ
コンパイルは通るのですが実行すると
【ハンドルされていない例外は xx.exeにあります。
  0xC0000005: Access Violation】
というエラーが発生しました(汗)
↓こうゆうメッセージもでています
例外処理 (初回) は ww.exe にあります: 0xC0000005: Access Violation。

↑で書いたソースのCFontの宣言をヘッダーファイルに移動させた
だけなのですが・・・なにがいけなかったのでしょうか?
たびたびの初歩的な質問で申し訳ありませんが
ご教授いただけませんでしょうかM(__)M


Blue  2005-05-10 20:43:17  No: 57340

そのエラーはいつ起こるのですか?
1度ボタンをおしたらOKだったが、2回目おしたらエラーがでたとか?
私も一応ソースをコピーして動かしてみましたが、
ボタンを2回押さない限りエラーが起こりませんでした。
(このエラーを消す方法はCreateFontのまえにDeleteObject処理を入れるだけですが。)


まっち  2005-05-10 22:29:19  No: 57341

>Blueさん

コンパイルはOKでしたが
実行した瞬間、発生していました(^−^;
画面が起動される(作成される)前に起きてるようです
ちょっといろいろ自分で調べてみます。
お手数おかけしますM(__)M


りえ  2006-10-17 09:18:40  No: 57342

まっち様
Blue様

丁度まっち様と同じようなエラーに悩まされていたのですが、
Blue様のアドバイスのようにDeleteObjectをしたらエラーが出なくなりました。ありがとうございます。

MFC,VC++6.0 です。
プロパティシートのページのひとつにリストコントロールを貼って、
OnInitDialogでリストコントロールのフォントを変えようとしていました。
最初の1回目だけはうまくフォントの変わったリストコントロールが表示されたのですが
2回目以降の実行では、表示される前に
「ハンドルされていない例外はxxxxxxにあります。」と
エラーダイアログが出て落ち、
エラーメッセージには
「例外処理 (初回) は xxx.exe (COMCTL32.DLL) にあります: 0xC0000005: Access Violation。」
と出ていました。

CreateFont直前にDeletObjectをする事と、
OnDestroyでもDeletObjectをする事で解決しました。
まだ細かく調べていませんがとりあえず表示されないうちに落ちるのは
直りました。
自分の勉強のためにもまた落ちないためにも原因やより良い方法を
もう少し探してみます。
まっち様、Blue様、ありがとうございました。m(_ _)m


PATIO  2006-10-18 00:57:47  No: 57343

これって毎回CreateFontしてませんか?
フォントクラスのインスタンスをダイアログクラスのメンバー変数で
宣言しておき、ダイアログのコンストラクタで行うようにした方が
処理に無駄がないと思います。
メンバー変数にしておけば、ダイアログクラスのデストラクタで
フォントクラスのデストラクタが走りますから開放は自動で行われます。
あと、思うのですけれど一回設定しておけば、変更の必要が無い限り
毎回変更する必要はないと思います。
で、DeleteObjectしていないのにCreateFontすると例外が出るのは
当たり前で、前のフォントの破棄を自動的に行うわけではないので
使う側できちんと管理しないとだめと言う話だと思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加