数据复制消息WM_COPYDATA

WM_COPYDATA是一个非常特殊的消息,此消息可能携带一个比较大的消息参数,而其他消息都只能携带两个固定大小的参数(WPARAMLPARAM)。

WM_COPYDATA的两个参数如下:

wParam//发送或传递这个消息的窗口

lParam//指向包含要发送的数据的COPYDATASTRUCT结构的指针

在发送WM_COPYDATA消息时,WM_COPYDATAwParam参数应该赋值为发送此消息的窗口,而lParam消息参数指向一个COPYDATASTRUCT结构类型的变量:

typedefstructtagCOPYDATASTRUCT {

ULONG_PTR dwData;//可以是任意值

DWORDcbData;//lpData内存区域的字节数

PVOIDlpData;//需要发送给目标窗口所在进程的数据

} COPYDATASTRUCT, *PCOPYDATASTRUCT;

在消息发送时,系统会将整个COPYDATASTRUCTlpData所指向的内容全部发送给目标进程。目标进程窗口在收到WM_COPYDATA后,可以从lParam参数中提取出数据。

数据发送端代码片段:

// ************ Globals ************

//

#defineASCEDISPLAY 1

typedefstructtagASCEREC//将用户输入的消息封装在这个结构中

{

wchar_ts1[80];

wchar_ts2[80];

DWORD n;

} ASCEREC;

COPYDATASTRUCT AsceCDS;

ASCEREC AsceRec;

HRESULT hResult;

BOOL CALLBACK InfoDlgProc( HWND, UINT, WPARAM, LPARAM );

// ************ Code fragment ****************

// Get data from user. InfoDlgProc stores the information in AsceRec.

//

DialogBox( ghInstance, TEXT("InfoDlg"), hWnd, (DLGPROC) InfoDlgProc );

//

// Copy data into structure to be passed via WM_COPYDATA.

// Also, we assume that truncation of the data is acceptable.

//

hResult = StringCbCopy(AsceRec.s1,sizeof(AsceRec.s1), szFirstName );

if(hResult != S_OK)

returnFalse;

hResult = StringCbCopy(AsceRec.s2,sizeof(AsceRec.s2), szLastName );

if(hResult != S_OK)

returnFalse;

AsceRec.n = nAge;

//

// Fill the COPYDATA structure

//

AsceCDS.dwData = ASCEDISPLAY;// function identifier

AsceCDS.cbData =sizeof( AsceRec );// size of data

AsceCDS.lpData = &AsceRec;// data structure

//

// Call function, passing data in &AsceCDS

//此处假设接收进程具有一个类名为Disp32Class的标题为"Hidden Window"的窗口

hwDispatch = FindWindow( TEXT("Disp32Class"), TEXT("Hidden Window"));

if( hwDispatch != NULL )

SendMessage( hwDispatch,//接收消息的窗口的句柄

WM_COPYDATA,//要发送的消息

(WPARAM)(HWND) hWnd,//发送或传递这个消息的窗口

(LPARAM) (LPVOID) &AsceCDS );//指向包含要发送的数据的

//COPYDATASTRUCT结构的指针

else

MessageBox( hWnd, TEXT("Can't send WM_COPYDATA"), TEXT("ASCEApp"), MB_OK );

数据接收端代码片段:

// ************ Globals ************

//

#defineASCEDISPLAY 1

typedefstructtagASCEREC

{

wchar_ts1[80];

wchar_ts2[80];

DWORD n;

} ASCEREC;

PCOPYDATASTRUCT pAsceCDS;

voidWINAPI AsceDisplay( LPTSTR, LPTSTR, DWORD );

//

// ************ Code fragment ****************

//

caseWM_COPYDATA:

pAsceCDS = (PCOPYDATASTRUCT) lParam;

switch( pAsceCDS->dwData )

{

caseASCEDISPLAY:

AsceDisplay( (LPTSTR) ((ASCEREC *)(pAsceCDS->lpData))->s1,

(LPTSTR) ((ASCEREC *)(pAsceCDS->lpData))->s2,

(DWORD) ((ASCEREC *)(pAsceCDS->lpData))->n );

}

break;

WM_COPYDATA消息的不足之处:

1)必须要有一个窗体来接收消息和数据(缺乏灵活性),数据在使用之前先得拷贝到一个映射文件(浪费资源);

2)只能是本机内的进程间通信;

3)必须让两个进程在启动后,相互知道主窗口的HWND(至少一方);

4)使用WM_COPYDATA消息时,只能用SendMessage()函数发送而不能使用PostMessage(),而这两个函数的区别是SendMessage()发出消息后不是立即返回,而是在接收方的消息响应函数处理完之后才返回,并能够得到返回结果,在此期间发送方程序将被阻塞,即SendMessage()函数后面的语句不能被继续执行;而PostMessage()函数在发出消息后将立即返回,且无法获得消息的执行结果。

由此可见,在交换数据量较大的情况下实现数据频繁而快速地交换时,使用WM_COPYDATA消息的方法不合适,因为当数据传输过于频繁时,容易导致数据的丢失。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值