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

📄 xsockclientctl.cpp

📁 組态软件设计与开发的配套源代码
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////
//	Author				:	Bala Murali
//	XSockClientCtl.cpp	:	Implementation of the CXSockClientCtrl ActiveX Control class.
//	Creation Date		:	03/09/2000
//	Version				:	Initial Release
/////////////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "XSockClient.h"
#include "XSockClientCtl.h"
#include "XSockClientPpg.h"


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


CXSockClientCtrl* m_pControl = NULL;

IMPLEMENT_DYNCREATE(CXSockClientCtrl, COleControl)


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

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


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

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


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

BEGIN_EVENT_MAP(CXSockClientCtrl, COleControl)
	//{{AFX_EVENT_MAP(CXSockClientCtrl)
	EVENT_CUSTOM("OnConnect", FireOnConnect, VTS_NONE)
	EVENT_CUSTOM("OnClose", FireOnClose, VTS_NONE)
	EVENT_CUSTOM("OnSend", FireOnSend, VTS_NONE)
	EVENT_CUSTOM("OnError", FireOnError, VTS_BSTR)
	EVENT_CUSTOM("OnReceive", FireOnReceive, VTS_BSTR  VTS_I4)
	//}}AFX_EVENT_MAP
END_EVENT_MAP()


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

BEGIN_PROPPAGEIDS(CXSockClientCtrl, 1)
	PROPPAGEID(CXSockClientPropPage::guid)
END_PROPPAGEIDS(CXSockClientCtrl)


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

IMPLEMENT_OLECREATE_EX(CXSockClientCtrl, "XSOCKCLIENT.XSockClientCtrl.1",
	0x2328f294, 0xdd85, 0x11d3, 0xb4, 0xaf, 0, 0xc0, 0x4f, 0x2b, 0x30, 0xe)


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

IMPLEMENT_OLETYPELIB(CXSockClientCtrl, _tlid, _wVerMajor, _wVerMinor)


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

const IID BASED_CODE IID_DXSockClient =
		{ 0x2328f292, 0xdd85, 0x11d3, { 0xb4, 0xaf, 0, 0xc0, 0x4f, 0x2b, 0x30, 0xe } };
const IID BASED_CODE IID_DXSockClientEvents =
		{ 0x2328f293, 0xdd85, 0x11d3, { 0xb4, 0xaf, 0, 0xc0, 0x4f, 0x2b, 0x30, 0xe } };


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

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

IMPLEMENT_OLECTLTYPE(CXSockClientCtrl, IDS_XSOCKCLIENT, _dwXSockClientOleMisc)


/////////////////////////////////////////////////////////////////////////////
// CXSockClientCtrl::CXSockClientCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CXSockClientCtrl

BOOL CXSockClientCtrl::CXSockClientCtrlFactory::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_XSOCKCLIENT,
			IDB_XSOCKCLIENT,
			afxRegApartmentThreading,
			_dwXSockClientOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


/////////////////////////////////////////////////////////////////////////////
// CXSockClientCtrl::CXSockClientCtrl - Constructor

CXSockClientCtrl::CXSockClientCtrl():m_bConnect(FALSE),m_nBuffLen(4096),
									 m_RemotePort(0),m_LocalPort(0),m_bNullTerminate(TRUE)
{
	InitializeIIDs(&IID_DXSockClient, &IID_DXSockClientEvents);
	m_pControl = this;
	m_lpBuff = new char[m_nBuffLen+1]; // +1 is for NULL terminated strings
	m_bitmap.LoadBitmap(IDB_XSOCKCLIENT);
}


/////////////////////////////////////////////////////////////////////////////
// CXSockClientCtrl::~CXSockClientCtrl - Destructor

CXSockClientCtrl::~CXSockClientCtrl()
{
	delete[] m_lpBuff;
}


/////////////////////////////////////////////////////////////////////////////
// CXSockClientCtrl::OnDraw - Drawing function

void CXSockClientCtrl::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);

}

/////////////////////////////////////////////////////////////////////////////
// CXSockClientCtrl::DoPropExchange - Persistence support

void CXSockClientCtrl::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);
}


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

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


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

void CXSockClientCtrl::AboutBox()
{
	CDialog dlgAbout(IDD_ABOUTBOX_XSOCKCLIENT);
	dlgAbout.DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CXSockClientCtrl message handlers

void CXSockClientCtrl::Close() 
{
	m_ConnectS.Close();
	m_bConnect = FALSE;
}


BOOL CXSockClientCtrl::Connect(LPCTSTR lpRemoteAddress, long nRemotePort ) 
{
	if ( !m_bConnect )
	{
		if ( !m_ConnectS.Create(m_LocalPort, SOCK_STREAM, 
				FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, 
				m_LocalAddress) ) {
				if ( !SocketError() )
					return FALSE;
			}
		
		m_bConnect = TRUE;

		if ( !m_ConnectS.Connect(lpRemoteAddress,nRemotePort) ) {
			return SocketError();
			}
	}

	return FALSE;
}


BOOL CXSockClientCtrl::Send(LPCTSTR lpData, long nDataLen) 
{
	long nTotalByteSent = 0;
	long nByteSent = 0;
	long nByteLen = nDataLen;

	while ( nTotalByteSent < nDataLen )
	{
		if ( (nByteSent = m_ConnectS.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;
}


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

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

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

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


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

	SocketError(nErrorCode);
	return FALSE;
}

void CXSockClientCtrl::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;
	}

	m_pControl->FireOnError(strError);
}


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

void CXSockClientCtrl::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();
	}
}



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

void CXSockClientCtrl::SetNullTerminate(BOOL bNewValue) 
{
	m_bNullTerminate = bNewValue;

	SetModifiedFlag();
}

⌨️ 快捷键说明

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