Contents Up Previous Next

Interprocess communication overview

Classes: wxDDEServer, wxDDEConnection, wxDDEClient, wxTCPServer, wxTCPConnection, wxTCPClient

wxWindows has a number of different classes to help with interprocess communication and network programming. This section only discusses one family of classes - the DDE-like protocol - but here's a list of other useful classes:

Further information on these classes will be available in due course.

wxWindows has a high-level protocol based on Windows DDE. There are two implementations of this DDE-like protocol: one using real DDE running on Windows only, and another using TCP/IP (sockets) that runs on most platforms. Since the API is the same apart from the names of the classes, you should find it easy to switch between the two implementations.

The following description refers to 'DDE' but remember that the equivalent wxTCP... classes can be used in much the same way.

Three classes are central to the DDE API:

  1. wxDDEClient. This represents the client application, and is used only within a client program.
  2. wxDDEServer. This represents the server application, and is used only within a server program.
  3. wxDDEConnection. This represents the connection from the current client or server to the other application (server or client), and can be used in both server and client programs. Most DDE transactions operate on this object.

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 vetoes 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:

  1. Derive a class from wxDDEServer.
  2. Override the handler OnAcceptConnection for accepting or rejecting a connection, on the basis of the topic argument. This member must create and return a connection object if the connection is accepted.
  3. Create an instance of your server object, and call Create to activate it, giving it a service name.
  4. Derive a class from wxDDEConnection.
  5. Provide handlers for various messages that are sent to the server side of a wxDDEConnection.

To create a working client, the programmer must:

  1. Derive a class from wxDDEClient.
  2. Override the handler OnMakeConnection to create and return an appropriate connection object.
  3. Create an instance of your client object.
  4. Derive a class from wxDDEConnection.
  5. Provide handlers for various messages that are sent to the client side of a wxDDEConnection.
  6. When appropriate, create a new connection by sending a MakeConnection message to the client object, with arguments host name (processed in Unix only), service name, and topic name for this connection. The client object will call OnMakeConnection to create a connection object of the desired type.
  7. Use the wxDDEConnection member functions to send messages to the server.

Data transfer
Examples
More DDE details


Data transfer

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.


Examples

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.


More DDE details

A wxDDEClient 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 wxDDEConnection and another from wxDDEClient. The custom wxDDEConnection class will intercept communications in a 'conversation' with a server, and the custom wxDDEServer is required so that a user-overridden wxDDEClient::OnMakeConnection member can return a wxDDEConnection of the required class, when a connection is made.

For example:

class MyConnection: public wxDDEConnection
{
 public:
  MyConnection(void)::wxDDEConnection(ipc_buffer, 3999) {}
  ~MyConnection(void) { }
  bool OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format)
  { wxMessageBox(topic, data); }
};

class MyClient: public wxDDEClient
{
 public:
  MyClient(void) {}
  wxConnectionBase *OnMakeConnection(void) { return new MyConnection; }
};

Here, MyConnection will respond to OnAdvise messages sent by the server.

When the client application starts, it must create an instance of the derived wxDDEClient. 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 wxDDEClient::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.

  wxString server = "4242";
  wxString hostName;
  wxGetHostName(hostName);

  // Create a new client
  MyClient *client = new MyClient;
  connection = (MyConnection *)client->MakeConnection(hostName, server, "IPC TEST");

  if (!connection)
  {
    wxMessageBox("Failed to make connection to server", "Client Demo Error");
    return NULL;
  }
  connection->StartAdvise("Item");
Note that it is no longer necessary to call wxDDEInitialize or wxDDECleanUp, since wxWindows will do this itself if necessary.