The MQReceiveMessage function allows you to read messages in the queue. When reading messages, you can either peek at (not removing them) or retrieve the messages (removing them) in the queue.
Messages can be read either synchronously, asynchronously, or through a transaction.
HRESULT APIENTRY MQReceiveMessage(
QUEUEHANDLE hSource,
DWORD dwTimeout,
DWORD dwAction,
MQMSGPROPS pMessageProps,
LPOVERLAPPED lpOverlapped,
PMQRECEIVECALLBACK fnReceiveCallback,
HANDLE hCursor,
Transaction *pTransaction
);
If a cursor was not created by MQCreateCursor (hCursor is NULL), the queue's cursor can only point to the first message in the queue.
MQCreateCursor must be called (hCursor is not NULL) before MQ_ACTION_PEEK_NEXT can be used.
On output, it contains the received message property values.
Transaction object can be obtained internally from MSMQ (by calling MQBeginTransaction), or externally from Microsoft® DTC (Distributed Transaction Coordinator).
Constants include:
NULL indicates the message is not retrieved as part of a transaction.
All message properties can be read. However, only those properties specified in the pMessageProps parameter are returned to the calling application; other properties are simply discarded when the message is read. For example, when browsing for messages, some applications may choose to retrieve the size of the message without retrieving the message body itself. To do this, PROPID_M_BODY_SIZE is included in pMessageProps and PROPID_M_BODY is not; the size of the message is returned to the calling application and the message body is not.
The hCursor parameter contains the handle to a cursor created by MQCreateCursor. Using a cursor is optional and is only needed when you want to read messages that are not at the front of the queue.
When using a cursor, you must peek at the first message in the queue by setting dwAction to MQ_ACTION_PEEK_CURRENT followed by subsequent calls with dwAction set to MQ_ACTION_PEEK_NEXT.
The dwAction parameter specifies how MSMQ reads the message (either peek or receive) and which message is read. For a description of how MSMQ reads the messages in the queue, see:
To retrieve the message body, PROPID_M_BODY must be specified in pMessageProps. The VT field of the corresponding element in the aPropVar array should be set to VT_UI1 | VT_VECTOR, allowing MSMQ to use the buffer specified in CAUI1 to store the message. If the supplied buffer is too small to contain the entire message body, MQReceiveMessage fails and MQ_ERROR_BUFFER_OVERFLOW is returned. The buffer is filled to capacity, and the full message remains in the queue. When this happens, the other properties specified by pMessageProps are still read.
To retrieve the size of the message, specify PROPID_M_BODY_SIZE in pMessageProps. MSMQ sets PROPID_M_BODY_SIZE to the size of the message body, even if MQReceiveMessage fails because the message body exceeded the buffer allocated by PROPID_M_BODY. When retrieving the message body size, the CAUI1 structure associated with the PROPID_M_BODY property does not indicate the size. The cElems field of the CAUI1 structure merely indicates the maximum message body, which could be copied into the pElems buffer. The cElems field is never modified by MSMQ.
Not all properties require the application to specify the property type in the VT field of the aPropVar array. For these properties, the corresponding VT field in the aPropVar array can be set to VT_NULL.
When reading messages in a queue, the function's time-out timer (dwTimeout) can be set to 0, a specific amount of time, or INFINITE. A message can be retrieved if it is available at that period of time.
To synchronously read messages, fnReceiveCallback and lpOverlapped must be set to NULL. When this is done, the calling thread is blocked until a suitable message is available or a time-out occurs.
For an example of using MQReceiveMessage to read messages synchronously, see Reading Messages Synchronously.
When asynchronously reading messages, MQReceiveMessage returns a SUCCESS value as soon as a suitable message is found. Otherwise, the function returns immediately with the return value MQ_INFORMATION_OPERATION_PENDING. This return value indicates that the operation is pending and will be completed as soon as a suitable message can be found. Asynchronous receive is based on standard Microsoft® Win32® mechanisms.
There are three possible ways to read messages asynchronously:
When multiple asynchronous MQReceiveMessage calls are outstanding, several callbacks are registered; upon arrival of a message, the first registered callback is called.
For more information on the OVERLAPPED structure, see the Microsoft Platform SDK.
For more information, see CreateIOCompletionPort in the Microsoft Platform SDK.
The output parameters to an asynchronous call to MQReceiveMessage should be kept intact until the operation completes (that is, you cannot free them or reuse them). Use automatic variables with caution.
For an example of using MQReceiveMessage to read messages asynchronously, see Reading Messages Asynchronously.
If MQReceiveMessage is called as part of a transaction (pTransaction is not set to MQ_NO_TRANSACTION or NULL), the following parameters must be set accordingly:
When the call is made, MSMQ performs the following tasks.
For more information about MSMQ transactions, see MSMQ Transactions.
When reading acknowledgment messages in an administration queue, you can see if the original message failed by looking at the class property (PROPID_M_CLASS) of the acknowledgment message. The class property will contain a positive or negative acknowledgment.
If the class property is positive, the original message body is not included in the acknowledgment message. If the class property is negative, the message body is included as the message body of the acknowledgment message. For a complete description of all the properties of the acknowledgment message, see Acknowledgment Messages.
The receiving application can pass PROPID_M_RESP_QUEUE to MQReceiveMessage to see if the sending application expects a response to the message. The messages sent back to the response queue specified by this property must be understood by the original sending application.
When receiving a message, always check PROPID_M_RESP_QUEUE to see if it is not NULL. If it is not NULL, send responses to the specified response queue.
Response queue handles returned by MQOpenQueue can be cached to eliminate the need to call MQOpenQueue several times for the same response queue.
For an example of sending response messages, see Sending Messages that Request a Response.
For examples of using MQReceiveMessage, see Reading Messages Using a Cursor.
Windows NT: Requires version 4.0 SP3 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in mq.h.
Import Library: Use mqrt.lib.
Unicode: Defined only as Unicode.
MQCreateCursor, MQMSGPROPS, MQOpenQueue, PROPVARIANT, MQSetQueueSecurity, PROPID_M_BODY, PROPID_M_BODY_SIZE, PROPID_M_CLASS, PROPID_M_RESP_QUEUE