Microsoft Word 透過 COM 互操作暴露豐富的事件模型,C# 以委派為基礎實現事件訂閱。本文系統整理 Word 2000/2002/2003 三版本支援的事件清單,並提供完整的 Visual C# 自動化客戶端範例,涵蓋文件開啟/關閉/列印/儲存、視窗互動、郵件合併等核心場景。
| 事件 | 觸發時機 |
|---|---|
| Close | 文件關閉時 |
| DocumentBeforeClose | 文件關閉前 |
| DocumentBeforePrint | 文件列印前 |
| DocumentBeforeSave | 文件儲存前 |
| DocumentChange | 新建/開啟/切換活動文件 |
| DocumentOpen | 文件開啟時 |
| GotFocus / LostFocus | ActiveX 控制項焦點變化 |
| New | 基於範本建立新文件(僅範本中程序生效) |
| NewDocument | 建立新文件時 |
| Open | 文件開啟時 |
| Quit | 使用者結束 Word |
| WindowActivate / WindowDeactivate | 文件視窗啟用/停用 |
| WindowBeforeDoubleClick | 編輯區雙擊前 |
| WindowBeforeRightClick | 編輯區右鍵前 |
| WindowSelectionChange | 活動視窗選取範圍變化 |
| 事件 | 說明 |
|---|---|
| EPostageInsert | 插入電子郵資 |
| EPostagePropertyDialog | 彈出郵資屬性對話框 |
| MailMergeAfterMerge / AfterRecordMerge | 郵件合併完成/單筆完成 |
| MailMergeBeforeMerge / BeforeRecordMerge | 郵件合併開始/單筆開始前 |
| MailMergeDataSourceLoad / Validate | 資料來源載入/驗證 |
| MailMergeWizardSendToCustom / StateChange | 精靈自訂按鈕/步驟切換 |
| WindowSize | 應用程式視窗大小/位置變化 |
(原文未列出 2003 獨有事件,通常為 XML/智慧標籤相關擴展)
Button (button1)button1_Click 撰寫代碼
using System;
using System.Diagnostics;
using System.Windows.Forms;
using Word = Microsoft.Office.Interop.Word;
namespace WordEventDemo
{
public partial class Form1 : Form
{
private Word.Application _wordApp;
public Form1() => InitializeComponent();
private void button1_Click(object sender, EventArgs e)
{
// 1. 啟動 Word 並建立文件
_wordApp = new Word.Application { Visible = true };
var missing = Type.Missing;
var doc = _wordApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);
doc.Content.Text = "Handle Events for Microsoft Word Using C#.";
doc = null; // 釋放文件參考,避免 RCW 洩漏
// 2. 訂閱事件(使用 ApplicationEvents4 介面)
_wordApp.DocumentBeforeClose += OnDocumentBeforeClose;
_wordApp.DocumentBeforeSave += OnDocumentBeforeSave;
_wordApp.DocumentChange += OnDocumentChange;
_wordApp.WindowBeforeDoubleClick += OnWindowBeforeDoubleClick;
_wordApp.WindowBeforeRightClick += OnWindowBeforeRightClick;
}
// 3. 事件處理器
private void OnDocumentBeforeClose(Word.Document doc, ref bool cancel)
=> Debug.WriteLine($"DocumentBeforeClose: {doc.Name}");
private void OnDocumentBeforeSave(Word.Document doc, ref bool saveAsUI, ref bool cancel)
=> Debug.WriteLine($"DocumentBeforeSave: {doc.Name}");
private void OnDocumentChange()
=> Debug.WriteLine("DocumentChange");
private void OnWindowBeforeDoubleClick(Word.Selection sel, ref bool cancel)
=> Debug.WriteLine($"WindowBeforeDoubleClick: {sel.Text}");
private void OnWindowBeforeRightClick(Word.Selection sel, ref bool cancel)
=> Debug.WriteLine($"WindowBeforeRightClick: {sel.Text}");
// 4. 關閉時清理
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (_wordApp != null)
{
_wordApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(_wordApp);
}
base.OnFormClosing(e);
}
}
}
每個事件對應專用委派類型,如 ApplicationEvents4_DocumentBeforeCloseEventHandler,參數包含 Word.Document 與 ref bool Cancel,允許取消操作。
Marshal.ReleaseComObject,否則 Word 進程殘留app.Documents.Add() → 產生中間 RCW 無法釋放
// 編譯時綁定特定版本 PIA,執行時需對應版本 Word
// 跨版本部署建議:
// 1. 使用晚期綁定 (dynamic / Type.InvokeMember)
// 2. 或引用最低版本 PIA (Word 2000) 並啟用「內嵌 Interop 類型」
| 問題 | 原因 | 解決 |
|---|---|---|
| 事件不觸發 | 未持有 Application 實例變數,被 GC 回收 | 將 _wordApp 設為類別欄位 |
| Word 進程不退出 | RCW 未釋放 / 事件未取消訂閱 | Quit() + ReleaseComObject + -= 事件 |
| 拋出 COMException 0x800A11FD | Word 忙碌/對話框開啟中 | 重試機制 / 捕獲例外稍後再試 |
| 中文路徑/內容亂碼 | 編碼不匹配 | 確保文件編碼 UTF-8,Word 內部為 Unicode |
DocumentBeforeSave 觸發 Git commit 或雲端同步WindowBeforeDoubleClick 檢測敏感詞彙,Cancel = true 阻止操作結語:C# 操作 Word 事件的核心在於委派訂閱模型與COM 物件生命週期管理。掌握事件清單、正確釋放 RCW、處理版本相容,即可構建穩健的 Office 自動化解決方案。下一步嘗試整合 VSTO (Visual Studio Tools for Office) 獲得更原生的開發體驗與部署優勢。