Connecting to a Remote Computer (Visual C++ 5.0 and later)

Take the following steps to start a project and to add some code that will let you connect to a remote computer that is acting as a server.

1.

Run the server executable you created in Initializing a Computer as a Server and Accepting Connections.

2.

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

 

d.

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

 

e.

Click the OK button.

3.

In the Step 1 dialog box, do the following:

 

a.

Select Dialog based.

 

b.

Click the Next button.

4.

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.

5.

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.

6.

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

7.

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

8.

Add the L_OcxErr.H, and Ltnetocx.h files, to your project as follows:

 

a.

Copy the L_ocx40.h, l_ocxerr.h, and Ltnetocx.h files to your project directory, from the \lead\include\ directory.

 

b.

In the Project Workspace, click the FileView tab.

 

c.

Double-click the remote files folder to open it.

 

d.

Double-click the Dependencies folder (the Header Files folder in 5.0) to open it.

 

e.

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

 

f.

Add the following lines to the end of the file:

#include "L_OCX40.H"
#include "Ltnetocx.h"

9.

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

 

a.

Copy the l_ocxerr.h file to your project directory, from the \lead\include\ directory.

 

b.

In the Project Workspace, click the FileView tab.

 

c.

Double-click the remote files folder to open it.

 

d.

Double-click the Header Files folder to open it.

 

e.

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

 

f.

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\\ltrnt14n.dll" no_namespace, named_guids
#include "L_OCXERR.H"

10.

Add an Edit box control to the main window and give it the following ID:

 

ID

 

IDC_Remote

11.

Add two command buttons to the main window and set the ID and Caption properties as follows:

 

ID

Caption

 

IDC_CONNECT

Connect To Remote

 

IDC_DISCONNECT

Disconnect From Remote

12.

Do the following to add m_Remote to the CRemoteDlg class and link the variable using dynamic data exchange:

 

a.

Press Ctrl-W. (The MFC ClassWizard dialog box appears.)

 

b.

Click the Member Variables tab.

 

c.

In the Class Name box, select CRemoteDlg.

 

d.

In the Control IDs list, select IDC_Remote.

 

e.

Click the Add Variable... button.

 

f.

Specify m_Remote as the variable name, and control as the category.

 

g.

Click OK to close the dialog box, and click OK to close the MFC ClassWizard.

13.

 

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

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

14.

Add the following code to the OnInitDialog procedure in the RemoteDlg.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(); 

15.

Edit the RemoteDlg.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); 

16.

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 CRemoteDlg;

 

i.

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

// Attributes
public:
   CRemoteDlg *m_pDlg;

 

j.

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

#include "RemoteDlg.h"

17.

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

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the remote 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"

18.

Edit the header for the Sink class:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the remote 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 OnInetConnected(short);afx_msg void OnInetDisconnected(short);

19.

Edit the source for the Sink class:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the remote 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,"InetConnected",3,OnInetConnected,VT_EMPTY,VTS_I2)
DISP_FUNCTION_ID(CRasterInetSink,"InetDisconnected",4,OnInetDisconnected,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::OnInetConnected (short iComputer)
{
   TCHAR szHostName[80];
   BSTR bstrText;
   CString strText;
   CString cs;

   //add this connection to our SendList
   m_pDlg->m_pRasterInet->put_SendList(m_pDlg->m_pRasterInet->SendListNum, iComputer);

   m_pDlg->m_pRasterInet->InetGetHostName(iComputer, HOST_NAME_DESCRP);
   bstrText = m_pDlg->m_pRasterInet->GetInetHostName();

   strText = bstrText;
   lstrcpy(szHostName, (LPCTSTR)strText);
   cs.Format(TEXT("Connected to:%s"), strText);
   AfxMessageBox(cs);
   ::SysFreeString(bstrText);
}

void CRasterInetSink::OnInetDisconnected(short iComputer)
{
   AfxMessageBox(TEXT("Disconnected from remote computer"));
}

20.

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

 

a.

In the Class name combo box, select CRemoteDlg.

 

b.

In the Object IDs list box, select CRemoteDlg.

 

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.

21.

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(); 

22.

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

 

c.

In the Object IDs list box, select IDC_CONNECT.

 

d.

In the Messages list box, select BN_CLICKED.

 

e.

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

 

f.

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

int nRet;
CString cs,text;

m_pRasterInet->EnableMethodErrors = FALSE;
/* get the name of the computer entered in the edit box control */
m_Remote.GetWindowText(text);
/* Connect to remote computer on port 1000 */
BSTR bstrtext = text.AllocSysString();
nRet = m_pRasterInet->InetConnect(bstrtext, 1000);
SysFreeString(bstrtext);
if (nRet != 0)
{
   cs.Format(TEXT(" %s\n %s\n"), TEXT("Error connecting to :"), text);
   AfxMessageBox(cs);
}

23.

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

 

c.

In the Object IDs list box, select IDC_DISCONNECT.

 

d.

In the Messages list box, select BN_CLICKED.

 

e.

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

 

f.

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

int nRet;
CString cs;
/* We are assuming only one connection in this example.
Therefore, the handle to the remote computer will be
in the first position in the SendList.
*/
nRet = m_pRasterInet->InetDisconnect(m_pRasterInet->GetSendList(0));
if (nRet != 0)
{
   cs.Format(TEXT("%s %d\n"), TEXT("Error disconnecting from the server:"),nRet);
   AfxMessageBox(cs);
}

24.

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

CoInitialize(NULL);

25.

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

CoUninitialize();

26.

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

27.

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

28.

Save the object to use as a starting point for other tasks in the tutorials.