Classes: wxServer, wxConnection, wxClient.
The following describes how wxWindows implements DDE. The following three classes are central.
Messages between applications are usually identified by three variables: connection object, topic name and item name. A data string is a fourth element of some messages. To create a connection (a conversation in Windows parlance), the client application sends the message MakeConnection to the client object, with a string service name to identify the server and a topic name to identify the topic for the duration of the connection. Under UNIX, the service name must contain an integer port identifier.
The server then responds and either vetos the connection or allows it. If allowed, a connection object is created which persists until the connection is closed. The connection object is then used for subsequent messages between client and server.
To create a working server, the programmer must:
To create a working client, the programmer must:
Data transfer
Examples
Remote Procedure Call
More DDE details
These are the ways that data can be transferred from one application to another.
The default data type is wxCF_TEXT (ASCII text), and the default data size is the length of the null-terminated string. Windows-specific data types could also be used on the PC.
See the sample programs server and client in the IPC samples directory. Run the server, then the client. This demonstrates using the Execute, Request, and Poke commands from the client, together with an Advise loop: selecting an item in the server list box causes that item to be highlighted in the client list box.
See also the source for wxHelp, which is a DDE server, and the files wx_help.h and wx_help.cc which implement the client interface to wxHelp.
DDE is quite a low level protocol, and all encoding and decoding of messages must be done by the client and server applications. The wxWindows extension PrologIO implements a remote procedure call protocol (RPC) so that a server can implement a library of functions for a client to call. PrologIO makes it easy for applications to pack and unpack the arguments and return value(s) of procedure calls, and provides a mechanism for the server to register its available calls and automatically handle the routing of calls to appropriate server callbacks, one to a procedure definition. All this makes calling or implementing server facilities childishly simple. Since PrologIO sits on top of the DDE wrapper, it is also platform independent. See the separate PrologIO manual and PrologIO.
A wxClient object represents the client part of a client-server DDE (Dynamic Data Exchange) conversation (available in both Windows and UNIX).
To create a client which can communicate with a suitable server, you need to derive a class from wxConnection and another from wxClient. The custom wxConnection class will intercept communications in a 'conversation' with a server, and the custom wxServer is required so that a user-overriden wxClient::OnMakeConnection member can return a wxConnection of the required class, when a connection is made.
For example:
class MyConnection: public wxConnection { public: MyConnection(void)::wxConnection(ipc_buffer, 3999) {} ~MyConnection(void) { } Bool OnAdvise(char *topic, char *item, char *data, int size, int format) { wxMessageBox(topic, data); } }; class MyClient: public wxClient { public: MyClient(void) {} wxConnection *OnMakeConnection(void) { return new MyConnection; } };Here, MyConnection will respond to OnAdvise messages sent by the server.
When the client application starts, it must first call wxIPCInitialize before creating an instance of the derived wxClient. In the following, command line arguments are used to pass the host name (the name of the machine the server is running on) and the server name (identifying the server process). Calling wxClient::MakeConnection implicitly creates an instance of MyConnection if the request for a connection is accepted, and the client then requests an Advise loop from the server, where the server calls the client when data has changed.
wxIPCInitialize(); char *server = "4242"; char hostName[256]; wxGetHostName(hostName, sizeof(hostName)); char *host = hostName; if (argc > 1) server = argv[1]; if (argc > 2) host = argv[2]; // Create a new client MyClient *client = new MyClient; the_connection = (MyConnection *)client->MakeConnection(host, server, "IPC TEST"); if (!the_connection) { wxMessageBox("Failed to make connection to server", "Client Demo Error"); return NULL; } the_connection->StartAdvise("Item");