ToC DocOverview CGDoc RelNotes FAQ Index PermutedIndex
Allegro CL version 11.0

dde operators


active-client-ports

Generic Function, dde package

Arguments: dde-info

Returns a list of client-port objects representing the connections that the Lisp process of the argument dde-info has made (and not yet closed) with other applications that are acting as DDE servers. Call dde-info to retrieve the dde-info object for a particular process to pass to this function.

The client-port accessor functions port-name, port-topic, and port-application may be called on each of the objects in the returned list to retrieve information about each DDE connection.

See dde.html for information about DDE support.


active-server-ports

Generic Function, dde package

Arguments: dde-info

Returns a list of (internal) server-port objects representing the connections that DDE client applications have made (and not yet closed) with the Lisp DDE server that is running in the process of the argument dde-info, if any. Call dde-info to retrieve the dde-info object for a particular process to pass to this function.

The list members are instances of the cg::server-port class, which is not exported at this time, and which does not contain information that has been generalized into something useful to applications. The length of the returned list, however, indicates how many active connections the server currently has with DDE client programs.

See dde.html for information about DDE support.


answer-request

Generic Function, dde package

Arguments: topic item command-result

This method is invoked when another application sends a request to the lisp DDE server. You should modify this method to return a string as appropriate for the passed-in topic and item, which will always be keyword symbols. The default method returns the null string.

The command-result argument can normally be ignored --- it contains the result of the previous command that was executed for this topic by the application that is sending this request, and is passed here for the special version of this method which returns that value when the item is :command-result.

See dde.html for information about DDE support.


case-sensitive-dde

Generic Function, dde package

Arguments: dde-info

This function has an effect only in case-insensitive Lisps (i.e. a Lisp where the value of *current-case-mode* is either :case-insensitive-upper or :case-insensitive-lower).

Returns the value of the case-sensitive-dde property of the process associated with dde-info. (Call dde-info to retrieve the dde-info instance for a particular Lisp process.) The value for any process will initially be the value of the variable *case-sensitive-dde*, but (setf case-sensitive-dde) may be called at any time to change the value for a particular Lisp process.

When nil (the default for *case-sensitive-dde*) and a case-insensitive Lisp is running, then any DDE topic and item names are changed to the preferred string-case of the Lisp either before converting them to symbols to use in Lisp or after converting them to strings to pass to other DDE programs. So if another DDE application passes the topic "LarrySanders" to Lisp, a :case-insensitive-upper Lisp would handle the topic name as the keyword :LARRYSANDERS and a :case-insensitive-lower Lisp would handle the topic name as the keyword :larrysanders. This is done by default partly to make the printing and handling of the symbols more convenient, and also because the documentation for some DDE programs does not make it clear exactly what string-case they really use for their topic and item names.

On the other hand, some DDE programs deal with topic and item names in a case-sensitive way, though this is less common. If you need to communicate with such a program from a case-insensitive Lisp, then you will probably need to set either the *case-sensitive-dde* global default or the case-sensitive-dde property for a particular Lisp process to true. Then Lisp will not modify the string-case at all when converting between symbols and DDE strings.

See dde.html for information about DDE support.


close-dde

Function, dde package

Arguments: &rest ignore

Closes all DDE client and server ports that were opened in the current process by calling open-port and/or open-server. This is done automatically by the OS when Lisp or a standalone DDE Lisp application exits, but perhaps it is desirable to call this function explicitly to clean up no-longer-used resources.

See dde.html for information about DDE support.


close-port

Function, dde package

Arguments: client-port

Deactivates this DDE port. If this function is not used, all client ports are closed anyway when close-dde is called.

See dde.html for information about DDE support.


close-server

Function, dde package

Arguments:

Makes this lisp process no longer act as a DDE server. The server can be re-opened later after closing it.

See dde.html for information about DDE support.


convert-returned-dde-buffer

Generic Function, dde package

Arguments: port buffer length

This generic function is called whenever an Allegro application is acting as a DDE client, and has called send-request. Its purpose is to convert the raw data being returned by the DDE server into a value that is directly useful by the lisp application. This generic function is not to be called by an application, but an application needs to supply its own method whenever the data returned by the DDE server is not a null-terminated string, which is assumed by the default method.

port is the DDE port on which send-request was called.

buffer is a foreign byte vector containing the raw DDE reply. Its data should be read with fslot-value-typed and converted into a Common Lisp value to return. For example, the following form will read the byte at index 12 in the buffer:

(ff:fslot-value-typed '(:array byte) :foreign buffer 12)

length is the length of the data being returned by the DDE server.

Most DDE servers will include terminating data in the buffer such as a null character (a zero byte) or a zero longword, so either the terminating data or the length argument could be used to determine the length of the data.

If this generic function is being called as the result of calling send-request for a :cold link, then the value that is returned by this generic function will then be returned by the call to send-request.

If send-request was instead called for a :warm or :hot link, then the value that is returned by this generic function will be passed to the application's receive-advice method for this dde-port.

The default method assumes that buffer contains a null-terminated string. It reads a string from the buffer and then calls convert-returned-dde-string to further convert the string as needed.

The value returned by convert-returned-dde-string is then returned by the default method.

Here is the default method:

(defmethod convert-returned-dde-buffer ((port dde-port) buffer length)
  (convert-returned-dde-string
   port (string-from-dde-buffer buffer length)))

See dde.html for information about DDE support.


convert-returned-dde-string

Generic Function, dde package

Arguments:

This generic function is called by default whenever an Allegro CL application is acting as a DDE client, and has called send-request. Its purpose is to convert a single lisp string that is received from the DDE server into a value that is more directly useful by the lisp application.

This generic function is not to be called by an application, but an application may want to add methods for particular DDE client ports, depending on the form of the data passed by the particular DDE server.

port is the DDE port on which send-request was called.

string is the string to convert.

To handle typical DDE implementations, the default method divides the string into a number of substrings wherever the string is delimited by either a tab character or a newline character. It then returns a list of these substrings. A custom method could be supplied either if it is inappropriate to divide the string in this way, or to convert the string into non-string objects in some way.

Note that not all DDE servers return data as null-terminated strings. Some servers, for example, return a vector of longwords terminated by a zero longword. In this case, the Allegro CL application should supply a method for the related generic function convert-returned-dde-buffer, and bypass convert-returned-dde-string entirely.

Here is the default method:

(defmethod convert-returned-dde-string ((port client-port) string)
  (setq string (string-right-trim '(#\tab #\newline) string))
  (if* (find #\tab string)
     then (if* (find #\newline string)
             then (mapcar (lambda (s)
                            (delimited-string-to-list s #\tab))
                    (delimited-string-to-list string #\newline))
             else (delimited-string-to-list string #\tab))
     else (delimited-string-to-list string #\newline)))

See dde.html for information about DDE support.


dde-info

Function, dde package

Arguments: &key (process sys:*current-process*)

Returns the single dde-info instance for the specified process, which defaults to the current process (the value of *current-process*). If no dde-info object has been created yet for the specified process, then one is created and returned; otherwise the existing dde-info object for the process is returned (and therefore the returned value will always be the same object for any given process).

This object must be passed to certain DDE functions that return information about this process' DDE state. These functions are

See dde.html for information about DDE support.


dde-message

Generic Function, dde package

Arguments: (port dde-port) message Key warning

This generic function is called as various DDE events occur, to tell a DDE client or server that is running in lisp what has happened. The default method may be overridden in order to handle or display the messages as desired.

port is the client-port or server-port (each is a sublcass of dde-port) to which the message pertains. message is a string containing the message. warning is true if the message is a warning rather than simply informational.

Here is the default method, which simply prints the messages to *trace-output* when *generate-dde-messages* is true:

(defmethod dde-message ((port dde-port) message &key warning)
  (when *generate-dde-messages*
    (when warning (win:MessageBeep 0))
    (format *trace-output* 
        (if warning
            "~&DDE Warning:  ~a~%"
          "~&DDE: ~a~%")
      message)))

See dde.html for information about DDE support.


dword-list-from-dde-buffer

Function, dde package

Arguments: buffer length &key zero-terminated

This function may be called from a custom convert-returned-dde-buffer method for use with DDE servers that return values as a vector of longwords. buffer and length should be the buffer and length arguments that were passed to convert-returned-dde-buffer. zero-terminated should be passed as true if the longword vector returned by the DDE server terminates the vector with a longword zero. A list of numbers is returned, one for each longword.

See dde.html for information about DDE support.


execute-command

Generic Function, dde package

Arguments: topic command-string

This generic function is invoked when another application sends the Lisp DDE server a command to execute. You may write methods on this generic function to execute arbitrary commands as appropriate. This method's action can depend on the particular topic name, which is always a keyword symbol. The value returned by this generic function can be retrieved later by the application if it sends a request with the :command-result item for this topic.

For the special topic :eval, the built-in method below executes the command string as a lisp form. Your own execute-command methods for a runtime application should do some sort of command execution that you implement.

(defmethod execute-command ((topic (eql :eval)) command-string)
   (let ((*read-tolerant* t))
      (eval (read-from-string command-string))))

See dde.html for information about DDE support.


free-item

Function, dde package

Arguments: dde-topic-or-item-name

Frees an OS dde string handle resource used by a dde-topic-or-item-name. The argument can be either a symbol or a string, just as you would pass it as a dde topic or item name to other dde functions.

When passing symbols or strings that serve as dde topic and item names, internally a special handle is created for each name, and the name is passed quickly to and/or from DDE by simply passing the handle. There is a limit in the OS to the number of such strings that may be created. Usually this is not a problem, since Allegro knows to always re-use the same dde string handle for a given topic or item name. So if you call (send-request spreadsheet-port :current-row-number) thousands of times, only one dde string handle will be created for the item name "current-row-number". These string handles are freed automatically either when close-dde is called or when lisp exits.

But if, on the other hand, the item names are not a handful of constants but are instead some sort of variable that is being passed as many different values (for example, passing "RxCy" as an item name to a spreadsheet to ask for the value of cell x, y, with lots of different values of x and y being passed), then many dde string handles may be getting created and may even exceed the maximum that may be created. If this is a possibility, then you may want to explicitly call free-item on such dde item names after passing them to dde functions. This will free each handle shortly after it is created, to leave maximum capacity for further string handles. If the same item-name is used again later after it has been freed, then the dde string handle for it will be recreated internally automatically, so you don't have to make sure that you are no longer using a particular topic or item name before you call free-item on it.


open-port

Function, dde package

Arguments: client-port

Connects with the DDE server application named by the port-application of the specified client-port, for the topic named by the port-topic of the client-port. This must be done for any client-port before the communication with the DDE server can commence.

To change the topic or application of a client-port, it must first be closed with close-port and then reopened with open-port (after changing the port-topic or port-application of the port). It may be more straightforward, however, to use a separate client-port object for each topic of each application that is used.

See dde.html for information about DDE support.


open-server

Function, dde package

Arguments: &key (name *service-name*) (topics *service-topics*) (server-port-class 'server-port)

Establishes the current Lisp process as a DDE server. Any DDE client program can thereafter (until close-server or close-dde is called) connect to this server by specifying the service name indicated by the name argument and one of the topics indicated by the topics argument.

A service name or topic may be either a string or a symbol, though they are always passed between programs as strings. When a symbol, its symbol-name is used to communicate with other programs.

The name argument defaults to the value of *service-name*, which initially is the symbol :allegro, meaning that a DDE client program would specify the service name as "allegro" to connect to the Lisp DDE server. The topics argument defaults to the value of *service-topics*, which initially is the list of symbols (nil :system, :eval), meaning that a DDE client program would specify either "nil", "system", or "eval" as the topic in order to connect to the Lisp DDE server.

server-port-class is the name of the class that should be instantiated internally whenever a DDE client program connects to this DDE server. The default is server-port (naming the class server-port).
It may be useful to pass the name of a server-port subclass that you have created in order to specialize a dde-message method on that subclass.

The functions service-name and service-topics may be called later to retrieve the values that were most recently specified as the open-server arguments in a particular process.

Any Lisp process can act as only a single DDE server, though DDE client programs may each open multiple client ports to it.

See dde.html for information about DDE support.


port-application

Generic Function, dde package

Arguments: client-port

Returns the "service" name of the DDE server application that this client-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.

See dde.html for information about DDE support.


port-name

Generic Function, dde package

Arguments: dde-port

Returns the symbol that serves as the name of a DDE client-port. The name may be useful for identifying the port programmatically, or recognizing it when the object is printed or when it is mentioned in a DDE message.

The name may be set either by passing the :name initarg when calling make-instance to create a client-port, or later by calling (setf port-name). Otherwise a gensymed name is used.

See dde.html for information about DDE support.


port-open-p

Function, dde package

Arguments: port

Returns t if the DDE port is open and nil otherwise.

See dde.html for information about DDE support.


port-topic

Generic Function, dde package

Arguments: dde-port

An accessor on a DDE port that returns the topic of a client port or server port.

See dde.html for information about DDE support.


post-advice

Function, dde package

Arguments: topic item

A lisp DDE server application should call this function whenever a DDE item for which it handles hot or warm links has changed. This will result in [answer-request] being invoked if a warm or hot link is currently established for the item by any DDE clients.

See dde.html for information about DDE support.


receive-advice

Generic Function, dde package

Arguments: port topic item value

If send-request was called with a link type of :hot or :warm, then this generic function will be invoked whenever the server tells us that the value for the requested item has changed. You may write methods on this generic function to handle these change notifications however it is appropriate for your application.

If the send-request link was :hot, then value will be the DDE server's new value for this topic and item, as converted by the convert-returned-dde-buffer method for this DDE port. If the link was :warm, then value will be nil, and send-request (with a :cold link) must then be called if the application needs to know the new value, rather than the simple fact that a change to this topic and item has occurred.

See dde.html for information about DDE support.


receive-value

Generic Function, dde package

Arguments: topic item value-string

This generic function is invoked when an application "pokes" a value to the lisp DDE server. You may write methods on this generic function to process the poked values as needed. If you consider the value to be "accepted" by your lisp application, then you should write the method to return true, or else nil to tell the client that you have rejected the poked information.

The default receive-value method for all topics interprets the item argument as a lisp symbol in the current package, and sets its value to be a lisp object that is read from the value-string passed in.

See dde.html for information about DDE support.


send-command

Function, dde package

Arguments: client-port command-string &key timeout

Sends a DDE "Execute" message to this port's server application. Command-string should be whatever arbitrary string is expected by that DDE server. Many servers accept strings as they would be written in that application's macro language, sometimes surrounded by required square brackets.

Returns true if the command is accepted, and nil if it is rejected. The optional timeout argument is in milliseconds. If the command is neither accepted nor rejected within this timeout period, then nil is returned.

See dde.html for information about DDE support.


send-request

Function, dde package

Arguments: client-port item &key link timeout

Sends a DDE "Request" or "Advice" message to retrieve information from a DDE server for a particular item.

If link is :cold (which is the default), then the values returned by the DDE server application are synchronously returned from the call to send-request. If link is :warm or :hot, then send-request does not return an answer from the DDE server application, but instead starts an "advice" link with the server; whenever the server's value for the requested item has changed, the server asynchronously sends a message to Allegro CL, and the receive-advice method for this DDE port is then called with the values from the server. If link is :stop, then any advice link that was previously started for this item is stopped.

When unsuccessful, send-request returns nil. When successful, it returns a value from the DDE server for a :cold link, or t for a :warm, :hot, or :stop link. nil normally indicates that the DDE server does not support the particular request that was made.

The raw data buffer returned by the DDE server is first passed to the convert-returned-dde-buffer method for the port. That method should return a single value (perhaps constructing a list from multiple values that the server has encoded into the buffer), which is then either returned from send-request for a :cold link or passed to the port's receive-advice method for a :warm or :hot link. Refer to convert-returned-dde-buffer and convert-returned-dde-string for more information on converting the values from the server. If the request is unsuccessful, as when the server doesn't handle the requested item, then nil is returned.

Many applications that act as DDE servers implement a topic called system and an item called sysitems, and sometimes an item called topics, to which you can send a request to find out about additional topics.

See dde.html for information about DDE support.


send-value

Function, dde package

Arguments: client-port item value-string &key timeout

Sends a DDE "Poke" message to send unsolicited information to a DDE server. true is returned if the server accepted the poke, and nil otherwise.

See dde.html for information about DDE support.


server-active-p

Generic Function, dde package

Arguments: dde-info

Returns true if the Lisp process of the argument dde-info is currently running as a DDE server, and returns nil otherwise. This is true for any process after the process has called open-server and before it later calls either close-server or close-dde or it exits. Call dde-info to retrieve the dde-info object for a particular Lisp process.

See dde.html for information about DDE support.


service-name

Generic Function, dde package

Arguments: dde-info

If a DDE server is currently running in the Lisp process associated with dde-info, returns the DDE service name that DDE client programs must use to connect with that DDE server. Returns `nil if open-server has never been called in that process. dde-info must be an instance of dde-info.

This service name is determined by the name argument to the most recent call to open-server in the process of dde-info. The default value is the value of *service-name*, which is initially the symbol :allegro. This means that the DDE service name used by a DDE client program to connect to a lisp DDE server should be "allegro" by default. (The Allegro DDE facility uses symbols for service and topic names, though DDE itself uses strings.)

Call dde-info to retrieve the dde-info instance to pass to this function.

For a client-port in Lisp, the service name is known as the port-application.

To change the service-name for a Lisp DDE server process, call close-server and then call open-server with a new name argument.

See dde.html for information about DDE support.


service-topics

Generic Function, dde package

Arguments: dde-info

Returns the list of DDE service topics that the DDE server running in the process associated with dde-info (if any) claims that it will respond to, or returns if open-server has never been called in that process. This list is determined by the value of the topics argument to the most recent call to open-server; this argument defaults to the value of *service-topics*. If the list is empty, the server will accept any topic; otherwise it will accept only the topics in the list, and will cause any DDE client program that attempts to connect with some other topic to fail to connect.

If an application adds topics to the default service topics, it should write answer-request, execute-command, and/or receive-value methods as appropriate that handle each of the custom supported topics when they are passed as the value of the topic argument of those generic functions. (There are built-in methods to handle the default service topics; see *service-topics*.)

Call dde-info to retrieve the dde-info object associated with a particular project.

To change the service-process for a Lisp DDE server process, call close-server and then call open-server with a new topics argument.

See dde.html for information about DDE support.


string-from-dde-buffer

Function, dde package

Arguments: buffer length

This function may be called from a custom convert-returned-dde-buffer method for use with typical DDE servers that return values as null-terminated strings. buffer and length should be the buffer and length arguments that were passed to convert-returned-dde-buffer. A Lisp string is returned.

See dde.html for information about DDE support.


sysitems

Generic Function, dde package

Arguments: dde-info

Returns the value of the sysitems property of the Lisp DDE server process associated with dde-info, which must be an instance of dde-info.

If another program opens a client DDE port with the "System" topic and connects to a DDE server running in a Lisp process, and then it issues a DDE request for the "sysitems" item, then a built-in answer-request method will return the sysitems of the Lisp server process to which it connected.

The value should be a list of item names to which the Lisp DDE server will respond if the items are sent in requests using the "system" topic. The sysitems for any Lisp process will initially be the value of the variable *sysitems*, but you may call (setf sysitems) at any time to change the sysitems for a particular process.

Call dde-info to retrieve the dde-info instance of a particular Lisp process.

See dde.html for information about DDE support.


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

ToC DocOverview CGDoc RelNotes FAQ Index PermutedIndex
Allegro CL version 11.0