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

MFC 專案中使用 CScrollView 實現對話框滾動子視圖

     編輯:關於C語言

場景痛點

對話框承載大量控件(如下拉選單、編輯框)時,單一螢幕無法完整顯示。傳統做法在 WM_VSCROLL 訊息中手動計算並移動每個控件座標,不僅程式碼冗長,還易出現「滾動不乾淨」、隱藏控件無法恢復顯示等問題。

CScrollView 解決方案

CScrollView 封裝了滾動邏輯:建立一個可滾動的視圖區域,超出可視範圍的內容自動隱藏,透過捲軸瀏覽。將其作為子視圖嵌入對話框,即可像操作普通控件一樣管理內部元件。

實作步驟

1. 建立自訂視圖類別

專案右鍵 → Add Class → MFC Class,基類選 CScrollView,命名為 CMyScrollView。

新增 MFC 類別對話框

2. 對話框類別新增成員變數

// ScrollViewTestDlg.h
class CScrollViewTestDlg : public CDialogEx {
    CMyScrollView* m_pMyView;   // 滾動視圖指標
    // ...
};

3. OnInitDialog 中建立並初始化視圖

BOOL CScrollViewTestDlg::OnInitDialog() {
    CDialogEx::OnInitDialog();

    // 建立視圖物件
    m_pMyView = (CMyScrollView*)(RUNTIME_CLASS(CMyScrollView)->CreateObject());
    CCreateContext context;
    context.m_pCurrentDoc = NULL;

    // 建立視窗:初始大小 100x100,稍後調整
    m_pMyView->Create(NULL, NULL, WS_BORDER,
                      CRect(0, 0, 100, 100), this, WM_USER + 1, &context);

    ((CView*)m_pMyView)->OnInitialUpdate();  // 重要:觸發初始化
    m_pMyView->ShowWindow(SW_SHOW);

    return TRUE;
}

4. 設定捲軸範圍(關鍵步驟)

OnInitialUpdate 會根據視窗大小自動計算捲軸參數。若視窗較小(如 200x200),系統會認為無需捲軸。必須在 OnInitialUpdate 之後呼叫 SetScrollSizes 強制設定虛擬大小:

SIZE size;
size.cx = 500;   // 虛擬寬度
size.cy = 500;   // 虛擬高度
m_pMyView->SetScrollSizes(MM_TEXT, size);   // 必須在 OnInitialUpdate 之後呼叫

顯示捲軸後的效果

5. 向滾動視圖動態加入控件

// 成員變數
CMFCButton* m_button;

// OnInitDialog 續寫
m_button = new CMFCButton();
m_button->Create(_T("Hello"), WS_VISIBLE,
                 CRect(5, 5, 80, 250),   // 座標相對於 CMyScrollView 客戶區
                 m_pMyView, WM_USER + 1);

滾動視圖內的按鈕

常用輔助函數

  • CheckScrollBars(BOOL& bHasHorzBar, BOOL& bHasVertBar):檢查捲軸是否存在。
  • GetDeviceScrollPosition():取得目前捲軸位置(CPoint)。
  • SetScaleToFitSize(SIZE sizeTotal):依內容自動調整視圖縮放。

注意事項

  1. 視圖建立後必須呼叫 OnInitialUpdate,否則捲軸參數不會初始化。
  2. SetScrollSizes 一定要在 OnInitialUpdate 之後呼叫,否則會被覆蓋。
  3. 子視圖內控件的座標系統是相對於 CScrollView 的客戶區原點 (0,0),與對話框座標無關。
  4. 記得在對話框解構時 delete m_pMyView; delete m_button; 避免記憶體洩漏。

總結

使用 CScrollView 作為容器,將複雜的滾動邏輯封裝於框架層,開發者只需專注於業務控件的佈局。此法不僅程式碼簡潔,更能完美處理隱藏控件的顯示/隱藏狀態切換,是 MFC 對話框大量控件佈局的最佳實踐。

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