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

VC++ 操作 SQL Server 主從表:視窗分割、多視圖通訊、樹狀目錄與列表控件實戰

     編輯:VC 教學

專案背景

採用 VC + SQL Server 架構的 MFC 單文檔應用程式,核心需求包含:視窗分割、多視圖通訊、列表控件操作、樹狀控件遞歸建立目錄、主從表資料顯示。本文針對各關鍵技術點進行模組化說明。

一、靜態視窗分割 CSplitterWnd

於 CMainFrame::OnCreateClient() 中建立兩層巢狀分割:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
    CRect rect; GetClientRect(&rect);
    // 第一層:1列2欄 (左:樹狀目錄, 右:再分割)
    m_wndSplitter1.CreateStatic(this, 1, 2);
    m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CClassTreeView), CSize(150,150), pContext);
    // 第二層:針對右側窗格 (0,1) 再切 2列1欄 (上:主表, 下:從表)
    m_wndSplitter2.CreateStatic(&m_wndSplitter1, 2, 1, WS_CHILD|WS_VISIBLE,
        m_wndSplitter1.IdFromRowCol(0,1));
    m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CDagView), CSize(0,0), pContext);     // 主表
    m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CDagDetailView), CSize(0,0), pContext); // 從表
    m_wndSplitter2.SetRowInfo(0, rect.Height()/2, 0); // 初始上下各半
    return TRUE; // 切記不可呼叫基類 OnCreateClient
}

關鍵點:CreateStatic 建立固定行列,CreateView 填入不同 CView 衍生類,IdFromRowCol 取得窗格 ID 供巢狀分割使用。

二、多視圖間通訊:透過主框架取得視圖指標

因專案僅單一 CDocument,額外視圖不共享文件,故採「主框架中轉」法:

CMainFrame* pFrame = static_cast<CMainFrame*>(AfxGetMainWnd());
CDagDetailView* pDetail = static_cast<CDagDetailView*>(
    pFrame->m_wndSplitter2.GetPane(1, 0)); // 取得下方面板指標
// 現在可呼叫 pDetail->RefreshData() 等自訂函式

建議使用 static_cast 而非 C 風格轉型,型別安全且易維護。

三、列表控件 CListCtrl 進階操作

  • 報表檢視:SetWindowLong(m_hWnd, GWL_STYLE, LVS_REPORT | ...) 設定 LVS_REPORT 風格,呈現類 DataGrid 效果。
  • 擴展風格:ListView_SetExtendedListViewStyleEx(m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES, ...) 啟用整列選取、格線。
  • 事件處理:
    • NM_CLICK:單擊回應(需自行 HitTest 判斷欄位)。
    • LVN_ITEMCHANGED:選取變更,NM_LISTVIEW* pNM = (NM_LISTVIEW*)pNMHDR 判斷 uChanged & LVIF_STATE 及 uNewState & LVIS_SELECTED。

四、樹狀控件 CTreeCtrl 遞歸建立資料庫目錄

遞歸函式 BuildTree(HTREEITEM hParent, long lParentID):

  1. 執行 SQL 查詢 SELECT * FROM Categories WHERE ParentID = ?。
  2. 迴圈 InsertItem 取得 HTREEITEM hChild,SetItemData(hChild, lChildID) 存放主鍵。
  3. 遞歸呼叫 BuildTree(hChild, lChildID) 處理子節點。

配合 TVN_SELCHANGED 事件,取得 GetItemData(hSel) 即為該節點 ID,進而查詢從表資料刷新列表。

五、主從表資料同步顯示

採用 CRecordset (或 ADO) 兩組資料集:
m_rsMaster 綁定主表列表,m_rsDetail 依主表選取的 PK 篩選 (m_strFilter = "MasterID = " + strID) 並 Requery()。列表 LVN_ITEMCHANGED 事件中更新從表過濾條件並重查。

總結

靜態分割奠定版面基礎,主框架中轉解決視圖通訊,列表/樹狀控件配合資料庫操作完成主從表互動。模組化設計讓各功能低耦合、高內聚,易於擴展維護。

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