ID Number: Q69028
3.00
WINDOWS
Summary:
This article discusses the dynamic data exchange (DDE) protocol
outlined in the Windows Software Development Kit (SDK) manuals. In
particular, the article describes the proper handling of atoms during
processing of the WM_DDE_INITIATE and WM_DDE_ACK messages.
More Information:
These code samples are provided in Chapter 22 of the "Microsoft
Windows Software Development Kit Guide to Programming" as examples of
the proper way to initiate a DDE conversation.
This code from page 22-7 demonstrates how a DDE client initiates a
conversation:
atomApplication = GlobalAddAtom("Server");
atomTopic = GlobalAddAtom(szTopic);
SendMessage(-1, WM_DDE_INITIATE, hwndClientDDE,
MAKELONG(atomApplication, atomTopic)) )
GlobalDeleteAtom(atomApplication);
GlobalDeleteAtom(atomTopic);
In response to this message, any active DDE server(s) is to create an
atom with the name of each topic that it supports and use SendMessage
to SEND a WM_DDE_ACK message back to the client.
This code is taken from pages 22-8 and 22-9:
atomApplication = GlobalAddAtom("Server");
atomTopic = GlobalAddAtom(szTopic);
if (!SendMessage(hwndClient, WM_DDE_ACK, hwndServerDDE,
MAKELONG(atomApplication, atomTopic)))
{
GlobalDeleteAtom(atomApplication);
GlobalDeleteAtom(atomTopic);
}
The "if" statement here is unnecessary because the client will delete
the atoms sent to it during the processing of the WM_DDE_ACK message.
This code should be rewritten as:
atomApplication = GlobalAddAtom("Server");
atomTopic = GlobalAddAtom(szTopic);
// Check to see if we support topic
if (MAKELONG(atomApplication, atomTopic) == lParam)
{
// create server window
hWndServer = CreateServerWnd(...);
// acknowledge conversation
SendMessage(hwndClient, WM_DDE_ACK, hwndServer,
MAKELONG(atomApplication, atomTopic));
}
else // if not then delete the atoms WE created
{
GlobalDeleteAtom(atomApplication);
GlobalDeleteAtom(atomTopic);
}
This code demonstrates how the client should process the WM_DDE_ACK
message:
case WM_DDE_ACK:
if (fInitiate) /* In initiate sequence */
{
/* take action */
GlobalDeleteAtom(LOWORD(lParam));
GlobalDeleteAtom(HIWORD(lParam));
}
/* respond to other type of ACKs */
return 0;
There is some confusion as to what exactly should be done in response
to a WM_DDE_ACK message. Page 15-8 of the "Microsoft Windows Software
Development Kit Reference Volume 2" specifies four things to check
when responding to a WM_DDE_ACK message:
1. Delete all atoms associated with the ACK message.
2. If the WM_DDE_ACK has an accompanying hData object, the object
should be deleted.
3. If the WM_DDE_ACK is a negative response to a WM_DDE_ADVISE, the
hOptions object sent with the WM_DDE_ADVISE message should be
deleted.
4. If the WM_DDE_ACK is a negative response to a WM_DDE_EXECUTE, the
hCommands object sent with the WM_DDE_EXECUTE message should be
deleted.
Since the sending application has no way of telling when the
WM_DDE_ACK is received, it is important that the receiver perform the
necessary cleanup upon receipt of the message.