利用消息机制实现VC与Delphi之间的通讯(发送自定义消息)
摘要: 本文介绍了使用Windows消息机制实现由不同语言编制的程序之间的相互通讯、联系,并以当前较为流行的两种语言Microsoft Visual C++ 6.0和Borland delphi 5.0为对象,用这两种语言各编制一应用程序,并能很好的通过消息进行交互。
一、 引言
编制较大型的程序往往需要将一个项目分割成若干个模块,由若干个开发小组共同完成。笔者曾参加过几个大型项目的研发工作,根据需要往往要将项目分为解为几大部分,分到三、四家科研单位共同完成,由于各单位较分散,彼此之间的协调只能根据预先制定好的接口协议来完成,即每个单位同其他单位的程序之间的交互只通过几个接口来完成。而且各单位采用的开发语言也不同,这就为使这些不同语言的程序之间的交互增加了困难。笔者根据实际工作摸索出一些解决上述问题的一些方法,下面就对此作些介绍。
二、 程序设计思路
虽然各个单位采取不同的开发语言,从Microsoft Visual C++ 6.0到Borland delphi 5.0乃至Microsoft Visual Basic 6.0,但有一点是相同的:都是工作于Win 32操作系统下的。而Win 32操作系统有一个很重要的机制--消息。我们可以用Microsoft Visual Studio 6.0附带的DDE Spy工具去拦截运行于Windows操作系统下的应用程序所发出的各种消息,而不管这些应用程序是使用何种语言编制的。所以我们可以明确一点:即只要捕获到目标程序的窗口句柄,就能向其发送消息,并可附带两个消息参数将信息传递过去。而用于发送消息的两个函数PostMessage和SendMessage在定义上也很好的体现了这一点:
| BOOL PostMessage( HWND hWnd, // 目标窗口句柄 UINT Msg, //发送的消息 WPARAM wParam, // 第一个消息参数 LPARAM lParam // 第二个消息参数); BOOL SendMessage( HWND hWnd, // 目标窗口句柄 |
可以看出,从原理上采用消息是可以沟通两个由不同语言编制的程序的,下面通过两个分别由Microsoft Visual C++ 6.0和Borland delphi 5.0编制的模拟程序来简要介绍一下该方法的实现过程。
三、 由Borland delphi 5.0编制的模拟程序的实现
新建一个工程,由于在Microsoft Visual C++ 6.0下要捕获其他应用程序的窗口句柄要通过API函数FindWindow(……)来实现,而此函数是根据目标窗口的窗口标题来判断是哪个窗口的,所以要保证两种语言编制的程序能可靠的通信,必须要保证各自窗口标题不发生改变。所以在本程序中需要通过修改窗口的属性来改变窗体的标题,将其设为"delphi消息接收、发送程序"。
在Borland delphi 5.0下向Microsoft Visual C++ 6.0发送消息比较简单,只须调用Win32 API函数findwindow(……)在当前的所有的窗口中根据对方程序窗体的标题进行搜寻即可。当获取到对方程序的窗口句柄后可以用postmessage(……)或是sendmessage(……)函数对其发送消息了,需要说明的是这两个函数虽然都是向指定窗口发送消息,但前者是"邮递"性质,只要把消息发出去了就算干完了,而不关心对方接收到消息后是否处理;而后者却是一直等待对方把消息处理完,如若对方不处理该消息,那么sendmessage(……)函数也不会返回。虽然差别很细微,但在实际应用中如能选取恰当的消息发送函数,往往会使程序更加完美。发送消息的关键代码如下:
| …… {nil参数指定搜寻所有的窗口,捕获窗口标题为"vc消息接收、发送程序"的应用程序的句柄} hwnd:=findwindow(nil,pchar(’vc消息接收、发送程序’)); postmessage(hwnd,2000,0,1); |
要响应从Microsoft Visual C++ 6.0发送来的消息,则比较麻烦,首先要添加一个用来描述消息的数据结构,可以定义如下:
| type Tmymessage=record a:cardinal; b:integer; c:integer; d:integer; end; |
在Borland delphi 5.0里响应消息不需要有消息映射,只须象添加一个普通的过程一样,只是其入口参数必须为刚才所添加的消息结构对象并在其后添加一个消息号即可,比如 procedure receive(var message:Tmymessage);message 2000;在消息响应函数里可以通过判断入口参数的消息结构里的 b、c两数据成员变量来获取随消息发送来的两个消息参数。并根据特定的数值作出相应的反应。
四、 由Microsoft Visual C++ 6.0 编制的模拟程序的实现
在Microsoft Visual C++ 6.0下实现消息发送、响应的设计思路和实现方法与前面提到的方法基本类似,也是将自己的标题固定以便对方获取自己的窗口句柄来向自己发消息,但响应消息时需要靠消息映射来显式实现。
固定自己的程序窗口标题一般是在工程的应用程序类的初始化函数OnInitial()里作如下修改:
| …… m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->SetWindowText("vc消息接收、发送程序"); m_pMainWnd->UpdateWindow(); …… |
需要特别说明的是并非在所有的类里都可以添加从其他程序发来消息的响应函数,只有在主框架类里才能接收到外部程序发送来的消息,因为外部程序捕获的句柄只是根据程序标题捕获到的程序主框架的句柄,所以只能将消息发送到主框架类了。自定义消息和消息映射的添加实现情况如下:
在主框架类的头文件中修改如下片段:
| …… #define WM_MYMSG 2000 …… //{{AFX_MSG(CMainFrame) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG void OnRecvMsg(WPARAM wParam,LPARAM lParam); DECLARE_MESSAGE_MAP() …… |
再在主框架类的实现文件里修改如下片段:
| …… BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG_MAP ON_MESSAGE(WM_TOdelphi,OnRecvMsg) END_MESSAGE_MAP() …… void CMainFrame::OnRecvMsg(WPARAM wParam,LPARAM lParam) |
其中,从wParam 传来的参数是接收到的消息附带的第一个参数;从lParam传来的参数是接收到的消息附带的第二个参数。可以通过这两个参数从对方获取更多的附加信息。
至于向对方发送消息则和前一个程序非常类似,寻找对方窗口可以用Win32 API函数的FindWindow(……),也可以使用MFC的CWnd类的FindWindow(……),后者返回的直接是窗口指针,实现的主要代码如下:
| …… //获取以"delphi消息接收、发送程序"为标题的delphi程序的窗口句柄 CWnd *pWnd=CWnd::FindWindow(NULL,"delphi消息接收、发送程序"); //只有当确实捕获到窗口时才向其发送消息,否则会引起异常错误。 if (pWnd) pWnd->PostMessage(WM_MYMSG,0,1); …… |
WM_MYMSG是自定义消息,0,1是附带的两个消息参数。具体意义可以通过接口协议自行制定。
五、 检验程序的交互情况
首先在各自的编程环境下编译完毕,运行后打开Microsoft Visual Studio 6.0附带的调试工具包DDE Spy,当一个程序从另外一个程序接收到发送来的消息,执行完特定的工作后。可以通过DDE Spy监视到确实是从一个进程发出自定义消息,然后经过Win 32系统的消息队列被另外一个进程所接收并响应。
结论:
本程序通过一个简单的例子对在异种语言编制的程序中使用消息作为通讯工具的方法做了简单的介绍,在实际应用中还要考虑许多具体的细节问题,实现起来也要远比本程序烦琐的多。但通过这种方式来解决混合编程中的小数据量的频繁数据通讯无疑是很有优势的。
http://soft.zhiding.cn/software_zone/2007/1017/560580.shtml
利用消息机制实现VC与Delphi之间的通讯(发送自定义消息)的更多相关文章
- 深入Delphi -- Windows 消息机制
http://www.txsz.net/xs/delphi/3/Windows%20%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.htm Windows 消息机制 by m ...
- 锻造完美U盘小偷:活用消息机制
锻造完美U盘小偷:活用消息机制作者:灰狐来源:灰狐's Blog 注:本文已发表在<黑客防线>2008年第1期,转载请注明出处. 以前经常看到有人做出一些蛮有意思的小工具,其中最多的似乎就 ...
- android开发系列之消息机制
最近接触到一个比较有挑战性的项目,我发现里面使用大量的消息机制,现在这篇博客我想具体分析一下:android里面的消息到底是什么东西,消息机制到底有什么好处呢? 其实说到android消息机制,我们可 ...
- Android全面解析之由浅及深Handler消息机制
前言 很高兴遇见你~ 欢迎阅读我的文章. 关于Handler的博客可谓是俯拾皆是,而这也是一个老生常谈的话题,可见的他非常基础,也非常重要.但很多的博客,却很少有从入门开始介绍,这在我一开始学习的时候 ...
- 史上最详细的Android消息机制源码解析
本人只是Android菜鸡一个,写技术文章只是为了总结自己最近学习到的知识,从来不敢为人师,如果里面有不正确的地方请大家尽情指出,谢谢! 606页Android最新面试题含答案,有兴趣可以点击获取. ...
- android学习日记25--ANR和Hander消息机制
1.ANR(Application Not Responding)定义 在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:A ...
- Android(java)学习笔记202:Handler消息机制的原理和实现
联合学习 Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系 1. 首先我们通过一个实例案例来引出一个异常: (1)布局文件activity_m ...
- Android(java)学习笔记145:Handler消息机制的原理和实现
联合学习 Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系 1. 首先我们通过一个实例案例来引出一个异常: (1)布局文件activity_m ...
- Angular10 组件之间的通讯
1 父组件和子组件之间的通讯 2 利用中间组件实现两个组件之间的通讯 3 利用服务实现两个组件之间的通讯 2017年8月26日20:09:13 待更新... 1 组件之间的关系图 1.1 父子关系 1 ...
随机推荐
- Unity UGUI——Rect Transform包(Anchors)
Anchors(锚)操作演示 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXJfQUhhbw==/font/5a6L5L2T/fontsize/400/ ...
- mongose TypeError: Cannot read property 'findOne' of undefined
最近在node的一个项目中,需要在model的一个数据表中写一个钩子函数去调用另外一个文件中的方法,一开始我采用了将此方法放入到global中,直接从global.meteod这样去获取.后来我又尝试 ...
- Crystal Report - 利用后台代码设计或实现水晶报表工具栏相关功能
水晶报表工具栏分页按钮响应事件: 水晶报表中有自带的分页功能,在设置好每页显示的记录后会自动分页,并自动记录总页数和保存当前页,在工具栏可以通过“首页”“尾页”“下一页”“上一页”和“跳页”进行页面跳 ...
- 下面介绍一个 yii2.0 的 Rbac 权限设置,闲话少说,直接上代码,
1.首先我们要在组件里面配置一下 Rbac ,如下所示(common/config/main-local.php或者main.php). 'authManager' => [ 'class' ...
- 用C++写android程序(包含界面+发短信)
首先为什么要用C++写android程序呢?主要是因为java写的android程序太容易被发编译,相对于java编译后的dex文件,底层的native so更加不容易被反编译,所以为了安全起见,可以 ...
- quick-cocos2d-x游戏开发【8】——动画与动作
动画与动作,在quick中都有对其封装,所以我们还是来看一下吧. 总的来说,对于帧动画,quick封装的方法我们能够常常使用,这是很方便的,以下直接上代码来直观感受下, 比方,14张帧图片,採用coc ...
- silverlight,WPF动画终极攻略之迟来的第三章 动画整合篇(Blend 4开发)
原文:silverlight,WPF动画终极攻略之迟来的第三章 动画整合篇(Blend 4开发) 有个问题想请教下大家,我仿了腾讯的SL版QQ,相似度95%以上.我想写成教程教大家怎么开发出来,会不会 ...
- Hopfield 神经网络及稳态性的证明
根据其提出者,John Joseph Hopfield 命名.Hopfield 在 1982 年提出的划时代的:Neural networks and physical systems with em ...
- ISO9000 质量管理和质量保证系列国际标准
(一)ISO9000认证的背景国际标准化组织(ISO)是世界上最主要的非政府间国际标准化机构,成立于二次世界大战以后,总部位于瑞士日内瓦.该组织的目的是在世界范围内促进标准化及有关工作的发展,以利于国 ...
- (记录)mysql分页查询,参数化过程的坑
在最近的工作中,由于历史遗留,一个分页查询没有参数化,被查出来有sql注入危险,所以对这个查询进行了参数化修改. 一看不知道,看了吓一跳,可能由于种种原因,分页查询sql是在存储过程中拼接出来的,wh ...