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

VC++ 自動化客戶端操作 Word 2000 完整指南

     編輯:VC 教學

自動化技術概述

自動化是基於 COM/DCOM 的技術,讓一個應用程式(自動化客戶端)控制另一個應用程式(自動化伺服器)的物件,使用其提供的豐富功能。Microsoft Office 套件成員(Word、Excel、PowerPoint)皆為自動化伺服器。

核心概念

角色說明範例
自動化伺服器提供物件、方法、屬性供他人使用Word.Application、Excel.Application
自動化客戶端使用伺服器提供的物件、方法、屬性我們的 VC++ 程式
IDispatch 介面通用介面,支援晚期綁定,跨語言呼叫所有自動化物件皆實作此介面

自動化分類

  • 本地自動化: 客戶端與伺服器在同一台電腦
  • 遠端自動化: 透過 DCOM 在網路上不同電腦間進行

VC++ 實作自動化的關鍵技術

1. 類別向導產生包裝類別

  1. 專案右鍵 → Add Class → MFC Class from TypeLib
  2. 選擇 Microsoft Word 9.0 Object Library (Word 2000)
  3. 選擇需包裝的類別(通常全選)
  4. 產生的檔案:msword9.h、msword9.cpp

2. 核心包裝類別


// 主要類別對應
_Application          → Word 應用程式
_Document             → 文件物件
_Selection            → 選取範圍
Documents             → 文件集合

3. VARIANT 與 COleVariant

自動化參數傳遞使用 VARIANT,MFC 提供 COleVariant 包裝:


// 常用建構式
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  // 選擇性參數
COleVariant vtTrue((short)TRUE);                               // 布林值
COleVariant vtFalse((short)FALSE);
COleVariant vtFileName("C:\\Test.doc");                        // 字串
COleVariant vtIndex(1);                                        // 數值

完整實作範例:開啟 Word 文件並提取內容

專案設定

  • 建立 Single Document 專案
  • View 基類選 CEditView(內建編輯控件)
  • 包含產生的 msword9.h

核心程式碼


// WordAutomation.cpp
#include "stdafx.h"
#include "WordAutomation.h"
#include "msword9.h"  // 類別向導產生的包裝類別

void CWordAutomationView::OnFileOpenWord()
{
    CFileDialog dlg(TRUE, _T("doc"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                    _T("Word 文件 (*.doc)|*.doc|所有檔案 (*.*)|*.*||"));
    if (dlg.DoModal() != IDOK) return;
    
    CString strFile = dlg.GetPathName();
    ExtractWordContent(strFile);
}

void CWordAutomationView::ExtractWordContent(LPCTSTR lpszFilePath)
{
    _Application wordApp;           // Word 應用程式物件
    _Document wordDoc;              // 文件物件
    _Selection wordSel;             // 選取範圍物件
    COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    COleVariant vtFalse((short)FALSE);
    COleVariant vtTrue((short)TRUE);
    
    try {
        // 1. 啟動 Word (若已執行則連接現有實例)
        if (!wordApp.CreateDispatch(_T("Word.Application"))) {
            AfxMessageBox(_T("無法啟動 Word!"));
            return;
        }
        
        // 可見性設定(背景處理設為 FALSE)
        wordApp.SetVisible(FALSE);
        
        // 2. 開啟文件
        COleVariant vtFile(lpszFilePath);
        COleVariant vtConfirm(FALSE), vtReadOnly(FALSE), vtAddRecent(FALSE);
        COleVariant vtPwdDoc, vtPwdTmpl, vtRevert(FALSE), vtWritePwdDoc, vtWritePwdTmpl;
        COleVariant vtFormat((short)wdOpenFormatAuto);
        
        wordDoc = wordApp.GetDocuments().Open(
            vtFile, vtConfirm, vtReadOnly, vtAddRecent,
            vtPwdDoc, vtPwdTmpl, vtRevert,
            vtWritePwdDoc, vtWritePwdTmpl, vtFormat);
        
        // 3. 全選內容
        wordSel = wordApp.GetSelection();
        wordSel.WholeStory();   // 等同 Ctrl+A
        
        // 4. 複製到剪貼簿
        wordSel.Copy();
        
        // 5. 關閉文件(不儲存)
        wordDoc.Close(vtFalse, vtOptional, vtOptional);
        
        // 6. 退出 Word
        wordApp.Quit(vtFalse, vtOptional, vtOptional);
        
        // 7. 從剪貼簿取得內容並顯示
        PasteFromClipboard();
        
    } catch (COleException* e) {
        TCHAR szErr[256];
        e->GetErrorMessage(szErr, 255);
        AfxMessageBox(CString(_T("OLE 錯誤:")) + szErr);
        e->Delete();
    } catch (CMemoryException* e) {
        AfxMessageBox(_T("記憶體不足!"));
        e->Delete();
    } catch (...) {
        AfxMessageBox(_T("未知錯誤!"));
    }
}

void CWordAutomationView::PasteFromClipboard()
{
    // 確保為 CEditView
    CEditView* pView = DYNAMIC_DOWNCAST(CEditView, this);
    if (pView) {
        // 貼上剪貼簿內容到編輯控件
        pView->OnEditPaste();
    }
}

VBA 巨集錄製:探索物件模型的關鍵

Word 內建 VBA 編輯器可錄製巨集,產生的程式碼直接對應自動化物件模型:

錄製步驟

  1. Word 中:工具 → 巨集 → 錄製新巨集
  2. 命名(如 Macro1),開始錄製
  3. 執行操作:開啟文件、全選、複製
  4. 停止錄製,檢視程式碼(工具 → 巨集 → 編輯)

產生的 VBA 程式碼對照


Sub Macro1()
    Documents.Open FileName:="Test.doc", ConfirmConversions:=False, _
        ReadOnly:=False, AddToRecentFiles:=False, PasswordDocument:="", _
        PasswordTemplate:="", Revert:=False, WritePasswordDocument:="", _
        WritePasswordTemplate:="", Format:=wdOpenFormatAuto
    Selection.WholeStory
    Selection.Copy
End Sub

對應物件:Documents、Selection → VC++ 中為 wordApp.GetDocuments()、wordApp.GetSelection()

進階操作範例

1. 尋找與取代


wordSel.GetFind().ClearFormatting();
wordSel.GetFind().GetReplacement().ClearFormatting();
wordSel.GetFind().Execute(
    COleVariant(_T("舊文字")),      // FindWhat
    vtOptional, vtOptional, vtOptional, vtOptional, vtOptional,
    vtOptional, vtOptional, vtOptional,
    COleVariant(_T("新文字")),      // ReplaceWith
    COleVariant((short)wdReplaceAll) // Replace
);

2. 插入表格


COleVariant vtRange = wordSel.GetRange();
wordDoc.GetTables().Add(vtRange, 3, 4, vtOptional, vtOptional);
// 取得表格並填入資料
_Table table = wordDoc.GetTables().Item(1);
table.Cell(1, 1).GetRange().SetText(_T("標題1"));
table.Cell(1, 2).GetRange().SetText(_T("標題2"));

3. 另存為其他格式


COleVariant vtSaveAs(_T("C:\\Output.html"));
COleVariant vtFormat((short)wdFormatHTML);
wordDoc.SaveAs(vtSaveAs, vtFormat, vtOptional, vtOptional, 
               vtOptional, vtOptional, vtOptional, vtOptional,
               vtOptional, vtOptional, vtOptional, vtOptional,
               vtOptional, vtOptional, vtOptional, vtOptional);

4. 郵件合併


wordDoc.MailMerge().OpenDataSource(
    COleVariant(_T("C:\\Data.xlsx")), vtOptional, vtOptional,
    vtOptional, vtOptional, vtOptional, vtOptional,
    COleVariant(_T("Sheet1$")), vtOptional, vtOptional);
wordDoc.MailMerge().Destination = wdSendToNewDocument;
wordDoc.MailMerge().Execute(vtOptional);

常見問題與解決方案

問題原因解決
CreateDispatch 失敗Word 未安裝、ProgID 錯誤、權限不足檢查註冊表 HKEY_CLASSES_ROOT\Word.Application、以管理員執行、修復 Office
參數錯誤 (DISP_E_TYPEMISMATCH)VARIANT 類型不匹配嚴格對應 VBA 參數類型、使用正確 VT_* 常數
執行緒模型不匹配STA/MTA 不一致AfxOleInit() 初始化、確保主執行緒為 STA
Word 進程殘留例外發生時未正確 Quit使用 try/catch/finally 確保釋放、或用智慧指標包裝
中文亂碼字碼頁不匹配設定 COleVariant 使用 VT_BSTR、確保專案為 Unicode

效能與最佳實踐

  • 重用 Word 實例: 避免頻繁 CreateDispatch/Quit,維護全域 _Application 指標
  • 背景處理: wordApp.SetVisible(FALSE) 並停用螢幕更新 wordApp.SetScreenUpdating(FALSE)
  • 批次操作: 一次開啟多個文件處理,減少啟動開銷
  • 錯誤恢復: 實作心跳檢測,偵測 Word 掛掉時自動重啟
  • 版本兼容: 使用 Word.Application 無版本 ProgID,或透過註冊表偵測安裝版本

安全性考量

  • 不信任的文件可能包含巨集病毒 → 開啟前設定 wordApp.SetAutomationSecurity(msoAutomationSecurityForceDisable)
  • 避免在服務中直接自動化 Word(非互動式桌面問題) → 改用 Open XML SDK 或第三方庫
  • 文件密碼保護處理 → 正確傳遞密碼參數

結語

VC++ 透過自動化技術操作 Word 2000,核心在於:理解 COM/IDispatch 機制、善用類別向導產生包裝類別、參考 VBA 巨集探索物件模型、正確處理 VARIANT 參數與例外。掌握此技術可構建強大的文件處理、報表生成、格式轉換等企業級應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved