SAMPLE: Two-Way Communication Using IDispatch in MFC

ID: Q147952

2.00 2.10 2.20 4.00 4.10 WINDOWS NT

 kbfile

The information in this article applies to:

SUMMARY

Although there may be several ways to implement communication between two executables, this sample illustrates a simple way a server and a client application can communicate using IDispatch interfaces. This may not be the best method, but it is straight forward to implement. Using dual interfaces may provide a better solution, however.

The sample consists of two executables. One, GENERAT.EXE, is a local server, and the other, GENCLNT.EXE, is a client of the server. Both client and server are automation servers in that they both support automation interfaces. The client application starts the server via CreateDispatch and thus obtains the servers IDispatch interface. The client then passes its IDispatch interface to the server using one of the server's interface methods. At this point, two-way communication between the client and the server is possible.

Be sure to run the server stand-alone once before running it from the client. This will register the server and enable the client to start it dynamically.

The following file is available for download from the Microsoft Software Library:

 ~ Dispcom.exe (size: 98071 bytes) 

For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q119591
   TITLE     : How to Obtain Microsoft Support Files from Online Services

NOTE: Use the -d option when running Dispcom.exe to decompress the file and recreate the proper directory structure.

MORE INFORMATION

The GENERAT.EXE local server generates and displays random colors. It can either generate one color each time as it is requested, or it can continuously generate colors in response to a WM_TIMER message. The GENERAT.EXE server can run either stand-alone or it can be controlled by a client (in this case the GENCLNT.EXE application). In either case, the server will be visible, and the server's user interface will be active. This means the client and the server will need to communicate with each other to keep the user interface of the client and server synchronized and to process requests from the other.

Below is a list of relavent methods from GENERAT.EXE and GENCLNT.EXE and a description of each method.

GENERAT.EXE methods:

BOOL SetAdviseDI(LPDISPATCH DispIToAdvise);

    The client starts the server via CreateDispatch and thus obtains the
    IDispatch pointer of the server.  Once the client has the server's
    IDispatch  pointer, it can call this method in the server sending
    its own IDispatch pointer.  At this point, two-way communication is
    possible between the client and the server.

void ReleaseAdviseDI();

    Called by the client to tell the server to release the
    IDispatch pointer of the client.

BOOL AnimateColors();

    Called by the client to request that the server generate colors in
    response to WM_TIMER messages.

void GenNewColor();

    Called by the client to request that the server generate a single
    new color.

GENCLNT.EXE methods:

void SetAnimateUI();

    Called by the server when Animate Colors is chosen via the server
    user interface. This keeps the Animate Colors menu choice of the client
    synchronized with that of the server.

void NotifyColorChange(const VARIANT FAR& refColor);

    Called by the server when a color is generated. Called regardless
    of whether the color was requested by the client or the server.

Note: In order to compile this sample under VC 4.0 and later it will be necessary to replace the following code from generat.cpp:

Replace:

   POSITION pos = AfxGetApp()->m_templateList.GetHeadPosition();
   while (pos != NULL)
   {
      CDocTemplate* pTemplate = (CDocTemplate*)AfxGetApp()->
         m_templateList.GetNext(pos);
      ASSERT(pTemplate->IsKindOf(RUNTIME_CLASS(CDocTemplate)));

With:

   POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition();
   while (pos != NULL)
   {
      CDocTemplate* pTemplate = (CDocTemplate*)AfxGetApp()->
         GetNextDocTemplate(pos);
      ASSERT(pTemplate->IsKindOf(RUNTIME_CLASS(CDocTemplate)));

REFERENCES

For information about the necessity of calling AddRef on an IDispatch pointer passed across process boundaries, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q133042
   TITLE     : How to Pass IDispatch Pointer & Avoid an Application Error

KBCategory: kbfile KBSubcategory: MfcOLE kbsample Additional reference words: 1.50 1.51 1.52 1.52b 2.00 2.10 2.20 2.50 2.51 2.52 2.52b 3.00 3.10 3.20 4.00 4.10 softlib
Keywords          : kbcode kbole kbsample kbMFC kbVC 
Version           : 2.00 2.10 2.20 4.00 4.10
Platform          : NT WINDOWS

Last Reviewed: May 22, 1998