ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-06-08 14:01:13  阅读:800  来源: 互联网

标签:c clipboard com ole


我想问的问题是:

(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示例的实现).

总之,我要做的准备粘贴的工作是:

>有一个实现IOLEObject,IDataObject,IPersistStorage和IViewObject的OLEObject类(不太确定IViewObject).
>有一个实现IDataObject的DataObject类(与1中的对象相同,但只有IDataObject接口).
>在2个对象的IDataObject的实现中,至少具有“Object Descriptor”,“Embed Source”和“MetaFilePict”类型的数据. MetaFile可以通过Convert an image into WMF with .NET?中提供的方法创建.
>确保COM可以访问这些类并正确注册. https://limbioliong.wordpress.com/2011/08/30/creating-a-com-server-using-c/
>执行复制时,通过StgCreateDocfile构造IStorage,使用WriteClassStg设置OLEObject的GUID,并在其中写入OLEObject所需的其他数据.
>构造DataObject类并将其作为“嵌入源”提供给IStorage.
>使用OleSetClipboard将DataObject设置为剪贴板.

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

我完成后会在这里添加一些代码,以便其他寻找OLE细节的人可以轻松找到它.

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

标签:c,clipboard,com,ole
来源: https://codeday.me/bug/20190608/1198443.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有