C-C++ Code Example: Reading Report Messages

 

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

This example provides an application-defined function that synchronously reads each message in a report queue, peeking at the PROPID_M_CLASS property and displaying the label of each report message that is in the queue.

For information on tracing the route of a message, see Tracing Messages.

To read report messages

  1. Define the maximum number of queue properties to be specified and a queue property counter.

  2. Define a MQMSGPROPS structure.

  3. Specify the message properties to be retrieved. This example retrieves the following properties.

    PROPID_M_CLASS: Specifies whether the message is a report message.

    PROPID_M_LABEL: Specifies the report information.

    Note

    The message label is a summary of what is in the message body.

    PROPID_M_LABEL_LEN: Required to retrieve the message label. The maximum label length, including the string-terminating character, is MQ_MAX_MSG_LABEL_LEN (250 Unicode characters).

  4. Initialize the MQMSGPROPS structure.

  5. Call MQOpenQueue to open the queue with receive access. Receive access allows the application to peek at or remove messages in the queue.

  6. Call MQCreateCursor to create the cursor for navigating the queue. The returned cursor handle is used in the calls to read messages.

  7. Call MQReceiveMessage with peek access to peek at the first message in the queue. This call also initializes the cursor so that the cursor points at the first message in the queue.

  8. In a loop structure, continue to call MQReceiveMessage to peek at the messages in the queue.

Note

The PROPID_M_LABEL_LEN property must be reset to its maximum value (MQ_MAX_MSG_LABEL_LEN) after each call to read a message. If the label length is not reset, an error is returned if the new message label is longer than the previous message label.

  1. Call MQCloseQueue and MQCloseCursor to free the resources.

Code Example

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

HRESULT ReadMassagesInReportQueue(  
                                  LPCWSTR wszQueueFormatName  
                                  )  
{  
  
  // Validate the input string.  
  if (wszQueueFormatName == NULL)  
  {  
    return MQ_ERROR_INVALID_PARAMETER;  
  }  
  
  // Define the required constants and variables.  
  const int NUMBEROFPROPERTIES = 3;                   // Number of properties  
  DWORD cPropId = 0;                                  // Property counter  
  int iClassPlace;  
  
  // Define an MQMSGPROPS structure.  
  MQMSGPROPS msgprops;  
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];  
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];  
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];  
  
  HANDLE hQueue;                                      // Queue handle  
  HANDLE hCursor;                                     // Cursor handle  
  HRESULT hr;                                         // Define results  
  WCHAR wszLabelBuffer[MQ_MAX_MSG_LABEL_LEN];  
  
  // Specify the message properties to be retrieved.  
  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           // Property ID  
  aMsgPropVar[cPropId].vt =VT_UI4;                    // Type indicator  
  aMsgPropVar[cPropId].ulVal = MQ_MAX_MSG_LABEL_LEN;  // Label buffer size  
  cPropId++;  
  
  aMsgPropId[cPropId] = PROPID_M_LABEL;               // Property ID  
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                // Type indicator  
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;      // Label buffer  
  cPropId++;  
  
  aMsgPropId[cPropId] = PROPID_M_CLASS;               // Property ID  
  aMsgPropVar[cPropId].vt = VT_UI2;                   // Type indicator  
  cPropId++;  
  
  // Initialize the MQMSGPROPS structure.  
  msgprops.cProp = cPropId;                           // Number of message properties  
  msgprops.aPropID = aMsgPropId;                      // IDs of the message properties  
  msgprops.aPropVar = aMsgPropVar;                    // Values of the message properties  
  msgprops.aStatus  = aMsgStatus;                     // Error reports  
  
  // Open the report queue to read messages.  
  hr = MQOpenQueue(  
                   wszQueueFormatName,                // Format name of the report queue  
                   MQ_RECEIVE_ACCESS,                 // Access mode  
                   MQ_DENY_RECEIVE_SHARE,             // Share mode  
                   &hQueue                            // OUT: Handle of the report queue  
                   );  
  if (FAILED(hr))  
  {  
    return hr;  
  }  
  
  // Create the cursor used to navigate through the report queue.  
  hr = MQCreateCursor(  
                      hQueue,                         // Queue handle  
                      &hCursor                        // OUT: Handle to the cursor  
                      );  
  if (FAILED(hr))  
  {  
    MQCloseQueue(hQueue);  
    return hr;  
  }  
  
  // Peek at first message in the queue.  
  
  hr = MQReceiveMessage(  
                        hQueue,                  // Queue handle  
                        0,                       // Maximum time (msec) to read the message  
                        MQ_ACTION_PEEK_CURRENT,  // Receive action  
                        &msgprops,               // Message property structure  
                        NULL,                    // No OVERLAPPED structure  
                        NULL,                    // No callback function  
                        hCursor,                 // Cursor handle  
                        MQ_NO_TRANSACTION        // Not in a transaction  
                        );  
  if (FAILED(hr))  
  {  
    MQCloseCursor(hCursor);  
    MQCloseQueue(hQueue);  
    return hr;  
  }  
  
  // Print the label of all the report massages in the queue.  
  do  
  {  
  
    // If the class of the message is MQMSG_CLASS_REPORT,   
    // then print the label of the message.  
    if (aMsgPropVar[iClassPlace].uiVal == MQMSG_CLASS_REPORT)  
    {  
      wprintf(L"%s\n",wszLabelBuffer);  
    }   
    // Reset the label size and read next message.  
    aMsgPropVar[0].ulVal = MQ_MAX_MSG_LABEL_LEN;   
    hr = MQReceiveMessage(  
                          hQueue,               // Queue handle  
                          0,                    // Maximum time (msec) to read the message  
                          MQ_ACTION_PEEK_NEXT,  // Receive action  
                          &msgprops,            // Message property structure  
                          NULL,                 // No OVERLAPPED structure  
                          NULL,                 // No callback function  
                          hCursor,              // Cursor handle  
                          MQ_NO_TRANSACTION                  // Not in a transaction  
                          );  
  
  } while (SUCCEEDED(hr));  
  
  // Close cursor and queue.  
  hr = MQCloseCursor(hCursor);  
  if (FAILED(hr))  
  {  
    MQCloseQueue(hQueue);  
    return hr;  
  }  
  hr = MQCloseQueue(hQueue);  
  return hr;  
}