C-C++ COM Code Example: Reading Messages Synchronously

 

Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista

The following example provides an application-defined function that synchronously reads each message in a known queue, removing each message as it is read.

For information about reading messages synchronously, see Synchronous Reading.

This example uses smart pointers to the following Message Queuing interfaces.

To use smart pointers, your application must import Mqoa.dll. You can import this DLL using the #import directive and specify the MSMQ namespace.

#import "mqoa.dll"  
using namespace MSMQ;  

Before using any smart pointer, your application must call CoInitialize or CoInitializeEx to initialize the COM library. After the COM library is no longer needed, your application must call CoUnitialize. For more information, see Using Message Queuing COM Components in Visual C++ and C.

To read messages synchronously

  1. Declare a smart pointer to an MSMQQueue interface and create smart pointers to MSMQQueueInfo and MSMQMessage interfaces.

  2. Create the path name of the queue and set it in the MSMQQueueInfo object.

Note

wcslen properly handles only null-terminated strings. This function does not verify that the strings passed to it are null-terminated. It is the responsibility of the caller to ensure that the strings passed are null-terminated.

  1. Call MSMQQueueInfo.Open to open the queue.

  2. In a loop structure, call MSMQQueue.Receive to read all the messages in the queue.

  3. Call MSMQQueue.Close to close the queue.

Code Example

The following code example can be run on all versions of Message Queuing.

HRESULT ReceiveMessage(  
                       WCHAR *wszComputerName,  
                       WCHAR *wszQueueName  
                       )  
{  
  
  // Validate the input strings.  
  if (wszComputerName == NULL || wszQueueName == NULL)  
  {  
    return MQ_ERROR_INVALID_PARAMETER;  
  }  
  
  HRESULT             hr = S_OK;  
  IMSMQQueuePtr       pQueue;  
  WCHAR               *wszTmpPathName = NULL;  
  
  try  
  {  
    IMSMQQueueInfoPtr pInfo("MSMQ.MSMQQueueInfo");  
    int               nComputerNameLength = 0;  
    int               nQueueNameLength = 0;  
    int               nPathNameLength = 0;  
  
    // Create the path name of the destination queue.  
    nComputerNameLength = wcslen(wszComputerName);  
    nQueueNameLength = wcslen(wszQueueName);  
    nPathNameLength = nComputerNameLength + nQueueNameLength + 2;  
    wszTmpPathName = new WCHAR[nPathNameLength];  
    if (wszTmpPathName)  
    {  
      memset(wszTmpPathName, 0, nPathNameLength*sizeof(WCHAR));  
      // ************************************  
      // You must concatenate wszComputerName, "\", wszQueueName into    
      // the wszTmpPathName buffer.  
      // wszTmpPathName = wszComputerName + "\" + wszQueueName  
      // ************************************    
      pInfo->PathName = wszTmpPathName;     
    }  
  
    // Open the queue for receive access.  
    pQueue = pInfo->Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE);  
    IMSMQMessagePtr   pMsg("MSMQ.MSMQMessage");  
    _variant_t       vtTimeOut((long)1000);        // 1 second until receive time-out  
    _variant_t       bvtWantBody((bool)true);      // Set to retrieve message body  
  
    // Read all the messages in queue until 1 second time-out.   
    for( ; ; )  
    {  
      TCHAR szMessage[1024];  
      pMsg = pQueue->Receive(&vtMissing, &vtMissing, &bvtWantBody, &vtTimeOut);  
  
      if (pMsg == NULL)  
      {  
          // ************************************  
          // You must copy the string "No message, closing queue."   
          // into the szMessage buffer.  
          // ************************************  
        MessageBox(NULL, szMessage, NULL, MB_OK);  
        pQueue->Close();  
        pQueue = NULL;  
        break;  
      }  
  
      wprintf(L"The following messages were received successfully from the queue %s\n", (WCHAR *)pInfo->PathName);  
  
      // Display the message label and body   
      _bstr_t           bstrLabel;  
      _bstr_t           bstrBody;  
      bstrLabel = pMsg->Label;  
      bstrBody = pMsg->Body;  
      wprintf(L"Message Label = '%s'\n", (WCHAR *)bstrLabel);  
      //This example assumes the message body is a Unicode string  
      wprintf(L"Message Body = '%s'\n", (WCHAR *)bstrBody);  
  
      _stprintf_s(szMessage, 1024, TEXT("Removed message from queue %s"), (TCHAR *)pInfo->PathName);  
      // ************************************  
      // You must concatenate "Removed message from queue " and   
      // (TCHAR *)pInfo->PathName into the szMessage variable.  
      // szMessage = "Removed message from queue "  +   
      // (TCHAR *)pInfo->PathName  
      // ************************************  
      MessageBox(NULL, szMessage, NULL, MB_OK);  
    }  
  }  
  catch (const _com_error& comerr)   
  {  
    hr = comerr.Error();  
  
    wprintf("Error Code = 0x%X\nError Description = %s\n", hr, (WCHAR *)comerr.Description() );  
    if (pQueue)  
    {  
      pQueue->Close();  
    }  
  }  
  
  delete [] wszTmpPathName;  
  
  return hr;  
}