簡體   English   中英

如何比較 Word Interop 對象的“引用相等性”並確定某個段落所屬的集合或父對象?

[英]How can I compare Word Interop objects for "reference equality" AND determine collection or parent object to which, say, a paragraph belongs?

我希望能夠:

  1. 在“引用相等”的基礎上比較 Word Interop COM 代理;
  2. 從特定對象(例如段落)映射到它來自的集合,或者至少
  3. 確定兩段是否來自同一部分,哪一段相對在前一段之前

我為什么要這樣做? 我正在嘗試構建一個 Word 插件,它的作用類似於拼寫檢查器,因為它在后台運行(后台我的意思是使用 SendMessage 從主 Word 線程中定期竊取時間)並掃描文檔以確定文本“令牌”。 我希望能夠保留一組令牌並在文檔更改時更新它們。 一個具體的例子是,如果用戶編輯了一個給定的段落,我想重新掃描該段落並更新指向該段落的數據結構。 如果無法在用戶編輯的段落(即選擇范圍開始所在的段落)和我“存儲”在數據結構中的段落之間進行映射,我就不能這樣做。


上面第 1 項的示例代碼

如果我編寫以下 VBA 代碼:

Dim Para1 As Paragraph
Dim Para2a As Paragraph
Dim Para2b As Paragraph
Set Para1 = ActiveDocument.Paragraphs(1)
Set Para2a = Para1.Next
Set Para2b = Para1.Next.Next.Previous
If Para2a Is Para2b Then
    Debug.Print ("Para2a Is Para2b")
Else
    Debug.Print ("Para2a Is Not Para2b")
End If

然后我得到輸出:

"Para2a Is Not Para2b"

這可能在物理上是正確的(不同的 COM 代理),但在邏輯上不正確。 我需要能夠比較這些段落並確定它們在邏輯上是否是相同的底層段落。

(我打算用 C# 編寫插件,但上面的 VBA 代碼演示了在進行過多編碼之前我需要克服的問題)。

對於上面的第 2 項和第 3 項,希望它們是不言自明的。 假設我有一個段落(互操作代理)參考。 我想弄清楚它在文檔中的“位置”。 它屬於第 1 節嗎? 它在頁腳中嗎? 如果沒有這種能力,我所能做的就是在每次更改時重新掃描整個文檔,以了解事物的來源,這當然效率低下並且對應用程序用戶來說不夠及時。

任何想法都非常感謝! 我很樂意根據需要發布其他信息。

在 COM Interop 的上下文中導航引用相等的細節總是一個有趣的練習。

我不會知道Paragraph.Next()Paragraph.Previous()方法的實現細節,但是它們表現出的行為與基於 COM 的集合在運行時可調用包裝器創建方面的一般行為非常相似。

通常,如果可能,框架會避免創建新的 RCW 實例以響應對已初始化並分配了 RCW 的 COM 對象的其他引用。 如果指向IUnknown的特定指針的 RCW 已經存在,則由該 RCW 維護的內部引用計數增加,然后返回 RCW。 這允許框架避免增加實際 COM 對象的引用計數 ( AddRef )。

基於 COM 的集合是具有實現IEnumerable托管表示的 COM 對象,每次訪問項目時似乎都會生成一個新的 RCW,即使該項目在會話期間已被訪問。

例如:

Word.Document document = Application.ActiveDocument;
Paragraphs paragraphs = document.Paragraphs;

Paragraph first = paragraphs[1];
Paragraph second = paragraphs[1];

bool thisIsFalse = (first == second);

如果您想進行任何類型的“引用相等性”檢查,您需要從基於 COM 的集合中轉義,特別是在您的情況下: Paragraphs對象。 你可以簡單地通過抓住它的孩子並將它們存儲在你自己的、純粹管理和可預測的集合中來做到這一點,如下所示:

List<Paragraph> niceParagraphs = paragraphs.Cast<Paragraph>().ToList();

盡管將 LINQ 與 COM Interop 一起使用可能看起來有點嚇人(如果它對您來說不是……它真的應該!)但我相當確定上面的代碼是安全的,不會在那里留下任何懸空引用或其他任何東西可惡的。 但是,我還沒有詳盡地測試上述代碼。

不要忘記在完成這些資源后正確釋放它們,至少在您的需求需要這種謹慎級別的情況下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM