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

VC++ 高效能資料庫網格:CGridCtrl 虛擬模式實現 DBGrid

     編輯:VC 教學

痛點

標準 DBGrid、CListCtrl 逐行插入萬筆資料極慢、記憶體暴漲、滾動卡頓。CGridCtrl (CodeProject 經典開源專案) 提供虛擬模式:僅按需查詢可視區資料,支援百萬列流暢滾動。

虛擬模式初始化

m_Grid.SetVirtualMode(TRUE);
m_Grid.SetRowCount(nTotalRecords + 1); // +1 標題列
m_Grid.SetFixedRowCount(1);
m_Grid.SetColumnCount(nCols);
m_Grid.SetFixedColumnCount(1);

核心:GVN_GETDISPINFO 通知處理

BOOL CMyOdbcDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    if (wParam == m_Grid.GetDlgCtrlID()) {
        NMHDR* pHdr = (NMHDR*)lParam;
        if (pHdr->code == GVN_GETDISPINFO) {
            GV_DISPINFO* pDispInfo = (GV_DISPINFO*)lParam;
            SetGridItem(pDispInfo); // 我們填充文字、圖示、格式
            *pResult = 0;
            return TRUE;
        }
    }
    return CDialog::OnNotify(wParam, lParam, pResult);
}

void CMyOdbcDlg::SetGridItem(GV_DISPINFO* pInfo)
{
    int row = pInfo->item.row;    // 1-based (0=標題)
    int col = pInfo->item.col;    // 0-based
    if (row == 0) { // 標題列
        pInfo->item.strText = GetColumnCaption(col);
        return;
    }

    // 從資料集取得第 row 筆資料第 col 欄位
    // 策略 A:ADO Recordset 絕對定位 (較慢)
    // 策略 B:快取當前頁 100 筆到 vector (推薦)
    // 策略 C:異步預取下一頁,顯示 loading 佔位符

    pInfo->item.strText = GetCachedCellText(row, col);
    pInfo->item.lParam = row; // 可攜帶主鍵 ID
}

資料快取策略

策略適用場景複雜度
全量快取 (vector)< 5 萬列、欄位少低
分頁快取 (LRU)百萬列、隨機跳轉中
異步預取 + 佔位符網路資料庫、高延遲高

進階功能整合

  • 排序:點擊標題列觸發 GVN_COLUMNCLICK,重新查詢 ORDER BY 並 Invalidate()。
  • 篩選:工具列輸入條件 → 重新查詢 → SetRowCount 更新總數。
  • 編輯回寫:GVN_ENDLABELEDIT 取得新值 → 執行 UPDATE SQL → 更新快取。
  • 多選/複製:GetSelectedCellRange() 組裝 Tab 分隔文字 → OpenClipboard/SetClipboardData。

效能基準 (參考)

  • 100 萬列 × 10 欄,虛擬模式啟動 < 200ms,滾動 60fps (現代硬體)。
  • 記憶體佔用 < 50MB (分頁快取 200 列)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved