17 MFC进程通信

这篇具有很好参考价值的文章主要介绍了17 MFC进程通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

剪切板

设置界面
17 MFC进程通信,mfc,c++17 MFC进程通信,mfc,c++
17 MFC进程通信,mfc,c++

发送

//设置剪切板数据
void CClipboardDlg::OnBnClickedBtnSend()
{
	UpdateData(TRUE);
	if (m_strSend.IsEmpty())
	{
		MessageBox(L"请输入需要设置的文本", L"提示");
		return;
	}

	//打开剪切板
	if (FALSE == OpenClipboard())
	{
		CString str;
		str.Format(L"打开剪切板失败,错误代号:%d", GetLastError());
		MessageBox(str);
		return;
	}

	//清空剪切板
	EmptyClipboard();
	//在全局堆申请一块内存
	HGLOBAL hClip=GlobalAlloc(GMEM_MOVEABLE,m_strSend.GetLength()*2+1);
	//对全局堆内存枷锁
	TCHAR* pBuffer=(TCHAR*)GlobalLock(hClip);
	//清空内存
	ZeroMemory(pBuffer, m_strSend.GetLength() * 2 + 1);
	memcpy(pBuffer, m_strSend.GetBuffer(), m_strSend.GetLength() * 2 + 1);

	//解锁
	GlobalUnlock(hClip);

	//设置剪切板数据
	SetClipboardData(CF_UNICODETEXT, hClip);
	//关闭剪切板,一定要关闭剪切板
	CloseClipboard();
}

从剪切版里面接收数据

void CClipboardDlg::OnBnClickedBtnReceive()
{
	//打开剪切板
	if (FALSE == OpenClipboard())
	{
		CString str;
		str.Format(L"打开剪切板失败,错误代号:%d", GetLastError());
		MessageBox(str);
		return;
	}
	//检查截切版中是否有我们指定格式的数据
	if (IsClipboardFormatAvailable(CF_UNICODETEXT))
	{
		//得到剪切板数据
		HANDLE hClip=GetClipboardData(CF_UNICODETEXT);
		//把句柄转换为指针
		TCHAR* pBuffer=(TCHAR*)GlobalLock(hClip);
		m_strRecv = pBuffer;
		//解锁
		GlobalUnlock(hClip);
		UpdateData(FALSE);
	}
	//关闭剪切板,一定要关闭剪切板
	CloseClipboard();
}

17 MFC进程通信,mfc,c++

管道

命名管道(Named Pipe)和匿名管道(Anonymous Pipe)都是用于进程间通信的机制,但它们有一些区别。

命名管道(Named Pipe):

命名管道是具有唯一名称的管道,可以通过该名称在不同进程之间进行通信。
命名管道可以在本地机器上的不同进程之间进行通信,也可以在网络上的不同计算机之间进行通信。
命名管道支持全双工通信,可以同时进行读取和写入操作。
命名管道可以被多个进程打开和使用,允许多个读取者和写入者同时进行操作。
命名管道通常用于需要持久性连接和长期通信的场景,例如服务器和客户端之间的通信。

匿名管道(Anonymous Pipe):

匿名管道是一种无名称的管道,仅限于在父子进程或者兄弟进程之间进行通信。
匿名管道只能在同一个计算机上的相关进程之间进行通信,不能跨网络使用。
匿名管道是单向的,只能支持单向的数据流传输,例如从父进程到子进程。
匿名管道一般用于简单的进程间通信需求,例如父进程将数据传递给子进程进行处理。

匿名管道

父进程
17 MFC进程通信,mfc,c++
子进程
17 MFC进程通信,mfc,c++

子进程的*.exe放到父进程中
17 MFC进程通信,mfc,c++

父进程启动子进程

//创建子进程
void CParentPipDlg::OnBnClickedBtnCreate()
{
	//创建匿名管道
	//第1,2个参数:读写句柄
	//第3个参数:安全描述符
	SECURITY_ATTRIBUTES sa;
	sa.bInheritHandle = TRUE;//子进程继承父进程的句柄
	sa.lpSecurityDescriptor = NULL;//安全描述符
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);//结构体大小
	//第4个参数:缓冲区大小
	if (!CreatePipe(&m_hRead, &m_hWrite, &sa, 0))
	{
		MessageBox(L"创建匿名管道失败",L"提示");
		return;
	}



	TCHAR szCmdLine[MAX_PATH] = L"subPip.exe";
	//启动信息
	STARTUPINFO si = { 0 };
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESTDHANDLES;//标准输入输出
	si.hStdInput = m_hRead;//标准输入
	si.hStdOutput = m_hWrite;//写入
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);//标准输入输出错误句柄
	//进程信息
	PROCESS_INFORMATION pi = { 0 };

	if (!CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si,&pi))
	{
		CloseHandle(m_hRead);
		CloseHandle(m_hWrite);
		m_hRead = NULL;
		m_hWrite = NULL;
		MessageBox(L"创建子进程失败", L"提示");
		return;
	}
}

17 MFC进程通信,mfc,c++

父进程写入数据子进程读出数据

父进程写入数据

//写入数据
void CParentPipDlg::OnBnClickedBntWrite()
{
	wchar_t buffer[100]=L"我是父进程";
	//向文件或者其他输出设备写入数据的函数
	//第一个参数:写入句柄
	//第二个参数:待写入的数据缓冲区
	//第三个参数:待写入数据的字节数
	//第四个参数:实际写入的字节数
	//第五个参数;异步操作的重叠结构(可选)
	DWORD dwWrite;
	if (!WriteFile(m_hWrite, buffer, wcslen(buffer) * 2 + 1, &dwWrite, NULL))
	{
		MessageBox(L"写入数据失败");
		return;
	}

}

子进程读入数据
获取读取句柄和写入句柄

	m_hRead = GetStdHandle(STD_INPUT_HANDLE);
	m_hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
void CSubPipDlg::OnBnClickedBtnRead()
{
	wchar_t buffer[100] = { 0 };
	DWORD dwRead = 0;
	if (!ReadFile(m_hRead, buffer, sizeof(buffer), &dwRead, NULL))
	{
		MessageBox(L"读取数据失败");
		return;
	}

	MessageBox(buffer);
}

17 MFC进程通信,mfc,c++

子进程写入数据父进程读取数据原理一致

命名管道

命名管道服务器17 MFC进程通信,mfc,c++
命名管道客户端17 MFC进程通信,mfc,c++

服务器命名管道的创建

//命名管道
void CServerDlg::OnBnClickedBtnCreate()
{
	//第一个参数:名字,名字格式:\\.\pipe\pipename
	//第二个参数:打开模式 PIPE_ACCESS_DUPLEX双工模式,FILE_FLAG_OVERLAPPED 在读写过程中会发送一个信号
	//第三个参数:管道模式  PIPE_TYPE_MESSAGE 消息的方式
	//第四个参数:最大实例个数
	//第五个参数:输出的缓冲大小
	//第六个参数:输入的缓冲区大小
	//第七个参数:默认的超时时间
	//第八个参数:安全描述
	m_hPipe=CreateNamedPipe(L"\\\\.\\pipe\\test", PIPE_ACCESS_DUPLEX| FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE,1,1024,1024,0,NULL);

	if (m_hPipe == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"创建命名管道失败");
		return;
	}

	//创建匿名事件对象
	HANDLE hEvent=CreateEvent(NULL, TRUE, FALSE,NULL);


	//异步 I/O 操作的参数和状态信息
	OVERLAPPED ol = {0};
	ol.hEvent = hEvent;

	//等待客户端的链接
	//ConnectNamedPipe 等待客户端有没有连接管道
	if (FALSE == ConnectNamedPipe(m_hPipe, &ol))
	{
		if (GetLastError() != ERROR_IO_PENDING)
		{
			MessageBox(L"等待客户端链接失败");
			return;
		}
	}

	//判断有没有信号
	if (WaitForSingleObject(hEvent, INFINITE) == WAIT_FAILED)
	{
		MessageBox(L"等待对象失败");
		CloseHandle(m_hPipe);
		CloseHandle(hEvent);
		m_hPipe = NULL;
		return;
	}
	CloseHandle(hEvent);
}

客户端管道的连接

void CClientDlg::OnBnClickedBtnConnect()
{
	//判断有没有可以用的管道
	if (FALSE == WaitNamedPipe(L"\\\\.\\pipe\\test", NMPWAIT_WAIT_FOREVER))
	{
		MessageBox(L"当前没有可以利用的命名管道");
		return;
	}

	//打开管道
	//第一个参数:管道名
	//第二个参数:读写模式
	//第三个参数:共享模式 0表示不共享
	//第四个参数:安全属性
	//第五个参数:创建方式
	//第六个参数:文件属性
	//第七个参数:提供文件的拓展属性
	CClientDlg::m_hPipe=CreateFile(L"\\\\.\\pipe\\test", GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
	if (m_hPipe == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"打开管道失败");
		m_hPipe = NULL;
		return;
	}


}

17 MFC进程通信,mfc,c++

邮槽

邮槽是一种基于文件的通信机制,通过创建一个具有唯一名称的邮槽对象,进程可以向该邮槽写入消息,而其他进程可以从该邮槽读取消息。邮槽支持广播方式,即多个进程都可以从同一个邮槽读取相同的消息。需要注意的是,邮槽是单向的,只支持从邮槽中读取消息或者向邮槽写入消息,不能同时进行读写操作。此外,邮槽只能用于同一台计算机上的进程间通信,不能用于跨网络的通信。 邮槽是一种简单而可靠的进程间通信机制,适用于需要在同一台计算机上的多个进程之间传递消息的场景。使用邮槽可以实现进程之间的解耦和异步通信,提高系统的可扩展性和响应性。

邮槽服务器

设置ui
17 MFC进程通信,mfc,c++

初始化邮槽

BOOL CMailSlotDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	//创建油槽
	//第一个参数:名字
	//第二个参数:最大消息的最大大小
	//第三个参数:超时时间
	//第四个参数:安全属性
	m_hMailSlot=CreateMailslot(L"\\\\.\\mailslot\\test", 0, MAILSLOT_WAIT_FOREVER, NULL);
	if (m_hMailSlot == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"创建邮槽失败");
		return TRUE;
	}

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

读取内容

//读取
void CMailSlotDlg::OnBnClickedBtnRead()
{
	wchar_t buffer[100] = { 0 };
	DWORD dwRead=0;
	//第一个参数:窗口句柄
	//第二个参数:数据缓存
	//第三个参数:读取的大小
	//第四个参数:实际读了多少
	//第五个参数:溢出量
	if (!ReadFile(m_hMailSlot, buffer, sizeof(buffer), &dwRead, NULL))
	{
		MessageBox(L"读取数据失败");
		return;
	}
	MessageBox(buffer);
}

邮槽客户端

ui设置
17 MFC进程通信,mfc,c++

void CMailSlotClientDlg::OnBnClickedBtnWrite()
{
	HANDLE hMainSlot=CreateFile(L"\\\\.\\mailslot\\test", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hMainSlot == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"打开邮槽失败");
		return;
	}

	wchar_t buffer[100] = L"邮槽客户端";
	DWORD dwWrite = 0;
	if (!WriteFile(hMainSlot, buffer, wcslen(buffer) * 2 + 1, &dwWrite, NULL))
	{
		MessageBox(L"写入数据失败");
		return;
	}
}

17 MFC进程通信,mfc,c++文章来源地址https://www.toymoban.com/news/detail-537166.html

到了这里,关于17 MFC进程通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MFC网络通信-Udp服务端

    目录 1、UI的布局 2、代码的实现: (1)、自定义的子类CServerSocket (2)、重写OnReceive事件 (3)、在CUdpServerDlg类中处理 (4)、在OnInitDialog函数中 (5)、实现自定义函数ProcessPendingRead()处理接收到的数据 (6)、加入新客户的消息先进性判断是否位enter (7)、加入的新消息

    2024年02月05日
    浏览(25)
  • 18 MFC TCP和UDP 网络通信

    有错误代码可以进行查找 将错误代码输入 勾选高级功能 如果没有勾选 TCP服务器 ui 设置 添加套接字类 创建虚函数接收连接 在服务器里面创建客户端类 在客户端类中添加接收的响应函数 断开连接 // TCPChatServerDlg.h: 头文件 // TCPChatServerDlg.cpp: 实现文件 //ClistenSocket.h //ClistenSo

    2024年02月14日
    浏览(26)
  • MFC第十六天 CFileDialog、CEdit简介、(线程)进程的启动,以及Notepad的开发(托盘技术-->菜单功能)

    通用对话框 CCommonDialog 这些对话框类封装 Windows 公共对话框。 它们提供了易于使用的复杂对话框实现。 CFileDialog 提供用于打开或保存文件的标准对话框。 CColorDialog 提供用于选择颜色的标准对话框。 CFontDialog 提供用于选择字体的标准对话框。 CFindReplaceDialog 为搜索和替换操作

    2024年02月16日
    浏览(28)
  • MFC Socket和合信CTMC M266ES 运动控制型PLC通信进行数据交换

             1、前两篇文章通过对Snap7和S7-1200/S7-1500PLC的通信进行了详细的介绍。Snap7的优点开源性强、使用方便易于上手,跨平台和可移植性性强。但是Snap7也有个缺点就是只能访问PLC的DB、MB、I、Q区进行数据读写,不能对V区进行读写,有人说可以读写V区,但是目前我还没有得

    2024年02月01日
    浏览(43)
  • 【MFC】09.MFC视图-笔记

    MFC视图窗口:CView类 显示数据/画面 我们之前的绘图消息,都是在框架类上画出来的 视图窗口就覆盖在框架窗口上 视图窗口本质上也是窗口,只是和框架窗口风格不同 CView类也继承于CWnd类 CView也能处理消息,因为它继承于CWnd类 试图窗口没有边框等 视图窗口是框架窗口的子

    2024年02月14日
    浏览(29)
  • 【MFC】01.MFC框架-笔记

    MFC Microsoft Fundation class 微软基础类库 框架 基于Win32 SDK进行的封装 属性:缓解库关闭 属性-C/C++/代码生成/运行库/MTD 属性-常规-MFC的使用:在静态库中使用MFC,默认是使用的共享DLL,运行时库 SDK版本:开发软件的套件 WSK:开发驱动的套件 MFC基于类的管理 预编译头: Demo01.h

    2024年02月14日
    浏览(27)
  • MFC——我的第一个MFC

    我的第一个MFC是在图像软件设计课程中创建的,使用Visual Studio 2022软件,基于C++语言,依赖freeimage图像库,实现在窗口应用中对一幅图像进行各种处理功能(如中值滤波等) 微软基础类库(Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库,以C++类的形式封装了W

    2024年02月06日
    浏览(43)
  • 《MFC编程》:MFC的概念和作用

    MFC(Microsoft Foundation Classes),是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。 所以在MFC中,你可以直

    2024年02月02日
    浏览(23)
  • 【MFC】07.MFC六大机制:消息映射-笔记

    本专栏上两篇文章分别介绍了【MFC】05.MFC第一大机制:程序启动机制和【MFC】06.MFC第二大机制:窗口创建机制,这篇文章来为大家介绍MFC的第三大机制:消息映射 typfd要实现消息映射,必须满足的三个条件: 类必须继承于CmdTargert 类必须声明重定义 DECLARE_MESSAGE_MAP 类外必须实

    2024年02月13日
    浏览(34)
  • 【MFC】05.MFC六大机制:程序启动机制-笔记

    MFC程序开发所谓是非常简单,但是对于我们逆向人员来说,如果想要逆向MFC程序,那么我们就必须了解它背后的机制,这样我们才能够清晰地逆向出MFC程序,今天这篇文章就来带领大家了解MFC的第一大机制:程序启动机制: 首先,我们创建一个单文档架构程序,我们来观察一

    2024年02月13日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包