Working with MSMQ in Visual C++ by vkworld

Message Queuing Overview:

Message Queuing is a message infrastructure and a development platform for creating distributed, loosely-coupled messaging applications. Message queuing applications can use the Message Queuing infrastructure to communicate across heterogeneous networks and with computers that may be offline. Message Queuing provides guaranteed message delivery, efficient routing, security, transaction support, and priority-based messaging.

Applications can create queues, locate existing queues, open queues, send messages to queues, read messages in queues, set and retrieve queue properties, and set and retrieve the security descriptors of queues.

The following code does the following:

1. Create a new Queue

2. Opening an existing Queue

3. Sending and Receiving messages to/from Queues.

Creating the Project and Application:

To create the application, follow these steps in Visual C++ 6.0 IDE:

1. Create a new project, named RWMSMQ, using the same AppWizard settings in Visual C++ 6.0 IDE.

2. Choose Dialog based application.

3. Click Finish.

4.Select the Dialog from the Resource editor of Visual C++ IDE and the following controls as show in the following table:

TABLE 1. CONTROL PROPERTY SETTINGS

 

Object

Property

Setting

Static Text

ID

IDC_STATIC

 

Caption

MSMQ Server

Edit Box

ID

IDC_MSMQSERVER

Static Text

ID

IDC_STATIC

 

Caption

Message Label

Edit Box

ID

IDC_MSGLABEL

Group Box

ID

IDC_STATIC

 

Caption

QUEUE TYPE

Radio Button

ID

IDC_PRIVATE

 

Caption

Private

Radio Button

ID

IDC_PUBLIC

 

Caption

Public

Check Box

 ID

IDC_JOURNAL

Edit Box

ID

IDC_TEXT

Button

ID

IDC_CREATE

 

Caption

Create

Button

ID

IDC_SEND

 

Caption

Send

Button

ID

IDC_RECEIVE

 

Caption

Receive

Button

ID

IDC_CLEAR

 

Caption

Clear

Button

ID

IDC_EXIT

 

Caption

Exit

 

Right click on the Group box, go to properties window. Select the Group Checkbox.

Adding the Application Variables

Now you need to add a few other variables for the other controls, as listed in Table below.

CONTROL VARIABLES.

Object Name Category Type
IDC_MSMQSERVER m_ServerName  Value CString
IDC_MSGLABEL m_msgLabel Value CString
IDC_TEXT m_msgData Value CString
IDC_JOURNAL m_Journal Control CButton

 

After you add all the variables using the Class Wizard.

Add the member functions for the Command Buttons using Class Wizard in Visual C++ IDE.

Importing the MSMQ dll in Visual C++:

#import "mqoa.dll"
usingnamespaceMSMQ; 

Add the above code in RWMSMQDlg.h

Add the following function definitions in the RWMSMQDlg.h .After this comment write the following code:

Protected: 
// Generated message map functions 
afx_msgvoidReleaseAll();   
Adding the Global Variables: 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

 

Add the following Code after this code in the RWMSMQDlg.cpp:

// Global Variables
#define BUFSIZE 1024 
IMSMQQueuePtr        qDest;  // Represents Destination Queue
IMSMQQueueInfoPtr  qInfo;     //Represents an open instance of the destination queue
IMSMQQueueInfoPtr  qRead; 
IMSMQMessagePtr     qMsg;     //Represents the message  LPTSTRlpszSystemInfo;      // pointer to system information string 
DWORDcchBuff = BUFSIZE;    // size of computer 
TCHARtchBuffer[BUFSIZE];   // buffer for string

Initialization:

 

In OnInitDialog function Add the new code:

BOOLCRWMSMQDlg::OnInitDialog() 
{ 
   // TODO: Add extra initialization here 
   qDest = NULL; 
   CoInitialize(NULL); 
   try
   { 
     qInfo.CreateInstance("MSMQ.MSMQQueueInfo");        
     qRead.CreateInstance("MSMQ.MSMQQueueInfo");      qMsg.CreateInstance("MSMQ.MSMQMessage"); 
     lpszSystemInfo = tchBuffer;
     GetComputerName(lpszSystemInfo,&cchBuff); //Getting the ComputerName
     m_ServerName=lpszSystemInfo; 
     UpdateData(FALSE);  
} 
catch (_com_error)
{ 
  AfxMessageBox("Failed in CreateInstance of MSMQQueueInfo"); 
  PostQuitMessage(1); 
  ReleaseAll(); 
} 
 returnTRUE;  // return TRUE  unless you set the focus to a control
} 

THE Create FUNCTION: This function will create a queue .

voidCRWMSMQDlg::OnCreate()
{
 UpdateData(TRUE);
 try
 {
 qInfo->PathName=m_ServerName.AllocSysString(); // Setting the Queue Path
 qInfo->Label=m_msgLabel.AllocSysString(); // Setting the Queue Label
 qInfo->Create();
 qInfo->Journal=1; // Enabling the Journal Option
 qInfo->Update();
 qInfo->Refresh();
 }
 catch (_com_error)
 {
 AfxessageBox("Creating a Queue Failed");
 //ReleaseAll();
 }
 UpdateData(FALSE);
 m_msgLabel="";
}

THE Send FUNCTION: This function is used to send the message to the queue.

voidCRWMSMQDlg::OnSend()
{
 UpdateData(TRUE);
 CStringfname;
 VARIANTvMessage;
 try
 {
 // Create a direct format name of the queue, and
 // set the FormatName property of the MSMQQueueInfo object.
 fname="DIRECT=OS:";
 fname+=m_ServerName;
 qInfo->PathName=m_ServerName.AllocSysString();
 qInfo->FormatName = fname.AllocSysString(); 
// Open the queue.
 qDest = qInfo->Open(MQ_SEND_ACCESS, MQ_DENY_NONE);
 qMsg->Label = m_msgLabel.AllocSysString();
 VariantInit(&vMessage);
 vMessage.vt=VT_BSTR;
 vMessage.bstrVal=m_msgData.AllocSysString();
 qMsg->put_Body(vMessage);
 VariantClear(&vMessage);
 qMsg->Send(qDest);
 qDest->Close();
 }
 catch(_com_error)
 {
 AfxMessageBox("Sending the Queue failed","Send Queue",1);
 //ReleaseAll();
 }
}

THE Read FUNCTION: This function is used to Read the messages from queue and it will put in the Journal folder.

void CRWMSMQDlg::OnRead()
{
 UpdateData(TRUE);
 _variant_tvtReceiveTimeout;
 _bstr_tlabel,body;
 CStringfname;
 intstatus=m_journal.GetCheck();
 try
 {
 qRead->PathName=m_ServerName.AllocSysString();
 fname="DIRECT=OS:";
 fname+=m_ServerName;
 if(status==1) fname=fname+";Journal"; // If Journal Option is Checked
 qInfo->PathName=m_ServerName.AllocSysString();
 qRead->FormatName = fname.AllocSysString();
 qDest = qRead->Open(MQ_RECEIVE_ACCESS,MQ_DENY_NONE);
 qMsg = qDest->Receive(&vtMissing,&vtMissing,&vtMissing,&vtReceiveTimeout);
 label=qMsg->GetLabel();
 body=qMsg->GetBody().bstrVal;
 m_msgLabel=(LPSTR)label;
 m_msgData=(LPSTR)body;
 UpdateData(FALSE);
 qDest->Close();
 }
 catch(_com_error)
 {
 AfxMessageBox("Reading the Queue Failed","Read Queue",1); 
 //ReleaseAll();
 }
}

 

THE Clear FUNCTION: 

voidCRWMSMQDlg::OnClear()
{
  m_msgLabel="";
  m_msgData="";
  UpdateData(FALSE);
}

THE Exit FUNCTION: This function is used to Exit from dialog box.

voidCRWMSMQDlg::OnExit()

{

::PostQuitMessage(1);

}

THE Private FUNCTION:

voidCRWMSMQDlg::OnPrivate()
{
m_ServerName=lpszSystemInfo;
m_ServerName+="\Private$\";
UpdateData(FALSE);

}

THE Public FUNCTION:

voidCRWMSMQDlg::OnPublic()
{
  m_ServerName=lpszSystemInfo;
  m_ServerName+="\Public$\";
  UpdateData(FALSE);
}

THE ReleaseAll FUNCTION: This functions is to release the objects from memory and un-initialize the COM Library.

voidCRWMSMQDlg::ReleaseAll()
{
 qInfo->Release();
 qRead->Release();
 qMsg->Release();
 CoUninitialize();
}

Download the Project Files here.