Applications can use a callback function, a Windows Event mechanism, or a Microsoft® Windows NT® completion port to read messages asynchronously. When reading messages asynchronously, the application is notified if a message is available or if a timeout has occurred.
For information, see MQReceiveMessage.
Note In the following two examples, the first uses a callback function to retrieve the messages, and the second uses a Windows Event mechanism. Both examples read the first message in the queue.
void APIENTRY ReceiveCallbackRoutine(
HRESULT hrStatus,
QUEUEHANDLE hSource,
DWORD dwTimeout,
DWORD dwAction,
MQMSGPROPS* pMessageProps,
LPOVERLAPPED lpOverlapped,
HANDLE hCursor
)
{
// Process message.
}
hr = MQOpenQueue(
szwFormatNameBuffer, // Format name of the queue.
MQ_RECEIVE_ACCESS, // Access rights to the queue.
0, // No receive Exclusive.
&hQueue // OUT: handle to the opened queue.
);
// Set the PROPID_M_BODY property.
paPropId[dwPropIdCount] = PROPID_M_BODY; //PropId
paVariant[dwPropIdCount].vt = VT_VECTOR|VT_UI1; //Type
paVariant[dwPropIdCount].caub.cElems = MSG_BODY_LEN ; //Value
paVariant[dwPropIdCount].caub.pElems = new unsigned char[ MSG_BODY_LEN];
dwPropIdCount++;
// Set the MQMSGPROPS structure.
MsgProps.cProp = PropIdCount; //Number of properties.
MsgProps.aPropID = aPropId; //Ids of properties.
MsgProps.aPropVar = aVariant; //Values of properties.
MsgProps.aStatus = NULL; //No Error report.
hr = MQReceiveMessage(
hQueue, // handle to the Queue.
5 * 60 * 1000, // Max time (msec) to wait.
MQ_ACTION_RECEIVE, // Action.
pMsgProps, // Properties to retrieve.
NULL, // No overlapped structure.
ReceiveCallbackRoutine, // Callback function.
NULL, // No Cursor.
NULL // No transaction
);
The following example specifies a callback function, opens a queue with receive access, specifies the body of the message as the only message property to retrieve, and reads the first message of the queue using the callback function.
//////////////////////////////
// Receive callback function.
/////////////////////////////
void APIENTRY ReceiveCallbackRoutine(
HRESULT hr,
QUEUEHANDLE hSource,
DWORD dwTimeout,
DWORD dwAction,
MQMSGPROPS* pMessageProps,
LPOVERLAPPED lpOverlapped,
HANDLE hCursor
)
{
if (FAILED(hr))
{
// Error handler for Callback routine.
}
else
{
// Process message.
}
}
//////////////
// Open Queue
//////////////
HRESULT hr;
QUEUEHANDLE hQueue;
hr = MQOpenQueue(
szwFormatNameBuffer, // Format Name of the queue to be opened.
MQ_RECEIVE_ACCESS, // Access rights to the Queue.
0, // No receive Exclusive.
&hQueue // OUT: handle to the opened Queue.
);
if (FAILED(hr))
{
// Error handler for MQOpenQueue.
}
MQMSGPROPS * pMsgProps;
MQPROPVARIANT *paVariant;
MSGPROPID * paPropId;
DWORD dwPropIdCount = 0;
//
// The output parameters to an asynchronous call to MQReceiveMessage
// should be kept intact until the operation completes, you should
// not free or reuse them until the operation is complete.
//
pMsgProps = new MQMSGPROPS;
paVariant = new MQPROPVARIANT[ 10];
paPropId = new MSGPROPID[ 10];
//////////////////////////////////////////////////
// Prepare the message properties to be retrieved.
/////////////////////////////////////////////////
// Set the PROPID_M_BODY property.
paPropId[dwPropIdCount] = PROPID_M_BODY; //PropId
paVariant[dwPropIdCount].vt = VT_VECTOR|VT_UI1; //Type
paVariant[dwPropIdCount].caub.cElems = MSG_BODY_LEN ; //Value
paVariant[dwPropIdCount].caub.pElems = new unsigned char[ MSG_BODY_LEN];
dwPropIdCount++;
////////////////////////////////
// Set the MQMSGPROPS structure
///////////////////////////////
pMsgProps->cProp = dwPropIdCount; //Number of properties.
pMsgProps->aPropID = paPropId; //Ids of properties.
pMsgProps->aPropVar = paVariant; //Values of properties.
pMsgProps->aStatus = NULL; //No Error report.
///////////////////////////////////////////////
// Receive the message using callback function
// ReceiveCallbackRoutine.
///////////////////////////////////////////////
hr = MQReceiveMessage(
hQueue, // handle to the Queue.
5 * 60 * 1000, // Max time (msec) to wait.
MQ_ACTION_RECEIVE, // Action.
pMsgProps, // properties to retrieve.
NULL, // No overlapped structure.
ReceiveCallbackRoutine, // Callback function.
NULL, // No Cursor.
NULL // No transaction
);
if (FAILED(hr))
{
// Error handler for MQReceiveMessage.
}
hr = MQOpenQueue(
szwFormatNameBuffer, // Format name of the queue.
MQ_RECEIVE_ACCESS, // Access rights to the Queue.
0, // No receive Exclusive.
&hQueue // OUT: handle to the opened Queue.
);
// Set the PROPID_M_BODY property.
paPropId[dwPropIdCount] = PROPID_M_BODY; //PropId
paVariant[dwPropIdCount].vt = VT_VECTOR|VT_UI1; //Type
paVariant[dwPropIdCount].caub.cElems = MSG_BODY_LEN ; //Value
paVariant[dwPropIdCount].caub.pElems = new unsigned char[ MSG_BODY_LEN];
dwPropIdCount++;
// Set the MQMSGPROPS structure.
MsgProps.cProp = PropIdCount; //Number of properties.
MsgProps.aPropID = aPropId; //Ids of properties.
MsgProps.aPropVar = aVariant; //Values of properties.
MsgProps.aStatus = NULL; //No Error report.
OVERLAPPED *pov = new OVERLAPPED ;
pov->hEvent = CreateEvent(0, TRUE, TRUE, 0);
hr = MQReceiveMessage(
hQueue, // handle to the Queue.
5 * 60 * 1000, // Max time (msec) to wait.
MQ_ACTION_RECEIVE, // Action.
pMsgProps, // Properties to retrieve.
pov, // Overlapped structure.
NULL, // Callback function.
NULL, // No Cursor.
NULL // No transaction
);
if(hr == MQ_INFORMATION_OPERATION_PENDING)
{
WaitForSingleObject(pov->hEvent, INFINITE);
//
// Parse recieved results
//
}
CloseHandle(pov->hEvent);
The following example opens a queue with receive access, specifies the body of the message as the only message property to retrieve, and uses a Windows Event mechanism to read the first message of the queue.
//////////////
// Open Queue
//////////////
HRESULT hr;
QUEUEHANDLE hQueue;
hr = MQOpenQueue(
szwFormatNameBuffer, // Format Name of the queue to be opened.
MQ_RECEIVE_ACCESS, // Access rights to the Queue.
0, // No receive Exclusive.
&hQueue // OUT: handle to the opened Queue.
);
if (FAILED(hr))
{
// Error handler for MQOpenQueue.
}
MQMSGPROPS * pMsgProps;
MQPROPVARIANT *paVariant;
MSGPROPID * paPropId;
DWORD dwPropIdCount = 0;
//
// The output parameters of an asynchronous call to MQReceiveMessage
// should be kept intact until the operation completes, you cannot
// free them or reuse them.
//
pMsgProps = new MQMSGPROPS;
paVariant = new MQPROPVARIANT[ 10];
paPropId = new MSGPROPID[ 10];
//////////////////////////////////////////////////
// Prepare the message properties to be retrieved.
/////////////////////////////////////////////////
// Set the PROPID_M_BODY property.
paPropId[dwPropIdCount] = PROPID_M_BODY; //PropId
paVariant[dwPropIdCount].vt = VT_VECTOR|VT_UI1; //Type
paVariant[dwPropIdCount].caub.cElems = MSG_BODY_LEN ; //Value
paVariant[dwPropIdCount].caub.pElems = new unsigned char[ MSG_BODY_LEN];
dwPropIdCount++;
////////////////////////////////
// Set the MQMSGPROPS structure
///////////////////////////////
pMsgProps->cProp = dwPropIdCount; //Number of properties.
pMsgProps->aPropID = paPropId; //Ids of properties.
pMsgProps->aPropVar = paVariant; //Values of properties.
pMsgProps->aStatus = NULL; //No Error report.
/////////////////////////////////////////
// Create Event object using overlapped
// structure.
/////////////////////////////////////////
OVERLAPPED *pov = new OVERLAPPED ;
pov->hEvent = CreateEvent(0, TRUE, TRUE, 0);
/////////////////////////////////////////
// Retrieve the message using overlapped
// structure.
/////////////////////////////////////////
hr = MQReceiveMessage(
hQueue, // handle to the Queue.
5 * 60 * 1000, // Max time (msec) to wait.
MQ_ACTION_RECEIVE, // Action.
pMsgProps, // properties to retrieve.
pov, // Overlapped structure.
NULL, // No callback function.
NULL, // No Cursor.
NULL // No transaction
);
if (FAILED(hr))
{
// Error handler for MQReceiveMessage.
}
//////////////////////////////
// Windows Event handler.
//////////////////////////////
if (hr == MQ_INFORMATION_OPERATION_PENDING)
{
WaitForSingleObject(pov->hEvent, INFINITE);
//
// Parse recieved results
//
}
CloseHandle(pov->hEvent);
delete paVariant; //Free resources.
delete paPropId;