引入
我接着上篇博客讲,如果没有构建项目的童鞋请移步到操作系统——MFC实现进程创建和通信1
实现进程通信的方法有很多,我们先用一个比较简单的方法实现一下。
用PosMessage方法通信
通信原理
window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
从广义上讲,一个窗口可以获得对另一个窗口的引用(比如 targetWindow = window.opener),然后在窗口上调用 targetWindow.postMessage() 方法分发一个 MessageEvent 消息。接收消息的窗口可以根据需要自由处理此事件 (en-US)。传递给 window.postMessage() 的参数(比如 message )将通过消息事件对象暴露给接收消息的窗口。
大家可以看看官方的API文档,那个比较准确。Window.PostMessage
1、定义用户消息
在MFCApplication1Dlg.cpp和chileProcessDlg.cpp中分别添加宏定义消息,这个消息支持着两个进程的PostMessage通信。如果没有一个共同定义的宏变量,就需要加上一个窗口对另一个窗口的引用,为了方便就这么设计了~
//自定义用户消息
#define WM_MYMESSAGE WM_USER + 1
2、Mainapp中处理消息
在资源视图中双击(通过PostMessage)的button,跳转到button点击事件的处理程序中添加以下的代码:
void CMFCApplication1Dlg::OnBnClickedOk3()
{
HWND hWnd = ::FindWindow(_T("#32770"), _T("ChildProcess"));//目标进程的窗口类名(可通过Spy++工具查看)和窗口名
if (NULL != hWnd)
{
::PostMessage(hWnd, WM_MYMESSAGE,NULL, NULL);//发送用户消息
SetDlgItemText(IDC_EDIT1, _T("PostMessage已发送!"));
}
}
真正有用的其实就一句
::PostMessage(hWnd, WM_MYMESSAGE,NULL, NULL);//发送用户消息
这句话将消息WM_MYMESSAGE发送到了hwind中;
hwind是调用的查找函数找到名为ChildProcess的窗口就返回了。
然后我们如果找到了这个窗口就发送消息并且在本窗口中打印一句"PostMessage已发送!"
大家可以将文本框内容作为一个消息,双方定义一个Cstring接收一下就行了,这里我没有get文本框去获取内容
3、编译childProcessDlg.cpp
接下来我们再来处理一下接收消息的内容
在ChildProcessDlg.h里添加接受的函数声明:
protected:
afx_msg LRESULT OnMyMessage(WPARAM wp, LPARAM lp);
在ChildProcessDlg.cpp实现文件中添加自定义消息处理声明:
BEGIN_MESSAGE_MAP(CChileProcessDlg, CDialogEx)
/**
这些是框架自带的一些消息处理程序,都是空的,有兴趣的童鞋可以去了解复写一下,不用自己写接口应该用起来也方便。
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
*/
ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)//只添加这一句,其他为示意位置
/**
这些是我们之后要处理的消息声明
ON_EN_CHANGE(IDC_EDIT1, &CChileProcessDlg::OnEnChangeEdit1)
ON_WM_COPYDATA()
ON_BN_CLICKED(IDC_BUTTON1, &CChileProcessDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CChileProcessDlg::OnBnClickedButton2)
*/
END_MESSAGE_MAP()
在在ChildProcessDlg.cpp中添加自定义消息响应函数定义
LRESULT CChileProcessDlg::OnMyMessage(WPARAM wp, LPARAM lp)
{
SetDlgItemText(IDC_EDIT1, _T("收到PostMessage"));
/*
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
pEdit->SetSel(-1);
pEdit->ReplaceSel(_T("\r\n\n这是第1个子进程\r\n"));
*/
return 0;
}
我是直接在函数里面写上一个打印让自己看看有消息回复就行了,表示有WPARAM的参数传进来了。
4、重新生成childProcess项目
右键点击childProcess项目,重新生成一下 子窗口项目
重新生成之后.exe文件就被覆盖了,这个时候主项目再调用就是修改之后的child,要修改child代码的话每次都需要重新生成一下项目B让他覆盖掉之前的.exe文件。(=-=)
5、运行解决方案
运行解决方案,点击button去创建子进程B,然后再点击下一个button调用消息处理程序:
文章来源:https://www.toymoban.com/news/detail-731854.html
还有其他的消息通信方式,我放到下一遍博客上继续讲解
操作系统——MFC实现进程创建和通信3文章来源地址https://www.toymoban.com/news/detail-731854.html
到了这里,关于操作系统——MFC实现进程创建和通信2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!