FILE: MqPers.exe Sending Persistent COM Objects Using MSMQ in C+

Last reviewed: March 6, 1998
Article ID: Q174261
The information in this article applies to:
  • Microsoft Message Queue Server version 1.0

SUMMARY

With Microsoft Message Queuing Server it's possible to send the state of COM objects supporting the IPersistStream or IPersistStorage interface. This article discusses what is necessary to take advantage of this feature using Visual C++ and ATL.

MORE INFORMATION

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

 ~ MQPers.exe (size: 71772 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

Designing the Object Whose State Will Be Sent Over a Queue

The sample has two ActiveX components, Point and Line, which are implemented using ATL and Visual C++. In addition to the code generated by the ATL wizard, some additional lines have to be added for IPersistStream implementation. An object that implements IPersistStream is ready for sending its state over a MSMQ's queue.

Sending the Objects State Over the Queue

We use the #import directive in Visual C++ to manipulate the MSQM COM and the Point and Line objects. For additional information on how to initialize OLE when using the #import directive, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q169496
   TITLE     : INFO: Using ActiveX Data Objects (ADO) via #import in VC++"

The following code shows the declaration for the various ActiveX components used. The data types are defined in the compiler generated files Mqoa.tlh, Mqoa.tli, GraphObj.tlh, and GraphObj.tli:

   // For these ActiveX components we need only smart interface pointer
   IMSMQQueueInfosPtr   pQueueInfos;
   IMSMQQueueInfoPtr      pQueueInfo;
   IMSMQQueuePtr      pQueue;
   IUnknownPtr      pIUnknown;

   // Instantiate the following ActiveX components
   IMSMQQueryPtr      pQuery(__uuidof(MSMQQuery));
   IMSMQMessagePtr      pMessage(__uuidof(MSMQMessage));
   ILinePtr         pLine(__uuidof(Line));
   IPointPtr         pPoint(__uuidof(Point));

Sending object state requires a pointer to the IUnknown interface. The MSMQMessage component uses this interface to ask the object for the IPersistStream interface. The object's IUnknown interface pointer must be stored in a VARIANT and could then be assigned to the body property of the MSMQMessage object:

   ...

   if (n == 1) {
   // Initialize point object
      pPoint->x = 8;
      pPoint->y = 9;

       // The message body gets the IUnknown pointer
       pMessage->Body = static_cast<IUnknown*>(pPoint);

   } else {

      ...

   }

   pMessage->Send(pQueue);

   ...

Receiving the Objects State from the Queue

When an MSMQMessage instructs an ActiveX component to save its state to a stream, it also asks the component to save its CLSID to the stream. When receiving an object state, this enables the Microsoft Message Queue Server to instantiate the ActiveX component belonging to the transmitted CLSID.

The message body property of the received message actually is a VARIANT containing an IUnknown pointer to the interface of newly created object. Now it's up to the program to determine which object state was received and which object was created. One way to do this is to ask the IUnknown for ILine or the IPoint interface.

   ...

   // Get the next message
   pMessage = pQueue->Receive();

   IPointPtr      pPoint((IUnknown*)pMessage->Body);

   // Check if it's a Point object
   if (pPoint != NULL) {
         cout << "\nGot a Point Object: " << pPoint->x << "  " << \
   pPoint->y << "\n";

   }
   else {
      ILinePtr   pLine((IUnknown*)pMessage->Body);

      // Check if it's a Line object
      if (pLine != NULL) {
   cout << "\nGot a Line Object: " << pLine->x1 << " "
   <<  \       pLine->y1 << " " << pLine->x2 << " " << pLine->y2 << "\n";
      }
      else
         cout << "\nUnknown Object !!!\n";
   }
   pQueue->Close();

   ...

The complete sample source is provided. To compile the project you need Visual C++ 5.0

REFERENCES

MSMQ Online SDK help file

(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Michael Zill, Microsoft Corporation

Keywords          : MQVC
Version           : WINNT:1.0
Platform          : winnt
Issue type        : kbfile
Solution Type     : kbsample


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: March 6, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.