Initializing a Computer as a Server and Accepting Connections (Visual C++ 5.0 and later)

Take the following steps to start a project and to add some code that will let you initialize a computer as a server and accept connections.

1.

Start a new project as follows:

 

For C++ 5.0, run Microsoft Visual C++ 5.0, select the File >New menu option, and do the following:

 

a.

Click the Projects tab.

 

b.

Select MFC AppWizard (exe) as the project type

 

c.

In the Project name text box, specify server.

 

d.

In the Location text box, specify the path of the project.

 

e.

Click the OK button.

2.

In the Step 1 dialog box, do the following:

 

a.

Select Dialog based.

 

b.

Click the Next button.

3.

In the Step 2 of 4 dialog box, do the following:

 

a.

Ensure that About Box is selected.

 

b.

Ensure that 3D controls is selected.

 

c.

Select OLE controls (ActiveX controls in 5.0).

 

d.

Click the Next button.

4.

In the Step 3 of 4 dialog box, do the following:

 

a.

For comments, ensure that Yes, Please is selected.

 

b.

For how to use the MFC library, select As a shared DLL.

 

c.

Click the Next button.

5.

In the Step 4 of 4 dialog box, just click Finish.

6.

Read New Project Information, and click OK. (The AppWizard creates the project files and opens the project.)

7.

Add #import and #include statements to your program so you can access the LEAD COM constants and classes:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the server files folder to open it.

 

c.

Double-click the Header Files folder to open it.

 

d.

Double-click the StdAfx.h file to edit it.

 

e.

Add the following lines to the end of the file (keep in mind, you may have to change the path to where the dll's reside):

#import "d:\\winnt\\system32\\ltrvr14n.dll" no_namespace, named_guids
#import "d:\\winnt\\system32\\ltr14n.dll" no_namespace, named_guids
#import "d:\\winnt\\system32\\ltrvw14n.ocx" no_namespace, named_guids
#import "d:\\winnt\\system32\\ltrio14n.dll" no_namespace, named_guids
#import "d:\\winnt\\system32\\ltrpr14n.dll" no_namespace, named_guids
#import "d:\\winnt\\system32\\ltrnt14n.dll" no_namespace, named_guids

8.

Add a command button to the main window and set the ID and Caption properties as follows:

 

ID

Caption

 

IDC_SERVERINIT

Init Server

9.

Edit the serverDlg.H file and change the definition of CServerDlg : CDialog by inserting the following lines after DECLARE_MESSAGE_MAP:

public:
   short m_hServer;
   ILEADRasterInet *m_pRasterInet;
   CRasterInetSink *m_pRasterInetSink;
   IConnectionPoint *m_pInetCP;
   DWORD m_dwInetCookie;

10.

Add the following code to the OnInitDialog procedure in the ServerDlg.cpp, following the line "TODO: Add extra initialization here":

//Create the RasterInet object
CoCreateInstance(CLSID_LEADRasterInet, NULL, CLSCTX_ALL,
IID_ILEADRasterInet, (void**)&m_pRasterInet);
m_pRasterInet->EnableMethodErrors = FALSE;

//create a temp LEADRaster object and use it
IClassFactory2 *pCF2=NULL;
CLSID clsid;
ILEADRaster *pRaster=NULL;
static const WCHAR BASED_CODE _szID[] = L"LEADRaster.LEADRaster";

CLSIDFromProgID(_szID, &clsid);

CoGetClassObject(clsid, CLSCTX_ALL, NULL, IID_IClassFactory2, (void**)&pCF2);
//This object is licensed, so we need to pass a license key
static const WCHAR BASED_CODE _szLic[] = L"LEADTOOLS OCX Copyright (c) 1991-2004 LEAD Technologies, Inc.";
BSTR lpLic = SysAllocString(_szLic);
pCF2->CreateInstanceLic(NULL, NULL, IID_IUnknown, lpLic, (void**)&pRaster);
SysFreeString(lpLic);
pCF2->Release();
pRaster->Release();

11.

Edit the ServerDlg.CPP file and add the following code to the end of the OnInitDialog function (before the return!):

//Instantiate the sink class and hold a pointer to it.
m_pRasterInetSink = new CRasterInetSink;
m_pRasterInetSink->m_pDlg = this;

//Establish a connection between source and sink.
LPUNKNOWN pInetUnkSink = m_pRasterInetSink->GetIDispatch(FALSE);
AfxConnectionAdvise(m_pRasterInet, DIID__LTRASINETEvents, pInetUnkSink, FALSE, &m_dwInetCookie); 

12.

Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

Click the Add Class button.

 

b.

Click New....

 

c.

Type CRasterInetSink for the name of the class

 

d.

Select CCmdTarget for the base class of the new class.

 

e.

Under Automation, click the Automation radio button.

 

f.

Click OK to create the class.

 

g.

In the RasterInetSink.h file, move the destructor so that it is public:

// Implementation
virtual ~CRasterInetSink();
protected:

 

h.

In the RasterInetSink.h file, add the following to the top of the file:

 

 

class CServerDlg;

 

i.

In the RasterInetSink.h file, add the following to the CRasterInetSink class in the //Attributes public section:

// Attributes
public:
   CServerDlg *m_pDlg;

 

j.

In the RasterInetSink.cpp file, add the following to the top of the file (after the #include "RasterInetSink.h")

#include "ServerDlg.h"

13.

Add #include statements so you can access the new class:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the server files folder to open it.

 

c.

Double-click the Header Files folder to open it.

 

d.

Double-click the StdAfx.h file to edit it.

 

e.

Add the following lines to the end of the file:

#include <AFXCTL.H>
#include "RasterInetSink.h"

14.

Edit the header for the Sink class:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the server files folder to open it.

 

c.

Double-click the Header Files folder to open it.

 

d.

Double-click the RasterInetSink.h file to edit it.

 

e.

Add the following just before //}}AFX_MSG: afx_msg void OnInetAccept(short);

 

 

afx_msg void OnInetAccept(short);

15.

Edit the source for the Sink class:

 

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the server files folder to open it.

 

c.

Double-click the Source Files folder.

 

d.

Double-click the RasterInetSink.cpp file to edit it.

 

e.

Add the following to the DISPATCH_MAP:

DISP_FUNCTION_ID(CRasterInetSink,"InetAccept",5,OnInetAccept,VT_EMPTY,VTS_I2)

 

f.

Inside the BEGIN_INTERFACE_MAP section, change the INTERFACE_PART tothe following:

INTERFACE_PART(CRasterInetSink, DIID__LTRASINETEvents, Dispatch)

 

g.

Add the following to the end of the file:

void CRasterInetSink::OnInetAccept(short iServer)
{
   short hComputer;
   short nRet;
   L_TCHAR szHostName[80];
   BSTR bstrText;
   CString strText;
   CString cs;

   nRet = m_pDlg->m_pRasterInet->InetAcceptConnect(m_pDlg->m_hServer);
   hComputer = m_pDlg->m_pRasterInet->InetConnectedComputer();
   if(nRet != 0)
   {
      AfxMessageBox(TEXT("Error accepting connection!"));
      return;
   }

   m_pDlg->m_pRasterInet->InetGetHostName(hComputer, HOST_NAME_DESCRP);
   bstrText = m_pDlg->m_pRasterInet->GetInetHostName();
   //add to our list
   m_pDlg->m_pRasterInet->put_SendList(m_pDlg->m_pRasterInet->SendListNum, hComputer);
   strText = bstrText;
   lstrcpy(szHostName, (LPCTSTR)strText);
   ::SysFreeString(bstrText);
   cs.Format(TEXT("Connection accepted from:%s"), strText);
   AfxMessageBox(cs);
}

16.

Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

In the Class name combo box, select CServerDlg.

 

b.

In the Object IDs list box, select CServerDlg.

 

c.

In the Messages list box, select WM_DESTROY.

 

d.

Click the Add function button. Choose OK for the default function name (OnDestroy).

 

e.

Click the Edit Code button to start entering the code.

17.

Enter new code as follows:

//Terminate a connection between source and sink.
LPUNKNOWN pInetUnkSink = m_pRasterInetSink->GetIDispatch(FALSE);
AfxConnectionUnadvise(m_pRasterInet, DIID__LTRASINETEvents,
pInetUnkSink, FALSE, m_dwInetCookie);
delete m_pRasterInetSink;
m_pRasterInet->Release();
CDialog::OnDestroy(); 

18.

Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

Click the Message Maps tab.

 

b.

In the Class Name combo box, select CServerDlg.

 

c.

In the Object IDs list box, select IDC_SERVERINIT.

 

d.

In the Messages list box, select BN_CLICKED.

 

e.

Click the Add function button. Choose OK for the default function name (OnServerInit).

 

f.

Click the Edit Code button and code the OnServerInit procedure as follows:

int nRet;
CString cs;
m_pRasterInet->EnableMethodErrors = FALSE;
/* initialize server on port 1000 */
nRet = m_pRasterInet->InetServerInit(1000);
iServer = m_pRasterInet->GetInetServerHandle();

if(nRet != 0)
{
   cs.Format(TEXT("%s %d\n"),TEXT("Error initializing server:"), nRet);
   AfxMessageBox(cs);
}

19.

Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

Click the Message Maps tab.

 

b.

In the Class Name combo box, select CServerDlg.

 

c.

In the Object IDs list box, select IDCANCEL.

 

d.

In the Messages list box, select BN_CLICKED.

 

e.

Click the Add function button. Choose OK for the default function name (OnCancel).

 

f.

Click the Edit Code button and code the OnCancel procedure as follows:

int i, num;
/* disconnect all connections */
num = m_pRasterInet->GetConnectListNum();
for(i = 0; i < num; i++)
{
   m_pRasterInet->InetDisconnect(m_pRasterInet->GetConnectList(i));
}
CDialog::OnCancel();

20.

Edit the Server.CPP file and add the following code as the first line in the InitInstance function:

CoInitialize(NULL);

21.

Edit the Server.CPP file and add the following code as the next to last line in the InitInstance function (before the return)!:

CoUninitialize();

22.

On the main menu, select Build> Build server.exe to build the project.

23.

On the main menu, select Build> Execute server.exe to run the project.