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

Win32 開發入門(12):使用控制項——單選按鈕

     編輯:關於C++

啟用視覺樣式的關鍵步驟

在使用新版共用控制項(單選按鈕、核取方塊等)前,必須啟用 Common Controls 6.0,否則控制項會呈現 Windows 9x/2000 風格,且 LoadIconMetric 等 API 會調用失敗。需在程式碼加入三行:

#include <CommCtrl.h>
#pragma comment(lib, "Comctl32.lib")
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

version='6.0.0.0' 為關鍵,processorArchitecture='*' 可同時支援 x86/x64。

單選按鈕其實是 Button 類別

Win32 沒有獨立的 "RadioButton" 類別,單選按鈕與核取方塊皆為 Button 類別,差別在於視窗樣式:

  • BS_RADIOBUTTON:單選按鈕(不會自動處理選取狀態)
  • BS_AUTORADIOBUTTON:自動單選按鈕(系統自動處理互斥選取)
  • BS_CHECKBOX / BS_AUTOCHECKBOX:核取方塊

建立單選按鈕與分組機制

在 WM_CREATE 中建立:

CreateWindow(L"Button", L"男",
    WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP,
    12, yLoc, 60, 16, hwnd, (HMENU)IDC_RADBTN1, hInst, NULL);

WS_GROUP 是分組關鍵:

  • 擁有 WS_GROUP 的單選按鈕為該組第一個項目
  • 後續連續的單選按鈕(直到下一個 WS_GROUP)屬同一組
  • 同組內單選按鈕互斥,不同組互不干擾

範例:性別與顏色兩組單選按鈕


// 第一組:性別
CreateWindow(L"Button", L"男",  WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP, ...); // IDC_RADBTN1
CreateWindow(L"Button", L"女",  WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, ...);           // IDC_RADBTN2
CreateWindow(L"Button", L"人妖", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, ...);           // IDC_RADBTN3

// 第二組:顏色
CreateWindow(L"Button", L"藍色", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP, ...); // IDC_RADBTNBLUE
CreateWindow(L"Button", L"紅色", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, ...);           // IDC_RADBTNRED
CreateWindow(L"Button", L"綠色", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, ...);           // IDC_RADBTNGREEN

BS_RADIOBUTTON 不會自動選取

BS_AUTORADIOBUTTON 自動處理選取

兩組單選按鈕執行結果

完整程式碼清單

#include <Windows.h>
#include <WindowsX.h>
#include <CommCtrl.h>
#pragma comment(lib, "Comctl32.lib")
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

// 控制項 ID
#define IDC_RADBTN1      50001
#define IDC_RADBTN2      50002
#define IDC_RADBTN3      50003
#define IDC_RADBTNBLUE   51001
#define IDC_RADBTNRED    51002
#define IDC_RADBTNGREEN  51003
#define IDC_BTN_OK       1107

int WINAPI wWinMain(HINSTANCE hTheApp, HINSTANCE hPrevApp, LPWSTR lpCmd, int nShow) {
    PCWSTR cn = L"My", tt = L"應用程式";
    WNDCLASS wc = { sizeof(WNDCLASS) };
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpfnWndProc = WindowProc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    LoadIconMetric(hTheApp, IDI_APPLICATION, LIM_SMALL, &wc.hIcon);
    wc.lpszClassName = cn;
    wc.hInstance = hTheApp;
    RegisterClass(&wc);
    
    HWND hwnd = CreateWindow(cn, tt, WS_OVERLAPPEDWINDOW,
                             28, 34, 400, 330, NULL, NULL, hTheApp, NULL);
    if (!hwnd) return 0;
    ShowWindow(hwnd, nShow);
    UpdateWindow(hwnd);
    
    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_CREATE: {
            HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
            int yLoc = 0;
            
            // 性別標籤
            CreateWindow(L"Static", L"請問你的性別是:", SS_SIMPLE|WS_CHILD|WS_VISIBLE,
                         10, yLoc+=10, 160, 18, hwnd, NULL, hInst, NULL);
            // 第一組單選按鈕
            CreateWindow(L"Button", L"男", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
                         12, yLoc+=22, 60, 16, hwnd, (HMENU)IDC_RADBTN1, hInst, NULL);
            CreateWindow(L"Button", L"女", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                         12, yLoc+=20, 60, 16, hwnd, (HMENU)IDC_RADBTN2, hInst, NULL);
            CreateWindow(L"Button", L"人妖", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                         12, yLoc+=20, 60, 16, hwnd, (HMENU)IDC_RADBTN3, hInst, NULL);
            
            // 顏色標籤
            CreateWindow(L"Static", L"你喜歡哪一種顏色?", WS_CHILD|WS_VISIBLE|SS_SIMPLE,
                         10, yLoc+=38, 150, 18, hwnd, NULL, hInst, NULL);
            // 第二組單選按鈕
            CreateWindow(L"Button", L"藍色", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
                         12, yLoc+=22, 60, 16, hwnd, (HMENU)IDC_RADBTNBLUE, hInst, NULL);
            CreateWindow(L"Button", L"紅色", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                         12, yLoc+=20, 60, 16, hwnd, (HMENU)IDC_RADBTNRED, hInst, NULL);
            CreateWindow(L"Button", L"綠色", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                         12, yLoc+=20, 60, 16, hwnd, (HMENU)IDC_RADBTNGREEN, hInst, NULL);
            
            // 確定按鈕
            CreateWindow(L"Button", L"確定", WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,
                         230, 180, 80, 27, hwnd, (HMENU)IDC_BTN_OK, hInst, NULL);
        } return 0;
        
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
            
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

重點整理

  • 單選按鈕 = Button 類別 + BS_AUTORADIOBUTTON 樣式
  • WS_GROUP 決定互斥群組邊界
  • 必須啟用 Common Controls 6.0 才能獲得現代視覺風格
  • LoadIconMetric 等新 API 依賴視覺樣式清單
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved