📄 xsockserverctl.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 + -