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

VC++ 實現 SQL Server 主從表架構:分割視窗、多視圖通訊與樹狀列表綁定實戰

     編輯:關於VC++

前言

在 Windows 桌面開發中,採用 VC++ 搭配 SQL Server 建立主從表(Master-Detail)資料呈現是經典需求。本文以一個輕量級 Demo 為例,完整記錄了從視窗分割、多視圖通訊、列表與樹狀控件操作,到動態主從表綁定的核心技術細節,供開發者參考。

一、視窗分割架構:靜態分割器的嵌套應用

專案採用 SDI 架構,主框架視窗使用 CSplitterWnd 實現三欄式佈局:左側樹狀導航、右上主表列表、右下從表明細。關鍵在於巢狀分割器:先建立 1 行 2 列的外層分割器,再在第 2 列建立 2 行 1 列的內層分割器。

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(CDagDetialView), CSize(0, 0), pContext); // 從表
    m_wndSplitter2.SetRowInfo(0, rect.Height() / 2, 0); // 初始均分高度

    return TRUE; // 切記不可呼叫基類 OnCreateClient
}

要點:靜態分割器建立後窗格數量固定,但可拖曳分隔條調整比例;每個窗格獨立擁有捲軸,適合多視圖協作場景。

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

專案僅有一個 Document,三個 View 類別獨立運作。跨視圖呼叫的關鍵在於取得目標 View 的指標。採用「主框架中轉」策略:

// 在任意 View 或其他模組中取得 CDagDetialView 指標
CMainFrame* pFrame = static_cast<CMainFrame*>(AfxGetMainWnd());
CDagDetialView* pDetailView = static_cast<CDagDetialView*>(
    pFrame->m_wndSplitter2.GetPane(1, 0) ); // 內層分割器第 2 行第 1 列

取得指標後即可直接呼叫該 View 的公開方法(如 RefreshData()、SetFilter() 等),實現資料同步與命令傳遞。建議統一使用 static_cast 替代 C 風格強轉,提升型別安全。

三、列表控件(CListCtrl)報表模式與事件處理

採用 LVS_REPORT 風格呈現類 DataGrid 效果。關鍵設定與事件對照表:

  • 風格設定:SetWindowLong(m_hWnd, GWL_STYLE, LVS_REPORT | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP)
  • 選取變更:處理 LVN_ITEMCHANGED,判斷 NM_LISTVIEW::uNewState & LVIS_SELECTED
  • 單擊/雙擊:分別處理 NM_CLICK、NM_DBLCLK
void CDagView::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    CListCtrl& list = GetListCtrl();

    if (pNMListView->uNewState & LVIS_SELECTED)
    {
        int nRow = pNMListView->iItem;
        // 取得主鍵值 → 查詢從表 → 通知從表視圖刷新
        UpdateDetailView(nRow);
    }
    *pResult = 0;
}

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

資料表結構:menucode (PK)、menuname、parentcode (FK)。利用「父代碼長度 + 2 = 子代碼長度」特徵,遞歸插入節點:

void CClassTreeView::InitTree(CTreeCtrl& tree, HTREEITEM hParent, const CString& strParentCode)
{
    _RecordsetPtr pRs = ...; // 查詢 WHERE parentcode = strParentCode
    while (!pRs->adoEOF)
    {
        _variant_t var = pRs->GetCollect(_T("menucode"));
        CString strCode = (var.vt != VT_NULL) ? (LPCSTR)_bstr_t(var) : _T("");
        CString strName = ...; // 取得 menuname

        // 判斷是否為直系子節點(長度差 2 且前綴相符)
        if (strCode.Find(strParentCode) == 0 && strCode.GetLength() == strParentCode.GetLength() + 2)
        {
            HTREEITEM hChild = tree.InsertItem(strName, hParent, TVI_LAST);
            InitTree(tree, hChild, strCode); // 遞歸處理下一層
        }
        pRs->MoveNext();
    }
}

選取節點事件(TVN_SELCHANGED)中取得節點文字,呼叫主表視圖依條件重查資料。

五、主從表動態綁定:未知欄位名的通用實作

假設資料庫結構不固定,需動態發現主鍵、動態構建查詢。核心流程:

  1. 查詢主表主鍵欄位名(sp_pkeys 或 INFORMATION_SCHEMA.KEY_COLUMN_USAGE)
  2. 列表控件中取得當前選取行的主鍵值(需先透過標題列尋找欄位索引)
  3. 以主鍵值為參數查詢從表(SELECT * FROM Detail WHERE MasterID = ?)
  4. 將結果集動態填充至從表 CListCtrl(先清空欄位再 InsertColumn、InsertItem/SetItemText)
// 取得欄位索引輔助函式
int CDagView::GetColumnIndex(CListCtrl& list, LPCTSTR pszColName)
{
    CHeaderCtrl* pHeader = list.GetHeaderCtrl();
    int nCount = pHeader->GetItemCount();
    HDITEM hdi; hdi.mask = HDI_TEXT; TCHAR buf[256]; hdi.pszText = buf; hdi.cchTextMax = 256;

    for (int i = 0; i < nCount; ++i)
    {
        pHeader->GetItem(i, &hdi);
        if (_tcscmp(hdi.pszText, pszColName) == 0) return i;
    }
    return -1;
}

// 使用範例
int nCol = GetColumnIndex(list, _T("MasterID"));
CString strKey = list.GetItemText(nCurRow, nCol); // 取得主鍵值

雖較 .NET DataGrid 繁瑣,但掌握後可構建高度靈活的通用資料瀏覽元件。

六、總結與原始碼

本 Demo 在 Windows 2000 / VC6.0 環境開發測試通過。涵蓋分割視窗、多視圖協作、列表/樹狀控件深度操作、ADO 動態主從表綁定等實戰技巧。完整原始碼已打包,歡迎下載研究、改進與分享。

本文配套源碼

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