下动态数据交换技术之数据传送牛
DDE客户端的处理
客户对服务器发出的WM_DDE_DATA消息的响应主要完成对服务器提供数据项内容的提取。首先调用UnpackDDElParam()将消息参数lParam中包含的DDEDATA格式化内存块句柄和数据项原子标识值提取出来。在检验了数据格式的有效后,将共享内存块中的数据项内容读取出来:
UINT uLo, uHi; // lParam消息的低、高字
UnpackDDElParam(WM_DDE_DATA,lParam,uLo,uHi);//对lParam进行解包
HANDLE hDDEData = (HANDLE)uLo; // 取出DDEDATA句柄
ATOM atomItem = (ATOM)uHi; // 取出数据项原子标识值
DDEDATA* lpDDEData = (DDEDATA*)GlobalLock(hDDEData); // 锁定内存块
if (lpDDEData-cfFormat == CF_TEXT) { // 检验数据格式
// 报告服务器返回的数据项信息
CString sMessage = \"服务器返回的数据项内容为:\" + CString(lpDDEData-Value);
AfxMessageBox(sMessage);
}
GlobalUnlock(hDDEData); // 内存解锁
与请求传送消息相比,客户也可以在没有请求的情况下通过向服务器传送WM_DDE_POKE消息实现对服务器的数据项传输,使用的消息参数lParam的高字为数据项原子标识值,低字为全局共享内存块的DDEPOKE结构句柄。从下面给出的向服务器窗口发送WM_DDE_POKE消息的代码段不难看出其与服务器使用WM_DDE_DATA消息发送数据的过程是非常类似的:
CString sDataItem = \"Data from Client!\"; // 发送的数据项内容
// 分配DDEPOKE格式化的全局共享内存块
HGLOBAL hDDEPoke = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (LONG)sizeof(DDEPOKE) + tLength() + 2);
DDEPOKE* lpDDEPoke = (DDEPOKE*)GlobalLock(hDDEPoke); // 锁定内存块地址
lpDDEPoke-cfFormat = CF_TEXT; // 设置格式字段
::strcpy((LPSTR)lpDDEPoke-Value, sDataItem); // 填充数据项内容
::strcat((LPSTR)lpDDEPoke-Value, \"\\r\\n\"); // 添加终结字符
GlobalUnlock(hDDEPoke); // 解锁内存块
ATOM atomItem = GlobalAddAtom(\"Item B\"); // 获取数据项原子标识值
HWND hwndClient = GetSafeHwnd(); // 获取当前窗口的安全句柄
// 组合消息参数lParam
LONG lDataPack = PackDDElParam(WM_DDE_POKE, (UINT)hDDEPoke, atomItem);
// 向服务器窗口发送WM_DDE_POKE消息
::PostMessage(m_hwndServer, WM_DDE_POKE, (WPARAM)hwndClient, (LPARAM)lDataPack);
DDE服务器对数据的接收处理
服务器在响应WM_DDE_POKE消息后必须决定其是否能够接收客户发送来的格式数据。但不管服务器是否能够处理该数据都必须向客户发送一个WM_DDE_ACK消息作为应答,通过消息参数lParam的低字区分服务器是否成功接收数据:
UINT uLo, uHi; // lParam消息的低、高字
UnpackDDElParam(WM_DDE_DATA, lParam, uLo, uHi); // 对lParam进行解包
HANDLE hDDEPoke = (HANDLE)uLo; // 取出DDEPOKE句柄
ATOM atomItem = (ATOM)uHi; // 取出数据项原子标识值
DDEPOKE* lpDDEPoke = (DDEPOKE*)GlobalLock(hDDEPoke); // 锁定内存块
if (lpDDEPoke == NULL) {
// 组合消息参数lParam
LONG lDataPack = PackDDElParam(WM_DDE_ACK, (UINT)0, atomItem);
// 向客户发送否定应答
::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hwndServer, (LPARAM)lDataPack);
return;
}
if (lpDDEPoke-cfFormat == CF_TEXT) { // 检验数据格式
// 报告服务器返回的数据项信息
CString sMessage = \"客户发来数据:\" + CString(lpDDEPoke-Value);
AfxMessageBox(sMessage);
} else {
// 组合消息参数lParam
LONG lDataPack = PackDDElParam(WM_DDE_ACK, (UINT)0, atomItem);
// 向客户发送否定应答
::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hwndServer, (LPARAM)lDataPack);
就是不还。 GlobalUnlock(hDDEPoke); // 内存解锁
return;
}
GlobalUnlock(hDDEPoke); // 内存解锁
// 组合消息参数lParam
LONG lDataPack = PackDDElParam(WM_DDE_ACK, (UINT)0x8000, atomItem);
::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)m_hwndServer, (LPARAM)lDataPack); // 向客户发送肯定应答
小结
本文主要探讨了动态数据交换技术中的数据传送处理的具体实现过程,并给出了各主要环节的相关实现代码。本文所述代码在Windows 2000 Professional下由Microsoft Visual C++ 6.0编译通过。查看本文来源
福州白癜风治疗费用潍坊男科病医院
北京医院男科哪家医院好
- 美股短线赛艇 三大股指悉数转跌
- 探校跑断腿?更快来报名国际化学校咨询会·青岛站,心仪梦校一天看全!
- 为什么世界上没进化出会喷火的脊椎动物?伤敌八百自损一千而且还烫嘴
- 生来双目皆盲,却因修炼奇术成了“天眼大仙”不料看错姻缘,厄运连累整个后代
- 微信原先增加这个功能!
- 注意!晚餐要早还要不及!
- 美联储会议纪要前瞻:加息75个基点板上钉钉 利率到年底或晋升3.4%
- 天津在岗骑手近2万,19日起采用动态“随申码”核验身份
- 贴吧飞桨文心大模型全景图全面升级
- 催生无果后,人口出现负增长?经济学家提出解决方案,父母都一致
- 辽篮航空运输抵沈!金金缺席,空姐围住艾伦,双外明日回国,隔离7天
- 吃杏花“急性中毒”?过量食用慎防“杏花病”!