因为DDE使用内存对象将数据从一个应用程序传递到另一个应用程序,DDEML提供了一组DDE应用程序可用于创建和管理DDE对象的功能。
涉及数据交换的所有事务都要求提供数据的应用程序创建一个包含数据的本地缓冲区,然后调用DdeCreateDataHandle函数。此函数分配DDE对象,将数据从缓冲区复制到对象,并返回数据句柄。数据句柄是DDEML用于提供对DDE对象中数据的访问的双字值。要在DDE对象中共享数据,应用程序将数据句柄传递给DDEML,DDEML将句柄传递给正在接收数据事务的应用程序的DDE回调函数。
以下示例显示如何创建DDE对象并获取对象的句柄。在XTYP_ADVREQ事务中,回调函数将当前时间转换为ASCII字符串,将字符串复制到本地缓冲区,然后创建一个包含该字符串的DDE对象。回调函数将DDE对象(HDDEDATA)的句柄返回给DDEML,该对象将句柄传递给客户端应用程序。
typedef struct tagTIMEenen
{
INT hour; /* 0 - 11 hours for analog clock */
INT hour12; /* 12-hour format */
INT hour24; /* 24-hour format */
INT minute;
INT second;
INT ampm; /* 0 - AM , 1 - PM */
} TIME;
HDDEDATA EXPENTRY DdeCallback(UTYPE,uFmt,hconv,hsz1,hsz2,
-ruleHData,dwData1,dwData2)
UINT uType;
UINT uFmt;
HCONV hconv;
HSZ hsz1;
HSZ hsz2;
HDDEDATA hdata;
DWORD dwData1;
DWORD dwData2;
{
CHAR szBuf[32];
switch(uType){
case XTYP_ADVREQ:
if ((hsz1 == hszTime && hsz2 == hszNow) &&
(uFmt == CF_TEXT)) {
/ *将格式化的字符串复制到缓冲区。*/
itoa(tmTime.hour, szBuf, 10);
lstrcat(szBuf, ":");
if(tmTime.minute < 10)
lstrcat(szBuf, "0");
itoa(tmTime.minute, &szBuf[lstrlen(szBuf)], 10);
lstrcat(szBuf, ":");
if(tmTime.second < 10)
strcat(szBuf, "0");
itoa(tmTime.second, &szBuf[lstrlen(szBuf)], 10);
szBuf[lstrlen(szBuf)] = '\0';
/ *创建一个全局对象并返回其数据句柄。*/
return(DdeCreateDataHandle(
idInst,
(LPBYTE)szBuf,/ *实例标识符* /en
lstrlen(szBuf)+ 1,/ *源缓冲区长度* /
0,/ *从开始* /
hszNow,/ * item name string * /
CF_TEXT,/ *剪贴板格式* /
0)); /* no creation flags */
}其他
return (HDDEDATA) NULL;
.
./ *处理其他交易。*/
.
}
}
接收应用程序通过将数据句柄传递给DdeAccessData函数来获取指向DDE对象的指针。DdeAccessData返回的指针提供只读访问权限。应用程序应该使用指针查看数据,然后调用DdeUnaccessData函数使指针无效。应用程序可以使用DdeGetData功能将数据复制到本地缓冲区。
以下示例获取指向由【HDATA】参数标识的DDE对象的指针,将内容复制到本地缓冲区,然后使指针无效。
HDDEDATA hdata;
LPBYTE lpszAdviseData;
DWORD cbDataLen;
DWORD i;
char szData[32];
.
.
.
case XTYP_ADVDATA:
lpszAdviseData = DdeAccessData(hdata, &cbDataLen);
for (i = 0; i < cbDataLen; i++)
szData[i] = *lpszAdviseData++;
DdeUnaccessData(hdata);
return (HDDEDATA) TRUE;
.
.
.
通常,当创建数据句柄的应用程序将该句柄传递给DDEML时,该句柄在创建应用程序中变为无效。如果应用程序必须与单个应用程序共享数据,则这种情况不是问题。但是,如果应用程序必须与多个应用程序共享相同的数据,则创建应用程序应在DdeCreateDataHandle中指定HDATA_APPOWNED标志。这样做会使DDE对象成为创建应用程序的所有权,并防止DDEML使数据句柄无效。然后,只有在调用DdeCreateDataHandle一次后,应用程序可以传递数据句柄。
如果应用程序在DdeCreateDataHandle的【afCmd】参数中指定HDATA_APPOWNED标志,则必须调用DdeFreeDataHandle函数来释放内存句柄,而不管它是否将句柄传递给DDEML。在终止之前,应用程序必须调用DdeFreeDataHandle以释放它创建但未传递给DDEML的任何数据句柄。
尚未将DDE对象的句柄传递给DDEML的应用程序可以使用DdeAddData功能将数据添加到对象或覆盖对象中的数据。通常,应用程序使用DdeAddData来填充未初始化的DDE对象。应用程序将数据句柄传递给DDEML后,不能更改由句柄标识的DDE对象;它只能被释放。