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

MFC ODBC 資料庫應用完整實作:CRecordView 與 List Control 打造專業級資料管理介面

     編輯:關於C語言

在 Visual C++ 開發資料庫應用時,ODBC 雖非最新技術,但成熟穩定、文獻豐富,仍是許多維護專案的首選。本文示範以 CRecordView 為視圖基底,搭配 CRecordset 与 CListCtrl(報表模式),實現記錄的新增、刪除、修改、排序、查詢與即時顯示,採用 Access 資料庫(亦可擴充至 SQL Server、Oracle),介面簡潔直觀。

專案架構關鍵點

  • 文件/視圖架構:CRecordView 直接綁定 CRecordset,資料移動自動同步 UI。
  • List Control 報表模式:啟用 LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES,整行選取、格線清晰。
  • 封裝 Show() 方法:將「查詢資料集 → 填入 List Control」邏輯封裝,供初始化、刷新、查詢後共用。

List Control 初始化與欄位設定

void CLhwyView::OnInitialUpdate()
{
    CRecordView::OnInitialUpdate();

    // 啟用完整列選取與格線
    m_ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

    // 插入欄位(標題、寬度、對齊)
    m_ListCtrl.InsertColumn(0, _T("學號"), LVCFMT_LEFT, 90);
    m_ListCtrl.InsertColumn(1, _T("姓名"), LVCFMT_LEFT, 90);
    m_ListCtrl.InsertColumn(2, _T("數學"), LVCFMT_RIGHT, 90);
    m_ListCtrl.InsertColumn(3, _T("英語"), LVCFMT_RIGHT, 90);

    // 重要:屬性頁必須設定 View = Report
    Show(); // 初始載入所有記錄
}

封裝 Show() 重用查詢與顯示邏輯

int CLhwyView::Show()
{
    m_ListCtrl.DeleteAllItems(); // 清空舊資料
    if (!m_pSet->IsOpen()) return 0;

    m_pSet->MoveFirst();
    int i = 0;
    CString str;
    while (!m_pSet->IsEOF()) {
        // 欄位 0:學號(整數轉字串)
        str.Format(_T("%d"), m_pSet->m_column1);
        m_ListCtrl.InsertItem(i, str);

        // 欄位 1:姓名
        m_ListCtrl.SetItemText(i, 1, m_pSet->m_column2);

        // 欄位 2、3:數學、英語分數
        str.Format(_T("%d"), m_pSet->m_column3);
        m_ListCtrl.SetItemText(i, 2, str);
        str.Format(_T("%d"), m_pSet->m_column4);
        m_ListCtrl.SetItemText(i, 3, str);

        i++;
        m_pSet->MoveNext();
    }
    return i; // 回傳筆數
}

核心 CRUD 操作實作

新增記錄

void CLhwyView::OnAdd()
{
    if (m_pSet->CanAppend()) {
        m_pSet->AddNew();
        // 這裡可彈出對話框讓使用者輸入欄位值
        // 假設已由 DDX 綁定至 m_pSet 成員變數
        m_pSet->Update(); // 寫入資料庫
        Show();           // 刷新顯示
    }
}

刪除記錄

void CLhwyView::OnDelete()
{
    int nSel = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED);
    if (nSel == -1) return; // 未選取

    // 取得該列主鍵(學號)
    CString strId = m_ListCtrl.GetItemText(nSel, 0);
    long id = _ttol(strId);

    // 定位至該記錄並刪除
    CString strFilter;
    strFilter.Format(_T("學號 = %ld"), id);
    m_pSet->m_strFilter = strFilter;
    m_pSet->Requery();
    if (!m_pSet->IsEOF()) {
        m_pSet->Delete();
        m_pSet->m_strFilter.Empty();
        m_pSet->Requery();
        Show();
    }
}

修改記錄

void CLhwyView::OnEdit()
{
    int nSel = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED);
    if (nSel == -1) return;

    CString strId = m_ListCtrl.GetItemText(nSel, 0);
    long id = _ttol(strId);

    CString strFilter;
    strFilter.Format(_T("學號 = %ld"), id);
    m_pSet->m_strFilter = strFilter;
    m_pSet->Requery();
    if (!m_pSet->IsEOF()) {
        m_pSet->Edit();
        // 彈出編輯對話框,DDX 綁定 m_pSet 成員
        // 使用者確定後
        m_pSet->Update();
        m_pSet->m_strFilter.Empty();
        m_pSet->Requery();
        Show();
    }
}

排序與查詢

// 排序:點擊欄標題時
void CLhwyView::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
    NM_LISTVIEW* pNM = (NM_LISTVIEW*)pNMHDR;
    static int lastCol = -1;
    static BOOL bAsc = TRUE;

    if (pNM->iSubItem == lastCol) bAsc = !bAsc;
    else { lastCol = pNM->iSubItem; bAsc = TRUE; }

    CString sortField;
    switch (pNM->iSubItem) {
        case 0: sortField = _T("學號"); break;
        case 1: sortField = _T("姓名"); break;
        case 2: sortField = _T("數學"); break;
        case 3: sortField = _T("英語"); break;
    }
    m_pSet->m_strSort = sortField + (bAsc ? _T(" ASC") : _T(" DESC"));
    m_pSet->Requery();
    Show();
    *pResult = 0;
}

// 查詢:依姓名關鍵字模糊搜尋
void CLhwyView::OnSearch()
{
    CString keyword;
    GetDlgItemText(IDC_EDIT_SEARCH, keyword);
    if (keyword.IsEmpty()) { m_pSet->m_strFilter.Empty(); }
    else { m_pSet->m_strFilter.Format(_T("姓名 LIKE '*%s*'"), keyword); }
    m_pSet->Requery();
    Show();
}

資料庫連接設定

專案採用 DSN-less 連接字串,避免部署時需於客戶機器建立 ODBC 系統 DSN:

// 在 CRecordset 派生類的 GetDefaultConnect()
return _T("Driver={Microsoft Access Driver (*.mdb)};Dbq=student.mdb;");

若改用 SQL Server,僅需修改連接字串:

return _T("Driver={SQL Server};Server=.;Database=School;UID=sa;PWD=123;");

執行畫面

ODBC 學生資料管理系統介面

圖:完整的學生成績管理介面,支援增刪改查排序

避坑指南

  • CRecordView 需在 OnInitialUpdate 中呼叫 m_pSet->Open(),否則視圖無法綁定資料集。
  • Requery() 後記錄指標重置,務必檢查 IsBOF()/IsEOF() 再操作。
  • 大量資料時,Show() 逐筆 InsertItem 會閃爍,可改用 SetRedraw(FALSE) 批次更新。
  • Access 2000/2003 格式需安裝對應 ODBC 驅動程式;VC6 專案建議轉存為 .mdb (Access 97) 相容。

總結

透過 CRecordView + CRecordset + CListCtrl 的經典組合,配合 Show() 封裝與 m_strFilter/m_strSort 動態查詢排序,即可快速建構功能完整、介面專業的 ODBC 資料庫應用。此架構易於維護、擴充至其他資料庫,是 MFC 資料庫開發的標準範本。

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