养生

VC下動態數據交換技術之DDE數據傳送

2019-06-02 19:37:47来源:励志吧0次阅读

男性突然夜尿增多怎么办
男性为什么夜尿增多
尿频夜尿增多吃什么

  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编译通过。查看本文来源

欧美明星街拍示范 薄外套搭配小脚裤迷人养眼
广电“强推”TVOS 行政手段难敌市场趋势``
史上美的孕妇是她:娜塔丽·波特曼
分享到: