Win16 API   /   ボタン

ホーム    Windows API Primer

ボタン

button.c


#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int     PASCAL   WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
{
    WNDCLASS wc;
    HWND     hwnd;
    MSG      msg;
    
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "GREETING";
    
    RegisterClass(&wc);
    
    hwnd             = CreateWindow("GREETING",
                                    "Hello",
                                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                                    CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
                                    NULL, NULL, hInstance, NULL);
    
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
    }
    
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HWND button;
    static BOOL isHello = TRUE;
           RECT rect;
    
    switch (msg)
    {
    case WM_CREATE:
        GetClientRect(hwnd, &rect);
        button = CreateWindow("BUTTON",
                              "Greeting",
                              WS_CHILD | WS_VISIBLE,
                              (rect.right  - 70) / 2,
                              (rect.bottom - 30) / 2,
                              70, 30,
                              hwnd, (HMENU)100, NULL, NULL);
        break;
    case WM_SIZE:
        GetClientRect(hwnd, &rect);
        SetWindowPos (button, HWND_TOP,
                      (rect.right  - 70) / 2,
                      (rect.bottom - 30) / 2,
                      0, 0, SWP_NOSIZE);
        break;
    case WM_COMMAND:
        if (LOWORD(wParam) == 100)
        {
            if (isHello)
            {
                SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)"Goodby");
                isHello = FALSE;
            } else {
                SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)"Hello");
                isHello = TRUE;
            }
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

    


実行結果

「Greeting」ボタンをクリックするたびに、ウィンドウのタイトルが「Hello」と「Goodbye」を繰り返します。
ウィンドウのサイズを変更しても「Greeting」ボタンは常にウィンドウの中央に表示されます。


コード説明

  1. wc.style = CS_HREDRAW | CS_VREDRAW;
    CS_HREDRAW や CS_VREDRAW の CS はクラススタイルの略だと思えば覚えやすいでしょう。
  2. WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    WS はウィンドウスタイルの略だと思えば覚えやすいでしょう。
  3. CW_USEDEFAULT
    CW が何を表しているのか分かりません。
  4. case WM_CREATE:
    WM_CREATE はウィンドウが最初に作られた時に呼び出されるメッセージです。WM はウィンドウメッセージの略だと思えば覚えやすいでしょう。
  5. button = CreateWindow("BUTTON",
    ボタンコンポーネントのクラス名は BUTTON です。
  6. hwnd, (HMENU)100, NULL, NULL);
    CreateWindow の第9引数を (HMENU)100 とすると 100 という ID(整数値)でコマンド(命令)を送ることができます。
  7. case WM_SIZE:
    WM_SIZE はウィンドウのサイズが変更された時に呼び出されるメッセージです。
  8. case WM_COMMAND:
    WM_COMMAND はウィンドウでコマンド(命令)が発生した時に呼び出されるメッセージです。
  9. if (LOWORD(wParam) == 100)
    ウィンドウプロシージャの第4引数(wParam)の下位8bit(LOWORD)にコマンドを発したコンポーネントの ID(整数値)が入っています。
  10. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)"Goodby");
    SendMessage 関数でコンポーネントの設定を変更できます。引数は次のとおりです。
    1. 第1引数に設定を変更するコンポーネントを指定します。
    2. 第2引数に何を設定するのかを指定します。WM_SETTEXT はコンポーネントに表示される文字列を設定します。
    3. 第3引数に WPARAM 値を指定しますが、不要な場合は 0 と指定できます。
    4. 第4引数に設定する値を指定します。今回の場合は、"Goodbye"という文字列を LPARAM 型にキャストして指定しています。


11762 visits
Posted: Jul. 17, 2020
Update: Jul. 18, 2020

ホーム        Windows API Primer     目次