延續先前 ODBC 版本,本專案改用 DAO (Data Access Objects) 存取 Access 資料庫。因 DAO 不直接支援最新 Access 格式,需先轉換為舊版。核心功能:

BOOL CListDlg::OnInitDialog() {
// ... 視窗初始化 ...
m_pDB = new CDaoDatabase;
CString dbPath = GetAppPath() + "\\db6.mdb";
try { m_pDB->Open(dbPath); }
catch (CDaoException* e) { /* 錯誤處理 */ }
CDaoTableDefInfo info;
for (int i = 0; i < m_pDB->GetTableDefCount(); i++) {
m_pDB->GetTableDefInfo(i, info);
if (!(info.m_lAttributes & dbSystemObject))
m_Com.AddString(info.m_strName); // 僅使用者資料表
}
m_pRecordSet = new CDaoRecordset(m_pDB);
return TRUE;
}
void CListDlg::OnStart() {
if (m_pRecordSet->IsOpen()) m_pRecordSet->Close();
m_List1.DeleteAllItems();
// 清除舊欄位
for (long i = 0; i < nField; i++) m_List1.DeleteColumn(0);
m_Com.GetLBText(m_Com.GetCurSel(), m_GetString);
if (m_GetString == "關閉班級") { /* 重置旗標 */ return; }
CString sql = "SELECT * FROM " + m_GetString;
try { m_pRecordSet->Open(dbOpenDynaset, sql); }
catch (CDaoException* e) { /* 錯誤處理 */ }
// 依據欄位資訊動態建立 ListView 欄位
nField = m_pRecordSet->GetFieldCount();
LV_COLUMN lvCol = { LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM, LVCFMT_LEFT, 67 };
for (int i = 0; i < nField; i++) {
CDaoFieldInfo fi; m_pRecordSet->GetFieldInfo(i, fi);
lvCol.pszText = (LPSTR)(LPCSTR)fi.m_strName;
m_List1.InsertColumn(i, &lvCol);
}
// 設定擴充樣式
m_List1.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
// 載入所有資料
m_pRecordSet->MoveFirst(); m_pRecordSet->MoveLast();
long cnt = m_pRecordSet->GetRecordCount();
OnGetdispinfoList(cnt, nField);
}
OnGetdispinfoList支援多種資料型別(VT_I2, VT_I4, VT_R4, VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_BOOL 等)自動轉字串顯示,透過 SetAbsolutePosition 定位記錄、GetFieldValue 取值。
void CListDlg::OnGetdispinfoList(long row, long col) {
COleVariant var;
for (long i = 0; i < row; i++) {
m_pRecordSet->SetAbsolutePosition(i);
for (long j = 0; j < col; j++) {
m_pRecordSet->GetFieldValue(j, var);
// 型別判斷轉換...
CString str = VariantToString(var);
if (j == 0) m_List1.InsertItem(i, str, 0);
else m_List1.SetItemText(i, j, str);
}
}
}