首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

實現 IE 風格無對話框列印網頁:IOleCommandTarget::Exec(OLECMDID_PRINT) 一鍵列印技術

     編輯:關於C語言

在內嵌 WebBrowser 控件 (SHDocVw.WebBrowser / IWebBrowser2) 的應用程式中,若要實現類似 IE 工具列「列印」按鈕的效果——不彈出列印對話框、直接使用預設印表機列印當前文件——可透過 IOleCommandTarget::Exec 執行 OLECMDID_PRINT 命令。本文提供完整的 MFC 實作程式碼、介面查詢流程與錯誤處理。

核心原理

  • WebBrowser 控件實作 IOleCommandTarget 介面,支援標準編輯命令 (列印、另存、複製、選取全部等)。
  • 呼叫 Exec(NULL, OLECMDID_PRINT, 0, NULL, NULL) 即觸發內建列印邏輯,繞過 PrintDlg。
  • 需先取得文件物件的 IDispatch,再 QueryInterface 為 IOleCommandTarget。

完整 MFC 實作程式碼

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") // 部分建置環境需要

擴充:其他實用 OLECMDID 命令

命令 ID功能參數說明
OLECMDID_PRINT直接列印 (無對話框)無參數
OLECMDID_PRINTPREVIEW列印預覽無參數
OLECMDID_PAGESETUP頁面設定對話框無參數
OLECMDID_SAVEAS另存為對話框無參數
OLECMDID_COPY複製選取內容無參數
OLECMDID_SELECTALL全選無參數
OLECMDID_ZOOM縮放比例pvaIn 指向 VARIANT (長整數百分比)
OLECMDID_GETZOOM取得目前縮放pvaOut 接收 VARIANT

進階:列印前自訂頁邊距/頁首頁尾

直接列印使用系統預設頁面設定。若需程式控制:

  1. 先呼叫 OLECMDID_PAGESETUP 讓使用者設定 (會彈出對話框)。
  2. 或使用 IWebBrowser2::ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, ...) 搭配 IPrintTemplate 實作自訂列印模板 (較複雜)。

錯誤碼對照與除錯

替代方案:IWebBrowser2::ExecWB

// 更高層封裝,直接在 IWebBrowser2 上呼叫
HRESULT hr = m_wndBrowser.GetControlUnknown()->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser);
if (SUCCEEDED(hr)) {
    hr = pBrowser->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
    pBrowser->Release();
}

OLECMDEXECOPT_DONTPROMPTUSER (0x2) 明確指示不提示使用者,效果等同 IOleCommandTarget::Exec。

總結

透過 IOleCommandTarget::Exec(OLECMDID_PRINT) 或 IWebBrowser2::ExecWB,只需幾行程式碼即可實現 IE 風格的「一鍵列印」功能,無需處理複雜的 PrintDlg、DEVMODE、DOCINFO 等 GDI 列印細節。關鍵在於正確取得文件的 IDispatch、查詢 IOleCommandTarget、嚴格釋放介面,並在 DocumentComplete 事件後執行以確保文件就緒。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
HRESULT含義對策
E_NOINTERFACE文件不支援 IOleCommandTarget確認文件已完全載入 (DocumentComplete 事件後)
OLECMDERR_E_NOTSUPPORTED命令不支援 (如非 HTML 文件)檢查文件類型,僅 HTML/RTF 支援列印
OLECMDERR_E_DISABLED命令當前禁用 (如正在載入中)等待 READYSTATE_COMPLETE
E_FAIL列印子系統錯誤 (印表機離線、驅動異常)檢查印表機狀態、嘗試 OLECMDID_PRINTPREVIEW 先驗證