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

VC++ 滑桿控制項 CSliderCtrl 完整應用指南:屬性設定、事件處理、與 Edit 控制項同步

     編輯:VC 教學

前言

`CSliderCtrl`(滑桿/軌跡條)是直觀數值輸入控制項,常用於音量、亮度、進度、參數調整。本文系統整理屬性設定 API、事件訊息處理、與 Edit 控制項雙向同步的完整實作流程,基於 VC++ 6.0 / VS2019 通用 MFC 架構。

一、建立專案與控制項配置

  1. 對話方塊專案,放置 `Slider Control` (IDC_SLIDER) 與 `Edit Control` (IDC_EDIT_VALUE)。
  2. Slider 屬性:勾選 `Tick Marks`(刻度)、`Auto Ticks`、設定 `Orientation`(水平/垂直)。
  3. ClassWizard 關聯變數:`CSliderCtrl m_slider`、Edit 關聯 `int m_nValue`(或 `CString`)。

二、核心屬性設定 API

功能函數說明
取得/設定範圍GetRange(min, max) / SetRange(min, max, bRedraw)預設 0~100,可設負值
取得/設定當前位置GetPos() / SetPos(pos)即時數值
取得/設定行步長GetLineSize() / SetLineSize(n)鍵盤左右鍵/點擊槽區移動量,預設 1
取得/設定頁步長GetPageSize() / SetPageSize(n)PgUp/PgDn 移動量,預設 10
設定刻度頻率SetTicFreq(n)每 n 單位一個刻度,0=無刻度
設定指定位置刻度SetTic(pos)手動加入特定刻度
清除所有刻度ClearTics(bRedraw)
取得/設定選取範圍GetSelection(min, max) / SetSelection(min, max)篩選區間高亮(需 `TBS_ENABLESELRANGE` 樣式)
設定提示工具SetToolTips(hWndTip)滑鼠懸停顯示數值

初始化範例


BOOL CSliderDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    m_slider.SetRange(-100, 100);     // 範圍 -100 ~ 100
    m_slider.SetTicFreq(10);          // 每 10 單位一個刻度
    m_slider.SetLineSize(1);          // 方向鍵步長 1
    m_slider.SetPageSize(10);         // PgUp/PgDn 步長 10
    m_slider.SetPos(0);               // 初始值 0
    m_nValue = 0; UpdateData(FALSE);  // 同步 Edit
    return TRUE;
}

三、事件處理:NM_CUSTOMDRAW / NM_RELEASEDCAPTURE

最常用的是 **`NM_RELEASEDCAPTURE`**(使用者釋放滑鼠拖曳結束)或 **`NM_CUSTOMDRAW`**(每次重繪,含拖曳中)。若需即時同步 Edit,用 `NM_CUSTOMDRAW` 配合 `CDDS_PREPAINT` 階段讀取位置。


void CSliderDlg::OnCustomDrawSlider(NMHDR* pNMHDR, LRESULT* pResult)
{
    NMCUSTOMDRAW* pNMCD = (NMCUSTOMDRAW*)pNMHDR;
    if (pNMCD->dwDrawStage == CDDS_PREPAINT)
    {
        UpdateData(TRUE); // 從控制項讀取 m_nValue
        m_nValue = m_slider.GetPos();
        UpdateData(FALSE); // 寫入 Edit
    }
    *pResult = 0;
}

或使用 `ON_NOTIFY_REFLECT(NM_RELEASEDCAPTURE, OnSliderReleased)` 僅在拖曳結束同步,減少更新頻率。

四、雙向同步:Edit 修改更新 Slider


void CSliderDlg::OnEnChangeEditValue()
{
    UpdateData(TRUE); // 讀取 Edit 輸入的 m_nValue
    // 限制範圍
    int min, max; m_slider.GetRange(min, max);
    if (m_nValue < min) m_nValue = min;
    if (m_nValue > max) m_nValue = max;
    m_slider.SetPos(m_nValue);
    // 不需 UpdateData(FALSE),避免遞迴
}

注意:Edit 控制項需設定 `ES_NUMBER` 樣式限制輸入數字,或在 `OnEnChange` 中過濾非數字。

五、垂直滑桿與反向座標

垂直滑桿(`TBS_VERT`)預設**上方為最大值、下方為最小值**。若需反向(如音量:上大下小),可在 `SetRange` 交換 min/max,或自行映射:`pos = max - (value - min)`。

六、自訂繪製:NM_CUSTOMDRAW 進階

可自訂滑塊顏色、軌道漸層、刻度標籤:


void CSliderDlg::OnCustomDrawSlider(NMHDR* pNMHDR, LRESULT* pResult)
{
    NMCUSTOMDRAW* pNMCD = (NMCUSTOMDRAW*)pNMHDR;
    switch (pNMCD->dwDrawStage)
    {
    case CDDS_PREPAINT:
        *pResult = CDRF_NOTIFYITEMDRAW; break;
    case CDDS_ITEMPREPAINT:
        // 繪製軌道
        if (pNMCD->dwItemSpec == TBCD_CHANNEL)
        {
            CDC* pDC = CDC::FromHandle(pNMCD->hdc);
            CRect rc = pNMCD->rc;
            // 漸層填充...
            *pResult = CDRF_SKIPDEFAULT; // 我們已繪製
        }
        // 繪製滑塊
        else if (pNMCD->dwItemSpec == TBCD_THUMB)
        {
            // 圓形滑塊、陰影...
            *pResult = CDRF_SKIPDEFAULT;
        }
        // 繪製刻度
        else if (pNMCD->dwItemSpec == TBCD_TICS)
        {
            *pResult = CDRF_SKIPDEFAULT;
        }
        break;
    }
}

七、執行效果

Slider 與 Edit 同步示範

拖曳滑塊時 Edit 即時顯示數值,Edit 輸入數值按 Enter 後滑塊跳轉對應位置,刻度清晰,支援鍵盤方向鍵/PgUp/PgDn 操作。

八、常見問題

  • SetRange 後 SetPos 不生效:確保 `SetRange` 在 `SetPos` 之前呼叫,且範圍包含目標值。
  • 刻度不顯示:需設定 `TBS_AUTOTICKS` 樣式或手動 `SetTicFreq`/`SetTic`。
  • 垂直滑桿方向反了:見第 5 節映射處理。
  • 高 DPI 模糊:啟用 DPI 感知 Manifest,或改用 `CMFCCustomSlider` (MFC Feature Pack)。

九、結語

`CSliderCtrl` 功能豐富、API 直觀。掌握 範圍/步長/刻度設定 → 事件同步 Edit → 雙向綁定 → 自訂繪製 完整鏈路,即可構建專業級參數調整介面。建議將同步邏輯封裝為 `CSliderEditSync` 輔助類別,一鍵套用至專案中所有滑桿控制項。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved