请教OLE将IDataObject放在什么地方?

windcsn 2006-03-06 10:01:59
当我们开始DoDragDrop的时候,我们需要准备一个数据对象IDataObject和另外一个接口,然后我们就拖着数据到目标对象上;一般情况下,只有在数据到达目标对象上才知道数据是什么,但现在我想在我一开始拖动的时候就知道数据是什么。
我想,OLE肯定在拖动的过程中就将数据存储到一个位置了,否则,它到达目标对象时不可能知道源数据是什么,所以现在只要能找到这个数据存放位置,也就知道了。
希望大家给予指教!
...全文
264 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
windcsn 2006-03-14
  • 打赏
  • 举报
回复
期待中呀。。。。。。
xiaoqiqixiao 2006-03-13
  • 打赏
  • 举报
回复
呵呵,我也被绕晕了,我没说Drag&Drop不用OLE支持啊,只是说,这整个过程都是在这个DoDragDrop函数中实现的,也就是说,OLE是不需要将IOleDataObject指针放到某个地方的,因为这个IOleDataObject指针是DoDragDrop函数的参数。
来模拟一下这个DoDragDrop的过程吧,
OLE在DoDragDrop中不断的GetMessage(函数当然可以托管消息,你也可以的),判断鼠标和键盘消息,并用WindowFromPoint函数(我估计)判断当前鼠标在哪个窗口,然后查找是否有和这个窗口相关的IDropTarget指针,如果有就调用IDropTarget的DragEnter,DragOver等等方法,在这些方法中传入DoDragDrop函数的一个参数,也就是IDataObject指针(但是,这里面的过程应该复杂的多,因为IDropTarget在别的应用程序中,所以不应该是直接调用IDropTarget指针的),或许,中间还可能再调用IDropSource的某些方法。当检测到鼠标放开时,DoDragDrop做些收尾工作后就退出了吧,程序的消息循环也恢复正常了。
但是,不管怎样,这中间,基本上不会存在将IDataObject放在某个特定的地方,然后OLE去取来用这种情况吧。
也许OLE在调节不同的应用程序之间时会有可能列集IDataObject到其它的内存空间,不过,这个可能就牵涉到OLE的基本了吧,应该是和操作系统打交道的吧。或许,OLE将IDataObject放在某个地方是指这个意思吧。
windcsn 2006-03-13
  • 打赏
  • 举报
回复
实际上图中表示的,DODRAGDROP这个API正好是OLE的一部分
windcsn 2006-03-13
  • 打赏
  • 举报
回复
也说明了一点,消息依然存在,消息依然被OLE处理
windcsn 2006-03-13
  • 打赏
  • 举报
回复
呵呵,你这么说和我说的没有任何区别,你想说明什么问题来
xiaoqiqixiao 2006-03-13
  • 打赏
  • 举报
回复
哎,该怎么说楼主好呢,都说了可以在函数中用GetMessage或PeekMessage得到消息了。OLE在DoDragDrop中开了一个消息循环的。楼主在msdn中搜索IDropTarget,里面有一个题为
Sources and Targets: The OLE Drag and Drop Protocol的文章
在里面有一张图,这张图就大概描述了DoDragDrop的一个过程。估计其它文章也有这种图的,楼主仔细搜搜吧。
windcsn 2006-03-13
  • 打赏
  • 举报
回复
呵呵,我对消息很清楚
谢谢你的回答
我也可以告诉你,你在DoDragDrop的时候,即使鼠标的左键没有放下,但你应该知道鼠标在移动,这个Windows消息不会发送给SOURCE,同样,你在这个过程中按键盘上的CTRL和SHIFT等也不会发送给SOURCE,难道他们不产生消息?不会的,因为OLE能知道你移动鼠标或者按下了CTRL或SHIFT等,所以消息肯定不会被HANG UP的。同时,INSIDE OLE中也明确的说明了这点。
我觉得我可能需要反汇编才能看到是怎么搞的了,估计这边没有人可以回答;或者不愿意回答
xiaoqiqixiao 2006-03-13
  • 打赏
  • 举报
回复
楼主应该好好看看消息的知识了,基本上来讲(用::DispatchMessage派发消息的话),如果一个消息处理没有返回的话,是不可以处理其它消息的。你在哪启动DoDragDrop的,一般是在OnLButtonDown之类的消息处理里面吧,即使不是,也应该是在某个消息的处理函数中,在DoDragDrop没有返回前,这个消息处理当然不会返回,那么Windows的消息循环也就一直断在那了,其它消息当然没法收到。(当然也可以收到,你得在函数中自己调用GetMessage或PeekMessage等,MFC的DoModal就是这么干的)

至于说Drag&Drop需要OLE的支持,那是肯定的,因为你要知道,你的IDropTarget有可能是别的应用程序的,而你的IDataObject和IDropSoure则又是另外一个应用程序,它们的指针分属于不同的应用程序,一般来讲,OLE可能会需要列集IDropTarget吧,可能会有其它的方法,那可以肯定的是必需要OLE的支持(如果是同一个应用程序,则不需要)。OLE是什么,嵌入,链接,本身就是设计来针对不同应用程序之间数据交换的。

其实,个人以为,不通过OLE,也可以实现整个Drag&Drop的,至少在同一个应用程序中是没问题的,不过目前没搞清楚,OLE是怎样将IDropTarget指针和窗口联系在一起的,应该是通过一张表结构之类的,但是,这张表放在哪就不太清楚了。不过遗憾的告诉你,这张表中放着IDropSource和IOleObject指针的可能性很少。

说了一堆,于楼主的问题无益,不过不吐不快,见谅。
windcsn 2006-03-13
  • 打赏
  • 举报
回复
呵呵,其实你说的没有错
我们假设我们自己是OLE,那么我们控制这些消息循环,那么我们还从调用DoDragDrop的Application接收到IDataObject这个数据COM,我们还ACTIVE鼠标到达的目标应用程序的IDataObject这个COM接口。。。
好,那么我们应该知道IDataObject是什么东西,即使在鼠标没有到达目标程序。
OLE的基本,我要是能对其能特别了解就好了,或者我是MICRSOFT就好了。

希望各位能明白
windcsn 2006-03-12
  • 打赏
  • 举报
回复
呵呵
谢谢七七兄弟的回答
根据我测试得到的结果,在源启动(调用)DoDragDrop函数之后,无论是鼠标还是键盘消息,这个窗口都接受不到了,那么谁管理了?是这个函数,当然不是,函数没有管理和接受消息的能力,所以就是OLE代替源窗口管理了。
再说一件事情,你看过INSIDE OLE吗?DragDrop是其支持的一想能力,毋庸质疑其使用OLE来实现的,那么OLE肯定知道这个过程。
还有一件事情,如果你从Explorer.exe这个进程拖一个文件到某个窗口,你说怎么样实现IDropTarget?请教
windcsn 2006-03-12
  • 打赏
  • 举报
回复
或者说是参数
windcsn 2006-03-12
  • 打赏
  • 举报
回复
呵呵,你说的很好“这个时候系统接管拖放操作,记录四个参数值(不包括具体的数据)”,我就要这四个参数,我想你也知道IDataObject中实际上已经包含了需要的内容。
你明白我的意思了吗?
我相信OLE一定把数据放在什么地方了。。。
firmbird 2006-03-12
  • 打赏
  • 举报
回复
源对象调用DoDragDrop告诉系统准备拖放操作,并且提供了四个参数,其中前两个是IDataObject * pDataObject, IDropSource * pDropSource,(楼主应该明白这两个参数的意义吧?)这个时候系统接管拖放操作,记录四个参数值(不包括具体的数据),源对象本身不关心拖放目标是哪个,当鼠标经过其他应用程序窗口时,系统会查询该应用程序是否实现了IDragTarget接口,如果实现了,该系统调用目标对象接口函数DragEnter(),传入相应的参数,其中包括IDataObject * pDataObject,目标对象取得pDataObject接口指针,通过该接口指针直接向源对象查询相应的数据格式是不是目标对象所支持的,并做出相应的反应,就是说查询并取得数据的过程跟系统无关。
如果你要在目标对象(包括拖动经过、拖动结束)之外的程序取得源对象的数据,估计只能Hook DoDragDrop函数调用,然后取得IDataObject接口指针。
xiaoqiqixiao 2006-03-11
  • 打赏
  • 举报
回复
楼主不知道想明白没有,DoDragDrop是一个函数,请记住,是一个函数,你的IDataObject指针,IDragSource指针等等,都只是函数的参数,不关OLE的事,你的DragEnter,DragOver什么的,都是在函数内部所调用的东西,OLE并不需要将IDragSource或IDataObject指针保存在某一个特殊的位置,当然也许可以在函数内部会保存为一个局部变量,但那有什么用。

你现在希望做的是得到函数的某一个参数,Hook API是一个好方法了。

不过,如果楼主的源是一个窗口的话,楼主应该可以实现一个IDropTarget并关联源窗口,这样应该能在源窗口上就可以知道IDataObject了。
windcsn 2006-03-10
  • 打赏
  • 举报
回复
呵呵,我比你晕啊
只有IDropTarget才有DragEnter和DragOver等,但哪个太迟了,你难道是在TARGET上拖,首先肯定是IDragSource选择对象,然后在这个上面MOVE,再到TARGET上MOVE,但我需要在SOURCE上MOVE的时候就需要知道了
firmbird 2006-03-10
  • 打赏
  • 举报
回复
晕啊,拖动开始的时候连目标都还没有选定,怎么告诉目标啊?拖动时,鼠标经过窗体上方时,实际了IDropTarget接口的程序会收到DragEnter事件,在这个事件的传入参数中有IDataObject接口指针。
如果是源程序或者目标程序之外的第三方程序相介入这个过程,估计只能用钩子了。
windcsn 2006-03-10
  • 打赏
  • 举报
回复
你说的一点都没有错,但系统怎么样作为中介考虑过没有?按照正常的思维,OLE应该告诉目标,员数据在什么地方,对,那么我就需要这个,就需要OLE告诉我什么,并且在一开始拖动的时候就告诉我,而不是到了目标才告诉我
firmbird 2006-03-10
  • 打赏
  • 举报
回复
拖动操作是源跟目标程序之间的数据传递,系统只是作为传递开始前中介,不负责具体数据存储跟发送,数据是直接在源跟目标程序间交流的。
windcsn 2006-03-10
  • 打赏
  • 举报
回复
如xiaoqiqixiao说,OLE确实来判断,但最终是判断鼠标和键盘Event来决定是drop还是取消。 但他将数据应该放在一个位置,哪怕是指针。
windcsn 2006-03-10
  • 打赏
  • 举报
回复
各位老大,我想你们还没有明白我的意思。如果我将数据DROP到目标对象上已经迟了,那样很简单,谁不知道检查,关键是现在,我一开始拖动就想知道,例如:我HOOK API:DoDragDrop这个API,只要程序调用这个API我就知道他要开始拖动了,而且可以知道IDataObject是什么东西了,不要等到到了目标窗口才知道。但关键是,我现在不想HOOK。 大家知道COPY&PASTE是通过剪贴板的,但我发现,在拖动过程中剪贴板是不变化的,所以WINDOWS在Drag&drop的时候并没有通过它,而是通过了其他的办法!
加载更多回复(6)

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧