`CSliderCtrl`(滑桿/軌跡條)是直觀數值輸入控制項,常用於音量、亮度、進度、參數調整。本文系統整理屬性設定 API、事件訊息處理、與 Edit 控制項雙向同步的完整實作流程,基於 VC++ 6.0 / VS2019 通用 MFC 架構。
| 功能 | 函數 | 說明 |
|---|---|---|
| 取得/設定範圍 | 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_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)` 僅在拖曳結束同步,減少更新頻率。
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)`。
可自訂滑塊顏色、軌道漸層、刻度標籤:
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;
}
}

拖曳滑塊時 Edit 即時顯示數值,Edit 輸入數值按 Enter 後滑塊跳轉對應位置,刻度清晰,支援鍵盤方向鍵/PgUp/PgDn 操作。
`CSliderCtrl` 功能豐富、API 直觀。掌握 範圍/步長/刻度設定 → 事件同步 Edit → 雙向綁定 → 自訂繪製 完整鏈路,即可構建專業級參數調整介面。建議將同步邏輯封裝為 `CSliderEditSync` 輔助類別,一鍵套用至專案中所有滑桿控制項。