ユーニックス総合研究所

  • home
  • archives
  • windows-rs-button

ボタンの配置 - Rustで作るWindowsアプリ

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

ボタンを配置する

Windows APIでボタンを配置するにはボタン用のウィンドウを子ウィンドウとして作成し配置します。WM_CREATEでボタンを作成しWM_PAINTでボタンを描画します。基本的にはラベルの作成とやることは一緒ですが、ボタンではボタンをクリックしたときのメッセージを処理する必要があります。ここではボタンがクリックされたらメッセージボックスを表示する、という処理を行いたいと思います。

ウィンドウプロシージャ内にボタン用の変数を作る

extern "system" fn window_proc(  
    window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM  
) -> LRESULT {  
    static mut HWND_BTN: HWND = HWND(0);  // ボタン用のハンドル  
    static BTN_ID: i32 = 1;  // ボタンの識別ID  
    ...  
}  

ウィンドウプロシージャ内に静的な変数としてボタンのハンドル用の変数とボタンのIDを表す整数の変数を定義します。ボタンのハンドルはミュータブルで変更可能にしておきます。このハンドルはWM_CREATEメッセージの処理で再初期化されます。

WM_CREATEの編集

    WM_CREATE => {  
        HWND_BTN = CreateWindowExW(  
            WINDOW_EX_STYLE::default(),  
            w!("BUTTON"),  // ボタンのウィンドウクラス名  
            w!("クリックしてください"),  // ボタンに表示するテキスト  
            WS_VISIBLE | WS_CHILD,  // スタイル  
            40, 40,  // xおよびy座標  
            200, 80,  // 幅および高さ  
            window,  // 親ウィンドウのハンドル  
            HMENU(BTN_ID as isize),  // メニューハンドル(子ウィンドウの識別子の指定)  
            None,  // インスタンスハンドル  
            None,  // 追加のアプリケーションデータ  
        );  
        LRESULT(0)  
    }  

WM_CREATEでボタンの作成を行います。ボタンの作成もラベルと同様にCreateWindowExW関数を使います。ラベルと違うところはウィンドウクラス名がBUTTONになっている点です。それからボタンの識別ID用にHMENU(BTN_ID as isize)を引数に渡しています。このHMENUの引数はメニューハンドルですがこれはスタイルに応じて子ウィンドウの識別子になります。

WM_PAINTの編集

    // ウィンドウの変更によりクライアント領域の内容が変わった  
    WM_PAINT => {  
        println!("再描画します。");  

        // 指定したウィンドウの更新領域から四角形を削除する  
        ValidateRect(window, None);  

        // ボタンを再描画  
        RedrawWindow(HWND_BTN, None, None, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);  

        LRESULT(0)  
    }  

WM_PAINTメッセージの処理でRedrawWindow関数を呼び出してボタンを再描画するようにします。ラベルと同様にこれを忘れるとボタンが表示されないので注意してください。

WM_COMMANDの編集

    WM_COMMAND => {  
        if wparam.0 == BTN_ID as usize {  
            MessageBoxW(None, w!("クリックしました"), w!("メッセージ"), MB_OK);  
        }  
        LRESULT(0)  
    }  

ボタンがクリックされるとWM_COMMANDメッセージが送信されますのでこれでボタンが押されたかどうか検出します。wparamにはボタンの識別IDが入ってますのでこれとBTN_IDを比較し、同じであればそのボタン用の処理であるメッセージボックスの表示を行います。