ユーニックス総合研究所

  • home
  • archives
  • windows-rs-label-bg

ラベルの色を変える - Rustで作るWindowsアプリ

  • 作成日: 2023-05-12
  • 更新日: 2023-12-24
  • カテゴリ: windows-rs

ラベルの前景色、背景色を変える

静的コントロールとしてラベルを配置するとラベルの色を変えたいということがあります。
ラベルの色ですがWindows APIにおける静的コントロールの色の変更方法は少し独特と言えます。

これはWM_CTLCOLORSTATICメッセージを処理してこのメッセージが送られてきた時に静的コントロールの色を変更します。
WM_CTLCOLORSTATICではすべての静的コントロールの色を一括で変更することもできますし、特定のコントロールの色を変えることも可能です。

ラベルの背景色の定義

extern "system" fn window_proc(  
    window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM  
) -> LRESULT {  
    unsafe {  
        static mut HWND_LABEL: HWND = HWND(0);  
        static mut COUNT: i32 = 0;  
        static mut H_BG_BRUSH: HBRUSH = HBRUSH(0);  // ラベルの背景用の論理ブラシ  

        ...  
    }  
    ...  
}  

まずラベルの背景色をHBRUSH構造体で定義します。ここではウィンドウプロシージャ関数内に静的変数として定義します。静的な定義では動的な関数を呼び出すことができませんので上記のようにH_BG_BRUSHを初期化だけしておきます。このH_BG_BRUSHの色の設定はWM_CREATEで行います。

    WM_CREATE => {  
        ...  
        H_BG_BRUSH = CreateSolidBrush(COLORREF(0x00000000)); // 黒背景  
        ...  
    }  

CreateSolidBursh関数で黒色のブラシを作成し、H_BG_BRUSHに保存しておきます。このブラシの色がラベルの背景色になります。

WM_CTLCOLORSTATICの編集

ウィンドウプロシージャ内で以下の様にWM_CTLCOLORSTATICメッセージを処理するようにします。

    // 静的コントロールの色を変える  
    WM_CTLCOLORSTATIC => {  
        let hwnd_static: HWND = HWND(lparam.0 as isize);  

        if HWND_LABEL == hwnd_static {  
            // ラベルの色を変える  
            let hdc: HDC = HDC(wparam.0 as isize);  
            SetTextColor(hdc, COLORREF(0x00ff0000));  // 文字色は青色  
            SetBkColor(hdc, COLORREF(0x0000ff00));  // 文字背景は緑色  
            LRESULT(H_BG_BRUSH.0)  // ラベルの背景色を変更  
        } else {  
            LRESULT(0)  
        }  
    }  

WM_CTLCOLORSTATICではlparamに静的コントロールのハンドル、wparamにデバイス コンテキストのハンドルが入っています。これを取り出して変数にしておきます。またhwnd_staticHWND_LABELであったら現在の静的コントロールがHWND_LABELのラベルであることになりますので、色の変更を行います。
色の変更ではSetTextColor関数とSetBkColor関数でテキストの前景色と後景色を変更できます。またウィンドウプロシージャ関数の返り値としてH_BG_BRUSHを返すとコントロールの背景色を変更できます。

H_BG_BRUSHの破棄

    // ウィンドウが破棄される  
    WM_DESTROY => {  
        ...  
        DeleteObject(H_BG_BRUSH);  
        ...  
    }  

CreateSolidBursh関数で作成した論理ブラシはDeleteObject関数で削除する必要があります。削除を忘れた場合はリソースリークになります。