利用消息机制实现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 ...
随机推荐
- 【序列操作IV】树状数组套线段树/树套树
题目描述 给出序列 a1,a2,…,an(0≤ai≤109),有关序列的两种操作. 1. ai(1≤i≤n)变成 x(0≤x≤109). 2. 求 al,al+1,…,ar(1≤l≤r≤n)第 k(1 ...
- TensorFlow 学习(四)—— computation graph
TensorFlow 的计算需要事先定义一个 computation graph(计算图),该图是一个抽象的结构,只有在评估(evaluate)时,才有数值解,这点和 numpy 不同.这张图由一组节 ...
- 一个git pull无法使用的问题
之前通过git管理的一个项目,今天直接用eclipse通过ssh加入工程后,每次通过git命令行pull代码都报以下错误: Unable to negotiate with 21.12.1.167 p ...
- WPF 高性能笔
原文:WPF 高性能笔 本文告诉大家WPF的INK的实现,和如何做一个高性能的笔. 高性能的笔迹在 WPF 包含两个部分,一个是就是输入,第二个就是渲染. 如果需要经过路由事件才收到输入,如果有人在路 ...
- SpringCloud学习笔记-zuul网关
公司目前使用的是dubbo方式实现微服务,想试水改造接口层服务为Spring Cloud, 以下是网络拓补图. 第一层负载均衡可以用nginx或者zuul(即有2层zuul), 本图画的是nginx. ...
- 我的MBTI职业性格测试
背景 最近在看<程序员的思维训练--开发人之前能的九堂课>,其中讲到了 MBTI 职业性格测试的指导意义.记起来两年多以前在面试 ASES 的时候有做过这个测试,只可惜当时的测试结果在好几 ...
- vs中添加MySql实体集流程
默认情况下只有下图: 首先需要下载mysql为vs和ef提供的驱动(可以去官网下载对应的版本) 然后打开vs开始添加实体类 首先在NuGet中安装MySql.Data和MySql.Data.Entit ...
- 《北京IT报道》你可以成为下一个《万万没有想到》?
10一个月29当天上午,一位名为<北京IT报道>在视频短剧IT朋友谁快速刷新的互联网商业圈.这种制作粗糙.演员表情僵硬.安置赤裸网络剧,但对布局和内容因IT互联网从业者的生活,深受广大用户 ...
- Android Studio怎样提示函数使用方法
Eclipse有一个非常好的功能,就是当你代码调用某个android API时,鼠标移到相应的函数或者方法上,就会自己主动有一个悬 浮窗提示该函数的说明(所包括的參数含义,该方法功能).迁移到Andr ...
- Proxy Design Pattern 代理设计模式
代理设计模式.此模式是用于serverclient排序.互联网接入,也经常使用的类代理,我觉得这种感觉很复杂.但是,这种设计模式本身是非常easy的. 是一类调用另一个类的功能.客户调用类,实际工作是 ...