Herman Rodent
Microsoft Developer Network Technology Group
Created: October 1, 1992
There are two sample applications associated with this technical article.
Click to view or copy the files in the StockSrv sample application.
Click to view or copy the files in the DDERecon sample application.
Dynamic data exchange (DDE) is a powerful feature of the Microsoft® Windows™ operating environment. DDE provides a protocol through which applications can exchange data of all sorts. In order for DDE client applications to communicate effectively with DDE servers, those servers must support the System topic consistently and correctly.
This article describes what supporting the System topic involves and provides sample code that you can include in your own application.
Dynamic data exchange (DDE) has been a part of Microsoft® Windows™ since version 2.1 was released. Since then it has been built into many applications and is used as the base mechanism for Object Linking and Embedding (OLE) version 1.0. Implementing a complete version of the DDE protocol—not a trivial matter—resulted in slight variations as different developers interpreted the specification.
The recently introduced dynamic data exchange management library (DDEML) provides a set of functions for DDE and implements the protocol on behalf of an application. Applications written to use DDEML are, therefore, more consistent in their behavior and communicate better with each other than applications that implement the DDE protocol themselves. Development of DDE support in an application is also much simpler when DDEML is used.
Even with DDEML, a substantial amount of work remains to be done in implementing DDE fully. This article proposes some conventions to follow when doing this work and provides some example code that shows how popular applications such as Microsoft Excel support DDE. The sample code can be directly included into your own application.
Throughout this article, I use must support to refer to features that must be included in any good implementation of a DDE client or server; should support to refer to features that might be a little more trouble to do and the application could live without, but that generally make life easier and, therefore, ought to be considered; and could support to refer to those neat features you came up with at the last minute that mean something to your own applications, but others probably won't use.
This document assumes that all DDE is done via the DDEML interface.
A server is an application that provides one or more DDE services. A service name is the name of a DDE service provided by a server. A server may provide one or more services. Commonly, a server only provides a single service and the name of that service is the same as the name of the server. Using a single name for both the service and the server is convenient when it comes time to reconnect a conversation, because if the server is not started for that service, we know the name of the application to invoke. Figure 1 shows the DDE name hierarchy.
Figure 1. The DDE name hierarchy
If you are creating a DDE server, you should consider naming the service and the server by the same name and having the server provide just one service. If you must support multiple service names in a single server, you will have to publish the list of service names so that users of DDE client applications can use them. If you think your server needs to have multiple service names, you probably ought to set up more topics under a single service name. It's better to have topic names that are fabricated by concatenating words than to have multiple services, because supporting multiple services in one server prohibits clients from inferring the name of the server from the service name. The sample code for this article assumes only one service per server.
Microsoft Excel's service name is the same as that of the application (Excel). Microsoft Excel assumes that other DDE services are provided by a server whose name is the same as the service it is providing, so Microsoft Excel can't start a DDE server whose name isn't the same as its service name.
DDE servers that support the System topic enable client applications to browse the list of topics provided by the server. Furthermore, a complete implementation of the System topic enables clients to enumerate what formats are supported by the server, the status of the server, and Help text about the server.
The Microsoft Windows version 3.1 Software Development Kit (SDK) documentation briefly discusses the System topic. (See the SDK Programmer's Reference, Volume 1: Overview, Part 2, Section 5.1.4, and the SDK Guide to Programming, Part 3, Section 22.5.) The discussion in the SDK is a little ambiguous and lacks the detail required to code a solid implementation. This article and its sample code are intended to fill in those details.
The System topic must support a small set of items; it should also support a few other items to provide a complete implementation; and it could support additional items of your own design. Table 1 shows various System topic items. In each case, its constant identifier from DDEML.H is shown with its current string equivalent in quotation marks. You should always use the DDEML.H constant in your application rather than the actual text to ensure portability of your code across systems. The second column in the table shows whether this item must be, should be, or could be supported under the System topic. Note that tab-delimited lists are, of course, only for the CF_TEXT format, which must be supported. On Windows NT™ operating systems, the CF_UNICODETEXT format must also be supported.
Table 1. System Topic Items
Name | Support | Description |
SZDDESYS_ITEM_TOPICS "Topics" |
Must | A tab-delimited list of the string names of the set of topics supported by this service. The list of topics may vary from moment to moment. |
SZDDESYS_ITEM_SYSITEMS "SysItems" |
Must | A tab-delimited list of items supported under the System topic. This list must include SZDDESYS_ITEM_TOPICS, SZDDESYS_ITEM_SYSITEMS, SZDDE_ITEM_ITEMLIST, and SZDDESYS_ITEM_FORMATS. A server may support additional System topic items. |
SZDDESYS_ITEM_FORMATS "Formats" |
Must | A tab-delimited list of string names of all the formats supported by the server. The server must support CF_TEXT and may support additional formats. On Windows NT, the server must also support CF_UNICODETEXT. Note that the SDK documentation erroneously suggests a list of format numbers, instead of a tab-delimited list of format names. For more information, see the "Formatting String Lists" section later in this article. |
SZDDE_ITEM_ITEMLIST "TopicItemList" |
Should | A tab-delimited list of items supported under the System topic. This list must include SZDDESYS_ITEM_TOPICS, SZDDESYS_ITEM_SYSITEMS, SZDDE_ITEM_ITEMLIST, and SZDDESYS_ITEM_FORMATS. A server may support additional System topic items. "TopicItemList" is a list of items available for any given topic. If the topic is the System topic, this list of items is the same as the list of items returned for SZDDESYS_ITEM_SYSITEMS. |
SZDDESYS_ITEM_HELP "Help" |
Should | This item is the root to the Help support for the server. |
SZDDESYS_ITEM_STATUS "Status" |
Should | An indication of the readiness of the server. The server should return either the "Busy" string or the "Ready" string. |
SZDDESYS_ITEM_RTNMSG "ReturnMessage" |
Could | Supporting data for the most recent WM_DDE_ACK message. This can be used to retrieve more data about the completion of a transaction than the return value of the transaction request provided. |
As with the System topic, other (non-System) topics have at least one item they must support and others they should. The following table lists these items.
Table 2. Non-System Topic Items
Name | Support | Description |
SZDDE_ITEM_ITEMLIST "TopicItemList" |
Must | A tab-delimited list of items supported under this topic. This list must include SZDDE_ITEM_ITEMLIST, as well as the list of items defined by the server for this topic. |
SZDDESYS_ITEM_FORMATS "Formats" |
Should | A tab-delimited list of string names of all the formats supported by the server for this topic. See the section "Formatting String Lists" later in this article. |
It is worth noting here that the item for format lists (SZDDESYS_ITEM_FORMATS) is used both as an item of the System topic, which you must support, and as an item of other non-System topics that you should support. There is no SZDDE_ITEM_FORMATS constant—both the system and non-System topics use SZDDESYS_ITEM_FORMATS. The returned information in each case, however, is not the same.
When the "Formats" item is requested for the System topic, the server must return a list containing the union of all the formats it supports for all topics. So, for example, a server that supports the System topic, waveforms, and pictures might return the following C-type string: "TEXT\tWAVE\tBITMAP". The returned list of formats does not imply that all topics are available in all formats.
When the "Formats" item is requested for a non-System topic, the server should return a list containing the union of all the formats for all the items that it might provide data on for that topic. Again, not all items of the topic need be rendered in every format, so a server that has an "images" topic might return the string: "BITMAP\tMETAFILEPICT".
This does not mean that all items in the "images" topic are available in both BITMAP and METAFILEPICT formats, though. Some may be available only in one, some in the other, and the rest in both.
Many of the items above require the server to return a tab-delimited list of string names. In order that all DDE clients can successfully parse these strings, here are some rules to follow:
Table 3. String Names for Standard Windows Formats
Format name | Standard string name |
CF_TEXT | "TEXT" |
CF_BITMAP | "BITMAP" |
CF_METAFILEPICT | "METAFILEPICT" |
CF_SYLK | "SYLK" |
CF_DIF | "DIF" |
CF_TIFF | "TIFF" |
CF_OEMTEXT | "OEMTEXT" |
CF_DIB | "DIB" |
CF_PALETTE | "PALETTE" |
CF_PENDATA | "PENDATA" |
CF_RIFF | "RIFF" |
CF_WAVE | "WAVE" |
CF_UNICODETEXT | "UNICODETEXT" |
CF_ENHMETAFILE | "ENHMETAFILE" |
The names of Clipboard formats are not case-dependent.
When parsing string lists in client applications (or a server that is also a client), it is prudent to assume the worst possible formatting and follow these guidelines in implementing your code:
In other words, do a good job yourself and assume the worst from everyone else.
Supporting the Help topic is a good idea, but the way it's supported is pretty much up to the server. You can assume that this Help is very specific to the server. The application using your server will most likely have its own Help on generic use of DDE in the application, so your server Help is there to provide specific details such as the exact syntax required to access a cell or range of cells in a spreadsheet. Here are some ideas for how you might provide Help support:
StockSrv is a DDE server application that implements support for the System topic. It does this by including a code module that follows the guidelines set down in this document. You can get most of the system support for your own application by simply including the same source-code module that StockSrv uses.
The DDERecon application is a DDE client that was written primarily to show how DDE hot links can be established. It uses the System topic information to populate lists in a dialog box used to browse available DDE servers and establish DDE links with them. For more information, see the technical article "DDE Hot Links" on the Microsoft Developer Network CD (Technical Articles, Platform Articles, DDE Articles).