C-C++ Code Example: Navigating Using Lookup Identifiers
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 navigates through the queue using the lookup identifiers of messages in the queue.
When navigating with lookup identifiers, keep the following in mind.
Receiving applications can start at the front of the queue, at the end of the queue, or at a specific message if the lookup identifier for that message is known.
Receiving applications can read the next message or a previous message by using the appropriate peek or receive method. This example starts at the front and navigates to the end of the queue.
There is no time-out parameter when reading messages synchronously.
For more information on lookup identifiers, see Navigating with Lookup Identifiers.
To navigate a queue using lookup identifiers
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, PROPID_M_LABEL_LEN, and PROPID_M_LOOKUPID. 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 MQReceiveMessageByLookupId to read the first message in the queue. Note that in this call the dwLookupAction parameter is set to MQ_LOOKUP_PEEK_FIRST and the ullLookupId parameter is set to 0 (zero).
In a loop structure, process the current message and then call MQReceiveMessageByLookupId to read the next message. Note that in this call the dwLookupAction parameter is set to MQ_LOOKUP_PEEK_NEXT and the ullLookupId parameter is set to lookup identifier of the previous call.
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 MQCloseQueue to release resources used to open the queue.
Code Example
The following code example requires MSMQ 3.0.
HRESULT NavigateLookupId(
LPCWSTR wszQueueFormatName
)
{
// Define the required parameters.
const int NUMBEROFPROPERTIES = 3; // Number of properties
DWORD cPropId = 0; // Properties counter
HRESULT hr = MQ_OK; // Return code
HANDLE hQueue = NULL; // Queue handle
WCHAR wszLabelBuffer[MQ_MAX_MSG_LABEL_LEN]; // Label buffer
ULONGLONG ullLookupId; // Lookup identifier of the current message
// Define an MQMSGPROPS structure.
MQMSGPROPS msgProps;
MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
HRESULT aMsgStatus[NUMBEROFPROPERTIES];
// 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_LOOKUPID; // Property ID
aMsgPropVar[cPropId].vt = VT_UI8; // 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 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: Queue handle
);
if (FAILED(hr))
{
return hr;
}
// Peek at the first message in the queue.
hr = MQReceiveMessageByLookupId(
hQueue, // Queue handle
0, // No need for a lookup identifier
MQ_LOOKUP_PEEK_FIRST, // Access mode
&msgProps, // Message property structure
NULL, // No OVERLAPPED structure
NULL, // No callback function
MQ_NO_TRANSACTION // Not in a transaction
);
while (SUCCEEDED(hr))
{
// Process the message.
wprintf(L"%s\n", msgProps.aPropVar[1].pwszVal);
aMsgPropVar[0].ulVal = MQ_MAX_MSG_LABEL_LEN; // Reset the label buffer size.
ullLookupId = msgProps.aPropVar[2].uhVal.QuadPart;
// Peek at the next message using the current message lookup identifier.
hr = MQReceiveMessageByLookupId(
hQueue, // Queue handle
ullLookupId, // The lookup identifier
MQ_LOOKUP_PEEK_NEXT, // Access mode
&msgProps, // Message property structure
NULL, // No OVERLAPPED structure
NULL, // No callback function
MQ_NO_TRANSACTION // Not in a transaction
);
}
// Close the queue.
hr = MQCloseQueue(hQueue);
return hr;
}