Windows支持进程间的消息通信:注册消息(register messages)

和其它消息通信的区别:

WM_* 只用于windows预定义的消息,都有特定的含义;

WM_USER+* 只能用于窗口过程(即通信目标必须是窗口类注册的窗口),否则无效;

WM_COPYDATA 是一个特殊的WM_*消息,但只用于同步通信,必须使用SendMessage。

注册消息:比WM_USER+*更灵活,常用于多个进程同时处理统一个消息(注意是进程而不只是窗口)。

 

发送方和接收方都需要做的:


// 1、定义注册消息:参数字符串必须在系统内保证唯一
static const UINT WM_CHECK_ITS_ME = RegisterWindowMessage(_T("##DUIVISION_APPLICATION##"));

// 2、定义消息数据结构
// 进程间消息内容的结构定义
struct DUI_INTERPROCESS_MSG
{
	TCHAR	wAppName[128];		// 应用名
	UINT	uControlID;			// 控件ID
	TCHAR	wControlName[64];	// 控件名字
	UINT	uMsg;				// 消息
	WPARAM	wParam;				// 参数1
	LPARAM	lParam;				// 参数2
	TCHAR	wInfo[10240];		// 信息字符串
	UINT	uDataLen;			// 扩展部分长度
};

1、发送方:

BOOL SendInterprocessMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, CString strAppName, CString strInfo)
{
	// number of characters in memory-mapped file
	const DWORD dwMemoryFileSize = sizeof(DUI_INTERPROCESS_MSG);

	// memory-mapped file name
	const LPCTSTR sMemoryFileName = _T("DF034858-1608-4147-0604-4A0CD86F6C9F");

	HANDLE hFileMapping = NULL;
	LPVOID pViewOfFile = NULL;

	// Create file mapping which can contain dwMemoryFileSize characters
	hFileMapping = CreateFileMapping(
		INVALID_HANDLE_VALUE,           // system paging file
		NULL,                           // security attributes
		PAGE_READWRITE,                 // protection
		0,                              // high-order DWORD of size
		dwMemoryFileSize*sizeof(TCHAR), // low-order DWORD of size
		sMemoryFileName);               // name

	DWORD dwError = GetLastError();     // if ERROR_ALREADY_EXISTS 
	// this instance is not first (other instance created file mapping)

	if(! hFileMapping)
	{
		//TRACE(_T("Creating of file mapping failed.\n"));
		return FALSE;
	}

	pViewOfFile = MapViewOfFile(
		hFileMapping,               // handle to file-mapping object
		FILE_MAP_ALL_ACCESS,        // desired access
		0,
		0,
		0);                         // map all file

	if(!pViewOfFile)
	{
		//TRACE(_T("MapViewOfFile failed.\n"));
		CloseHandle(hFileMapping);
		return FALSE;
	}

	// 初始化进程间通知消息
	DUI_INTERPROCESS_MSG interMsg;
	memset(&interMsg, 0, sizeof(DUI_INTERPROCESS_MSG));
	_tcscpy_s(interMsg.wAppName, strAppName.GetBuffer(0));
	strAppName.ReleaseBuffer();
	interMsg.uControlID = APP_IPC;	// 控件ID使用预定义的进程间消息控件ID
	interMsg.uMsg = uMsg;
	interMsg.wParam = wParam;
	interMsg.lParam = lParam;
	_tcscpy_s(interMsg.wInfo, strInfo.GetBuffer(0));
	strInfo.ReleaseBuffer();
	memcpy(pViewOfFile, &interMsg, sizeof(DUI_INTERPROCESS_MSG));

	ULONG_PTR result;
	LRESULT ok = SendMessageTimeout(HWND_BROADCAST,	// 发送广播消息
		WM_CHECK_ITS_ME,
		wParam,			// wParam参数,表示应用类型
		0,				// lParam参数,默认为0
		SMTO_BLOCK |
		SMTO_ABORTIFHUNG,
		200,			// 超时时间
		&result);

	UnmapViewOfFile(pViewOfFile);
	CloseHandle(hFileMapping);

	return TRUE;
}

3、接收方

在窗口处理过程中加入消息处理:

        // 1、以MFC为例
	BEGIN_MESSAGE_MAP(CDlgBase, CDialog)
		ON_REGISTERED_MESSAGE(WM_CHECK_ITS_ME, OnCheckItsMe)
	END_MESSAGE_MAP()


        // 函数实现:
        LRESULT CDlgBase::OnCheckItsMe(WPARAM wParam, LPARAM lParam)
	{
		// wParam用于区分应用,lParam用于具体命令,传送的内容则通过内存映射文件传递
		// 此跨进称消息是通过广播方式传送的,因此所有窗口都会收到,只有主窗口需要处理此消息,其他窗口应该忽略
		// 主窗口收到消息之后调用事件处理对象进行处理


		// 判断是否当前的应用
		if(wParam != GetAppID())
		{
			return FALSE;
		}

		// 获取内存映射文件的内容
		// number of characters in memory-mapped file
		const DWORD dwMemoryFileSize = sizeof(DUI_INTERPROCESS_MSG);

		// memory-mapped file name
		const LPCTSTR sMemoryFileName = _T("DF034858-1608-4147-0604-4A0CD86F6C9F");

		HANDLE hFileMapping = NULL;
		LPVOID pViewOfFile = NULL;

		// Create file mapping which can contain dwMemoryFileSize characters
		hFileMapping = CreateFileMapping(
			INVALID_HANDLE_VALUE,           // system paging file
			NULL,                           // security attributes
			PAGE_READWRITE,                 // protection
			0,                              // high-order DWORD of size
			dwMemoryFileSize*sizeof(TCHAR), // low-order DWORD of size
			sMemoryFileName);               // name

		DWORD dwError = GetLastError();     // if ERROR_ALREADY_EXISTS 
		// this instance is not first (other instance created file mapping)

		if(! hFileMapping)
		{
			//TRACE(_T("Creating of file mapping failed.\n"));
			return FALSE;
		}

		pViewOfFile = MapViewOfFile(
			hFileMapping,               // handle to file-mapping object
			FILE_MAP_ALL_ACCESS,        // desired access
			0,
			0,
			0);                         // map all file

		if(!pViewOfFile)
		{
			//TRACE(_T("MapViewOfFile failed.\n"));
			CloseHandle(hFileMapping);
			return FALSE;
		}

		DUI_INTERPROCESS_MSG interMsg;
		memcpy(&interMsg, pViewOfFile, sizeof(DUI_INTERPROCESS_MSG));

		UnmapViewOfFile(pViewOfFile);
		CloseHandle(hFileMapping);


		return TRUE;
	}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值