フォントのサイズの変更 - Rustで作るWindowsアプリ
目次
フォントのサイズの変更
ラベルなどの静的コントロールのフォントのサイズを変更するには以下の手順で行います。
- SendMessageW関数でウィンドウからフォントを取得する
- GetObjectW関数でフォントのロジカル情報を取得する
- CreateFontIndirectW関数で新しいフォントを作成する
- SendMessageW関数でウィンドウに新しいフォントを設定する
ウィンドウというのはハンドルのことでラベルの場合はラベルのハンドルがそうです。実際のフォントのサイズの変更にはフォントのロジカル情報を取得する必要があり、これにはGetObjectW
関数を使います。フォントサイズを変更したらそのロジカル情報をもとに新しいフォントをCreateFontIndirectW
関数で作成し、それをウィンドウにセットします。
WM_CREATEの編集
// ウィンドウの作成時に呼ばれる WM_CREATE => { // ラベルの作成 HWND_LABEL = CreateWindowExW( WINDOW_EX_STYLE::default(), w!("STATIC"), // ラベルのウィンドウクラス名 w!("0回描画されました。"), // ラベルに表示するテキスト WS_VISIBLE | WS_CHILD, // スタイル 50, 50, // XおよびY座標 400, 48, // 幅および高さ window, // 親ウィンドウのハンドル None, // メニューハンドル(使用しない) None, // インスタンスハンドル None // 追加のアプリケーションデータ ); // フォントの取得 let lresult: LRESULT = SendMessageW( HWND_LABEL, WM_GETFONT, WPARAM::default(), LPARAM::default() ); // フォントのロジカル情報の取得 let mut lf: LOGFONTW = LOGFONTW::default(); GetObjectW( HGDIOBJ(lresult.0), std::mem::size_of::<LOGFONTW>() as i32, Some(&mut lf as *mut LOGFONTW as *mut std::os::raw::c_void), ); lf.lfHeight = 48; // フォントサイズの変更 // 新しいフォントの作成 let h_new_font = CreateFontIndirectW(&lf); // 新しいフォントをウィンドウに設定 SendMessageW( HWND_LABEL, WM_SETFONT, WPARAM(h_new_font.0 as usize), LPARAM::default() ); LRESULT(0) }
フォントのサイズの設定はウィンドウの作成時に行えばいいので、ここではWM_CREATE
を編集します。ラベルの大きさもフォントのサイズに合わせて変更していますので注意してください。
注目してほしいのはGetObjectW
関数です。この関数はRustではかなりunsafe
なコードを書かないと実行できません。第3引数にポインタを指定するのですが、このポインタへの変更にいくらかキャストが必要です。もっとも、unsafe
と言ってもC言語などではごくごく一般的なコードになります。あくまでRustのメモリ安全のレベルから言うとunsafe
なだけで古のC言語使いはこういったコードをずっと書いてきたはずです。
std::os::raw::c_void
はC言語で言うとvoid
型に当たります。void
とは「何もない」ことを表すC言語の型です。C言語では型の抽象化の際にこのvoid
型を使うことがあります。特にvoid
型のポインタは何にでもキャストできるいわゆる「何でもあり」なポインタです。言語の安全機能の外にあるポインタなので扱いには注意が必要となります。
GetObjectW
関数では第2引数に第3引数のサイズを渡しています。このサイズが適当じゃないとメモリの読み書きに「こっそり」失敗することもあるので注意が必要です。
SendMessageW関数
pub unsafe fn SendMessageW<P0, P1, P2>( hwnd: P0, // ウィンドウへのハンドル msg: u32, // 送信するメッセージ wparam: P1, // 追加のメッセージの情報 lparam: P2 // 追加のメッセージの情報 ) -> LRESULT where P0: IntoParam<HWND>, P1: IntoParam<WPARAM>, P2: IntoParam<LPARAM>,
指定したウィンドウに指定のメッセージを送信します。この関数はウィンドウのウィンドウ プロシージャを呼び出して処理させます。
第1引数のhwnd
がHWND_BROADCAST
である時、メッセージはシステム内のすべての最上位ウィンドウに送信されます。この時、メッセージは子ウィンドウには送信されません。
msg
に指定できるメッセージですがフォントの取り扱いでは以下のメッセージを使用します。
- WM_GETFONT ... コントロールが描画しているフォントの取得
- WM_SETFONT ... コントロールに描画用のフォントを設定
返り値はメッセージによって変わりますが、WM_GETFONT
を指定した場合はHFONT
と互換性のある値になります。WM_SETFONT
の場合は返り値を返しません。
LOGFONTW構造体
Struct windows::Win32::Graphics::Gdi::LOGFONTW #[repr(C)] pub struct LOGFONTW { pub lfHeight: i32, // フォントの文字の高さ pub lfWidth: i32, // フォントの文字の平均幅 pub lfEscapement: i32, // 文字送りの方向とx軸との角度 pub lfOrientation: i32, // ベースラインとx軸との角度 pub lfWeight: i32, // 0 ~ 1000の範囲のフォントの太さ pub lfItalic: u8, // TRUEの場合は斜体フォント pub lfUnderline: u8, // TRUEの場合は下線付きフォント pub lfStrikeOut: u8, // TRUEの場合は取り消し線フォント pub lfCharSet: FONT_CHARSET, // 文字セット pub lfOutPrecision: FONT_OUTPUT_PRECISION, // 出力精度 pub lfClipPrecision: FONT_CLIP_PRECISION, // クリッピングの精度 pub lfQuality: FONT_QUALITY, // 出力品質 pub lfPitchAndFamily: u8, // フォントのピッチとファミリ pub lfFaceName: [u16; 32], // null終端されたフォントのタイプフェイス名 }
LOGFONTW
はフォントの属性の定義の構造体です。上記の属性に値を指定することでフォントの属性を変更できます。フォントのサイズの変更では上記のlfHeight
やlfWidth
などを設定します。
GetObjectW関数
Function windows::Win32::Graphics::Gdi::GetObjectW pub unsafe fn GetObjectW<P0>( h: P0, // ハンドル c: i32, // pvのデータサイズ pv: Option<*mut c_void> // 保存先のポインタ ) -> i32 where P0: IntoParam<HGDIOBJ>,
この関数は指定したグラフィックス オブジェクトの情報を取得します。
返り値はpv
に格納されたバッファーのバイト数です。pv
がNoneの場合はバッファーに格納するために必要なバイト数を返します。関数が失敗したら0
を返します。
std::mem::size_of関数
Function std::mem::size_of pub const fn size_of<T>() -> usize
std::mem::size_of
関数はT
のバイト数を返します。この関数はC言語で言うところのsizeof
演算子に当たります。
CreateFontIndirectW関数
Function windows::Win32::Graphics::Gdi::CreateFontIndirectW pub unsafe fn CreateFontIndirectW( lplf: *const LOGFONTW // フォントの属性情報 ) -> HFONT
この関数は指定されたフォントの属性情報でフォントを作成します。作成したフォントはデバイス コンテキストなどで使うことができます。
返り値は作成したフォントへのハンドルです。関数が失敗した場合はHFONT
のis_invalid
メソッドがtrue
になります。
HFONT構造体
Struct windows::Win32::Graphics::Gdi::HFONT #[repr(transparent)] pub struct HFONT(pub isize);
HFONT
はフォントのハンドルでisize
のラッパーのタプル構造体です。
この型はC言語のコードで言うと
typedef HANDLE HFONT;
になっており、HANDLE
型のエイリアスです。