1.  进程内消息:

(1). 仅仅传消息码

(2). 传送消息串

发送端:
void CTestDlg::OnBnClickedButtonSend()
{
CString* msg = new CString("发送的字符串");
::SendMessage(m_hWnd,WM_USER+1,0,(LPARAM)msg);
delete msg;
} 接收端:
afx_msg HRESULT OnClickBtn(WPARAM,LPARAM); BEGIN_MESSAGE_MAP
ON_MESSAGE(WM_USER+1,OnClickBtn)
END_MESSAGE_MAP() HRESULT CSendMessageDlg::OnClickBtn1(WPARAM wParam,LPARAM lParam)
{
CString* rmsg = (CString*)lParam;
MessageBox(*rmsg);
return TRUE;
}

 2.  进程间通讯:

PostMessge或者SendMessage()实现进程间通讯

(1)两个不同的进程不能用上面的方法。当然仅仅发送消息不发内容是能够的。

(2)两个进程因为使用的是相互独立的两个虚拟内存空间,同一地址对不同的进程来说并不一定指向同一物理内存,内容也就不一定一样。因此不同进程无法通过传地址的方式传递字符串(可是同一进程下的不同线程是能够的)

2.解决的方法

发送WM_COPYDATA消息在进程间传送数据

(1)发送消息

The exchange of data is performed by finding the other application (using FindWindow) and sending a WM_COPYDATA message to that window

使用FindWindow找到窗体。然后发送WM_COPYDATA消息。字符串附加到COPYDATASTRUCT 结构体

LRESULT copyDataResult;  //copyDataResult has value returned by other app
CWnd *pOtherWnd = CWnd::FindWindow(NULL, strWindowTitle); if (pOtherWnd)
{
COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = strDataToSend.GetLength(); //data length
cpd.lpData = (void*)strDataToSend.GetBuffer(cpd.cbData); //data buffer
copyDataResult = pOtherWnd->SendMessage(WM_COPYDATA,(WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(),(LPARAM)&cpd);
strDataToSend.ReleaseBuffer();
}
else
{
AfxMessageBox("Unable to find other app.");
}

(2)加入消息

The other app should handle the WM_COPYDATA message in the following manner

BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
...
ON_WM_COPYDATA()
...
END_MESSAGE_MAP()

(3)消息处理

BOOL CMyWnd::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
CString strRecievedText = (LPCSTR) (pCopyDataStruct->lpData);
return CMyWnd::OnCopyData(pWnd, pCopyDataStruct);
}

五、PostMessage  和SendMessage的差别

(1). PostMessage 和SendMessage的差别主要在于是否等待其它程序消息处理完毕。

PostMessage仅仅是把消息放入队列,无论其它程序是否处理都返回,然后继续运行。

而SendMessage则必须等待其它程序处理消息完毕后才返回继续运行。因为SendMessage消息不放进消息队列, 所以PreTranslateMessage里无法收到其消息。

(2). 这两个函数的返回值也不同

原型:

BOOL        PostMessage(HWND hWnd。UINT Msg,WPARAM wParam,LPARAM lParam);

LRESULT SendMessage(HWND hWnd。UINT Msg。WPARAM wParam。LPARAM IParam);

SendMessage的返回值表示其它程序消息处理函数的返回值(如return 10,  则long nRet = SendMessage(...) = 12)。

PostMessage的返回值仅表示PostMessage函数运行是否成功,成功返回非零,否则返回零。

举比例如以下(仅仅传消息码):

方法1: PostMessge或者SendMessage()消息机制

项目1中发送消息:

#define WM_MYMESSAGE WM_USER + 1 

//目标进程的窗体类名(可通过Spy++工具查看)和窗体名
CWnd *pWnd = CWnd::FindWindow("#32770", "MfcTest");
if (NULL != pWnd)
{
pWnd->PostMessage(WM_MYMESSAGE, NULL, NULL);
} 或者:
HWND hWnd = ::FindWindow("#32770", "MfcTest");
if (NULL != hWnd)
{
::PostMessage(hWnd, WM_MYMESSAGE, NULL, NULL);
}

项目2中接收消息:

.h中声明:

afx_msg LRESULT OnMyMessage(WPARAM wp, LPARAM lp);

.cpp中定义:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
...
ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
...
END_MESSAGE_MAP()

LRESULT CMfcTestDlg::OnMyMessage(WPARAM wp, LPARAM lp)
{
AfxMessageBox("Hello World");
return 0;
}

说明:

使用PostMessage或SendMessage均可,差别在于SendMessage堵塞,直到目标窗体程序处理完消息再返回,而PostMessage是将一个消息寄送到一个线程的消息队列后就马上返回。通常使用PostMessage,假设为了探測目标进程是否存在,则用SendMessage比較好。

方法2: 消息接收端採用PreTranslateMessage()来处理

发送端代码:

#define WM_MYMESSAGE WM_USER + 1 

//目标进程的窗体类名(可通过Spy++工具查看)和窗体名
CWnd *pWnd = CWnd::FindWindow("#32770", "MfcTest");
if (NULL != pWnd)
{
pWnd->PostMessage(WM_MYMESSAGE, NULL, NULL);
} 或者:
HWND hWnd = ::FindWindow("#32770", "MfcTest");
if (NULL != hWnd)
{
::PostMessage(hWnd, WM_MYMESSAGE, NULL, NULL);
}

接收端代码:

.h声明

BOOL CMfcTestDlg::PreTranslateMessage(MSG* pMsg);

.cpp定义

#define WM_MYMESSAGE WM_USER + 1 

BOOL CMfcTestDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_USER + 1)
{
AfxMessageBox("Hello World");
} return CDialog::PreTranslateMessage(pMsg);
}

说明:

这里将接收端处理放在PreTranslateMessage 中, 因此发送端必须选择 PostMessage, 由于SendMessage消息不放进消息队列, PreTranslateMessage里不能收到这个消息。






VC进程间通信之消息传递PostMessge()或SendMessage()的更多相关文章

  1. 深度解析VC中的消息传递机制

    摘要:Windows编程和Dos编程,一个很大的区别就是,Windows编程是事件驱动,消息传递的.所以,要学好Windows编程,必须 对消息机制有一个清楚的认识,本文希望能够对消息的传递做一个全面 ...

  2. Unity的3种消息传递方法(SendMessage等)

    为了方便多个物体间的消息传达与接收,Unity中包含了几种消息推送机制 : 分别为SendMessage.SendMessageUpwards.BroadcastMessage. 我们首先以SendM ...

  3. android log 学习

    一,Bug出现了, 需要“干掉”它 bug一听挺吓人的,但是只要你懂了,android里的bug是很好解决的,因为android里提供了LOG机制,具体的底层代码,以后在来分析,只要你会看bug, a ...

  4. [深入学习Redis]RedisAPI的原子性分析

    在学习Redis的常用操作时,经常看到介绍说,Redis的set.get以及hset等等命令的执行都是原子性的,但是令自己百思不得其解的是,为什么这些操作是原子性的? 原子性 原子性是数据库的事务中的 ...

  5. Redis API的原子性分析

    在学习Redis的常用操作时,经常看到介绍说,Redis的set.get以及hset等等命令的执行都是原子性的,但是令自己百思不得其解的是,为什么这些操作是原子性的? 原子性 原子性是数据库的事务中的 ...

  6. 知其所以然~redis的原子性

    原子性 原子性是数据库的事务中的特性.在数据库事务的情景下,原子性指的是:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节. 对于Redis而言,命 ...

  7. [OS] 操作系统常考知识点

    转自:http://jennica.space/2017/03/21/os-principle/ 大纲如下: 1.操作系统概述2.操作系统运行环境3.进程线程模型4.处理器调度5.同步机制6.存储模型 ...

  8. MFC 监控界面上所有文本框值的变化

    //控件消息,菜单,按钮等 BOOL CXXDlg::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 int wm ...

  9. iOS App Crash原理分析

    预备知识:OS X系统分析 1.内核XNU是Darwin的核心,也是整个OS X的核心.XNU本身由以下几个组件构成: Mach微核心 BSD层 libKern I/O Kit 此外,内核是模块化的, ...

随机推荐

  1. aplusb 数论

    题目描述 SillyHook 要给小朋友出题了,他想,对于初学者,第一题肯定是a+b啊, 但当他出完数据后神奇地发现.in 不见了,只留下了一些.out,他想还原.in,但 情况实在太多了,于是他想要 ...

  2. rand()与 srand()

    一   头文件 <time.h> srand()就是给rand()提供种子seed. 在C语言中,srand()与rand()是随机函数,其中srand函数是伪随机数发生器的初始化函数,原 ...

  3. ofbiz数据库表结构设计(3)- 订单ORDER

    对于订单来说,主要的表就是ORDER_HEADER和ORDER_ITEM.ORDER_HEADER就是所谓的订单头,一条记录代表一条订单. ORDER_PAYMENT_PREFERENCE是订单的支付 ...

  4. SPOJ QTREE Query on a tree V

    You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...

  5. POJ1111 Image Perimeters

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8790   Accepted: 5260 Description Techn ...

  6. java常见设计模式简要总结

    设计模式六大原则 1.开放封闭原则:对扩展开放,对修改封闭,意即程序拓展时不要动原有的代码 2.LSP原则:任何基类可以出现的地方,子类一定可以出现 3.依赖倒置原则:使用接口,依赖于抽象而不是具体 ...

  7. Linux和Windows兼容

    1. 介绍 我们知道Linux上的应用程序是ELF格式的,而Windows则是PE格式 所以要解决这个问题首先二进制加载问题:其次,就是API问题,两者的API完全不同要实现兼容,就需要构建一个虚拟层 ...

  8. Python学习杂记_9_集合操作

    集合集合是由花括号括起来的一组数据,特点是“数据不重复”,“无序”,“类型不统一”.其中数据不重复是它最重要的特点,常常用于“去重”操作,Set(list)方法可以把列表强制转换成集合. 集合的一些操 ...

  9. 了解Binder机制原理和底层实现

    参考:http://www.2cto.com/kf/201606/515548.html 1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Andr ...

  10. 多线程设计模式 - Future模式

    Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用.这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门.或者说 ...