在內嵌 WebBrowser 控件 (SHDocVw.WebBrowser / IWebBrowser2) 的應用程式中,若要實現類似 IE 工具列「列印」按鈕的效果——不彈出列印對話框、直接使用預設印表機列印當前文件——可透過 IOleCommandTarget::Exec 執行 OLECMDID_PRINT 命令。本文提供完整的 MFC 實作程式碼、介面查詢流程與錯誤處理。
IOleCommandTarget 介面,支援標準編輯命令 (列印、另存、複製、選取全部等)。Exec(NULL, OLECMDID_PRINT, 0, NULL, NULL) 即觸發內建列印邏輯,繞過 PrintDlg。IDispatch,再 QueryInterface 為 IOleCommandTarget。void CMyBrowserView::OnFilePrint()
{
// 1. 取得文件的 IDispatch 介面
LPDISPATCH pDisp = m_wndBrowser.GetDocument(); // CWnd::GetDocument() 包裝
if (!pDisp) {
TRACE(_T("GetDocument() 失敗\n"));
return;
}
// 2. QueryInterface 取得 IOleCommandTarget
LPOLECOMMANDTARGET pCmdTarget = NULL;
HRESULT hr = pDisp->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&pCmdTarget);
if (FAILED(hr) || !pCmdTarget) {
TRACE(_T("QueryInterface IOleCommandTarget 失敗: 0x%08X\n"), hr);
pDisp->Release();
return;
}
// 3. 執行列印命令
// pguidCmdGroup = NULL (標準命令組)
// nCmdID = OLECMDID_PRINT
// nCmdExecOpt = 0 (預設執行選項)
// pvaIn = NULL (無輸入參數)
// pvaOut = NULL (無輸出參數)
hr = pCmdTarget->Exec(NULL, OLECMDID_PRINT, 0, NULL, NULL);
if (FAILED(hr)) {
TRACE(_T("Exec(OLECMDID_PRINT) 失敗: 0x%08X\n"), hr);
// 可能原因:文件未完全載入、無列印權限、印表機離線
}
// 4. 釋放介面 (嚴格順序)
pCmdTarget->Release();
pDisp->Release();
}
#include // IOleCommandTarget, OLECMDID_PRINT
// 或
#include // 同樣定義
#pragma comment(lib, "mshtml.lib") // 部分建置環境需要
| 命令 ID | 功能 | 參數說明 |
|---|---|---|
OLECMDID_PRINT | 直接列印 (無對話框) | 無參數 |
OLECMDID_PRINTPREVIEW | 列印預覽 | 無參數 |
OLECMDID_PAGESETUP | 頁面設定對話框 | 無參數 |
OLECMDID_SAVEAS | 另存為對話框 | 無參數 |
OLECMDID_COPY | 複製選取內容 | 無參數 |
OLECMDID_SELECTALL | 全選 | 無參數 |
OLECMDID_ZOOM | 縮放比例 | pvaIn 指向 VARIANT (長整數百分比) |
OLECMDID_GETZOOM | 取得目前縮放 | pvaOut 接收 VARIANT |
直接列印使用系統預設頁面設定。若需程式控制:
OLECMDID_PAGESETUP 讓使用者設定 (會彈出對話框)。IWebBrowser2::ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, ...) 搭配 IPrintTemplate 實作自訂列印模板 (較複雜)。| HRESULT | 含義 | 對策 |
|---|---|---|
E_NOINTERFACE | 文件不支援 IOleCommandTarget | 確認文件已完全載入 (DocumentComplete 事件後) |
OLECMDERR_E_NOTSUPPORTED | 命令不支援 (如非 HTML 文件) | 檢查文件類型,僅 HTML/RTF 支援列印 |
OLECMDERR_E_DISABLED | 命令當前禁用 (如正在載入中) | 等待 READYSTATE_COMPLETE |
E_FAIL | 列印子系統錯誤 (印表機離線、驅動異常) | 檢查印表機狀態、嘗試 OLECMDID_PRINTPREVIEW 先驗證 |