Windows SDK: DDE Protocol for Initiate and Acknowledge

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.