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
Define the maximum number of properties and the property counter.
Define the MQMSGPROPS structure.
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).
Initialize the MQMSGPROPS structure.
Call MQOpenQueue to read the messages in the queue.
Call MQReceiveMessage to read the first message in the queue.
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.
- 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;
}