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