设为首页 收藏本站
查看: 779|回复: 0

[经验分享] Windows DDE通讯

[复制链接]

尚未签到

发表于 2015-12-16 07:56:09 | 显示全部楼层 |阅读模式
Windows DDE通讯(服务器/客户端模式)



在Windows系统中,各个应用程序(进程)之间常常需要交换、传递数据,这就要解决进程间的数据通信问题。

在最初的16位Windows3.x系统中,所有Windows应用程序共享单一地址,任何进程都能够对这一共享地址空间的数据进行读写操作。随着Windwos98、WindowsNT、Windows2000等32位的操作系统的出现,规定每个进程都有自己的地址空间,一个Windows进程不能存取另一个进程的私有数据,也就是说,虽然两个进程可以用具有相同值的指针寻址,但所读写的只是它们各自的数据,这样就减少了进程之间的相互干扰。

那么上述技术的采用是否意味着各个应用程序之间不能进行数据交换了呢?答案当然是否定的,强大的Windows系统早已为我们设计了很多方案来解决进行间的通信问题,这里我们只探讨如何通过动态数据交换(DDE)方法实现进程间的数据通信。

本实例程序功能如下,服务器端有两个数据项,一个是输入的字符串,另一个是定时增加的整数。运行该程序的两个实例后,两个程序就可以建立DDE连接,实现数据的传递,并将另外一个实例传送过来的数据显示出来。下图为程序编译运行后的效果图:


http://blog.iyunv.com/attachment/201506/2/29756466_1433239568BHbN.bmp   


图一、DDE方法实现进程间数据通信程序的界面效果图


一、实现方法

自从微软推出Windows操作系统以来,动态数据交换(DDE)就已经成为Windows的部分,并且很多Windwos应用程序都使用了DDE技术来实现进程之间的数据交换。DDE是建立在Windows内部消息系统、全局和共享全局内存基础上的一种协议,用来协调Windows应用程序之间的数据交换和命令调用,它已经成为应用程序之间通信的一种常用方法。

DDE应用程序可以分为四种类型:客户类型、服务器类型、客户/服务器类型和监视器。DDE会话发生在客户应用程序和服务器应用程序之间。客户应用程序从服务器应用程序请求数据或服务,服务器应用程序响应客户应用程序的数据或服务请求。客户/服务器应用程序是既可以发出请求,又可以提供信息,监视器应用程序则是用语调试的目的。

DDE协议使用三级树型命名:服务(SERVICE)、主题(TOPIC)和数据项(ITEM)来标识DDE所要传送的数据单元。服务使应用程序具有了提供给其他程序的数据交换能力;主题类似于目录,是建立会话连接的参数:ITEM才是DDE具体通信时要传送的数据内容,比如一个数据或一个字符串。

动态交换管理库(DDEML)提供了DDE和应用程序级协议。使用DDEML开发的应用程序无论是在运行一致性方面还是在应用程序相互通信方面性能均优于没有使用DDEML的应用程序。而且DDEML的应用使得开发支持DDE的应用程序容易了许多。

建立DDE会话后,客户程序和服务器程序可以通过三种链接方式进行数据交换,分别是:

1、冷链接:客户程序申请数据,服务器程序立即给客户程序发送数据;

2、温链接:服务器程序通知客户程序数据数据项发生了改变,但是并没有将已发生的值发送给客户程序。

3、热链接:当数据项发生变化时,服务器程序立即把变化后的值发送给客户程序,这是最常用、最方便的方法,下面的例子就使用的这种方法。

  

DDE编程过程:

A、DDE会话初始化:使用API函数DdeInitialize(),在DDEML中注册应用。

B、会话建立

服务器:注册服务DdeNameService.

客户:连接DdeConnect.

C、会话过程

类似于Windows的消息循环,会话的过程就是事务处理的过程。客户通过DdeClientTransaction()来发出事务请求,通过DDE回调函数,服务器处理客户事务请求,返回DdeCreateDataHandle来发送数据,同时客户可以调用DdeGetData()获取数据。

D、会话结束

可由服务方或客户方来终止会话,推出程序时要注消服务,释放资源,调用DdeUninitialize()。

  

二、编程步骤

1、启动Visual C++6.0,新建一个基于对话框的MFC应用程序,取名为DDEdemo,添加两个Group Box控件并分别在其上放置编辑控件IDC_EDIT、静态控件ID_STATIC1、ID_STATIC2、 ID_STATIC3,用Wizard添加对应成员变m_edit(CString类型),添加并将其Caption置空,最后的界面如图一所示;

2、使用CLASSWIZARD添加对话框函数,分别为WM_DESTORY、WM_INITDIALOG、WM_TIMER及IDC_EDIT的EN_CHANGE消息建立对应函数;

  3、在DDEdemoDlg.CPP中加入#include "ddel.h"以使用DDEML函数。并添加以下宏定义和全局变量:
  


  #define NITEM 2
  const char szApp[] ="Server";
  const char szTopic[]= "Topic";
  //SERVER ITEM名称字符串数组
  const char*pszItem[NITEM] = {"Item1","Item2"};
  int count = 1;//计数
  //存放服务器中的数据项内容
  CStringServerData[NITEM];
  HCONV hConv = 0;
  DWORD idInst = 0;
  HWND hWnd;
  HANDLE hInst;
  HSZ hszApp = 0;
  HSZ hszTopic = 0;
  HSZ hszItem[NITEM];
  BOOL bConnect;
  

  编写代码:
  1、回调函数定义

  HDDEDATA CALLBACKDdeCallback(UINT wType,UINT wFmt,HCONV hConv,HSZ Topic,HSZ Item,
  HDDEDATA hData,DWORD lData1,DWORD lData2)
  {
  int I;
  char tmp[255];
  switch(wType)
  {
  case XTYP_ADVSTART:
  case XTYP_CONNECT:
  return ((HDDEDATA)TRUE);
  case XTYP_ADVDATA://有数据到来
  for(I=0;IAppendMenu(MF_STRING,IDM_ABOUTBOX,
strAboutMenu);
  }
  }
  

  // Set the icon for this dialog.  The framework does this automatically
  // when the application's main window is not a dialog
  SetIcon(m_hIcon, TRUE);               // Set big icon
  SetIcon(m_hIcon, FALSE);              // Set small icon
  
  // TODO: Add extra initialization here
  hWnd = m_hWnd;
  if(DdeInitialize(&idInst,(PFNCALLBACK)DdeCallback,APPCMD_FILTERINITS|
  CBF_FAIL_EXECUTES|CBF_SKIP_CONNECT_CONFIRMS|CBF_FAIL_SELFCONNECTIONS|
  CBF_FAIL_POKES,0))
  {
  MessageBox("DDE SERVER初始化失败!");
  return FALSE;
  }
  hInst=AfxGetApp()->m_hInstance;
  //创建DDE string
  hszApp=DdeCreateStringHandle(idInst,szApp,0);
  hszTopic=DdeCreateStringHandle(idInst,szTopic,0);

  for(int I=0;I

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-151722-1-1.html 上篇帖子: Windows下Qt静态编译全解 下篇帖子: windows窗体控件之LisBox(列表框)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表