ChemDraw DDE
Transaction Types

  1. Execute Transactions [The server receives the command string in the "hData" item.] Example of usage from the client side, using DDEML:

    const char data[] = "OPEN D:\mf\strychnine.chm";
    HDDEDATA retval;

    retVal = DdeClientTransaction (
    data,           // the command
    strlen(data)+1, //len of data, incl. term. null
    m_hConv,        //handle of the conversation
    0,              //handle of item name string
    0,               //clipboard data format
    XTYP_EXECUTE,   //transaction type
    5000,           //timeout: 5 seconds
    &result);       //transaction result

    BOOL success = (retVal != NULL);
  2. Request transactions [The server receives the command string in the "item name."] The returned data has the format:
    status msg len msg command-specific data
    bytes: 1 1 0+ 0+

    The message, if present, is not null-terminated.

    Example of usage from the client side:

    const char data[] = "MAKE_METAFILE
                         D:\mf\strychnine.chm";
    HDDEDATA retval;

    retVal = DdeClientTransaction (
    NULL,           //no arg expected
    0,              //len of the preceding arg
    m_hConv,        //handle of the conversation
    MakeStringHandle (data)  //handle of a data item
    CF_TEXT,        //clipboard data format
    XTYP_REQUEST,   //transaction type
    15000,          //timeout: 15 seconds
    &result);       //transaction result

    if (retVal) {
      numBytes = DdeGetData (retVal, NULL, 0, 0);
      BYTE buf = malloc (numBytes);
      DWORD numBytesCopied = DdeGetData (retVal, buf,
                             numBytes, 0); //0=offset

      BYTE b2 [2];

      DdeGetData (retVal, b2, 2, 0); //get first two                                  //bytes

      BOOL success = b2 [0];

      //There will be an error string, i.e. b2[1]
      //non-zero, if and only if success is False.

      if (!success) {
        char *errMsg = new char [b2 [1]];

        // 2=offset
        DdeGetData (retVal, errMsg, b2 [1], 2);
        MessageBox (errMsg);
      }
      else {
        // If the command returns special data, it
        //resides at offset (2 + b2[1]).
      }
    }

  3. Advise Loop ("warm") Transactions There is only one usage of an advise loop in the server, viz. in conjunction with the EDIT command, to notify the client whenever its structure being edited in ChemDraw changes. The value of the datum passed from client to server in the advise loop request is "Changed " plus the full path name of the temporary disk file through which edit changes are communicated. The advise loop should be set up after the EDIT command has been issued. The filename referenced in the Advise Loop command should be identical to that issued in the EDIT command. The client initially writes this file, ChemDraw picks it up, updates it periodically, notifying the client when it does so. Example of setting up the advise loop from the client side, using DDEML:

    //note space after "Changed"
    const char data[] = "CHANGED " + filename;
    HDDEDATA retval;

    retVal = DdeClientTransaction (
    NULL,           //no arg expected
    0,              //length of the preceding arg
    m_hConv,        //handle of the conversation
    MakeStringHandle (data)  //handle of a data item
    CF_TEXT,        //clipboard data format
    XTYP_ADVSTART,  //transaction type
    5000,           //timeout: 5 seconds
    &result);       //transaction result

    BOOL success = (retVal != NULL);

    where MakeStringHandle amounts to:

    return DdeCreateStringHandle (gDDE_instance, data,                                 CP_WINANSI);


2005 CambridgeSoft Corporation. All Rights Reserved. Privacy Statement
Tel  800 315-7300 / 617 588-9300     Fax  617 588-9390     Email   info@cambridgesoft.com
CambridgeSoft Corporation, 100 CambridgePark Drive, Cambridge, MA 02140 USA