簡體   English   中英

如何在C#中實現OLE服務器

[英]How to implement OLE server in C#

我想問的問題是:

(1)如果我通過剪貼板類與剪貼板交互,那么“嵌入源”和“MetaFilePict”流應該是什么?

(2)如果我通過COM接口IDataObject與剪貼板交互,我應該怎么處理“嵌入源”和“MetaFilePict”中的句柄?

(3)在C#中有更好的方法來實現OLE(客戶端或服務器會幫助我)嗎?

更多細節:

我正在尋求在C#中實現OLE服務器(外部Windows API和其他適用於x86的方法對我來說都可以,只要它們可以在一個C#項目中)。 我找不到任何不涉及MFC的OLE示例。 所以我先嘗試了一下。

我的第一步是查看其他OLE服務器執行哪些操作以將其數據放入剪貼板。 我已經嘗試了2種與剪貼板交互的方法:NET Clipboard類,它給我三個Streams,如后面所述,以及OleGetClipboard返回的IDataObject接口,它給了我指針。

我發現Origin放了三個數據條目:Object Descriptor,Embed Source和MetaFilePict。 它們似乎是Stream。 如果我從三個Streams讀取所有字節,將它們放回新的DataObject並再次將DataObject放到剪貼板中,我可以將原始對象粘貼到例如Word中,這意味着三個Streams的內容足夠用於粘貼OLE容器。

我進一步發現,Object Descriptor包含帶有數據類guid和一些名稱的OBJECTDESCRIPTOR結構,我能夠實例化該對象並將其轉換為IOLEObject。 但我不知道其他兩個流,Embed Source和MetaFilePict應該是什么。 根據我的理解,Embed Source應該包含在創建它之后傳遞給IOLEObject的數據(可能是由InitFromData),但是我沒有成功。 並且重新編寫MetaFilePict,似乎沒有這個條目,其他兩個無法正常工作(如果只存在Object Descriptor和Embed Source,則粘貼在Word中最終沒有任何內容)。 但同樣,我不知道它里面是什么。 它似乎以ASCII字符串開頭(在我的例子中是“CPYA 4.2878 724#”)並且看起來不像WMF文件。

如果我使用COM對象IDataObject(在System.Runtime.InteropServices.ComTypes或Microsoft.VisualStudio.OLE.Interop命名空間中),我可以從中獲取HMETAFILEPICT,但我不知道如何使用該句柄。 PlayMetaFile無法正常工作。

編輯

在MFC中,該示例使用OleCreateFromData直接從剪貼板獲取的IDataObject創建對象。 這應該也適用於C#。 但這只是客戶端的實現。 我將嘗試找出如何實現服務器。

我不知道為什么我的問題被投了票。 實際上,我可以在互聯網上找到許多線程,要求提出類似的問題,但沒有一個最終得到完整的答案。 這是一種恥辱。

最后,在查看MFC示例代碼后,我自己找到了答案。 OLE對於新人來說真的很難學,特別是沒有MFC。 根本沒有人可以告訴你詳細的做什么。

首先,兩種方法都應該以相同的方式工作。 對於“對象描述符”,HGlobal只是一個內存塊,它只包含OBJECTDESCRIPTOR結構。 對於“嵌入源”,IStorage通常使用ILockBytes創建,ILockBytes只有一個內存塊。 問題是它上面有什么樣的數據。 實際上塊上是一種稱為OLE復合文件的格式。 它包含兩部分信息:guid和用於初始化IOLEObject的數據。 guid非常重要,因為它實際上是用於創建IOLEObject的那個。 “對象描述符”中的GUID僅用於顯示“特殊粘貼”對話框。 可以使用WriteClassStg API函數將GUID添加到IStorage中。 IStorage中包含的其他數據部分通常是一個名為“Contents”的單個流(至少這是我所擁有的MFC示例的實現)。

總之,我要做的准備粘貼的工作是:

  1. 有一個實現IOLEObject,IDataObject,IPersistStorage和IViewObject的OLEObject類(不太確定IViewObject)。
  2. 有一個實現IDataObject的DataObject類(與1中的對象做同樣的事情,但只有IDataObject接口)。
  3. 在2個對象的IDataObject的實現中,至少具有類型“Object Descriptor”,“Embed Source”和“MetaFilePict”的數據。 可以通過使用.NET將圖像轉換為WMF中提供的方法來創建MetaFile 嗎?
  4. 確保COM可以訪問這些類並正確注冊。 https://limbioliong.wordpress.com/2011/08/30/creating-a-com-server-using-c/
  5. 執行復制時,通過StgCreateDocfile構造IStorage,使用WriteClassStg設置OLEObject的GUID,並在其中寫入OLEObject所需的其他數據。
  6. 構造DataObject類並將其作為“嵌入源”提供給IStorage。
  7. 使用OleSetClipboard將DataObject設置為剪貼板。

似乎MFC注冊了一個允許創建OLEObject的IClassFactory。 我不知道如何在C#中實現這一點。

我完成后會在這里添加一些代碼,以便其他尋找OLE細節的人可以輕松找到它。

一個(幾乎沒有)工作的例子: https//github.com/acaly/SharpOle

暫無
暫無

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

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