Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

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

Syntax

HRESULT APIENTRY MQReceiveMessage(
  QUEUEHANDLE 
hSource,
  DWORD 
dwTimeout,
  DWORD 
dwAction,
  MQMSGPROPS 
pMessageProps,
  LPOVERLAPPED 
lpOverlapped,
  PMQRECEIVECALLBACK 
fnReceiveCallback,
  HANDLE 
hCursor,
  Transaction* 
pTransaction
);

Parameters

hSource

[in] Handle to the queue that contains the message.

For transactions, specify a queue on a local computer.

dwTimeout

[in] Time, in milliseconds, to wait for the message.

Can be set to INFINITE.

dwAction

[in] How the message is read in the queue.

Specify one of the following values.

Value Description

MQ_ACTION_RECEIVE

Reads the message at the current cursor location and removes it from the queue.

MQ_ACTION_PEEK_CURRENT

Reads the message at the current cursor location but does not remove it from the queue. The cursor remains pointing at the current message.

If a cursor was not created by MQCreateCursor( hCursoris NULL), the queue's cursor can only point to the first message in the queue.

MQ_ACTION_PEEK_NEXT

Reads the next message in the queue, skipping the message at the current cursor location, but does not remove it from the queue.

Before you can use MQ_ACTION_PEEK_NEXT, call MQCreateCursor( hCursoris not NULL).

pMessageProps

[in, out] On input, a pointer to an MQMSGPROPSstructure that specifies which message properties will be received.

Can be set to NULL.

On output, it contains the received message property values.

lpOverlapped

[in, out] Pointer to an overlapped structure.

Set to NULL for synchronous receive and transactions.

fnReceiveCallback

[in] Pointer to the callback function.

Set to NULL for synchronous receive and transactions.

hCursor

[in] Handle to a cursor for looking at messages in the queue.

Can be set to NULL.

See the following Remarkssection.

pTransaction

[in] Not supported; set to NULL.

Return Value

MQ_OK

Indicates success.

MQ_ERROR_ACCESS_DENIED

The action specified in dwActiondoes not agree with the access rights the queue was opened with.

MQ_ERROR_BUFFER_OVERFLOW

The supplied buffer for the message body is too small.

The part of the message body that fits into the buffer is copied, but the message is not removed from the queue.

MQ_ERROR_COMPUTER_DOES_NOT_SUPPORT_ENCRYPTION

If specified, the following properties return this error:

  • PROPID_M_HASH_ALG

  • PROPID_M_ENCRYPTION_ALG

  • PROPID_M_PROV_TYPE

  • PROPID_M_SECURITY_CONTEXT

Other encryption properties return NULL data.

MQ_ERROR_SENDERID_BUFFER_TOO_SMALL

The supplied sender identification buffer is too small to hold the sender identification.

MQ_ERROR_SYMM_KEY_BUFFER_TOO_SMALL

The supplied symmetric key buffer is too small to hold the symmetric key.

MQ_ERROR_SENDER_CERT_BUFFER_TOO_SMALL

The supplied sender certificate buffer is too small to hold the security certificate.

MQ_ERROR_SIGNATURE_BUFFER_TOO_SMALL

The supplied signature buffer is too small to hold the message's digital signature.

MQ_ERROR_PROV_NAME_BUFFER_TOO_SMALL

The supplied provider name buffer is too small to hold the cryptographic service provider's name.

MQ_ERROR_LABEL_BUFFER_TOO_SMALL

The supplied message label buffer is too small to hold the message's label.

MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL

The supplied format name buffer is too small to hold the format name of the queue.

MQ_ERROR_DTC_CONNECT

MSMQ could not connect with the Microsoft Distributed Transaction Coordinator (DTC).

MQ_ERROR_INSUFFICIENT_PROPERTIES

One of the following message properties was specified (in pMessageProps) without its associated length property:

MQ_ERROR_INVALID_HANDLE

The queue handle specified in hSourceis not valid.

MQ_ERROR_IO_TIMEOUT

No message was received within the time-out period specified by dwTimeout.

MQ_ERROR_MESSAGE_ALREADY_RECEIVED

A message pointed at by the cursor has been removed from the queue.

It can be removed by another process or by another call to MQReceiveMessageusing a different cursor, or if the message time-to-be-received timer has expired.

MQ_ERROR_OPERATION_CANCELLED

The operation was canceled before it could be completed.

For example, the queue handle was closed by another thread while waiting for a message.

MQ_ERROR_PROPERTY

One or more message properties specified in pMessagePropsresulted in an error.

MQ_ERROR_QUEUE_DELETED

The queue was deleted before the message could be read.

The specified queue handle is no longer valid and the queue handle must be closed.

MQ_ERROR_ILLEGAL_CURSOR_ACTION

MQ_ACTION_PEEK_NEXT cannot be used with the current cursor position.

MQ_ERROR_SERVICE_NOT_AVAILABLE

Cannot connect to the Queue Manager.

MQ_ERROR_STALE_HANDLE

The specified queue handle was obtained in a previous session of the Queue Manager service. To obtain a fresh handle, close the queue and open it again.

MQ_ERROR_TRANSACTION_USAGE

Transaction error. An attempt was made to open a remote queue for read access from within a transaction, or an attempt was made to read a message from a nontransactional queue from within a transaction.

MQ_INFORMATION_PROPERTY

One or more properties specified in pMessagePropsresulted in a warning code even though the function is completed.

Remarks

All message properties can be read. However, only properties specified in the pMessagePropsparameter are returned to the calling application; other properties are discarded when the message is read. For example, you can retrieve the size of the message without retrieving the message body.

The hCursorparameter contains the handle to a cursor created by MQCreateCursor. Using a cursor is optional and is only necessary when you want to read messages that are not at the front of the queue.

When using a cursor, before you make calls with dwActionset to MQ_ACTION_PEEK_NEXT, peek at the first message in the queue by setting dwActionto MQ_ACTION_PEEK_CURRENT.

To retrieve the message body, specify PROPID_M_BODYin pMessageProps. Set the VT field of the corresponding element in the aPropVararray to VT_UI1 | VT_VECTOR, allowing MSMQ to use the buffer specified in the CAUI1structure to store the message.

If the supplied buffer is too small to contain the entire message body, MQReceiveMessagefails 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 pMessagePropsare still read.

To retrieve the size of the message, specify PROPID_M_BODY_SIZEin pMessageProps. MSMQ sets PROPID_M_BODY_SIZE to the size of the message body, even if MQReceiveMessagefails because the message body exceeded the buffer allocated by PROPID_M_BODY.

When retrieving the message body size, the CAUI1structure associated with the PROPID_M_BODY property does not indicate the size. The cElemsfield of the CAUI1structure indicates the maximum message body, which could be copied into the pElemsbuffer. The cElemsfield is never modified by MSMQ.

Not all properties require the application to specify the property type in the VT field of the aPropVararray. For these properties, the corresponding VT field in the aPropVararray 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.

For Windows Mobile, messages cannot be read from a queue that resides on a computer without a direct connection. Opening a queue with receive or peek access requires a direct connection to the computer where the queue resides.

Synchronously Reading Messages

To synchronously read messages, set fnReceiveCallbackand lpOverlappedto NULL. When this is done, the calling thread is blocked until a suitable message is available or a time-out occurs.

Asynchronously Reading Messages

When asynchronously reading messages, MQReceiveMessagereturns a SUCCESS value if 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.

To read messages asynchronously, applications can use one of the following:

  • A callback function

  • A Windows Event mechanism

  • A completion port

When using a callback function, you can register only 64 callbacks at the same time.

Completion ports cannot be used by dependent client applications. On MSMQ independent clients and servers, queue handles are implemented as file handles, which allows them to be associated with completion ports. However, on dependent clients, queue handles are not file handles and as a result cannot be used with completion ports.

Keep the output parameters for an asynchronous call to MQReceiveMessageintact until the operation is complete (that is, until you cannot free or reuse them).

Use automatic variables with caution.

Messages in Administration Queues

When reading acknowledgment messages in an administration queue, you can see if the original message failed to reach its destination or was not retrieved from the queue by looking at the class property ( PROPID_M_CLASS) of the acknowledgment message.

The class property contains a positive or negative acknowledgment, depending on the acknowledgment level specified by the original message.

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.

Responding to Messages

The receiving application can determine if the sending application expects a response by retrieving the PROPID_M_RESP_QUEUEand PROPID_M_RESP_QUEUE_LENproperties when reading a message. If a response is requested, PROPID_M_RESP_QUEUE contains the format name of a response queue.

When opening a response queue to send several response messages, the receiving application can cache the queue handle returned by MQOpenQueue, eliminating the need to call MQOpenQueueseveral times for the same response queue.

Note:
OS versions prior to 2.12 require the MSMQ add-on pack.

Requirements

Header mq.h
Library msmqrt.lib
Windows Embedded CE Windows CE 2.0 and later
Windows Mobile Windows Mobile Version 5.0 and later
Note Versions prior to 2.12 require the MSMQ add-on pack

See Also