要发起DDE会话,客户端发送WM_DDE_INITIATE消息。通常,客户端通过调用SendMessage广播此消息,其中-1作为第一个参数。如果应用程序已经具有服务器应用程序的窗口句柄,则可以将消息直接发送到该窗口。客户端通过调用GlobalAddAtom为应用程序名称和主题名称准备原子。客户端可以通过为应用程序和主题提供NULL(通配符)原子来请求与任何潜在的服务器应用程序和任何潜在主题的会话。
以下示例说明了客户端如何启动会话,同时指定了应用程序和主题。
/ *全局变量* /
static BOOL fInInitiate = FALSE;
char *szApplication;
char *szTopic;
atomApplication = *szApplication == 0 ?
NULL : GlobalAddAtom((LPSTR) szApplication);
atomTopic = *szTopic == 0 ?
NULL : GlobalAddAtom((LPSTR) szTopic);
fInInitiate = TRUE;
SendMessage((HWND)-1,/ *广播消息* /
WM_DDE_INITIATE,/ *启动对话* /
(WPARAM)hwndClientDDE,/ *客户端DDE窗口* /
MAKELONG(atomApplication,/ * application-name atom * /
atomTopic)); /* topic-name atom */
fInInitiate = FALSE;
if (atomApplication != NULL)
GlobalDeleteAtom(atomApplication);
if (atomTopic != NULL)
GlobalDeleteAtom(atomTopic);
请注意,如果您的应用程序使用NULL原子,则不需要使用GlobalAddAtom和GlobalDeleteAtom函数。在此示例中,客户端应用程序分别创建包含服务器名称和主题名称的两个全局原子。
客户端应用程序在消息的【lParam的】参数中发送一个带有这两个原子的WM_DDE_INITIATE消息。在调用SendMessage函数时,特殊窗口句柄-1指示Windows将此消息发送到所有其他活动应用程序。SendMessage不会返回到客户端应用程序,直到接收到消息的所有应用程序,反过来都将控制权返回给Windows。这意味着在SendMessage呼叫返回之前,服务器应用程序发送的所有WM_DDE_ACK消息都被保证被客户端处理。
在SendMessage返回后,客户端应用程序将删除全局原子。
服务器应用程序根据下图所示的逻辑进行响应。
要确认一个或多个主题,服务器必须为每个会话创建原子(如果有多个主题,则需要重复的应用程序名称原子),并为每个会话发送WM_DDE_ACK消息,如以下示例所示。
if ((atomApplication = GlobalAddAtom("Server")) != 0) {
if ((atomTopic = GlobalAddAtom(szTopic)) != 0) {
SendMessage(hwndClientDDE,
WM_DDE_ACK,
(WPARAM)hwndServerDDE,
MAKELONG(atomApplication, atomTopic));
GlobalDeleteAtom(atomApplication);
}
GlobalDeleteAtom(atomTopic);
}
if ((atomApplication == 0) || (atomTopic == 0)) {
.
./ *错误处理* /
.
}
当服务器使用WM_DDE_ACK消息进行响应时,客户端应用程序应保存服务器窗口的句柄。接收句柄的客户机作为WM_DDE_ACK消息的【wParam中】参数,然后将所有后续的DDE消息发送到该句柄标识的服务器窗口。
如果您的客户端应用程序为应用程序名称或主题名称使用空原子,则希望应用程序从多个服务器应用程序接收确认。即使您的客户端应用程序不使用NULL原子,多个确认也可能来自DDE服务器的多个实例。服务器应始终为每个会话使用唯一的窗口。客户端应用程序中的窗口过程可以使用服务器窗口的句柄(作为WM_DDE_INITIATE的【lParam的】参数提供)来跟踪多个会话。这允许单个客户端窗口处理几个对话,而不需要终止并重新连接每个会话的新客户端窗口。