承接前三篇對話框基礎教程,本文實作一個完整的「軟體模型」:左側 Tree Control 導航、中間 List Control 列表、右側 Edit Box 資訊顯示,透過 Tree 節點選擇動態切換中間區域顯示的視窗 (List Control / 自定義對話框),並同步更新 Edit Box 文字。
CMyDialog1 : public CDialog, CMyDialog2 : public CDialogclass CTutorial1Dlg : public CDialog {
// TangramMiniCtrl (已在前篇建立)
CTangramMiniCtrl m_wndMiniCtrl;
// 控件變數 (DDX_Control)
CTreeCtrl m_wndTree;
CListCtrl m_wndList;
CEdit m_wndEdit;
// 自定義對話框實例
CMyDialog1* m_pMyDialog1;
CMyDialog2* m_pMyDialog2;
BOOL OnInitDialog() {
CDialog::OnInitDialog();
// 建立並安裝 List Control
m_wndMiniCtrl.SetWnd(_T("Page1_S0001_S0000"), (long)m_wndList.GetSafeHwnd());
// 建立並安裝 Tree Control
m_wndMiniCtrl.SetWnd(_T("Page1_S0003"), (long)m_wndTree.GetSafeHwnd());
// 建立並安裝 Edit Box
m_wndMiniCtrl.SetWnd(_T("Page1_S0002"), (long)m_wndEdit.GetSafeHwnd());
// 建立自定義對話框實例 (隱藏)
m_pMyDialog1 = new CMyDialog1(this);
m_pMyDialog2 = new CMyDialog2(this);
m_pMyDialog1->Create(IDD_MYDIALOG1_DIALOG, this);
m_pMyDialog2->Create(IDD_MYDIALOG2_DIALOG, this);
// 初始化 Tree 節點
HTREEITEM hRoot = m_wndTree.InsertItem(_T("ListView"));
m_wndTree.InsertItem(_T("ChildWindow1"), hRoot);
m_wndTree.InsertItem(_T("ChildWindow2"), hRoot);
m_wndTree.Expand(hRoot, TVE_EXPAND);
return TRUE;
}
};
void CTutorial1Dlg::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult) {
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
*pResult = 0;
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
if (!hItem) return;
CString strItemText = m_wndTree.GetItemText(hItem);
m_wndEdit.SetWindowText(_T("selected: \"") + strItemText + _T("\""));
// 根據節點文字動態切換中間區域視窗
if (strItemText.CompareNoCase(_T("ListView")) == 0) {
m_wndMiniCtrl.SetWnd(_T("Page1_S0001_S0000"), (long)m_wndList.GetSafeHwnd());
} else if (strItemText.CompareNoCase(_T("ChildWindow1")) == 0) {
m_wndMiniCtrl.SetWnd(_T("Page1_S0001_S0000"), (long)m_pMyDialog1->GetSafeHwnd());
} else {
m_wndMiniCtrl.SetWnd(_T("Page1_S0001_S0000"), (long)m_pMyDialog2->GetSafeHwnd());
}
}



Page1_S0001_S0000) 可重複呼叫 SetWnd 切換不同 HWND| 技術 | 應用場景 |
|---|---|
SetWnd(blankView, hWnd) | 將任意 HWND (控件/對話框/視圖) 嵌入指定 Tangram 空白視圖 |
Tree Control TVN_SELCHANGED | 導航驅動介面動態切換 |
| Child Dialog (WS_CHILD, WS_VISIBLE) | 模組化視窗單元,支援完整 UI 邏輯封裝 |
| DDX_Control + GetSafeHwnd() | MFC 控件包裝與原生 HWND 互轉 |
void CTutorial1Dlg::OnDestroy() {
if (m_pMyDialog1) { m_pMyDialog1->DestroyWindow(); delete m_pMyDialog1; }
if (m_pMyDialog2) { m_pMyDialog2->DestroyWindow(); delete m_pMyDialog2; }
CDialog::OnDestroy();
}
本教程展示 TangramMini 核心價值:將介面佈局 (XTML) 與業務視窗邏輯 (C++ 類別) 完全分離。導航樹、編輯區、資訊欄各自為獨立模組,透過 SetWnd 動態組合,實現高內聚、低耦合的介面架構。下一篇將進入 SDI/MDI 應用場景。