C-C++ Code Example: Navigating Using Cursors

 

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 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.

Note

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;  
}