工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
VC下动态数据交换技术之DDE数据传送
[文章信息]
作者:中国电波传播研究所青岛分所郎锐
时间:2004-10-10
出处:天极网
责任编辑:方舟
[文章导读]
 在建立DDE会话后,客户可以向服务窗口邮寄WM_DDE_REQUEST消息来请求指定的数据项
advertisement
热点推荐
· 真没想到VB也可以这样用之指针技术
· 禁止QQ登录的方法
· 给你的XML文件做个数字签名
· ImageReady制作“焰火”小动画
· Java加密和数字签名编程快速入门
[正文]

1 2  下一页

  冷数据链路的建立

  在建立DDE会话后,客户可以向服务窗口邮寄WM_DDE_REQUEST消息来请求指定的数据项。消息参数lParam的高字为指定数据项的原子标识值,低字为所要求的数据格式标识值。如果服务器没有找到匹配的数据项,将向客户邮寄一条否定应答消息WM_DDE_ACK;如果含有此数据项,则邮寄WM_DDE_DATA消息以响应客户的数据项请求,其消息参数lParam的高字为数据项原子标识值,低字为存放此数据项的全局共享内存块的DDEDATA结构句柄。

  对于上述方式,客户每需要一个数据项,都要向服务器窗口发送一次WM_DDE_REQUSET消息去请求数据项,由此可以建立冷数据链路。图1给出了服务器在能提供数据项和无法提供数据项的情况下所进行的消息流程:


图1 服务器在不同情况下对客户的应答

  客户通过下面的程序段代码完成对WM_DDE_REQUEST消息的邮寄,其中主要指定了数据项原子标识和数据格式:

HWND hwndClient = GetSafeHwnd(); // 获取服务器所在应用程序的窗口句柄
ATOM atomItem = GlobalAddAtom("Item A"); // 获取原子标识值
if (atomItem != 0) // 向服务器发出数据请求消息
::PostMessage(m_hwndServer, WM_DDE_REQUEST, (WPARAM)hwndClient, (LPARAM)MAKELONG(CF_TEXT, atomItem));

  DDE服务器的准备工作与消息处理

  DDE服务器窗口在创建之初就要首先进行一些准备工作,主要是对DDEDATA格式化的全局共享内存块的分配与设置,并指定所使用的格式字段和数据项内容,以便在接收到客户发来的数据项请求消息后,能将此共享内存块的句柄随应答消息传送给客户:

m_hwndServer = hwndServer; // 保存创建的DDE服务窗口
CString sDataItem = "HELLO WORLD!"; // 服务器数据项内容
// 分配DDEDATA格式化的全局共享内存块
m_hDDEData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (LONG)sizeof(DDEDATA) + sDataItem.GetLength() + 2);
// 锁定内存块地址
DDEDATA * lpDDEData = (DDEDATA*)GlobalLock(m_hDDEData);
lpDDEData->cfFormat = CF_TEXT; // 设置格式字段
::strcpy((LPSTR)lpDDEData->Value, sDataItem); // 填充数据项内容
::strcat((LPSTR)lpDDEData->Value, "\r\n"); // 添加终结字符
GlobalUnlock(m_hDDEData); // 解锁内存块

  在服务器进程对WM_DDE_REQUEST消息的响应函数中,首先从消息参数lParam中提取出请求的数据项原子标识值及数据格式。如果请求的数据格式与服务器提供的数据项格式一致,则进行枚举匹配,直至找到待请求的数据项。由于DDEDATA格式化的内存块句柄和数据项原子标识值是通过消息参数lParam传送到客户的,如果继续使用MAKELONG()进行高、低字组合,势必造成32位句柄值的破坏。对于这种情况应当使用PackDDElParam()函数进行组合。需要注意的是,在向客户传递WM_DDE_DATA消息时只能用PostMessage()函数去邮寄,而不能使用SendMessage()。如果服务器枚举完其提供的所有数据项后仍未找到匹配的数据项,就认为客户的本次请求失败,将向其邮寄WM_DDE_ACK消息作为否定应答,消息参数lParam的低字包含了状态信息。下面给出此部分的完整代码清单:

int ITEM_NUM = 3; // 服务器提供的数据项数目
CString ItemName[3] = {"Item A", "Item B", "Item C"}; // 服务器提供的数据项名
char szItemNameClient[255]; // 客户请求的数据项名
HWND hwndClient = (HWND)wParam; // 客户窗口句柄
short cfFormat = LOWORD(lParam); // 客户传来的数据格式
if (cfFormat == CF_TEXT){ // 格式一致则进入下一步操作
// 取客户请求的数据项名
GlobalGetAtomName(HIWORD(lParam), szItemNameClient, sizeof(szItemNameClient));
for (int i = 0; i < ITEM_NUM; i++){// 检索与服务器提供的哪个数据项匹配
if (strcmp(szItemNameClient, ItemName[i]) == 0) // 如检索到则跳出

break;
}
ATOM atomItem = GlobalAddAtom(ItemName[i]); // 获取原子标识值
// 若检索到数据项就发送WM_DDE_DATA消息,否则发送WM_DDE_ACK消息
if (i < ITEM_NUM){
LONG lDataPack = PackDDElParam(WM_DDE_DATA, (UINT)m_hDDEData, atomItem); // 组合消息参数lParam
::PostMessage(hwndClient, WM_DDE_DATA, (WPARAM)m_hwndServer, (LPARAM)lDataPack); // 邮寄WM_DDE_DATA消息
}
else {
DDEACK DDEAck; // 填充DDEACK结构
DDEAck.bAppReturnCode = 0;
DDEAck.reserved = 0;
DDEAck.fBusy = FALSE;
DDEAck.fAck = FALSE;
WORD wStatus = *(WORD*)&DDEAck;
::PostMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer, MAKELONG(wStatus, atomItem)); // 邮寄WM_DDE_ACK否定应答消息
}
GlobalDeleteAtom(atomItem); // 删除原子
GlobalFree(m_hDDEData); // 释放申请的内存
}


1 2  下一页

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • VC++与Matlab混合编程的研究与实现
  • OpenGL实现3DS文件中的模型自由旋转
  • 用Visual C++操作SQL Server主从表
  • VC++下命名管道编程的原理及实现
  • 用Media Player设计个性化媒体播放器
  • 民营家电商排队造手机 设备商全面杀入
  • 英特尔澄清杨旭任职传闻 官方没宣布此消息
  • 国资委河北密制联通拆分方案
  • 垃圾邮件害人害企害国 清除垃圾邮件不手软
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索