承接對話框教程,本文示範在 MFC SDI (Single Document Interface) 專案中整合 TangramMini,實現單文檔視圖區域的視覺化框架配置、分割視窗、標籤頁管理。關鍵差異:SDI 無 MDI 客戶區,需將 CView 視圖視窗嵌入 Tangram 空白視圖。
SDI → 選擇 Single documentTangramMini_i.c、TangramMini_i.h 至專案目錄stdafx.h 匯入:#include "TangramMini_i.c" → #include "TangramMini_i.h"class CMainFrame : public CFrameWnd {
ITangramMiniB2C* m_pMiniB2C;
ITangramMiniCtrl* m_pMiniCtrl;
};
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_TangramMiniB2C, NULL,
CLSCTX_INPROC_SERVER, IID_ITangramMiniB2C, (LPVOID*)&m_pMiniB2C);
if (SUCCEEDED(hr) && m_pMiniB2C) {
m_pMiniB2C->put_TargetHandle((LONG)m_hWnd); // 父視窗為主框架
m_pMiniB2C->get_TangramMiniCtrl(&m_pMiniCtrl);
VARIANT_BOOL bSucceed;
m_pMiniCtrl->LoadFile(L"test.xtml", &bSucceed);
// 關鍵差異:SDI 需指定 CView 視圖視窗句柄
// theApp.m_pClientView 為自行維護的 CView* 指標 (見下文)
m_pMiniCtrl->SetMDIClient(
L"Page1_S0001_S0000",
(LONG)theApp.m_pClientView->m_hWnd,
0, &bSucceed); // nMDIStyle 在 SDI 中無效果
}
return 0;
}
class CSDIApp : public CWinApp {
public:
CView* m_pClientView; // 指向當前作用中視圖
virtual BOOL InitInstance() {
// ... 標準初始化 ...
// 在 CMainFrame 建立視圖後,需將指標指派給 m_pClientView
// 通常在 CMainFrame::OnCreateClient 或 CView::OnInitialUpdate 中處理
}
};
關鍵點:SDI 架構下,視圖視窗由 CFrameWnd 管理,非 MDI 客戶區。需自行取得 CView 的 m_hWnd 傳給 SetMDIClient,TangramMini 會將該視圖視窗「平移」到指定空白視圖區域,並自適應大小。
使用 XTML Designer 修改 test.xtml,將原第 3 號空白視圖重新設計為三頁標籤頁:

CView 客戶區
// 在 OnCreate 或視圖初始化後安裝
CEdit* pEdit = new CEdit;
pEdit->Create(WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY,
CRect(0,0,0,0), &wndView, IDC_OUTPUT_EDIT);
m_pMiniCtrl->SetWnd(L"Output", (LONG)pEdit->GetSafeHwnd());
| 特性 | SDI | MDI |
|---|---|---|
| 目標嵌入視窗 | CView* m_pClientView | m_hWndMDIClient (或 0 自動) |
| SetMDIClient nMDIStyle | 無效 (傳 0) | 0-3 四種標籤風格 |
| 多文檔支援 | 單一文檔視圖 | 多子視窗 + 標籤管理 |
| 框架定義檔 | 可共用 | 可共用 |
TangramMini 在 SDI 中同樣發揮「視覺化框架定義 + 幾行程式碼整合」的優勢。關鍵在於正確取得 CView 視圖視窗句柄並傳遞給 SetMDIClient,後續業務視窗安裝、標題管理、佈局持久化 API 與 MDI 完全一致,學習曲線平緩。