How to Run Excel as a DDE Server

Written by martin cole
  • Share
  • Tweet
  • Share
  • Pin
  • Email
How to Run Excel as a DDE Server
(Jupiterimages/Polka Dot/Getty Images)

Dynamic Data Exchange (DDE) is a message protocol that gives Windows applications the tools to automatically exchange data. Making an application that gives data to programs like Excel is a main use for DDE. If you had a program that was fed with stock market quotes as they happen, for instance, DDE could permit an Excel user to view that information and reference it correctly in his calculations. Whatever your reason, creating a basic DDE server is challenging, but certainly achievable.

Skill level:

Things you need

  • Windows NT 4.0

Show MoreHide


  1. 1

    Open Visual C++ 6.0 and start a "New Project."

  2. 2

    Click on "Win32Application" to select it as the project type, then name it "DdemlSvr." Select "An Empty Project" when asked for the type of project you want.

  3. 3

    Add a file called "main.cpp." to your project.

  4. 4

    Copy the following code:

    include <windows.h>

    include <stdio.h>

    include <ddeml.h>

    // Globals...

    HSZ g_hszAppName;

    HSZ g_hszTopicName;

    HSZ g_hszItemName;

    int g_count = 0;

    DWORD g_idInst = 0;

    // Declarations:

    HDDEDATA EXPENTRY DdeCallback(UINT type, UINT fmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2);

    // WinMain()..

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    // Initialise DDEML...

    if(DdeInitialize(&g_idInst, DdeCallback, APPCLASS_STANDARD, 0)) {

      MessageBox(NULL, "DdeInitialize() failed", "Error", MB_SETFOREGROUND);
      return -1;


    // Create string handles...

    g_hszAppName = DdeCreateStringHandle(g_idInst, "DdemlSvr", NULL);

    g_hszTopicName = DdeCreateStringHandle(g_idInst, "MyTopic", NULL);

    g_hszItemName = DdeCreateStringHandle(g_idInst, "MyItem", NULL);

    if( (g_hszAppName == 0) || (g_hszTopicName == 0) || (g_hszItemName == 0) ) {

      MessageBox(NULL, "DdeCreateStringHandle() failed", "Error", MB_SETFOREGROUND);
      return -2;


    // Register DDE server

    if(!DdeNameService(g_idInst, g_hszAppName, NULL, DNS_REGISTER)) {

      MessageBox(NULL, "DdeNameService() failed!", "Error", MB_SETFOREGROUND);
      return -3;


    // Create a timer to simulate changing data...


    // Message loop:

    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0)) {

      // On WM_TIMER, change our counter, and update clients...
      if(msg.message == WM_TIMER) {
         DdePostAdvise(g_idInst, g_hszTopicName, g_hszItemName);


    return msg.wParam;


    // Our DDE Callback function...

    HDDEDATA EXPENTRY DdeCallback(UINT wType, UINT fmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2) {

    switch (wType) {

    // ----------------------------------------------------------------

    case XTYP_CONNECT:

      // Client is trying to connect. Respond TRUE if we have what they want...
      if ((!DdeCmpStringHandles(hsz1, g_hszTopicName)) &amp;&amp;
         (!DdeCmpStringHandles(hsz2, g_hszAppName)))
         return (HDDEDATA)TRUE;   // SERVER supports Topic|Service
         return FALSE;  // SERVER does not support Topic|Service
      // ----------------------------------------------------------------


      // Client starting advisory loop.
      // Say "ok" if we have what they are asking for...
      if((!DdeCmpStringHandles(hsz1, g_hszTopicName)) &amp;&amp;
         (!DdeCmpStringHandles(hsz2, g_hszItemName)))
         return (HDDEDATA)TRUE;   // SERVER supports Topic|Service
         return FALSE;  // SERVER does not support Topic|Service
      // ----------------------------------------------------------------

    case XTYP_ADVREQ:

      // Client wants our data. Since this is specific to Excel, we'll
      // go ahead and assume they want XlTable-formatted data. For a
      // generic DDE server, you might want to handle various formats
      // specified by the passed in fmt parameter.
      if(!DdeCmpStringHandles(hsz1, g_hszTopicName) &amp;&amp;
         !DdeCmpStringHandles(hsz2, g_hszItemName)) {
         short xltableData[100];
         // tdtTable record...
         xltableData[0] = 0x0010; // tdtTable
         xltableData[1] = 4; // 2 short ints following
         xltableData[2] = 1; // # rows
         xltableData[3] = 1; // # cols
         // tdtInt record...
         xltableData[4] = 0x0006;
         xltableData[5] = 2;
         xltableData[6] = (short)g_count;
         return DdeCreateDataHandle(g_idInst, (UCHAR*)xltableData, 2*7, 0, g_hszItemName, fmt, 0);
      // ----------------------------------------------------------------


      return (HDDEDATA)NULL;



  5. 5

    Paste the code into the file "main.cpp" that you created.

  6. 6

    Compile and then start up the project.

  1. 1

    Press "Ctrl" + "Shift" + "Esc" to bring up the Windows Task Manager, then select the "Processes" tab.

  2. 2

    Ensure that "DdemlSvr.exe" is one of the applications running on the list.

  3. 3

    Start up Microsoft Office Excel and type "=DdemlSvr|MyTopic!MyItem" into a cell. The cell should now contain the increasing value of the g_count.

  1. 1

    Run the "DdemlSvr.exe" in a Windows NT 4.0 machine that is networked. Then start "DdeShare" from the command line.

  2. 2

    Click "Shares" from the menu that appears, then "DDE Shares," followed by "Add a Share."

  3. 3

    Enter the following values under "Application Name":

    Share Name: MyShare$

    Old Style: DdemlSvr.DDE

    New Style: DdemlSvr.OLE

    Static: DdemlSvr

  4. 4

    Enter "MyTopic" into the three boxes under "Topic Name." Select "OK."

  5. 5

    Click on "MyShare$," then "Trust Share," then the "Initiate to Application Enable" checkbox. Select "OK" in all of the dialogue boxes and then quit "DdeShare."

  6. 6

    Run Excel on a different Windows NT 4.0 machine, but still on the same network.

  7. 7

    Copy the following:


  8. 8

    Paste what you copied into a cell in Excel. Replace "SERVERNAME" with the name of your network server machine. You should see a rapidly increasing number in the cell.

Don't Miss

  • All types
  • Articles
  • Slideshows
  • Videos
  • Most relevant
  • Most popular
  • Most recent

No articles available

No slideshows available

No videos available

By using the site, you consent to the use of cookies. For more information, please see our Cookie policy.