Microsoft KB Archive/279721

= How to use Dynamic Data Exchange (DDE) with Word and Excel from Visual C++ =

Article ID: 279721

Article Last Modified on 1/29/2007

-

APPLIES TO


 * Microsoft Excel 2000 Standard Edition
 * Microsoft Word 2000 Standard Edition
 * Microsoft Word 97 Standard Edition
 * Microsoft Excel 97 Standard Edition
 * Microsoft Visual C++ 6.0 Professional Edition
 * Microsoft Word 2002 Standard Edition
 * Microsoft Excel 2002 Standard Edition

-



This article was previously published under Q279721



SUMMARY
This article describes how to use Dynamic Data Exchange (DDE) in Visual C++ to communicate with Excel and Word.

NOTE: When possible, it is recommended that you use Automation, not DDE, to communicate with Excel or Word. Excel and Word have rich object models that provide functionality through Automation that is not available with DDE. Excel versions 5.0 and later, and Word versions 7.0 and later, support Automation.



Sample DDE Client
The following sample uses an Excel workbook or a Word document for the DDE topic.

For Excel, create a new workbook (C:\Test.xls) that contains data in cells A1 and A2. For Word, create a new document (C:\Test.doc) that contains text. Select some, but not all, of the text in the document and create a bookmark named &quot;MyBookmark&quot; at that location.  In Visual C++, create a new Win32 Console Application named &quot;DDEClient&quot;. In the AppWizard, select A Simple Application and then click Finish.  Replace the code in DDEClient.cpp with the following:
 * 1) include &quot;stdafx.h&quot;
 * 2) include &quot;windows.h&quot;
 * 3) include &quot;ddeml.h&quot;
 * 4) include &quot;stdio.h&quot;

HDDEDATA CALLBACK DdeCallback(   UINT uType,     // Transaction type.    UINT uFmt,      // Clipboard data format.    HCONV hconv,    // Handle to the conversation.    HSZ hsz1,       // Handle to a string.    HSZ hsz2,       // Handle to a string.    HDDEDATA hdata, // Handle to a global memory object.    DWORD dwData1,  // Transaction-specific data.    DWORD dwData2)  // Transaction-specific data. {   return 0; }

void DDEExecute(DWORD idInst, HCONV hConv, char* szCommand) {   HDDEDATA hData = DdeCreateDataHandle(idInst, (LPBYTE)szCommand,                               lstrlen(szCommand)+1, 0, NULL, CF_TEXT, 0); if (hData==NULL)  { printf(&quot;Command failed: %s\n&quot;, szCommand); }   else    { DdeClientTransaction((LPBYTE)hData, 0xFFFFFFFF, hConv, 0L, 0,                            XTYP_EXECUTE, TIMEOUT_ASYNC, NULL); } }

void DDERequest(DWORD idInst, HCONV hConv, char* szItem, char* sDesc) {   HSZ hszItem = DdeCreateStringHandle(idInst, szItem, 0); HDDEDATA hData = DdeClientTransaction(NULL,0,hConv,hszItem,CF_TEXT,                                 XTYP_REQUEST,5000, NULL); if (hData==NULL) {       printf(&quot;Request failed: %s\n&quot;, szItem); }   else {       char szResult[255]; DdeGetData(hData, (unsigned char *)szResult, 255, 0); printf(&quot;%s%s\n&quot;, sDesc, szResult); } }

void DDEPoke(DWORD idInst, HCONV hConv, char* szItem, char* szData) {   HSZ hszItem = DdeCreateStringHandle(idInst, szItem, 0); DdeClientTransaction((LPBYTE)szData, (DWORD)(lstrlen(szData)+1),                         hConv, hszItem, CF_TEXT,                          XTYP_POKE, 3000, NULL); DdeFreeStringHandle(idInst, hszItem); }

int main(int argc, char* argv[]) {   char szApp[] = &quot;EXCEL&quot;; char szTopic[] = &quot;C:\\Test.xls&quot;; char szCmd1[] = &quot;[APP.MINIMIZE]&quot;; char szItem1[] = &quot;R1C1&quot;; char szDesc1[] = &quot;A1 Contains: &quot;; char szItem2[] = &quot;R2C1&quot;; char szDesc2[] = &quot;A2 Contains: &quot;; char szItem3[] = &quot;R3C1&quot;; char szData3[] = &quot;Data from DDE Client&quot;; char szCmd2[] = &quot;[SELECT(\&quot;R3C1\&quot;)][FONT.PROPERTIES(,\&quot;Bold\&quot;)][SAVE][QUIT]&quot;;

//DDE Initialization DWORD idInst=0; UINT iReturn; iReturn = DdeInitialize(&idInst, (PFNCALLBACK)DdeCallback,                            APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0 ); if (iReturn!=DMLERR_NO_ERROR) {       printf(&quot;DDE Initialization Failed: 0x%04x\n&quot;, iReturn); Sleep(1500); return 0; }

//Start DDE Server and wait for it to become idle. HINSTANCE hRet = ShellExecute(0, &quot;open&quot;, szTopic, 0, 0, SW_SHOWNORMAL); if ((int)hRet < 33) {       printf(&quot;Unable to Start DDE Server: 0x%04x\n&quot;, hRet); Sleep(1500); DdeUninitialize(idInst); return 0; }   Sleep(1000);

//DDE Connect to Server using given AppName and topic. HSZ hszApp, hszTopic; HCONV hConv; hszApp = DdeCreateStringHandle(idInst, szApp, 0); hszTopic = DdeCreateStringHandle(idInst, szTopic, 0); hConv = DdeConnect(idInst, hszApp, hszTopic, NULL); DdeFreeStringHandle(idInst, hszApp); DdeFreeStringHandle(idInst, hszTopic); if (hConv == NULL) {       printf(&quot;DDE Connection Failed.\n&quot;); Sleep(1500); DdeUninitialize(idInst); return 0; }

//Execute commands/requests specific to the DDE Server. DDEExecute(idInst, hConv, szCmd1); DDERequest(idInst, hConv, szItem1, szDesc1); DDERequest(idInst, hConv, szItem2, szDesc2); DDEPoke(idInst, hConv, szItem3, szData3); DDEExecute(idInst, hConv, szCmd2);

//DDE Disconnect and Uninitialize. DdeDisconnect(hConv); DdeUninitialize(idInst);

Sleep(3000); return 1; }                     For Word, replace the first 7 lines in the main function with the following: char szApp[] = &quot;WINWORD&quot;; char szTopic[] = &quot;C:\\test.doc&quot;; char szCmd1[] = &quot;[AppMinimize][EditGoTo Destination:=\&quot;\\EndofDoc\&quot;][InsertPara]&quot;; char szItem1[] = &quot;\\Doc&quot;;     char szDesc1[] = &quot;Document contains: \n&quot;; char szItem2[] = &quot;MyBookmark&quot;; char szDesc2[] = &quot;MyBookmark contains: \n&quot;; char szItem3[] = &quot;\\EndofDoc&quot;; char szData3[] = &quot;Data from DDE Client&quot;; char szCmd2[] = &quot;[FileSave][FileExit(2)]&quot;;  Build and then run the application.

With Excel, the DDE client initiates a DDE conversation using the topic for the workbook file (C:\Test.xls) and performs the following actions:
 * Executes the APP.MINIMIZE command.
 * Requests the data in the items R1C1 and R2C1. Note that Excel requires that request items be in R1C1 notation.
 * Pokes data to R3C1.
 * Formats R3C1 in bold, saves the workbook, and then quits Excel.

With Word, the DDE client initiates a DDE conversation using the topic for the document file (C:\Test.doc) and performs the following actions:


 * Executes commands to minimize the application, go to the end of the document and insert a new paragraph.
 * Requests the item &quot;\Doc&quot; to retrieve the contents of the entire document. Note that \Doc is a predefined bookmark.
 * Requests the item &quot;MyBookmark&quot; to retrieve the text in the bookmark.
 * Executes commands to save the document and quit Word.

