⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsockserverctl.cpp

📁 基于组态开发的VC源码
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////
//	Author				:	Bala Murali
//	XSockServerCtl.cpp	:	Implementation of the CXSockServerCtrl ActiveX Control class.
//	Creation Date		:	03/09/2000
//	Version				:	Initial Release
/////////////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "XSockServer.h"
#include "XSockServerCtl.h"
#include "XSockServerPpg.h"


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

CXSockServerCtrl* m_pControl = NULL;

IMPLEMENT_DYNCREATE(CXSockServerCtrl, COleControl)


/////////////////////////////////////////////////////////////////////////////
// Message map

BEGIN_MESSAGE_MAP(CXSockServerCtrl, COleControl)
	//{{AFX_MSG_MAP(CXSockServerCtrl)
	//}}AFX_MSG_MAP
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Dispatch map

BEGIN_DISPATCH_MAP(CXSockServerCtrl, COleControl)
	//{{AFX_DISPATCH_MAP(CXSockServerCtrl)
	DISP_PROPERTY_EX(CXSockServerCtrl, "LocalAddress", GetLocalAddress, SetLocalAddress, VT_BSTR)
	DISP_PROPERTY_EX(CXSockServerCtrl, "LocalPort", GetLocalPort, SetLocalPort, VT_I4)
	DISP_PROPERTY_EX(CXSockServerCtrl, "NullTerminate", GetNullTerminate, SetNullTerminate, VT_BOOL)
	DISP_PROPERTY_EX(CXSockServerCtrl, "ReceiveBufferCount", GetReceiveBufferCount, SetReceiveBufferCount, VT_I4)
	DISP_FUNCTION(CXSockServerCtrl, "Listen", Listen, VT_BOOL, VTS_NONE)
	DISP_FUNCTION(CXSockServerCtrl, "Send", Send, VT_BOOL, VTS_I4 VTS_BSTR VTS_I4)
	DISP_FUNCTION(CXSockServerCtrl, "Close", Close, VT_EMPTY, VTS_NONE)
	//}}AFX_DISPATCH_MAP
	DISP_FUNCTION_ID(CXSockServerCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()


/////////////////////////////////////////////////////////////////////////////
// Event map

BEGIN_EVENT_MAP(CXSockServerCtrl, COleControl)
	//{{AFX_EVENT_MAP(CXSockServerCtrl)
	EVENT_CUSTOM("OnError", FireOnError, VTS_BSTR)
	EVENT_CUSTOM("OnClose", FireOnClose, VTS_I4)
	EVENT_CUSTOM("OnReceive", FireOnReceive, VTS_I4  VTS_BSTR  VTS_I4)
	EVENT_CUSTOM("OnAccept", FireOnAccept, VTS_I4)
	//}}AFX_EVENT_MAP
END_EVENT_MAP()


/////////////////////////////////////////////////////////////////////////////
// Property pages

// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CXSockServerCtrl, 1)
	PROPPAGEID(CXSockServerPropPage::guid)
END_PROPPAGEIDS(CXSockServerCtrl)


/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid

IMPLEMENT_OLECREATE_EX(CXSockServerCtrl, "XSOCKSERVER.XSockServerCtrl.1",
	0xf85053f6, 0xdd8f, 0x11d3, 0xb4, 0xaf, 0, 0xc0, 0x4f, 0x2b, 0x30, 0xe)


/////////////////////////////////////////////////////////////////////////////
// Type library ID and version

IMPLEMENT_OLETYPELIB(CXSockServerCtrl, _tlid, _wVerMajor, _wVerMinor)


/////////////////////////////////////////////////////////////////////////////
// Interface IDs

const IID BASED_CODE IID_DXSockServer =
		{ 0xf85053f4, 0xdd8f, 0x11d3, { 0xb4, 0xaf, 0, 0xc0, 0x4f, 0x2b, 0x30, 0xe } };
const IID BASED_CODE IID_DXSockServerEvents =
		{ 0xf85053f5, 0xdd8f, 0x11d3, { 0xb4, 0xaf, 0, 0xc0, 0x4f, 0x2b, 0x30, 0xe } };


/////////////////////////////////////////////////////////////////////////////
// Control type information

static const DWORD BASED_CODE _dwXSockServerOleMisc =
	OLEMISC_ACTIVATEWHENVISIBLE |
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CXSockServerCtrl, IDS_XSOCKSERVER, _dwXSockServerOleMisc)


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::CXSockServerCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CXSockServerCtrl

BOOL CXSockServerCtrl::CXSockServerCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO: Verify that your control follows apartment-model threading rules.
	// Refer to MFC TechNote 64 for more information.
	// If your control does not conform to the apartment-model rules, then
	// you must modify the code below, changing the 6th parameter from
	// afxRegApartmentThreading to 0.

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_XSOCKSERVER,
			IDB_XSOCKSERVER,
			afxRegApartmentThreading,
			_dwXSockServerOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::CXSockServerCtrl - Constructor

CXSockServerCtrl::CXSockServerCtrl(): m_bListen(FALSE),
									  m_LocalPort(0),
									  m_bNullTerminate(TRUE),
									  m_nBuffLen(4096)
{
	InitializeIIDs(&IID_DXSockServer, &IID_DXSockServerEvents);
	m_pControl = this;
	m_bitmap.LoadBitmap(IDB_XSOCKSERVER);
	m_lpBuff = new char[m_nBuffLen+1];// +1 is for adding NULL.
}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::~CXSockServerCtrl - Destructor

CXSockServerCtrl::~CXSockServerCtrl()
{
	DeleteList();
	delete[] m_lpBuff;
}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::OnDraw - Drawing function

void CXSockServerCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
	BITMAP bm;
	m_bitmap.GetObject (sizeof(BITMAP),&bm);
	CPoint size(bm.bmWidth,bm.bmHeight);
	pdc->DPtoLP(&size);

	CPoint org(0,0);
	pdc->DPtoLP(&org);

	CDC dcMem;
	dcMem.CreateCompatibleDC(pdc);
	CBitmap* pOldBitmap = dcMem.SelectObject(&m_bitmap);
	dcMem.SetMapMode (pdc->GetMapMode ());

//	pdc->StretchBlt(0, 0, rcBounds.Width(), rcBounds.Height(), &dcMem, org.x, org.y, size.x, size.y, SRCCOPY);
	pdc->BitBlt (0, 0, size.x, size.y, &dcMem, org.x, org.y, SRCCOPY);

	dcMem.SelectObject(pOldBitmap);

}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::DoPropExchange - Persistence support

void CXSockServerCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	PX_String(pPX, "LocalAddress", m_LocalAddress, _T(""));
	PX_Long(pPX, "LocalPort", m_LocalPort,0);
	PX_Bool(pPX,"NullTerminate",m_bNullTerminate);
	PX_Long(pPX, "ReceiveBufferCount", m_nBuffLen,4096);
}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::OnResetState - Reset control to default state

void CXSockServerCtrl::OnResetState()
{
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange
}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl::AboutBox - Display an "About" box to the user

void CXSockServerCtrl::AboutBox()
{
	CDialog dlgAbout(IDD_ABOUTBOX_XSOCKSERVER);
	dlgAbout.DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CXSockServerCtrl message handlers

BSTR CXSockServerCtrl::GetLocalAddress() 
{
	CString strResult = m_LocalAddress;
	return strResult.AllocSysString();
}

void CXSockServerCtrl::SetLocalAddress(LPCTSTR lpszNewValue) 
{
	m_LocalAddress = lpszNewValue;
	SetModifiedFlag();
}


long CXSockServerCtrl::GetLocalPort() 
{
	return m_LocalPort;
}

void CXSockServerCtrl::SetLocalPort(long nNewValue) 
{
	m_LocalPort = nNewValue;
	SetModifiedFlag();
}

BOOL CXSockServerCtrl::Listen() 
{
	if ( !m_bListen )
	{
		if ( !m_ListenS.Create(m_LocalPort, SOCK_STREAM, 
				FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, 
				m_LocalAddress) ) {
				if ( !SocketError() )
					return FALSE;
		}

		m_bListen = TRUE;

		if ( !m_ListenS.Listen() )
			return SocketError();
	}

	return TRUE;
}


void CXSockServerCtrl::Close() 
{
	m_ListenS.Close();
	m_bListen = FALSE;
}

BOOL CXSockServerCtrl::SocketError( )
{
	int nErrorCode = GetLastError( );
	if ( nErrorCode == WSAEWOULDBLOCK )
		return TRUE;

	SocketError(nErrorCode);
	return FALSE;
}

void CXSockServerCtrl::SocketError(int nErrorCode)
{
	CString strError;
	
	switch(nErrorCode)
	{
	case WSANOTINITIALISED:
		strError = "A successful AfxSocketInit must occur before using this API";
		break;

	case WSAENETDOWN:
		strError = "The Windows Sockets implementation detected that the network subsystem failed";
		break;

	case WSAEAFNOSUPPORT:
		strError = "The specified address family is not supported";
		break;

	case WSAEINPROGRESS:
		strError = "A blocking Windows Sockets operation is in progress";
		break;

	case WSAEPROTONOSUPPORT:
		strError = "The specified port is not supported";
		break;

	case WSAEPROTOTYPE:
		strError = "The specified port is the wrong type for this socket";
		break;

	case WSAESOCKTNOSUPPORT:
		strError = "The specified socket type is not supported in this address family";
		break;

	case WSAEACCES: 
		strError = "The requested address is a broadcast address, but the appropriate flag was not set";
		break;

	case WSAEFAULT: 
		strError = "The lpBuf argument is not in a valid part of the user address space";
		break;

	case WSAENETRESET:
		strError = "The connection must be reset because the Windows Sockets implementation dropped it";
		break;

	case WSAEOPNOTSUPP:
		strError = "MSG_OOB was specified, but the socket is not of type SOCK_STREAM";
		break;

	case WSAESHUTDOWN:
		strError = "The socket has been shut down; it is not possible to call Send on a socket after ShutDown has been invoked with nHow set to 1 or 2";
		break;

	case WSAEMSGSIZE:
		strError = "The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum supported by the Windows Sockets implementation";
		break;

	case WSAEINVAL:
		strError = "The socket has not been bound with Bind or The socket is already bound to an address";
		break;

	case WSAECONNABORTED:
		strError = "The virtual circuit was aborted due to timeout or other failure";
		break;

	case WSAECONNRESET:
		strError = "The virtual circuit was reset by the remote side";
		break;

	case WSAEADDRINUSE: 
		strError = "The specified address is already in use";
		break;

	case WSAEADDRNOTAVAIL: 
		strError = "The specified address is not available from the local machine";
		break;

	case WSAECONNREFUSED: 
		strError = "The attempt to connect was forcefully rejected";
		break;

	case WSAEDESTADDRREQ: 
		strError = "A destination address is required";
		break;

	case WSAEISCONN: 
		strError = "The socket is already connected";
		break;

	case WSAEMFILE: 
		strError = "No more file descriptors are available";
		break;

	case WSAENETUNREACH: 
		strError = "The network cannot be reached from this host at this time";
		break;

	case WSAENOBUFS: 
		strError = "No buffer space is available. The socket cannot be connected";
		break;

	case WSAENOTCONN: 
		strError = "The socket is not connected";
		break;

	case WSAENOTSOCK: 
		strError = "The descriptor is a file, not a socket";
		break;

	case WSAETIMEDOUT: 
		strError = "The attempt to connect timed out without establishing a connection";
		break;

	default:
			break;
	}

	FireOnError(strError);
}

BOOL CXSockServerCtrl::GetNullTerminate() 
{
	return m_bNullTerminate ;
}

void CXSockServerCtrl::SetNullTerminate(BOOL bNewValue) 
{
	m_bNullTerminate = bNewValue;
	SetModifiedFlag();
}

BOOL CXSockServerCtrl::Send(long lChildId, LPCTSTR lpData, long nDataLen) 
{
	CConnectS* pTemp = NULL;
	long nTotalByteSent = 0;
	long nByteSent = 0;
	long nByteLen = nDataLen;

	if (pTemp = GetConnectSObject(lChildId) )
	{
		while ( nTotalByteSent < nDataLen )
		{
			if ( (nByteSent = pTemp->Send(lpData, nByteLen)) == SOCKET_ERROR )
				return FALSE;

			nTotalByteSent += nByteSent;
			lpData += nByteSent;	// Discard the Buffer already sent
			nByteLen -= nByteSent;	// Reduce the Buffer length by bytes sent
		}

	}

	return TRUE;
}


CConnectS* CXSockServerCtrl::GetConnectSObject(long lChildId)
{
	CConnectS* pTemp = NULL;

	if (m_list.IsEmpty()== NULL)
	{
		POSITION pos = m_list.GetHeadPosition();
		UINT count	 = m_list.GetCount();

		for (UINT index=0; index<count; index++ )
		{
			pTemp  = m_list.GetNext(pos);

			if ( lChildId == pTemp->m_lChildId)
			{
					return pTemp;
			}	
		}	
	}	

	return pTemp;		// Method Failed, returns NULL at this point
}

void CXSockServerCtrl::DeleteList()
{
	POSITION pos = m_list.GetHeadPosition();
	while (pos != NULL)
	{
		delete m_list.GetNext(pos);
	}

	m_list.RemoveAll();
}

long CXSockServerCtrl::GetReceiveBufferCount() 
{
	return m_nBuffLen;
}

void CXSockServerCtrl::SetReceiveBufferCount(long nNewValue) 
{
	if ( nNewValue != 0 )
	{
		m_nBuffLen = nNewValue;
		delete[] m_lpBuff;
		m_lpBuff = new char[m_nBuffLen+1];// +1 is for NULL terminated strings
		SetModifiedFlag();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -