要执行DDE任务,许多DDEML函数需要访问字符串。例如,当客户端调用DdeConnect函数来请求与服务器的对话时,客户端必须指定服务名称和主题名称。应用程序通过传递字符串句柄(HSZ)而不是DDEML函数中的指针来指定字符串。A 【字符串句柄】是由系统分配的双字值,用于标识字符串。
应用程序可以通过调用DdeCreateStringHandle函数获取特定字符串的字符串句柄。此函数将字符串注册到系统,并向应用程序返回一个字符串句柄。应用程序可以将句柄传递给必须访问字符串的DDEML函数。以下示例获取系统主题字符串和服务名称字符串的字符串句柄。
HSZ hszServName;
HSZ hszSysTopic;
.
.
.
hszServName = DdeCreateStringHandle(
idInst,/ *实例标识符* /en
“MyServer”,/ *字符串注册* /
CP_WINANSI); /* Windows ANSI code page */
hszSysTopic = DdeCreateStringHandle(
idInst,/ *实例标识符* /en
SZDDESYS_TOPIC,/ *系统主题* /
CP_WINANSI); /* Windows ANSI code page */
.
.
.
上述示例中的【idInst】参数指定通过DdeInitialize函数获取的实例标识符。
应用程序的DDE回调函数在大多数DDE事务期间接收一个或多个字符串句柄。例如,服务器在XTYP_REQUEST事务期间接收两个字符串句柄:一个标识指定主题名称的字符串,另一个标识指定项目名称的字符串。应用程序可以获得与字符串句柄对应的字符串的长度,并通过调用DdeQueryString函数将字符串复制到应用程序定义的缓冲区,如下例所示。
DWORD idInst;
DWORD cb;
HSZ hszServ;
PSTR pszServName;
.
.
.
cb = DdeQueryString(idInst, hszServ, (LPSTR) NULL, 0,
CP_WINANSI) + 1;
pszServName = (PSTR) LocalAlloc(LPTR, (UINT) cb);
DdeQueryString(idInst, hszServ, pszServName, cb, CP_WINANSI);
.
.
.
一个实例特定的字符串句柄不能从字符串句柄映射到字符串并返回到字符串句柄。例如,尽管DdeQueryString从字符串句柄创建一个字符串,然后DdeCreateStringHandle从该字符串创建一个字符串句柄,但两个句柄不一样,如以下示例所示。
DWORD idInst;
DWORD cb;
HSZ hszInst, hszNew;
PSZ pszInst;
.
.
.
DdeQueryString(idInst, hszInst, pszInst, cb, CP_WINANSI);
hszNew = DdeCreateStringHandle(idInst, pszInst, CP_WINANSI);
/* hszNew != hszInst ! */
.
.
.
要比较两个字符串句柄的值,请使用DdeCmpStringHandles函数。
当回调函数返回时,传递给应用程序的DDE回调函数的字符串句柄将变为无效。回调函数使用DdeKeepStringHandle函数返回后,应用程序可以保存字符串句柄以供使用。
当应用程序调用{??989796082}时,系统将指定的字符串输入到字符串表中,并生成用于访问字符串的句柄。该系统还维护字符串表中每个字符串的使用计数。
当应用程序调用{??989796084}并指定表中已经存在的字符串时,系统将增加使用次数,而不是添加字符串的另一个出现。(应用程序还可以使用DdeKeepStringHandle来增加使用次数。)当应用程序调用{??989796087}功能时,系统将使用次数减少。
当其使用次数等于零时,将从表中删除一个字符串。因为多个应用程序可以获取特定字符串的句柄,所以应用程序不能释放字符串句柄多于创建或保留句柄的次数。否则,应用程序可能会导致从表中删除该字符串,拒绝其他应用程序访问该字符串。
DDEML字符串管理功能基于Windows原子管理器,并受到与原子相同的大小限制。