ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 11.0

## 1.0 DDE Introduction

DDE stands for Dynamic Data Exchange. Quoting from the Windows API Bible (a standard reference for programming with Windows): "Dynamic Data Exchange is a message protocol that allows Windows applications to exchange data."

Here we briefly describe the functionality available in Lisp for DDE. Note that we do not describe DDE in much detail. We assume you are familiar with using DDE between Windows applications. If you are not, please refer to standard Windows programming manuals. Here are some principles of using DDE in Lisp:

- Creation and management of DDE "string handles" is done automatically. You simply pass in Lisp strings or keyword symbols that name applications, topics, and items without worrying about the string handles.
- Rather than deal with the DDE callback function directly, you can simply supply a few Lisp methods which are invoked automatically when callbacks occur.
- Conversations with other tasks are implemented as CLOS instances (called ports), so you don't need to deal with the conversation handles directly.
- Lisp can act as either a client or server, and handle cold, warm, and hot links. Currently the only clipboard data format supported is text.

DDE functionality is not part the common-graphics package or inculded in the `:common-graphics` module. Its functionality is in the dde package in a module named `:dde`. It is not necessary to load Common Graphics to use DDE functionality. DDE functionality is only available on Windows.

## Loading the DDE module

Evaluating the form

    (require :dde)

will cause the DDE module to be loaded if it is not already present. It is not an error to evaluate this form when the DDE module is already loaded (the form will return `nil` in that case).

## 2.0 DDE Example

There is a simple example illustrating the DDE functionality in examples\cg\dde-examples.cl.

## 3.0 Creating a port where Lisp is the DDE client

Create a client-port instance by calling make-instance on the client-port class. Available initargs are:

- name: an arbitrary object (typically a symbol) to name this port. Defaults to :client-n, where n is an integer that is auto-generated to make the name unique.

- application: the "service" name of the DDE server application that this port will connect to. This is often the filename of the executable image that is run, such as "progman" for the Program manager, but can be any arbitrary string that that server chooses to use. This value can be either the official DDE string or the keyword symbol whose print name is that string.

- topic: the particular topic of the application that this port will address. (To address multiple topics of the same application, you must create multiple port instances.) This value can be either a string or a keyword symbol.

These attributes can be changed after the instance is created using setf and the accessors port-name, port-application, and port-topic (all are setf'able). The new values will be used if the port is closed and re-opened.

### Example of creating a port:

    ;; Create a port with the program manager acting as the DDE
    ;; server
    (setq port1 (make-instance 'client-port
                  :application :progman
                  :topic :progman))

### DDE and Multithreading

Any single DDE port (either a client or server port) will work only within a single thread during the time that it is open, and so all of the application code that uses a particular DDE port should run only in one thread. (A port could be opened and closed in one thread and then later opened and closed in another, but it would likely be tricky to ensure that the threads do not have the port open at the same time.)

When a DDE port is opened in a thread, a dde-info instance is created for that thread. The function dde-info applied to the process associated with a thread returns that instance, which can be used as the argument to various generic functions which provide information about the port.

The generic function can be used to poll and set values in a dde-info instance.

Separate DDE ports work in separate threads. Allegro CL will continue to automatically initialize DDE as needed whenever a first port is opened, though now this is handled separately in each thread that begins to use DDE.

## 4.0 DDE Functionality

- active-client-ports
- active-server-ports
- answer-request
- case-sensitive-dde (which uses *case-sensitive-dde* for its default)
- close-dde
- close-port
- close-server
- convert-returned-dde-buffer
- convert-returned-dde-string
- dde-info (the class)
- dde-info (the function)
- dde-message
- dword-list-from-dde-buffer
- execute-command
- *generate-dde-messages*
- open-port
- open-server
- port-application
- port-name,
- port-open-p
- port-topic
- post-advice
- receive-advice
- receive-value
- send-command
- send-request
- send-value
- server-active-p
- service-name (which uses *service-name* for its default)
- service-topics (which uses *service-topics* for its default)
- string-from-dde-buffer
- sysitems (which uses *sysitems* for its default)

## 5.0 Correspondence between Windows commands and DDE function names

The Windows API offers the function DdeClientTransaction, where the sixth argument is a constant that indicates the type of transaction. For those who are familiar with the Windows DDE API, here is the mapping from those transaction types to the corresponding client functions in Allegro's DDE facility.

- XTYP_REQUEST -> send-request with a `:cold` link
- XTYP_ADVSTART -> send-request with a `:warm` or `:hot` link
- XTYP_EXECUTE -> send-command
- XTYP_POKE -> send-value

Similarly, a DDE server callback function receives transactions of these same types. Here is the mapping from these types to the corresponding generic functions on which methods may be written to implement a DDE server in Allegro.

- XTYP_REQUEST -> answer-request
- XTYP_ADVSTART -> answer-request (along with calling post-advice)
- XTYP_EXECUTE -> execute-command
- XTYP_POKE -> receive-value

Copyright (c) Franz Inc. Lafayette, CA., USA. All rights reserved.

ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 11.0