C++进程通信实现-----WM_COPYDATA消息

工作中碰到了32位dll和64位dll通信问题,上网搜索了相关的问题,发现最简单的实现方式就是利用WM_COPYDATA消息传递,很多博客给出了实现代码,但大部分都是发送端C++,接收端C#或MFC。本文给出自己实现的简单例子,发送接收相互通信,都是用C++实现。

 

目录

 

WM_COPYDATA 消息

代码实现


WM_COPYDATA 消息

An application sends the WM_COPYDATA message to pass data to another application.即一个程序通过WM_COPYDATA消息传递数据给另一个程序。

该消息只能由 SendMessage() 发送 ,SendMessage()需要知道进程句柄,所以一般都搭配FindWindow()使用。通过FindWindow查找进程句柄,然后使用SendMessage() 向这个句柄发送信息

代码实现

进程A:

#include"windows.h"
#include"stdlib.h"
#include"stdio.h"
#include"tchar.h"
#include<thread>
#include<mutex>


HWND gHandB;
HWND gHandA;

int sendInit();
void sendMsg(int code, int len = 0, void* data = NULL);


LRESULT CALLBACK WindowProc(
	_In_  HWND hwnd,
	_In_  UINT message,
	_In_  WPARAM wParam,
	_In_  LPARAM lParam
	){
	if (message == WM_COPYDATA){

		COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;
		printf("Process A Rec:code = %x,msg = %s\n", pCopyData->dwData, pCopyData->lpData);

	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}


void msgThread(void* reserved){


	WNDCLASS wndClass;
	HINSTANCE hCurrentInst = GetModuleHandle(NULL);
	ZeroMemory(&wndClass, sizeof(WNDCLASS));
	wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc = WindowProc;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = hCurrentInst;
	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndClass.lpszMenuName = NULL;
	wndClass.lpszClassName = TEXT("ProcessA");
	RegisterClass(&wndClass);
	gHandA = CreateWindow(TEXT("ProcessA"), TEXT("ProcessA"),
		WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
		1, 1,
		320, 240,
		0, 0, hCurrentInst, 0);
	ShowWindow(gHandA, SW_HIDE);
	UpdateWindow(gHandA);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0) == TRUE) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

int sendInit(){

	int ret = 0;


	gHandB = FindWindow(NULL, _T("ProcessB"));
	if (gHandB == NULL)
		ret = -1;

	return ret;
}

void sendMsg(int code, int len, void* data){

	COPYDATASTRUCT CopyData;

	CopyData.dwData = code;//保存一个数值, 可以用来作标志等
	CopyData.cbData = len;// strlen(szSendBuf);//待发送的数据的长度
	CopyData.lpData = data;// szSendBuf;//待发送的数据的起始地址(可以为NULL)
	SendMessage(gHandB, WM_COPYDATA, (WPARAM)gHandB, (LPARAM)&CopyData);
}



int main(int argc, char* argv[]){


	printf("This is 进程A\n ");
	/**********************************************************************************/
	if (argc != 2)
		return -1;
	std::string svacExePath = argv[1];
	int ret = WinExec(svacExePath.c_str(), SW_SHOWMAXIMIZED);

	Sleep(100);

	if (ret > 31)
	printf("Execute SvacClient Success\n");

	

	std::thread msgThread(msgThread, (void*)NULL);
	msgThread.detach();

	
	//wait process B
	while (sendInit() != 0)
		Sleep(1);

	//send msg
	char _buf[] = "Msg from process A.";
	sendMsg(0x01, sizeof(_buf), _buf);
	//printf("Send initial success\n ");


	//close processB
	std::string killExe = "taskkill /f /t /im ";
	killExe += svacExePath;
	WinExec(killExe.c_str(), SW_HIDE);

	return 0;
}

进程B:

#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include<thread>



HWND gHandB;
HWND gHandA;



void sendMsg(int code, int len = 0, void* data = NULL);
int sendInit();


LRESULT CALLBACK WindowProc(
	_In_  HWND hwnd,
	_In_  UINT message,
	_In_  WPARAM wParam,
	_In_  LPARAM lParam
	){
	if (message == WM_COPYDATA){
		COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;
		printf("Process B Rec:code = %x,msg = %s\n", pCopyData->dwData, pCopyData->lpData);
		
		while (sendInit() != 0)
			Sleep(1);
		char _buf[] = "Msg from process B.";
		sendMsg(0x02, sizeof(_buf), _buf);
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}


void msgTreadFun(void* reserved){

	
	WNDCLASS wndClass;
	HINSTANCE hCurrentInst = GetModuleHandle(NULL);
	ZeroMemory(&wndClass, sizeof(WNDCLASS));
	wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc = WindowProc;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = hCurrentInst;
	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndClass.lpszMenuName = NULL;
	wndClass.lpszClassName = TEXT("ProcessB");
	RegisterClass(&wndClass);
	gHandB = CreateWindow(TEXT("ProcessB"), TEXT("ProcessB"),
		WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
		1, 1,
		320, 240,
		0, 0, hCurrentInst, 0);
	ShowWindow(gHandB, SW_HIDE);
	UpdateWindow(gHandB);

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0) == TRUE) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}


int sendInit(){

	int ret = 0;
	const char szDlgTitle[] = "ProcessA";
	gHandA = FindWindow(NULL, szDlgTitle);
	if (gHandA == NULL)
		ret = -1;

	return ret;
}

void sendMsg(int code, int len, void* data){

	COPYDATASTRUCT CopyData;

	CopyData.dwData = code;//保存一个数值, 可以用来作标志等
	CopyData.cbData = len;// strlen(szSendBuf);//待发送的数据的长度
	CopyData.lpData = data;// szSendBuf;//待发送的数据的起始地址(可以为NULL)
	SendMessage(gHandA, WM_COPYDATA, (WPARAM)gHandB, (LPARAM)&CopyData);
}


int main(int argc, char* argv[]){

	printf("This is 进程B\n ");
	/**********************************************************************************/
	int ret = 0;
	int time = 0;
	
	//Rec Thread
	std::thread msgThread(msgTreadFun, (void*)NULL);
	msgThread.detach();

	while (gHandB == NULL)
		Sleep(1);
	

	while (1){
		Sleep(1);
	}

	return 0;
}

 运行:

 

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值