进程通信专题
4、WM COPYDATA
1、课程目标
- 理解WM_COPYDATA的通信原理
- 掌握跨进程数据传递
- 学会窗口间的消息通信
- 理解WM_COPYDATA的安全应用
2、名词解释
| 术语 | 英文 | 说明 |
|---|---|---|
| WM_COPYDATA | Copy Data Message | 用于跨进程传递数据的消息 |
| COPYDATASTRUCT | Copy Data Structure | 传递数据的结构体 |
| 同步通信 | Synchronous | SendMessage是同步的 |
3、技术原理
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData; // 用户定义的数据
DWORD cbData; // 数据大小
PVOID lpData; // 数据指针
} COPYDATASTRUCT;
4、代码实现
4.1、示例1:发送数据
#include <windows.h>
#include <stdio.h>
#define MY_MSG_TYPE 1001
void SendData(HWND hTargetWnd, const void* data, size_t size) {
COPYDATASTRUCT cds;
cds.dwData = MY_MSG_TYPE;
cds.cbData = size;
cds.lpData = (PVOID)data;
SendMessage(hTargetWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
}
void SendStringDemo() {
HWND hTarget = FindWindow(NULL, TEXT("Receiver Window"));
if (hTarget) {
const char* message = "Hello from sender!";
SendData(hTarget, message, strlen(message) + 1);
}
}
4.2、示例2:接收数据
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK ReceiverWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_COPYDATA: {
COPYDATASTRUCT* pCds = (COPYDATASTRUCT*)lParam;
if (pCds->dwData == 1001) {
char* message = (char*)pCds->lpData;
printf("Received: %s\n", message);
// 可以返回TRUE表示处理成功
return TRUE;
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
4.3、示例3:结构体传递
#include <windows.h>
#include <stdio.h>
typedef struct {
int id;
char name[32];
double value;
} MyData;
void SendStructData(HWND hTarget) {
MyData data = {1, "Test", 3.14};
COPYDATASTRUCT cds;
cds.dwData = 2001;
cds.cbData = sizeof(MyData);
cds.lpData = &data;
SendMessage(hTarget, WM_COPYDATA, 0, (LPARAM)&cds);
}
void ReceiveStructData(COPYDATASTRUCT* pCds) {
if (pCds->dwData == 2001 && pCds->cbData == sizeof(MyData)) {
MyData* pData = (MyData*)pCds->lpData;
printf("ID: %d, Name: %s, Value: %.2f\n",
pData->id, pData->name, pData->value);
}
}
4.4、示例4:完整通信示例
#include <windows.h>
#include <stdio.h>
// 命令类型
#define CMD_PING 1
#define CMD_PONG 2
#define CMD_DATA 3
typedef struct {
int command;
char payload[256];
} Message;
void SendCommand(HWND hTarget, int cmd, const char* payload) {
Message msg;
msg.command = cmd;
strncpy(msg.payload, payload, sizeof(msg.payload)-1);
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = sizeof(Message);
cds.lpData = &msg;
SendMessage(hTarget, WM_COPYDATA, 0, (LPARAM)&cds);
}
LRESULT HandleCommand(HWND hWnd, COPYDATASTRUCT* pCds) {
if (pCds->cbData != sizeof(Message)) return FALSE;
Message* pMsg = (Message*)pCds->lpData;
switch (pMsg->command) {
case CMD_PING:
printf("Received PING, sending PONG\n");
// 回复PONG(需要获取发送者窗口)
break;
case CMD_DATA:
printf("Received data: %s\n", pMsg->payload);
break;
}
return TRUE;
}
5、课后作业
- 基础练习:实现两个进程间的WM_COPYDATA通信
- 结构传递:传递复杂结构体数据
- 双向通信:实现请求-响应模式
- 安全应用:理解WM_COPYDATA的安全限制