首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Win32 開發入門(11):使用控制項——按鈕基礎操作

     編輯:關於C++

控制項本質與建立時機

控制項本質上是子視窗,建立方式與視窗相同,使用 CreateWindow/CreateWindowEx,必須加上 WS_CHILD 與 WS_VISIBLE 樣式。建立時機通常在主視窗的 WM_CREATE 訊息中處理。

官方工具:Control Spy

Microsoft 提供 Control Spy 工具可預覽控制項外觀、樣式與訊息流向。下載連結:MSDN 下載頁面

建立按鈕並設定 ID

case WM_CREATE: {
    CreateWindow(L"Button", L"有種就來點擊我!",
                 WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
                 35, 45, 160, 65, hwnd, NULL, hg_app, NULL);
} return 0;

控制項 ID 設定:CreateWindow 的 hMenu 參數對子視窗而言即為控制項識別碼。習慣用 #define 定義常數:

#define IDB_ONE 3301
#define IDB_TWO 3302
#define IDB_THREE 3303

回應按鈕點擊 (WM_COMMAND)

按鈕點擊產生 WM_COMMAND:

  • LOWORD(wParam) = 控制項 ID
  • HIWORD(wParam) = 通知碼(如 BN_CLICKED)
  • lParam = 控制項視窗控制代碼
case WM_COMMAND: {
    switch (LOWORD(wParam)) {
        case IDB_ONE:
            MessageBox(hwnd, L"您點擊了第一個按鈕。", L"提示", MB_OK|MB_ICONINFORMATION);
            break;
        case IDB_TWO:
            MessageBox(hwnd, L"您點擊了第二個按鈕。", L"提示", MB_OK|MB_ICONINFORMATION);
            break;
        case IDB_THREE:
            MessageBox(hwnd, L"您點擊了第三個按鈕。", L"提示", MB_OK|MB_ICONINFORMATION);
            break;
    }
} return 0;

三個按鈕執行畫面

動態修改按鈕文字

利用 WM_COMMAND 的 lParam 取得按鈕控制代碼,發送 WM_SETTEXT 訊息:

case WM_COMMAND: {
    switch (LOWORD(wParam)) {
        case IDB_ONE:
            SendMessage((HWND)lParam, WM_SETTEXT, 0, (LPARAM)L"第一個按鈕已點擊");
            break;
        case IDB_TWO:
            SendMessage((HWND)lParam, WM_SETTEXT, 0, (LPARAM)L"第二個按鈕已點擊");
            break;
        case IDB_THREE:
            SendMessage((HWND)lParam, WM_SETTEXT, 0, (LPARAM)L"第三個按鈕已點擊");
            break;
    }
} return 0;

關鍵點:WindowProc 的第一個參數 hwnd 是主視窗控制代碼,操作按鈕必須用 lParam 轉型為 HWND。

按鈕文字變更效果

完整程式碼清單

#include <Windows.h>
#include <WinNT.h>

#define IDB_ONE 3301
#define IDB_TWO 3302
#define IDB_THREE 3303

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LPCWSTR lps_cl = L"MyApp";
LPCWSTR wd_text = L"超級應用";
HINSTANCE hg_app;

int WINAPI wWinMain(HINSTANCE hThisApp, HINSTANCE hPrevApp, LPWSTR lpCmd, int nShow) {
    WNDCLASSEX wc = { };
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.hInstance = hThisApp;
    wc.lpfnWndProc = (WNDPROC)WindowProc;
    wc.lpszClassName = lps_cl;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClassEx(&wc);
    
    HWND hwnd = CreateWindowEx(WS_EX_WINDOWEDGE, lps_cl, wd_text,
                               WS_OVERLAPPEDWINDOW, 20, 25, 400, 300,
                               NULL, NULL, hThisApp, NULL);
    if (hwnd == NULL) return -1;
    
    ShowWindow(hwnd, nShow);
    UpdateWindow(hwnd);
    hg_app = hThisApp;
    
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_CREATE: {
            CreateWindow(L"Button", L"按鈕一", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
                         35, 10, 160, 60, hwnd, (HMENU)IDB_ONE, hg_app, NULL);
            CreateWindow(L"Button", L"按鈕二", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
                         35, 80, 160, 60, hwnd, (HMENU)IDB_TWO, hg_app, NULL);
            CreateWindow(L"Button", L"按鈕三", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
                         35, 150, 160, 60, hwnd, (HMENU)IDB_THREE, hg_app, NULL);
        } return 0;
        case WM_COMMAND: {
            switch (LOWORD(wParam)) {
                case IDB_ONE:
                    SendMessage((HWND)lParam, WM_SETTEXT, 0, (LPARAM)L"第一個按鈕已點擊");
                    break;
                case IDB_TWO:
                    SendMessage((HWND)lParam, WM_SETTEXT, 0, (LPARAM)L"第二個按鈕已點擊");
                    break;
                case IDB_THREE:
                    SendMessage((HWND)lParam, WM_SETTEXT, 0, (LPARAM)L"第三個按鈕已點擊");
                    break;
            }
        } return 0;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

重點整理

  • 控制項 = 子視窗,需 WS_CHILD | WS_VISIBLE
  • 控制項 ID 透過 CreateWindow 的 hMenu 參數傳入
  • WM_COMMAND 回應按鈕點擊,lParam 為按鈕控制代碼
  • 修改按鈕文字:SendMessage(hBtn, WM_SETTEXT, 0, (LPARAM)新文字)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved