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