全部博文(282)
分类: 系统运维
2007-01-19 15:04:08
DDE是进程间的通讯方法,它使用共享内存实现进程之间的数据交换及使用协议达到传递数据的同步。
1.1 DDE协议
DDE协议是一组规则集,所有的DDE应用程序都必须遵循。
DDE协议可以应用于两种DDE应用程序之上:
/基于消息的DDE应用程序
/动态数据交换管理库应用程序
1.1.1会话的同步
DDE应用程序分为四种类型:客户,服务器,客户/服务器,监视器。
监视器应用程序可以解释所有DDE应用程序的DDE消息但不能执行他们,一般为调试之用。
DDE应用程序可以拥有多重并发会话。会话中的消息必须同步控制,但是不同会话之间可以异步切换。
DDE应用程序必须唯一地定义所有的会话。客户和服务器应用程序窗口句柄定义一个会话,因此客户应用程序可以和多重服务器会话,并用窗口句柄对来控制该会话。但是,如果客户应用程序和单个服务器进行多重对话,那该如何是好呢。一个解决办法是:为每个会话产生一个新的窗口,这样你的每一个会话都有一个唯一的窗口句柄。
1.1.2应用程序名,主题名,项目名
三层识别系统
应用程序名在层次结构的顶层,其下可以有多个主题名,一个主题名下面又可以有多个项目名。
1.1.3会话的初始化
客户应用程序用应用程序名和主题名发送WM_DDE_INITIATE消息初始化会话后,DDE就开始了。之后,需要有服务器应用程序响应这个消息。但并不是每一个服务器应用程序都必须响应这个消息的。客户应用程序在发送WM_DDE_INITIATE时,必须提供一些有关本身的信息以及哪个服务器是它所需的信息。客户应用程序:可能得不到任何应用程序的响应(因为没有你需要的应用程序),可能没有应用程序响应(因为你所需要的应用程序没有你所需要的主题),可能同时有几个应用程序响应了你(因为他们的应用程序名符合你的要求,并有你需要的主题),也可能有唯一的应用程序响应你(因为只有她合适)。
Peter站在一个黑暗的房子外面,和房子里面的人开始了会话。
à“George,这是Peter,愿意一起讨论DDE吗?“
à“这是Peter,有谁想讨论点东西吗“
这是两种不同的初始化方法
第一种:属于上面介绍的那种情况,房间里可能没有一个人叫George,也可能有很多个George,George可能并不愿意跟Peter讨论DDE,…(这种会话方式适合对房子里的人和需要谈论的主题有了一定的了解)
第二种:对房子里的人和需要谈论的主题没有一点了解。
一个工作良好的DDE客户应用程序在WM_DDE_INITIATE之后,必须处理消息所带回的所有可能的结果。如果没有服务器应用程序响应你的WM_DDE_INITIATE,则你需要提醒用户启动服务器应用程序。如果你得到很多个应用程序响应,你必须通过WM_DDE_TERMINATE来终止掉所有不需要的应用程序。
1.1.4会话中的交换
建立会话之后,就开始了真正有趣的工作:交换数据和执行服务。
WM_DDE_EXECUTE:指定客户应用程序需要服务器应用程序执行什么服务。
WM_DDE_EXECUTE消息和串一起传递,它包含了服务器应用程序的命令。(DDE定义了串的格式,没有规定串的内容)。
数据交换发生在三种方式中:
à客户应用程序向服务器应用程序申请数据在同一时间基础上。此时,应用程序发送WM_DDE_REQUEST消息,接着服务器应用程序用WM_DDE_DATA或者WM_DDE_ACK对请求作出响应。
à客户应用程序向服务器应用程序发送数据。此时客户应用程序发送WM_DDE_POKE消息将数据放置到服务器应用程序中,服务器应用程序接受到这个消息后,用WM_DDE_ACK消息来响应客户应用程序,表明它是否接收到数据。
à服务器应用程序报告客户应用程序有项改变了值。该种请求可产生两种形式:
à服务器应用程序发送通知给客户应用程序说明数据项发生了变化,但服务器不发送数据。
à服务器在每个数据变化时刻都发送数据。客户应用程序请求这项工作通过向服务器应用程序发送WM_DDE_ADVISE消息来实现,服务器应用程序用WM_DDE_ACK消息响应此消息。然后如果有数据变化,服务器应用程序就发送WM_DDE_DATA消息。如果客户应用程序只需要通知而不需要数据时,WM_DDE_DATA不包含数据。
冷链接:如果客户应用程序申请数据,并且服务器应用程序立即给客户应用程序发送数据。
温链接:服务器应用程序通知客户应用程序数据项发生变化,并没有将这个值发送给客户应用程序。
热链接:发生变化且服务器应用程序发送新的数据项值给客户应用程序。
1.1.5会话终止
客户应用程序或者服务器应用程序都能终止会话。
服务器也可以在它终止会话时,发送WM_DDE_TERMINATE消息,这项工作必须发生在应用程序调用PostQuitMessage函数并离开它的主消息循环之前。
1.1.6 DDE消息
DDE协议定义何时,如何以何地使用DDE消息。DDE消息格式规定可wParam包含了指向发送窗口的句柄。lParam确定了DDE消息所规定的信息。必须用SendMessage来发送WM_DDE_INITIATE消息,并且用WM_DDE_ACK来应答。另外其他消息用PostMessage来邮寄。
SendMessage函数中的句柄为-1时,表示传播消息给系统中所有的非子窗口。
SendMessage(hwnd, msg, wParam, MAKELONG(loworder, highorder));
lParam包含了指向全局内存块的句柄与原子的组合。
Note:关于原子的知识
Windows支持两种不同的Atom:
à局部原子,不能再两个应用程序之中共享
à全局原子,DDE应用程序将全局原子存放在Windows的全局原子表中,它存在于Window DLL的共享数据段之内。这样就允许所有的Window程序访问原子。
相关函数:
GlobalAddAtom()/GlobalDeleteAtom()/GlobalFindAtom()/GlobalGetAtom()
GlobalAddAtom()为每个原子维持引用计数。
例子程序
//Client APP
ATOM aApplication, aTopic;
aApplication = GlobalAddAtom(“Peter Server”);
aTopic = GlobalAddAtom(“Win DDE”);
SendMessage(-1, WM_DDE_INITIATE, hwndclient, MAKELONG(aApplication, aTopic));
GlobalDeleteAtom(aApplication);
GlobalDeleteAtom(aTopic);
//Server App
Case WM_DDE_INITIATE:
aApplication = GlobalAddAtom(“Peter Server”);
aTopic = GlobalAddAtom(“Win DDE”);
if((LOWORD(lParam) == aApplication) || !LOWORD(lParam) ) &&
(HIWORD(lParam) == aTopic || !HIWORD(lParam) )
{
If(SendMessage(wParam, WM_DDE_ACK, hwndServer,
MAKELONG(aApplication, aTopic)))
{
GlobalDeleteAtom(aApplication);
GlobalDeleteAtom(aTopic);
}
Return FALSE;
}
除了原子之外,在DDE消息中DDE应用程序传递指向全局内存块的句柄。全局内存块包含了DDE的结构或数据。如果要为DDE应用程序分配全局内存,可调用GlobalAlloc(),此时,应以GMEM_DDESHARE作为函数参数。