PDF (Portable Document Format) 為電子文件交換標準。Adobe 提供 ActiveX 控制項 (pdf.ocx / AcroPDF.dll) 讓開發者在應用程式內嵌 PDF 檢視功能。本文說明如何在 MFC 專案中整合 Acrobat Reader 5.x/6.x/7.x 控制項顯示 PDF。
| 版本 | 控制項檔案 | ProgID / ClassID | 類型庫 |
|---|---|---|---|
| 4.x 及之前 | pdf.ocx | 完整 ActiveX,可直接匯入 | 內建 |
| 5.x / 6.x | pdf.ocx | PDF.PdfCtrl.5 | pdf.tlb (ActiveX 子目錄) |
| 7.x | AcroPDF.dll | AcroPDF.PDF.1 | AcroPDF.dll (內建類型庫) |
關鍵差異:5.x/6.x/7.x 控制項缺少完整類型庫資訊,無法透過 ClassWizard 直接「加入 ActiveX 控制項」產生包裝類別。需改用 CWnd::CreateControl 建立視窗,再取得 IDispatch 介面指標,配合 COleDispatchDriver 衍生類別呼叫方法。
pdf.tlb (位於 Acrobat 安裝目錄 ActiveX 子資料夾)。_DPdf (或類似名稱),標頭檔 pdf.h。#include "pdf.h" // 包裝類別標頭檔
class CViewPDFDlg : public CDialog
{
protected:
_DPdf m_drvPDF; // PDF 元件驅動物件
CWnd m_wndPDF; // PDF 控制項視窗
// ...
};
OnInitDialog 初始化控制項並載入 PDFBOOL CViewPDFDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 關鍵:加入 WS_CLIPCHILDREN 防止控制項重繪異常
ModifyStyle(0, WS_CLIPCHILDREN);
CRect rt;
GetClientRect(&rt);
// 建立控制項視窗
m_wndPDF.CreateControl(_T("PDF.PdfCtrl.5"), NULL,
WS_CHILD | WS_VISIBLE, rt, this, 0);
// 取得 IDispatch 介面並連接驅動物件
LPUNKNOWN lpUnk = m_wndPDF.GetControlUnknown();
LPDISPATCH lpDisp;
lpUnk->QueryInterface(IID_IDispatch, (void**)&lpDisp);
m_drvPDF.AttachDispatch(lpDisp); // 銷毀時自動 Release
// 選擇 PDF 檔案
CFileDialog dlg(TRUE);
if (dlg.DoModal() == IDOK)
{
m_drvPDF.LoadFile(dlg.GetPathName()); // 載入並顯示
}
else
{
OnCancel();
}
return TRUE;
}
AcroPDF.dll → 產生類別 IAcroAXDocShim,標頭檔 acropdf.h。m_wndPDF.CreateControl(_T("AcroPDF.PDF.1"), ...)。| 方法 | 功能 |
|---|---|
LoadFile(path) | 載入並顯示 PDF 檔案 |
Print() | 列印文件 |
setZoom(percent) | 設定頁面縮放比例 |
setShowToolbar(BOOL) | 顯示/隱藏工具列 |
gotoFirstPage() | 跳至第一頁 |
gotoLastPage() | 跳至最後一頁 |
gotoNextPage() | 下一頁 |
gotoPreviousPage() | 上一頁 |
| 現象 | 原因與解決 |
|---|---|
| 控制項區域空白/黑畫面 | 缺少 WS_CLIPCHILDREN 風格,或父視窗重繪順序錯誤。 |
CreateControl 失敗 | ProgID 錯誤、控制項未註冊 (需重新安裝 Reader)、權限不足。 |
LoadFile 無反應 | 路徑錯誤、檔案損毀、Reader 版本過舊不支援該 PDF 版本。 |
| 記憶體洩漏 | 未正確 Release IDispatch,使用 COleDispatchDriver::AttachDispatch 可自動管理。 |
雖然新版 Acrobat ActiveX 控制項無法直接透過 ClassWizard 產生事件接收包裝類別,但利用 CreateControl + IDispatch + COleDispatchDriver 組合,仍能輕鬆整合 PDF 檢視功能。掌握此模式,亦可應用於其他缺乏完整類型庫的 ActiveX 控制項整合。