方案選型對比
| 方案 | 優點 | 缺點 |
| 啟動外部進程 (ShellExecute) | 零開發成本 | 跳出應用程式,體驗割裂 |
| COM 自動化嵌入 Office/Acrobat | 原生編輯能力 | 選單/工具列汙染自有 UI,部署依賴完整 Office |
| Microsoft WebBrowser 控件 | **無縫內嵌、支援 IE 能開啟的所有格式 (PDF/Word/HTML/圖片)、UI 乾淨** | 需目標機安裝對應檢視器 (Acrobat Reader/Word) |
控件整合步驟
- 專案 → 加入元件 → 「Microsoft Web Browser」 → 產生
CWebBrowser2 類別。
- 多文件架構 (MDI) 下,**每個視圖對應一個控件實例**,於
CView 衍生類宣告成員:CWebBrowser2 m_Web;。
OnInitialUpdate 動態建立控件佔滿用戶區:
CRect rect; GetClientRect(&rect);
m_Web.Create(NULL, WS_CHILD | WS_VISIBLE, rect, this, AFX_IDW_PANE_FIRST);
文件開啟與顯示流程
主框架:檔案對話框 → 新建文件
CFileDialog dlg(TRUE, _T("*.doc"), _T("*.doc"),
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("Word(*.doc)|*.doc|PDF(*.pdf)|*.pdf|HTML(*.htm)|*.htm|All(*.*)|*.*||"));
if (dlg.DoModal() == IDOK) {
m_strPath = dlg.GetPathName();
PostMessage(WM_COMMAND, ID_FILE_NEW); // 觸發 MDI 新建文件/視圖
}
視圖:導航至指定路徑
void CMyView::OnInitialUpdate() {
CView::OnInitialUpdate();
// 取得主框架傳遞的路徑
m_strFilePath = ((CMainFrame*)AfxGetMainWnd())->m_strPath;
((CMainFrame*)AfxGetMainWnd())->m_strPath = _T("about:blank");
m_Web.Navigate(m_strFilePath, NULL, NULL, NULL, NULL);
m_Web.SetResizable(TRUE);
}
視窗大小變更與重繪處理
void CMyView::OnSize(UINT nType, int cx, int cy) {
CView::OnSize(nType, cx, cy);
if (m_Web.m_hWnd) {
CRect rect; GetClientRect(&rect);
m_Web.SetWindowPos(&wndTop, rect.left, rect.top, rect.Width(), rect.Height(), 0);
m_Web.RedrawWindow();
}
}
void CMyView::OnDraw(CDC* pDC) {
if (m_Web.m_hWnd) m_Web.RedrawWindow();
}
實測效果與擴展性
- 同視窗並列開啟多個 PDF/Word 分頁 (MDI 子視窗各載一份 WebBrowser),Acrobat Reader 原生不支援並列。
- 支援所有 IE 可渲染格式:HTML、JPEG、TXT、XML 等,零代碼修改。
- 依賴環境:Windows 2000+、VC++ 6.0、Word 2000+、Acrobat Reader 5.0+。
常見坑點提醒
- 確保專案啟用
_ATL_APARTMENT_THREADED 或正確初始化 COM (AfxOleInit)。
- 分發檔案時攜帶對應的 Viewer 再分發包,或提供安裝引導。
- 大型文件載入時考慮顯示進度條,避免 UI 假死。