C/C++ Code Example: Navigating Using Cursors

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

For information navigating queues, see Navigating Queues.

To navigate a queue using cursors

  1. Define the maximum number of properties and the property counter.

  2. Define the MQMSGPROPS structure.

  3. Specify the message properties to be retrieved. This example retrieves PROPID_M_LABEL and PROPID_M_LABEL_LEN. 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 read the messages in the queue.

  6. Call MQReceiveMessage to read the first message in the queue.

  7. In a loop structure, process the current message and then call MQReceiveMessage to read the next message.

ms706029.note(en-us,VS.85).gifNote
The PROPID_M_LABEL_LEN property must be reset to its maximum value (MQ_MAX_MSG_LABEL_LEN) after each call to peek at 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 MQCloseCursor and MQCloseQueue to release resources used to create cursor and open the queue.

Code Example

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

HRESULT NavigateCursor(
                       LPCWSTR wszQueueFormatName
                       )
{
  //  Define the maximum number of properties and a property counter.
  const int NUMBEROFPROPERTIES = 5;                   // Maximum number of properties
  DWORD cPropId = 0;                                  // Property counter
  
  
  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];
  
  HANDLE hQueue = NULL;                              // Queue handle
  HANDLE hCursor = NULL;                             // Cursor handle
  HRESULT hr = MQ_OK;                                // Return code
  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++;
  
  
  // Initialize the MQMSGPROPS structure.
  msgprops.cProp = cPropId;                           // Number of message properties specified
  msgprops.aPropID = aMsgPropId;                      // IDs of the message properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of the message properties
  msgprops.aStatus  = aMsgStatus;                     // Error reports
  
  
  // Open the queue to read messages.
  hr = MQOpenQueue(
                   wszQueueFormatName,                // Format name of the queue
                   MQ_RECEIVE_ACCESS,                 // Access mode
                   MQ_DENY_RECEIVE_SHARE,             // Share mode
                   &hQueue                            // OUT: Handle of the queue
                   );
  if (FAILED(hr))
  {
    return hr;
  }
  
  
  // Create the cursor used to navigate through the 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;
  }
  
  
  // Process messages.
  do
  {
    wprintf(L"%s\n",wszLabelBuffer);
    aMsgPropVar[0].ulVal = MQ_MAX_MSG_LABEL_LEN;      // Reset the label buffer size.
    hr = MQReceiveMessage(
                          hQueue,                     // Queue handle
                          0,                         // Maximum time (msec)
                          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
                          );
    if (FAILED(hr))
    {
      break;
    }
  } while (SUCCEEDED(hr));
  
  
  // Close the cursor and queue.
  hr = MQCloseCursor(hCursor);
  if (FAILED(hr))
  {
    MQCloseQueue(hQueue);
    return hr;
  }
  hr = MQCloseQueue(hQueue);
  return hr;
}
Show:
© 2014 Microsoft