このサイトでは、分析、カスタマイズされたコンテンツ、および広告に Cookie を使用します。このサイトを引き続き閲覧すると、Cookie の使用に同意するものと見なされます。
Hi, Developers,
straightapps.com ロゴ
作成 December 16, 2022
トップページ > Windows トップ > リストボックスの文字サイズやフォントを変える
line
Windows 開発
line

ここでは、リストボックスの文字サイズやフォントを変える方法について、書いています。

Visual C++ で ( Visual Basic だと最初からフォントや文字サイズの指定ができたような気がします。 ) ちょっとしたツールを作成するとき、ダイアログにリストボックスを配置すると、 特に最近の高解像度のディスプレイを使用していると文字が小さいと感じます。

リストボックスの例

大きな字に変更したい場合はどうしたらよいか、忘れないように記録しています。 また、自由なフォントを使う方法についても書いています。

コードは Windows 10、Visual Studio 2022 で作成、確認したものです。 MFC ( Microsoft Foundation Class、マイクロソフトが提供する、便利なクラスライブラリです。 ) のクラスを使用していますが、MFC を使用しなくても同様のコードで動作すると思います。

▼ セクション一覧

文字のサイズを変える
行儀よく動作させる
フォントを変更する

なお、本サイトのご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。

文字のサイズを変える

投稿 December 16, 2022

リストボックスなどの コントロール ( ダイアログに配置できる、ボタンやエディット、その他いろいろなものをコントロールと呼んでいます。 ) はウィンドウですから、描画設定を持っています。 ですので描画設定を変更して、文字サイズを変えようとしています。

テストのために、ダイアログベースの MFC アプリを作成しました。 ここでは ChangeLBProp という名前にしています。

ダイアログにリストボックスを追加し、コントロール名を IDC_LIST としました。

この状態で、どのような表示になるかを確かめます。

ダイアログの初期化関数 OnInitDialog() で、リストボックスに確認用の文字列を出力します。 OnInitDialog 関数は、ダイアログクラス内に、 BOOL CChangeLBPropDlg::OnInitDialog() のように実装されています。

	CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST);
	pList->ResetContent();
	pList->AddString(_T("東京"));
	pList->AddString(_T("神奈川"));
	pList->AddString(_T("埼玉"));
	pList->AddString(_T("千葉"));

ビルドの設定は、Debug ビルドの x64 になっています。 このあたりは何も影響がないと思います。

リストボックスの例

枠に対して文字がだいぶ小さいので、大きくしたいと思います。

ちなみに VS2022 ではデフォルトでリストボックスのソート(並べ替え)のプロパティが True になっていますので、文字コード順に並んでいます。 設定順に表示させるには、「並べ替え」や「ソート」「Sort」のようなプロパティを False に変更します。


文字のサイズを変えるため描画のフォントを変えますので、ヘッダファイル、例えば ChangeLBPropDlg.h で、ダイアログクラスに CFont クラスを定義します。 これは MFC の、フォント情報を格納するクラスです。

protected:
	CFont* m_pFont;
	CFont m_font;

m_ で始まっているのはクラスのメンバである、という意味です。 CFont* は、 CFont を指すポインタです。

OK ボタン ( コントロール ID は IDOK です。 ) のハンドラ void OnBnClickedOk() を追加して、フォント変更を実装してみます。

動作を確認するためにユーザーの操作を求めていますが、初期化時に行ってしまっても問題ないでしょう。

void CChangeLBPropDlg::OnBnClickedOk()
{
	//CDialogEx::OnOK();

	CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST);
	LOGFONT lf;

	m_pFont = pList->GetFont();				// 元のフォントを取得
	m_pFont->GetLogFont(&lf);				// フォント情報を取り出し
	lf.lfHeight = -48;					// 欲しいサイズを指定
	m_font.CreateFontIndirect(&lf);				// フォントを作成
	pList->SetFont(&m_font);				// 作成したフォントを選択
}

まずは自動生成された、OK を返してダイアログを終了するための呼び出し OnOK() をコメントアウトします。

対象となるリストボックスを取得し、pList に設定しています。 また、フォント情報を格納する LOGFONT 構造体 を用意しています。

フォントの指定には WM_SETFONT メッセージを使うようですが、MFC ならウィンドウクラスの CWnd::SetFont 関数を使います。 CListBoxCWnd の派生クラスですので、このあとの手法はエディットコントロール CEdit など他のコントロールでも利用できるはずです(エディットコントロールのみテスト済み)。

CWnd::SetFont 関数には LOGFONT 構造体 を渡しますが、間違いなく設定するのは面倒ですので、 GetFont 関数現在のリストボックスのフォント情報を取得します。 そして必要な部分のみ書き換えます。

フォントのサイズは lfHeight で指定されています。 文字の高さをピクセル値で指定するには、負の値を設定します。 文字の高さを 48 ピクセルにしたい場合なら、-48 を設定します。

フォントサイズだけ変更し、あとは現在のままとなったフォント情報から、 CreateFontIndirect 関数で m_font にフォントを作成しています。 ちゃんとしたツールなら、正しく作成されたかを確認すべきでしょう。

最後に SetFont 関数でリストボックスに設定しています。

プログラムを実行し、OK ボタンをクリックすると、画面は自動的に更新されて大きな文字で表示されました。

文字が大きいリストボックスの例

▲ページ先頭へ

行儀よく動作させる

投稿 December 16, 2022

とりあえずは目的を達成できましたが、OK ボタンでフォントを生成して設定していますので、 OK ボタンが複数回クリックされると m_font がどんどん作成されてしまいます

現代ではオブジェクトの参照がなくなったら自動的に削除してくれる、ということもありますが、 そうでない場合はメモリを浪費しますし、やってくれるにしてもマナーが悪い感じですから、対策を入れておきます。

フォント設定を呼び出したか、また呼び出していないかの判定に m_pFont が使えそうです。 ダイアログの初期化関数 OnInitDialog で、m_pFont を NULL にしておきます。

	//	フォント情報を取得していません。
	m_pFont = NULL;

OK ボタン処理 OnBnClickedOk 関数では、 m_pFont が NULL の場合のみ、取得することとします。

	if (!m_pFont) {
		m_pFont = pList->GetFont();			// 元のフォントを取得
	}
	else {
		pList->SetFont(m_pFont, FALSE);
		m_font.DeleteObject();				// 作成したフォントを削除
	}

else 節、すでに m_pFont が設定されている場合は、前回作成した m_font を削除しています。

前回 m_font を作成していますので、m_font を再作成する前に削除しておけばクリーンです。 作成したフォントは DeleteObject() 呼び出しで削除できますが、 今はリストボックスに設定中ですから、そのタイミングで削除するのは良くなさそうです。

m_font の選択を解除するため、いったんもとの m_pFont に戻します。 なおここで指定している SetFont 関数の第 2 引数 FALSE は「再描画しない」という意味です。 省略すると TRUE ですので「再描画する」です。

これで少しマナーが良くなりましたが、まだプログラム終了時に設定しっぱなしになっています。

プログラム終了時についてはまず間違いなく正しくクリーンアップされるとは思いますが、 念のため、キャンセルボタン処理にフォントを戻すコードを入れておきます。

void CChangeLBPropDlg::OnBnClickedCancel()
{
	if (m_pFont) {
		CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST);
		pList->SetFont(m_pFont, FALSE);
		m_font.DeleteObject();				// 作成したフォントを削除
		m_pFont = NULL;
	}

	CDialogEx::OnCancel();
}

m_pFont が NULL ではない場合は m_font が作成され、リストボックスに選択されている状態ですから、 もとのフォント m_pFont を選択しなおして、m_font を削除しています。 m_font が削除されたら、m_pFont を NULL に戻しておき、何らかの理由でプログラムを終了しなかった場合に備えます。

これでプログラム終了時にもフォントが削除されることになります。

ちなみに、ウィンドウ右上のバツボタンシステムメニューの「閉じる」で閉じたときも この関数 OnBnClickedCancel が呼び出されていますので、 わざわざデストラクタや WM_CLOSE 処理などにコードを追加する必要はないと思います。

システムメニュー

CDialogEx::OnCancel(); の前に
MessageBox(_T("フォントをクリアしました。"));
のようなコードを追加すると、その動作を確認できます。

▲ページ先頭へ

フォントを変更する

投稿 December 16, 2022

LOGFONT を取得したついでに、フォントの指定も行ってみます。

本来であればインストールされているフォントを調べてその文字列を使用するべきですが、 今はテストですので、インストール済みのフォント名を直接指定してみます。 なお、フォント名は LF_FACESIZE バイト以内に収める必要がありますので、31 バイト + NULL まで、 つまりフォント名の部分は 31 文字(全角の場合は 2 文字分使用)までです。

	wsprintf(lf.lfFaceName, _T("メイリオ"));		// LF_FACESIZE(31文字)まで

フォントサイズの設定に続けて、フォント名の設定をしてみます。

メイリオフォント

行間が空きましたが、最初のゴシック系より少し細いフォントになったようです。

このように直接指定する場合には、インストールされていないフォントを指定しないように注意しなくてはいけません。

▲ページ先頭へ
line
関連トピックス
line

マルチモニタを制御

Windows PC で 2 台のモニタを接続している場合、2 台接続を検出し、座標を特定するためのコードについて書いています。

FTP でファイルをアップ&ダウンロード

Visual C++/MFC で、サーバーに FTP 接続してファイルをアップロード、ダウンロードするコードを書いています。

タイムスタンプを自由に変更する

Windows のファイルにある 3 種類のタイムスタンプ、作成日時、更新日時とアクセス日時を書き換えられるコードについて、書いています。

_sprintf でリンクエラーを回避する

古い Visual C++ プロジェクトから新しい環境に移行したとき、_sprintf でエラーが出る場合の回避方法について、書いています。

VS Community 2022 をインストールする

すでにインストールされている VS 2019 をアンインストールし、VS Community 2022 をインストールしなおしています。

line
その他のおすすめ
line

Android 開発トップ

Android 開発関連の情報を、書いています。

Windows 開発トップ

Windows 開発関連の情報を、書いています。



© 2017-2022 StraightApps.com 無断転載を禁じます。No reproduction without permission.