#if !defined(AFX_MFCWINSOCKCTL_H__7A7BCC5B_ED8C_40E3_AF64_316758B53655__INCLUDED_)
#define AFX_MFCWINSOCKCTL_H__7A7BCC5B_ED8C_40E3_AF64_316758B53655__INCLUDED_#if _MSC_VER > 1000
#pragma once
SOCKET OnlySock;//建立的唯一Socket,不允许重复建立多个
bool isOnlyConnect;//是否建立了连接
#endif // _MSC_VER > 1000// MFCWinSockCtl.h : Declaration of the CMFCWinSockCtrl ActiveX Control class./////////////////////////////////////////////////////////////////////////////
// CMFCWinSockCtrl : See MFCWinSockCtl.cpp for implementation.class CMFCWinSockCtrl : public COleControl
{
DECLARE_DYNCREATE(CMFCWinSockCtrl)
// Constructor
public:
CMFCWinSockCtrl();// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMFCWinSockCtrl)
public:
virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
virtual void DoPropExchange(CPropExchange* pPX);
virtual void OnResetState();
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL// Implementation
protected:
~CMFCWinSockCtrl(); DECLARE_OLECREATE_EX(CMFCWinSockCtrl)    // Class factory and guid
DECLARE_OLETYPELIB(CMFCWinSockCtrl)      // GetTypeInfo
DECLARE_PROPPAGEIDS(CMFCWinSockCtrl)     // Property page IDs
DECLARE_OLECTLTYPE(CMFCWinSockCtrl) // Type name and misc status// Message maps
//{{AFX_MSG(CMFCWinSockCtrl)
// NOTE - ClassWizard will add and remove member functions here.
//    DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()// Dispatch maps
//{{AFX_DISPATCH(CMFCWinSockCtrl)
afx_msg BOOL Connect(const VARIANT FAR& RemoteHost, const VARIANT FAR& RemotePort);
afx_msg BOOL DisConnect(const VARIANT FAR& RemoteHost, const VARIANT FAR& RemotePort);
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP() afx_msg void AboutBox();// Event maps
//{{AFX_EVENT(CMFCWinSockCtrl)
void FireCloseWinsock()
{FireEvent(eventidCloseWinsock,EVENT_PARAM(VTS_NONE));}
void FireRecvSockEvent()
{FireEvent(eventidRecvSockEvent,EVENT_PARAM(VTS_NONE));}
//}}AFX_EVENT
DECLARE_EVENT_MAP()// Dispatch and event IDs
public:
enum {
//{{AFX_DISP_ID(CMFCWinSockCtrl)
dispidConnect = 1L,
dispidDisConnect = 2L,
eventidCloseWinsock = 1L,
eventidRecvSockEvent = 2L,
//}}AFX_DISP_ID
};
};//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MFCWINSOCKCTL_H__7A7BCC5B_ED8C_40E3_AF64_316758B53655__INCLUDED)
=======================================================错误如下MFCWinSockCtl.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\MFCWinSock\MFCWinSockCtl.cpp(196) : error C2039: 'VariantToLong' : is not a member of 'CMFCWinSockCtrl'
        c:\program files\microsoft visual studio\myprojects\mfcwinsock\mfcwinsockctl.h(15) : see declaration of 'CMFCWinSockCtrl'
Error executing cl.exe.求助如何建立MFCWinSockCtrl下的VariantToLong Member函数定义谢谢WinsockMFC

解决方案 »

  1.   

    'VariantToLong' 
    你看这个变量是干什么用的,会不会这个变量写错了好象应该定义成variant vt;vt.VT_XX这么引用(XX是类型)
      

  2.   


    //类型转换,将VARIANT类型转换成Long类型
    long CMFCWinSockCtrl::VariantToLong(const VARIANT &var)
    {
    long r;
    switch(var.vt)
    {
    case VT_UI2://USHORT
    r = var.uiVal;
    break;
    case VT_UI4://ULONG
    r = var.ulVal;
    break;
    case VT_INT://INT
    r = var.intVal;
    break;
    case VT_UINT://UINT
    r = var.uintVal;
    break;
    case VT_I4://LONG
    r = var.lVal;
    break;
    case VT_UI1://BYTE
    r = var.bVal;
    break;
    case VT_I2://SHORT
    r = var.iVal;
    break;
    case VT_R4://FLOAT
    r = (long)var.fltVal;
    break;
    case VT_R8://DOUBLE
    r = (long)var.dblVal;
    break;
    default:
    r = -1;//无法转换该值
    break;
    }
    return r;
    }就是将VARIANT类型转换成Long类型的一个变量
      

  3.   

    // MFCWinSockCtl.cpp : Implementation of the CMFCWinSockCtrl ActiveX Control class.#include "stdafx.h"
    #include "MFCWinSock.h"
    #include "MFCWinSockCtl.h"
    #include "MFCWinSockPpg.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #ifndef WM_MYWINSOCK 
    #define WM_MYWINSOCK WM_USER+1888
    #endif
    IMPLEMENT_DYNCREATE(CMFCWinSockCtrl, COleControl)
    /////////////////////////////////////////////////////////////////////////////
    // Message mapBEGIN_MESSAGE_MAP(CMFCWinSockCtrl, COleControl)
    //{{AFX_MSG_MAP(CMFCWinSockCtrl)
    // NOTE - ClassWizard will add and remove message map entries
    //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG_MAP
    ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
    END_MESSAGE_MAP()
    /////////////////////////////////////////////////////////////////////////////
    // Dispatch mapBEGIN_DISPATCH_MAP(CMFCWinSockCtrl, COleControl)
    //{{AFX_DISPATCH_MAP(CMFCWinSockCtrl)
    DISP_FUNCTION(CMFCWinSockCtrl, "Connect", Connect, VT_BOOL, VTS_VARIANT VTS_VARIANT)
    DISP_FUNCTION(CMFCWinSockCtrl, "DisConnect", DisConnect, VT_BOOL, VTS_VARIANT VTS_VARIANT)
    //}}AFX_DISPATCH_MAP
    DISP_FUNCTION_ID(CMFCWinSockCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
    END_DISPATCH_MAP()
    /////////////////////////////////////////////////////////////////////////////
    // Event mapBEGIN_EVENT_MAP(CMFCWinSockCtrl, COleControl)
    //{{AFX_EVENT_MAP(CMFCWinSockCtrl)
    EVENT_CUSTOM("CloseWinsock", FireCloseWinsock, VTS_NONE)
    EVENT_CUSTOM("RecvSockEvent", FireRecvSockEvent, VTS_NONE)
    //}}AFX_EVENT_MAP
    END_EVENT_MAP()
    /////////////////////////////////////////////////////////////////////////////
    // Property pages// TODO: Add more property pages as needed.  Remember to increase the count!
    BEGIN_PROPPAGEIDS(CMFCWinSockCtrl, 1)
    PROPPAGEID(CMFCWinSockPropPage::guid)
    END_PROPPAGEIDS(CMFCWinSockCtrl)
    /////////////////////////////////////////////////////////////////////////////
    // Initialize class factory and guidIMPLEMENT_OLECREATE_EX(CMFCWinSockCtrl, "MFCWINSOCK.MFCWinSockCtrl.1",
    0x5d833b39, 0xb6f8, 0x4a8f, 0x9f, 0x95, 0xd4, 0xb4, 0x9c, 0x87, 0xae, 0x6b)
    /////////////////////////////////////////////////////////////////////////////
    // Type library ID and versionIMPLEMENT_OLETYPELIB(CMFCWinSockCtrl, _tlid, _wVerMajor, _wVerMinor)
    /////////////////////////////////////////////////////////////////////////////
    // Interface IDsconst IID BASED_CODE IID_DMFCWinSock =
    { 0xf6581081, 0x679c, 0x4538, { 0x85, 0xcb, 0x99, 0x4c, 0x2, 0xcd, 0xa6, 0x8a } };
    const IID BASED_CODE IID_DMFCWinSockEvents =
    { 0xf67d10a, 0x33d1, 0x49e8, { 0xa1, 0xef, 0xf, 0xb3, 0xef, 0xc3, 0x53, 0x1f } };
    /////////////////////////////////////////////////////////////////////////////
    // Control type informationstatic const DWORD BASED_CODE _dwMFCWinSockOleMisc =
    OLEMISC_ACTIVATEWHENVISIBLE |
    OLEMISC_SETCLIENTSITEFIRST |
    OLEMISC_INSIDEOUT |
    OLEMISC_CANTLINKINSIDE |
    OLEMISC_RECOMPOSEONRESIZE;IMPLEMENT_OLECTLTYPE(CMFCWinSockCtrl, IDS_MFCWINSOCK, _dwMFCWinSockOleMisc)
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::CMFCWinSockCtrlFactory::UpdateRegistry -
    // Adds or removes system registry entries for CMFCWinSockCtrl
    //类型转换,将VARIANT类型转换成Long类型
    long CMFCWinSockCtrl::VariantToLong(const VARIANT &var)
    {
    long r;
    switch(var.vt)
    {
    case VT_UI2://USHORT
    r = var.uiVal;
    break;
    case VT_UI4://ULONG
    r = var.ulVal;
    break;
    case VT_INT://INT
    r = var.intVal;
    break;
    case VT_UINT://UINT
    r = var.uintVal;
    break;
    case VT_I4://LONG
    r = var.lVal;
    break;
    case VT_UI1://BYTE
    r = var.bVal;
    break;
    case VT_I2://SHORT
    r = var.iVal;
    break;
    case VT_R4://FLOAT
    r = (long)var.fltVal;
    break;
    case VT_R8://DOUBLE
    r = (long)var.dblVal;
    break;
    default:
    r = -1;//无法转换该值
    break;
    }
    return r;
    }
    BOOL CMFCWinSockCtrl::CMFCWinSockCtrlFactory::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_MFCWINSOCK,
    IDB_MFCWINSOCK,
    afxRegApartmentThreading,
    _dwMFCWinSockOleMisc,
    _tlid,
    _wVerMajor,
    _wVerMinor);
    else
    return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
    }
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::CMFCWinSockCtrl - Constructor
    CMFCWinSockCtrl::CMFCWinSockCtrl()
    {
    InitializeIIDs(&IID_DMFCWinSock, &IID_DMFCWinSockEvents); // TODO: Initialize your control's instance data here.
    }
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::~CMFCWinSockCtrl - DestructorCMFCWinSockCtrl::~CMFCWinSockCtrl()
    {
    // TODO: Cleanup your control's instance data here.
    }
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::OnDraw - Drawing functionvoid CMFCWinSockCtrl::OnDraw(
    CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
    {
    // TODO: Replace the following code with your own drawing code.
    pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
    pdc->Ellipse(rcBounds);
    }
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::DoPropExchange - Persistence supportvoid CMFCWinSockCtrl::DoPropExchange(CPropExchange* pPX)
    {
    ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
    COleControl::DoPropExchange(pPX); // TODO: Call PX_ functions for each persistent custom property.}
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::OnResetState - Reset control to default statevoid CMFCWinSockCtrl::OnResetState()
    {
    COleControl::OnResetState();  // Resets defaults found in DoPropExchange // TODO: Reset any other control state here.
    }
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl::AboutBox - Display an "About" box to the uservoid CMFCWinSockCtrl::AboutBox()
    {
    CDialog dlgAbout(IDD_ABOUTBOX_MFCWINSOCK);
    dlgAbout.DoModal();
    }
    /////////////////////////////////////////////////////////////////////////////
    // CMFCWinSockCtrl message handlersBOOL CMFCWinSockCtrl::Connect(const VARIANT FAR& RemoteHost, const VARIANT FAR& RemotePort) 
    {
    // TODO: Add your dispatch handler code here
    if(isOnlyConnect)//该连接已建立,还没有断开
    return FALSE;

    CString IPAddress;
    int Port;//转换成整型的端口

    switch(RemoteHost.vt)
    {
    case VT_BSTR://字符串型
    IPAddress = CString(RemoteHost.bstrVal);
    break;
    case VT_BYREF|VT_I1://CHAR *
    IPAddress.Format("%s",RemoteHost.pcVal);//RemoteHost.pbstrVal);
    break;
    default:
    IPAddress = "";
    return FALSE;
    }

    Port = VariantToLong(RemotePort);//我们编写的一个VARIANT转换成long类型的函数
    if(Port<=0)
    return FALSE;

    _TCHAR *ip = 0;
    struct hostent *host = 0;
    struct sockaddr_in addr;
    ULONG dotIP = inet_addr(IPAddress);

    OnlySock = socket(AF_INET, SOCK_STREAM, 0);

    // 判断是否为点IP地址格式
    if (OnlySock == INVALID_SOCKET)
    {
    shutdown(OnlySock, 0x02);
    closesocket(OnlySock);//释放占有的SOCK资源
    return FALSE;
    }

    memset(&addr, 0, sizeof(struct sockaddr_in));
    // 设定 SOCKADDR_IN 结构的内容
    // 如果通讯协议是选择IP Protocol,那此值固定为AF_INET
    // AF_INET 与 PF_INET 这两个常量值相同
    addr.sin_family = AF_INET;
    addr.sin_port = htons(Port);
    addr.sin_addr.S_un.S_addr = dotIP;
    if (dotIP == INADDR_NONE)
    {
    host = gethostbyname(IPAddress);
    if (!host)
    {
    shutdown(OnlySock, 0x02);
    closesocket(OnlySock);//释放占有的SOCK资源
    return FALSE;
    };
    ip = inet_ntoa(*(struct in_addr*)(*host->h_addr_list));
    addr.sin_addr.S_un.S_addr = inet_addr(ip);
    }

    //开始连线
    if (connect(OnlySock, (LPSOCKADDR)&addr, sizeof(SOCKADDR)))
    {
    shutdown(OnlySock, 0x02);
    closesocket(OnlySock);//释放占有的SOCK资源
    return FALSE;
    }

    int   iError = WSAAsyncSelect(OnlySock, m_hWnd,WM_MYWINSOCK, FD_READ|FD_CLOSE); //只对网络断开和数据到达通知感兴趣
    if(iError == SOCKET_ERROR)//无法绑定Winsock的事件通知
    {   
    shutdown(OnlySock, 0x02);
    closesocket(OnlySock);//释放占有的SOCK资源
    return FALSE;
    }  

    isOnlyConnect = true;
    return TRUE;
    }
          
    BOOL CMFCWinSockCtrl::DisConnect(const VARIANT FAR& RemoteHost, const VARIANT FAR& RemotePort) 
    {
    // TODO: Add your dispatch handler code here return TRUE;
    }            
    LRESULT CMFCWinSockCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
    switch(message)
    {
    case WM_MYWINSOCK://响应自定义的消息
    switch(WSAGETSELECTEVENT(lParam))
    {
    case FD_READ://有新数据到达
    FireRecvSockEvent();
    break;
    case FD_CLOSE://对方已断掉当前连接
    FireCloseWinsock();
    break;
    }
    break;
    default:
    break;
    }
    // TODO: Add your specialized code here and/or call the base class

    return COleControl::WindowProc(message, wParam, lParam);
    }
    #endif