next up previous contents
Next: Using XLISP-STAT With NT Up: More Advanced Features Previous: Dynamic Loading

Dynamic Data Exchange

A Minimal Interface

A very minimal DDE interface is provided. The interface is very simple and based on the DDEML library. As a server, WXLS allows connections to the topic XLISP-STAT under the service name XLISP-STAT. It accepts two kinds of transactions:

As a client, there are three functions you can use that correspond fairly closely to their DDEML equivalents: dde-connect, dde-disconnect, and dde-client-transaction.

dde-connect takes two arguments, strings naming a service and a topic. The topic string is optional; it defaults to the service string. The return value is a descriptor of the conversation if the connection is established, otherwise it is nil. At the moment conversation descriptors are integer indices into a table, and the number of concurrent conversation is limited to 30. This may change.

dde-disconnect takes a conversation descriptor and attempts to close the conversation. If successful it returns t, otherwise nil. If dde-disconnect is called with no arguments, then all currently active conversations are terminated. In this case the return value is t if any are terminated, nil if not.

dde-client-transaction requires a conversation descriptor as its first argument. The remaining arguments are keyword arguments:

:type: Should be :request, :poke, or :execute; the default is :execute.
:data: A string, only only used by execute and poke transactions.
:item: An item name string, currently only used by poke and request transactions.
:timeout: a positive integer specifying the timeout in milliseconds. The default is 60000.
:binary: Used by request transactions. If false, the default, then the result string is created from all characters up to but excluding the first null character, if there is one. If true, a string of all characters is returned.

For a successful request transaction, the result is a string or binary array. All other successful transactions return t. If the transaction fails, nil is returned.

As an example, you could have WXLS communicate with WXLS by DDE (why you would want to I do not know, but it works):

> (dde-connect "xlisp-stat")
0
> (dde-client-transaction 0 :data "(+ 1 2)")
T
> (dde-client-transaction 0 :type :request :item "value")
"3"
> (dde-disconnect 0)
T
You can also communicate with the program manager:
> (dde-connect "progman")
0
> (dde-client-transaction 0 :type :request :item "Groups")
"Accessories\r
Gnu Emacs\r
Microsoft Visual C++ 5.0\r
Metrowerks CodeWarrior\r
StartUp\r
Adobe Acrobat\r
Macromedia Shockwave\r
StuffIt\r
Watcom C_C++\r
Watcom C_C++ Tools Help\r
Watcom C_C++ Additional Help\r
Borland C++ 5.02\r
Corman Lisp 1.21\r
Microsoft Reference\r
"
> (dde-client-transaction 0 :data "[ShowGroup(Gnu Emacs,1)]")
T
> (dde-disconnect 0)
T
The first transaction is an execute transaction that opens the Main group's window. The second is a request that obtains a list of the current groups.

There is one additional client function, dde-services. This function takes two optional arguments, service and a topic arguments, which should be strings or nil. It returns a list of all matching services as a list of lists of a service and a topic name. Some examples:

> (dde-services "progman")
(("PROGMAN"f "PROGMAN") ("SHELL" "APPPROPERTIES") ("FOLDERS" "APPPROPERTIES"))
> (dde-services)
(("XLISP-STAT" "XLISP-STAT") ("XLISP-STAT" "SYSTEM") ("PROGMAN" "PROGMAN")
 ("SHELL" "APPPROPERTIES") ("FOLDERS" "APPPROPERTIES"))
> (dde-services "shell")
(("PROGMAN" "PROGMAN") ("SHELL" "APPPROPERTIES") ("FOLDERS" "APPPROPERTIES"))

This DDE interface is experimental and may change. For the moment it seems adequate for providing configuring the integration of WXLS into Windows during setup.

A Higher-Level DDE Client Interface

I have recently added a few higher level functions to simplify acting as a DDE client. These functions are patterned after the DDE client interface in VBA. The available functions are dde-execute, dde-request, and dde-poke.

dde-execute takes a conversation descriptor and a command string as arguments. It returns t on success and nil on failure.

dde-request takes a conversation descriptor and an item string as arguments. It also accepts the :binary keyword argument. On success it returns a string or a binary array, depending on the binary argument; on failure it returns nil.

dde-poke takes a conversation descriptor, an item string, and a value as arguments. The value can be any Lisp object; if it is not a string it is converted to one using format with the ~s directive.

dde-services takes optional service and topic names and returns a list of all matching service-topic pairs.

As an example, here is how to interact with an Excel document. THIs assumes that Excel is running. This is adapted from an example provided by Russell Lenth.

First, you can ask Excel to load a spread sheet:

> (setf chan (dde-connect "excel" "system"))
0 
> (dde-execute chan "[Open(\"fred.xls\")]")
T
> (dde-disconnect chan)
T
Next, open a connection to the spread sheet and ask for the contents of the first column:
> (setf chan (dde-connect "excel" "[fred.xls]Sheet1"))
0
> (dde-request chan "c1")
"HELLO\r
2\r
"
Finally, place a new value is row 1, column 3, retrieve row 1, and close the connection:
 > (dde-poke 0 "r1c3" 5)
T
> (dde-request 0 "r1")
"HELLO\t3\t5\r
"
> (dde-disconnect chan)
T

Customizing the DDE Server

The DDE server has been redesigned to allow customization via an object-based interface. This is still very much experimental. Details are given elsewhere.


next up previous contents
Next: Using XLISP-STAT With NT Up: More Advanced Features Previous: Dynamic Loading

Luke Tierney
Mon Aug 30 09:50:11 CDT 1999