C-C++ COM Code Example: Reading Messages Synchronously
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
The following example provides an application-defined function that synchronously reads each message in a known queue, removing each message as it is read.
For information about reading messages synchronously, see Synchronous Reading.
This example uses smart pointers to the following Message Queuing interfaces.
MSMQQueue: Represents an open instance of the destination queue.
MSMQQueueInfo: Represents the destination queue.
MSMQMessage: Represents the message.
To use smart pointers, your application must import Mqoa.dll. You can import this DLL using the #import directive and specify the MSMQ namespace.
#import "mqoa.dll"
using namespace MSMQ;
Before using any smart pointer, your application must call CoInitialize or CoInitializeEx to initialize the COM library. After the COM library is no longer needed, your application must call CoUnitialize. For more information, see Using Message Queuing COM Components in Visual C++ and C.
To read messages synchronously
Declare a smart pointer to an MSMQQueue interface and create smart pointers to MSMQQueueInfo and MSMQMessage interfaces.
Create the path name of the queue and set it in the MSMQQueueInfo object.
Note
wcslen properly handles only null-terminated strings. This function does not verify that the strings passed to it are null-terminated. It is the responsibility of the caller to ensure that the strings passed are null-terminated.
Call MSMQQueueInfo.Open to open the queue.
In a loop structure, call MSMQQueue.Receive to read all the messages in the queue.
Call MSMQQueue.Close to close the queue.
Code Example
The following code example can be run on all versions of Message Queuing.
HRESULT ReceiveMessage(
WCHAR *wszComputerName,
WCHAR *wszQueueName
)
{
// Validate the input strings.
if (wszComputerName == NULL || wszQueueName == NULL)
{
return MQ_ERROR_INVALID_PARAMETER;
}
HRESULT hr = S_OK;
IMSMQQueuePtr pQueue;
WCHAR *wszTmpPathName = NULL;
try
{
IMSMQQueueInfoPtr pInfo("MSMQ.MSMQQueueInfo");
int nComputerNameLength = 0;
int nQueueNameLength = 0;
int nPathNameLength = 0;
// Create the path name of the destination queue.
nComputerNameLength = wcslen(wszComputerName);
nQueueNameLength = wcslen(wszQueueName);
nPathNameLength = nComputerNameLength + nQueueNameLength + 2;
wszTmpPathName = new WCHAR[nPathNameLength];
if (wszTmpPathName)
{
memset(wszTmpPathName, 0, nPathNameLength*sizeof(WCHAR));
// ************************************
// You must concatenate wszComputerName, "\", wszQueueName into
// the wszTmpPathName buffer.
// wszTmpPathName = wszComputerName + "\" + wszQueueName
// ************************************
pInfo->PathName = wszTmpPathName;
}
// Open the queue for receive access.
pQueue = pInfo->Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE);
IMSMQMessagePtr pMsg("MSMQ.MSMQMessage");
_variant_t vtTimeOut((long)1000); // 1 second until receive time-out
_variant_t bvtWantBody((bool)true); // Set to retrieve message body
// Read all the messages in queue until 1 second time-out.
for( ; ; )
{
TCHAR szMessage[1024];
pMsg = pQueue->Receive(&vtMissing, &vtMissing, &bvtWantBody, &vtTimeOut);
if (pMsg == NULL)
{
// ************************************
// You must copy the string "No message, closing queue."
// into the szMessage buffer.
// ************************************
MessageBox(NULL, szMessage, NULL, MB_OK);
pQueue->Close();
pQueue = NULL;
break;
}
wprintf(L"The following messages were received successfully from the queue %s\n", (WCHAR *)pInfo->PathName);
// Display the message label and body
_bstr_t bstrLabel;
_bstr_t bstrBody;
bstrLabel = pMsg->Label;
bstrBody = pMsg->Body;
wprintf(L"Message Label = '%s'\n", (WCHAR *)bstrLabel);
//This example assumes the message body is a Unicode string
wprintf(L"Message Body = '%s'\n", (WCHAR *)bstrBody);
_stprintf_s(szMessage, 1024, TEXT("Removed message from queue %s"), (TCHAR *)pInfo->PathName);
// ************************************
// You must concatenate "Removed message from queue " and
// (TCHAR *)pInfo->PathName into the szMessage variable.
// szMessage = "Removed message from queue " +
// (TCHAR *)pInfo->PathName
// ************************************
MessageBox(NULL, szMessage, NULL, MB_OK);
}
}
catch (const _com_error& comerr)
{
hr = comerr.Error();
wprintf("Error Code = 0x%X\nError Description = %s\n", hr, (WCHAR *)comerr.Description() );
if (pQueue)
{
pQueue->Close();
}
}
delete [] wszTmpPathName;
return hr;
}