首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C#中实现OLE服务器

如何在C#中实现OLE服务器
EN

Stack Overflow用户
提问于 2016-12-01 02:34:16
回答 1查看 1.2K关注 0票数 6

我想问的问题是:

(1)如果我通过剪贴板类与剪贴板交互,那么在“嵌入源”和"MetaFilePict“流中应该是什么?

(2)如果通过COM接口IDataObject与剪贴板交互,应该如何处理“嵌入源”和"MetaFilePict“中的句柄?

(3)是否有更好的方法在C#中实现OLE (客户机或服务器将帮助我)?

详细信息:

我正在C#中寻找OLE服务器的实现(extern和其他在x86上工作的方法对我来说都是可以的,只要它们可以在一个C#项目中)。我找不到不涉及MFC的OLE示例。所以我先试了一下。

我的第一步是看看其他OLE服务器做什么,以便将它们的数据放入剪贴板。我尝试了两种方法来与剪贴板进行交互: NET剪贴板类,它给我提供了后面描述的三个流,以及OleGetClipboard返回的OleGetClipboard接口,它为我提供了指针。

我发现原点放置了三个数据条目:对象描述符、嵌入源和MetaFilePict。他们似乎是溪流。如果我从这三个流中读取所有字节,将它们放回一个新的DataObject中,并再次将DataObject放到剪贴板上,我就能够将原始对象粘贴到例如Word中,这意味着这三个流的内容足够一个OLE容器粘贴。

我进一步发现,对象描述符包含带有数据类guid和一些名称的OBJECTDESCRIPTOR结构,并且能够实例化该对象并将其转换为IOLEObject。但是我不知道另外两个流,即Embed和MetaFilePict应该是什么。据我所知,Embed应该包含在创建IOLEObject (可能是通过InitFromData)之后传递给它的数据,但我没有成功。再加上MetaFilePict,似乎没有这个条目,其他两个就不能正常工作了(如果只有对象描述符和嵌入源存在,Word中的粘贴就什么都没有了)。但我还是不知道里面是什么。它似乎以一个ASCII字符串开始(在我的例子中它是"CPYA 4.2878 724#"),并且看起来不像WMF文件。

如果我使用COM对象IDataObject (无论是在System.Runtime.InteropServices.ComTypes还是Microsoft.VisualStudio.OLE.Interop名称空间中),我可以从它获得HMETAFILEPICT,但是我不知道如何使用句柄。PlayMetaFile对此不起作用。

编辑

在MFC中,示例使用OleCreateFromData直接从剪贴板获取的IDataObject创建对象。这也应该适用于C#。但这只是客户端的实现。我将尝试了解如何实现服务器。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-03 07:52:59

我不知道为什么我的问题被否决了。实际上,我可以在互联网上找到很多问类似问题的帖子,但没有一条得到完整的答案。这太可惜了。

最后,通过MFC示例代码,我自己找到了答案。对于一个新人来说,OLE真的很难学习,尤其是没有MFC的时候。没有人能详细地告诉你该怎么做。

首先,这两种方法都应该以相同的方式工作。对于“对象描述符”,HGlobal只是一个内存块,它只包含OBJECTDESCRIPTOR结构。对于“嵌入源”,IStorage通常是用ILockBytes创建的,它只有一个内存块。问题是它上有什么样的数据。实际上,块上有一种名为OLE复合文件的格式。它包含两部分信息:用于初始化IOLEObject的guid和数据。guid非常重要,因为它实际上是用来创建IOLEObject的。“对象描述符”中的GUID仅用于显示特殊粘贴对话框。GUID可以通过IStorage API函数添加到WriteClassStg中。IStorage中包含的数据的其他部分通常是一个名为“Content”的流(至少这是MFC示例的实现)。

最后,我要做的是准备粘贴:

  1. 有一个OLEObject类来实现IOLEObject、IDataObject、IPersistStorage和IViewObject (不太确定IViewObject)。
  2. 有一个实现DataObject的IDataObject类(与1中的对象执行相同的操作,但只执行IDataObject接口)。
  3. 在两个对象的IDataObject实现中,至少有“对象描述符”、“嵌入源”和"MetaFilePict“类型的数据。MetaFile可以由用.NET将图像转换为WMF?中提供的方法创建。
  4. 确保类可以被COM访问并正确注册。https://limbioliong.wordpress.com/2011/08/30/creating-a-com-server-using-c/
  5. 在执行副本时,通过StgCreateDocfile构造一个StgCreateDocfile,用WriteClassStg设置OLEObject的GUID,并在其中写入OLEObject所需的其他数据。
  6. 构造DataObject类并将其作为“嵌入源”提供给它。
  7. 将DataObject设置为带有OleSetClipboard的剪贴板。

似乎MFC注册了一个允许创建IClassFactory的OLEObject。我不知道如何在C#中实现这一点。

在完成之后,我将在这里添加一些代码,以便其他寻找OLE细节的人能够轻松找到它。

一个(勉强)工作的例子:https://github.com/acaly/SharpOle

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40901712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档