Developing A Simple MTS Client using Visual C++
Gopalan Suresh Raj

 

Note
To work with any of these samples, you will need the following:
.........................................Microsoft Visual C++ ver 6.0
.........................................Windows NT 4.0 Options Pack

The ClickClient counts and displays the number of times the User clicks on the "Click Here..." button during the lifetime of this client app. It uses the ClickServer to increment the count (Looks like our ClickClient client program is mathematically challenged :-) !!!!!!!!).


Figure : Shows the ClickClient MTS client program in action

The Steps involved in developing the MTS Client are

1. Create a new Dialog based Windows Application
2. Add code in the Client to call the MTS Server
3. Build and Run the Client

1. Create a new Windows Application
Create a Dialog Based Windows Application project in Visual C++ by selecting the New Project in the File menu, then choosing the MFC AppWizard (EXE) project template. Name the project ClickClient and choose Open.

2. Add code in the ClickClient to call the ClickServer MTS component
This is where we add code to the Client apps form to interact with the MTS ClickServer component.

1) Create a Dialog form similar to the one shown below.


Figure : Shows the form that we need to develop for our ClickClient program

2) To the "StdAfx.h" file, add the following piece of code:

#import "E:\com\gopalan\ClickServer\ClickServer.tlb" no_namespace

3) To the "ClickClient.cpp" file, add this piece of code in the InitInstance() of the Application just before the dialog is created:

  // Init OLE libraries and support
  if ( !AfxOleInit() )
  {
    AfxMessageBox ("OLE Initialization failed");
    return FALSE;
  }
4) To the CClientDialog class in the file "ClickClientDlg.h", add a couple of members:
 	IServerPtr  m_pServer;   // pointer to the MTS Server Component reference
	int         m_nClickCount // maintains the number of times client called server;

5) To the CClickClientDlg::OnInitDialog() member implementation in the file "ClickClientDlg.cpp", add the following code:

  CLSID   clsid;
  HRESULT hResult;
  
  hResult = CLSIDFromProgID (OLESTR("ClickServer.Server"), &clsid);
  if (FAILED(hResult))
  {
    AfxMessageBox ("Retrieval of ProgID failed...");
    return FALSE;
  }
  
  m_pServer.CreateInstance (clsid);

6) Add code to the CClickClientDlg::OnClickHere() method in the file "ClickClientDlg.cpp", so that the MTS Server component is invoked from the client whenever the "Click Here..." button is pressed on the dialog form.

void CClickClientDlg::OnClickHere() 
{
  // TODO: Add your control notification handler code here
  CStatic* pStatic = (CStatic*) GetDlgItem (IDC_STATIC);
  CString str;
  try {
    m_pServer->Increment (&m_nClickCount);
  } catch (...) {
  }
  str.Format ("That was Click Number %d, Buddy...", m_nClickCount);
  pStatic->SetWindowText(str);
  
}

The completed code for StdAfx.h is shown below:

StdAfx.h
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__928D10D9_876E_11D3_9822_006097A7D34F__INCLUDED_)
#define AFX_STDAFX_H__928D10D9_876E_11D3_9822_006097A7D34F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers

#include <afxwin.h>		// MFC core and standard components
#include <afxext.h>		// MFC extensions
#include <afxdisp.h>		// MFC Automation classes
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>		// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#import "E:\com\gopalan\ClickServer\ClickServer.tlb" no_namespace

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__928D10D9_876E_11D3_9822_006097A7D34F__INCLUDED_) 

The completed code for ClickClient.cpp is shown below:

ClickClient.cpp
// ClickClient.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "ClickClient.h"
#include "ClickClientDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CClickClientApp

BEGIN_MESSAGE_MAP(CClickClientApp, CWinApp)
	//{{AFX_MSG_MAP(CClickClientApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClickClientApp construction

CClickClientApp::CClickClientApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CClickClientApp object

CClickClientApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CClickClientApp initialization

BOOL CClickClientApp::InitInstance()
{
	AfxEnableControlContainer();

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();		// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Init OLE libraries and support
	if ( !AfxOleInit() )
	{
	    AfxMessageBox ("OLE Initialization failed");
	    return FALSE;
	}

	CClickClientDlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with OK
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with Cancel
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	//  application, rather than start the application's message pump.
	return FALSE;
}

The completed code for ClickClientDlg.h is shown below:

ClickClientDlg.h
// ClickClientDlg.h : header file
//

#if !defined(AFX_CLICKCLIENTDLG_H__928D10D7_876E_11D3_9822_006097A7D34F__INCLUDED_)
#define AFX_CLICKCLIENTDLG_H__928D10D7_876E_11D3_9822_006097A7D34F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CClickClientDlg dialog

class CClickClientDlg : public CDialog
{
  // Construction
public:
  CClickClientDlg(CWnd* pParent = NULL);	// standard constructor
  
  // Dialog Data
  //{{AFX_DATA(CClickClientDlg)
  enum { IDD = IDD_CLICKCLIENT_DIALOG };
		// NOTE: the ClassWizard will add data members here
  //}}AFX_DATA
  
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CClickClientDlg)
protected:
  virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
  //}}AFX_VIRTUAL
  
  // Implementation
protected:
  HICON m_hIcon;
  
  // Generated message map functions
  //{{AFX_MSG(CClickClientDlg)
  virtual BOOL OnInitDialog();
  afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
  afx_msg void OnPaint();
  afx_msg HCURSOR OnQueryDragIcon();
  afx_msg void OnClickHere();
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
private:
  IServerPtr  m_pServer;    // pointer to the MTS Server Component reference
  int         m_nClickCount;// maintains the number of times client called server;
  
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CLICKCLIENTDLG_H__928D10D7_876E_11D3_9822_006097A7D34F__INCLUDED_)

The completed code for ClickClientDlg.cpp is shown below:

ClickClientDlg.cpp
// ClickClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ClickClient.h"
#include "ClickClientDlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
  CAboutDlg();
  
  // Dialog Data
  //{{AFX_DATA(CAboutDlg)
  enum { IDD = IDD_ABOUTBOX };
  //}}AFX_DATA
  
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CAboutDlg)
protected:
  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  //}}AFX_VIRTUAL
  
  // Implementation
protected:
  //{{AFX_MSG(CAboutDlg)
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
  //{{AFX_DATA_INIT(CAboutDlg)
  //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CAboutDlg)
  //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClickClientDlg dialog

CClickClientDlg::CClickClientDlg(CWnd* pParent /*=NULL*/)
: CDialog(CClickClientDlg::IDD, pParent)
{
  //{{AFX_DATA_INIT(CClickClientDlg)
		// NOTE: the ClassWizard will add member initialization here
  //}}AFX_DATA_INIT
  // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  m_nClickCount = 0;
}

void CClickClientDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CClickClientDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
  //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CClickClientDlg, CDialog)
//{{AFX_MSG_MAP(CClickClientDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(ID_CLICKHERE, OnClickHere)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClickClientDlg message handlers

BOOL CClickClientDlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  
  // Add "About..." menu item to system menu.
  
  // IDM_ABOUTBOX must be in the system command range.
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX < 0xF000);
  
  CMenu* pSysMenu = GetSystemMenu(FALSE);
  if (pSysMenu != NULL)
  {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
      pSysMenu->AppendMenu(MF_SEPARATOR);
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
  }
  
  // Set the icon for this dialog.  The framework does this automatically
  //  when the application's main window is not a dialog
  SetIcon(m_hIcon, TRUE);			// Set big icon
  SetIcon(m_hIcon, FALSE);		// Set small icon
  
  // TODO: Add extra initialization here
  CLSID   clsid;
  HRESULT hResult;
  
  hResult = CLSIDFromProgID (OLESTR("ClickServer.Server"), &clsid);
  if (FAILED(hResult))
  {
    AfxMessageBox ("Retrieval of ProgID failed...");
    return FALSE;
  }
  
  m_pServer.CreateInstance (clsid);
  
  return TRUE;  // return TRUE  unless you set the focus to a control
}

void CClickClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  {
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
  }
  else
  {
    CDialog::OnSysCommand(nID, lParam);
  }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CClickClientDlg::OnPaint() 
{
  if (IsIconic())
  {
    CPaintDC dc(this); // device context for painting
    
    SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    
    // Center icon in client rectangle
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2;
    
    // Draw the icon
    dc.DrawIcon(x, y, m_hIcon);
  }
  else
  {
    CDialog::OnPaint();
  }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CClickClientDlg::OnQueryDragIcon()
{
  return (HCURSOR) m_hIcon;
}

void CClickClientDlg::OnClickHere() 
{
  // TODO: Add your control notification handler code here
  CStatic* pStatic = (CStatic*) GetDlgItem (IDC_STATIC);
  CString str;
  try {
    m_pServer->Increment (&m_nClickCount);
  } catch (...) {
  }
  str.Format ("That was Click Number %d, Buddy...", m_nClickCount);
  pStatic->SetWindowText(str);
  
}

4. Build and Run the Client program - ClickClient
Build the project by selecting Build from the Build menu. This creates a Windows executable with all the class files needed to execute the client. Run it and have fun...

Download the Entire Source as a Zip file

click here to go to the
Developing a Simple MTS Server Component Page...
click here to go to
My MTS HomePage...

Go to the Component Engineering Cornucopia page

This site was developed and is maintained by Gopalan Suresh Raj

This page has been visited times since February 24,1999.

Last Updated : Feb 24, '99

If you have any questions, comments, or problems regarding this site, please write to me I would love to hear from you.


Copyright (c) 1997-99, Gopalan Suresh Raj - All rights reserved. Terms of use.

All products and companies mentioned at this site,are trademarks of their respective owners.