www.gusucode.com > 用ActiveX重新包装了一个点对点通讯的DLL文件源码程序 > 用ActiveX重新包装了一个点对点通讯的DLL文件源码程序/P2P语音通信/VP2PCtrl.cpp
// VP2PCtrl.cpp : CVP2PCtrl ActiveX 控件类的实现。 /***************************************************** 作者:你家的玻璃不是我砸的@vckbase.com 联系方法:xiny120@hotmail.com BLOG:http://blog.vckbase.com/zaboli http://www.hotlove.cn 程序简介: 用ActiveX重新包装了一个点对点通讯的DLL文件(该DLL文件是VCKBASE上的一位前辈写的) 偶只是把它改成了一个MFC的ActiveX,这样可以方便的在VB,vbs,js等脚本语言,特别是用在IE 里面特别方便了。 此程序主要向你说明,其实ActiveX没有多么的神秘。你遵守的它的规则,什么功能都能添加到 ActiveX中,并且和写其它的普通的程序没有什么区别! 缺点:因为同时只能有一个程序打开音频设备,所以不能开两个实例进行聊天。本来打算改改好,只 发布成品ActiveX,不发布原代码的。可最近鸟事很多,没时间。。所以连源代码都贡献了~~~ 大家可以自己完善一下。如果您做了什么好的改进,请您给作者我发一份,我会十分感谢!!! ********************************************************/ #include "stdafx.h" #include "VP2P.h" #include "VP2PCtrl.h" #include "VP2PPropPage.h" #include ".\vp2pctrl.h" #include <comcat.h> #include "RecSocket.h" #ifdef _DEBUG #define new DEBUG_NEW #endif IMPLEMENT_DYNCREATE(CVP2PCtrl, COleControl) BEGIN_INTERFACE_MAP(CVP2PCtrl, COleControl) INTERFACE_PART(CVP2PCtrl, IID_IObjectSafety, ObjectSafety) END_INTERFACE_MAP() // 消息映射 BEGIN_MESSAGE_MAP(CVP2PCtrl, COleControl) ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit) ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) END_MESSAGE_MAP() // 调度映射 BEGIN_DISPATCH_MAP(CVP2PCtrl, COleControl) DISP_FUNCTION_ID(CVP2PCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE) DISP_FUNCTION_ID(CVP2PCtrl, "StartTalk", dispidStartTalk, StartTalk, VT_I4, VTS_BSTR VTS_I4 VTS_I4) DISP_FUNCTION_ID(CVP2PCtrl, "EndTalk", dispidEndTalk, EndTalk, VT_I4, VTS_NONE) DISP_FUNCTION_ID(CVP2PCtrl, "GetCtrlInfo", dispidGetCtrlInfo, GetCtrlInfo, VT_I4, VTS_PI1) DISP_PROPERTY_EX_ID(CVP2PCtrl, "strIP", dispidstrIP, GetstrIP, SetNotSupported, VT_BSTR) DISP_PROPERTY_EX_ID(CVP2PCtrl, "nTcpPort", dispidnTcpPort, GetnTcpPort, SetnTcpPort, VT_I4) DISP_PROPERTY_EX_ID(CVP2PCtrl, "nUdpPort", dispidnUdpPort, GetnUdpPort, SetnUdpPort, VT_I4) END_DISPATCH_MAP() // 事件映射 BEGIN_EVENT_MAP(CVP2PCtrl, COleControl) EVENT_CUSTOM_ID("me_OK", eventidme_OK, me_OK, VTS_I4 VTS_I4) END_EVENT_MAP() // 属性页 // TODO: 按需要添加更多属性页。请记住增加计数! BEGIN_PROPPAGEIDS(CVP2PCtrl, 1) PROPPAGEID(CVP2PPropPage::guid) END_PROPPAGEIDS(CVP2PCtrl) // 初始化类工厂和 guid IMPLEMENT_OLECREATE_EX(CVP2PCtrl, "VP2P.VP2PCtrl.1", 0xd3921f23, 0xa058, 0x46e1, 0x8b, 0x93, 0x3d, 0xca, 0x71, 0xb2, 0x7f, 0x3f) // 键入库 ID 和版本 IMPLEMENT_OLETYPELIB(CVP2PCtrl, _tlid, _wVerMajor, _wVerMinor) // 接口 ID const IID BASED_CODE IID_DVP2P = { 0x91379582, 0x7D2E, 0x49A7, { 0xA7, 0xC3, 0x1B, 0xB5, 0xDB, 0xFE, 0x9F, 0x75 } }; const IID BASED_CODE IID_DVP2PEvents = { 0x8ECC6E3C, 0x2651, 0x4E38, { 0xAC, 0xD0, 0xB9, 0xD8, 0x71, 0x44, 0x59, 0x78 } }; // 控件类型信息 static const DWORD BASED_CODE _dwVP2POleMisc = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CVP2PCtrl, IDS_VP2P, _dwVP2POleMisc) // CVP2PCtrl::CVP2PCtrlFactory::UpdateRegistry - // 添加或移除 CVP2PCtrl 的系统注册表项 BOOL CVP2PCtrl::CVP2PCtrlFactory::UpdateRegistry(BOOL bRegister) { // TODO: 验证您的控件是否符合单元模型线程处理规则。 // 有关更多信息,请参考 MFC 技术说明 64。 // 如果您的控件不符合单元模型规则,则 // 必须修改如下代码,将第六个参数从 // afxRegInsertable | afxRegApartmentThreading 改为 afxRegInsertable。 if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_VP2P, IDB_VP2P, afxRegInsertable | afxRegApartmentThreading, _dwVP2POleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } // CVP2PCtrl::CVP2PCtrl - 构造函数 CVP2PCtrl::CVP2PCtrl() { InitializeIIDs(&IID_DVP2P, &IID_DVP2PEvents); // TODO: 在此初始化控件的实例数据。 //AfxMessageBox("CVP2PCtrl::CVP2PCtrl()"); m_talk.Ini(); } // CVP2PCtrl::~CVP2PCtrl - 析构函数 CVP2PCtrl::~CVP2PCtrl() { // TODO: 在此清理控件的实例数据。 m_talk.End(); } // CVP2PCtrl::OnDraw - 绘图函数 void CVP2PCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { if (!pdc) return; // TODO: 用您自己的绘图代码替换下面的代码。 pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); //pdc->Ellipse(rcBounds); CString strOut; CRecSocket * pRec = m_talk.GetRecSocket(); if(pRec!=NULL) { char lpName[MAX_PATH+1]; memset(lpName,0,sizeof(lpName)); ::GetModuleFileName(NULL,lpName,sizeof(lpName)); strOut.Format("TCP:%d UDP:%d\r\nwww.hotlove.cn\r\n%s",m_talk.GetListenPort(),pRec->GetListenPort(),lpName); CFont f; f.CreatePointFont(90,"宋体"); CFont * of = pdc->SelectObject(&f); pdc->DrawText(strOut,CRect(rcBounds),DT_CENTER); pdc->SelectObject(of); } } // CVP2PCtrl::DoPropExchange - 持久性支持 void CVP2PCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: 为每个持久的自定义属性调用 PX_ 函数。 } // CVP2PCtrl::OnResetState - 将控件重置为默认状态 void CVP2PCtrl::OnResetState() { COleControl::OnResetState(); // 重置 DoPropExchange 中找到的默认值 //AfxMessageBox("CVP2PCtrl::OnResetState()"); // TODO: 在此重置任意其他控件状态。 } // CVP2PCtrl::AboutBox - 向用户显示“关于”框 void CVP2PCtrl::AboutBox() { CDialog dlgAbout(IDD_ABOUTBOX_VP2P); dlgAbout.DoModal(); } // CVP2PCtrl 消息处理程序 LONG CVP2PCtrl::StartTalk(LPCTSTR bstrIP,LONG nPort,LONG nUdpPort) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加调度处理程序代码 m_talk.Start(bstrIP,nPort,nUdpPort); return 0; } LONG CVP2PCtrl::EndTalk(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加调度处理程序代码 m_talk.End(); return 0; } // Implementation of IObjectSafety STDMETHODIMP CVP2PCtrl::XObjectSafety::GetInterfaceSafetyOptions( REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE_EX(CVP2PCtrl, ObjectSafety) if (!pdwSupportedOptions || !pdwEnabledOptions) { return E_POINTER; } *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; *pdwEnabledOptions = 0; if (NULL == pThis->GetInterface(&riid)) { TRACE("Requested interface is not supported.\n"); return E_NOINTERFACE; } // What interface is being checked out anyhow? OLECHAR szGUID[39]; int i = StringFromGUID2(riid, szGUID, 39); if (riid == IID_IDispatch) { // Client wants to know if object is safe for scripting *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; return S_OK; } else if (riid == IID_IPersistPropertyBag || riid == IID_IPersistStreamInit || riid == IID_IPersistStorage || riid == IID_IPersistMemory) { // Those are the persistence interfaces COleControl derived controls support // as indicated in AFXCTL.H // Client wants to know if object is safe for initializing from persistent data *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; return S_OK; } else { // Find out what interface this is, and decide what options to enable TRACE("We didn't account for the safety of this interface, and it's one we support...\n"); return E_NOINTERFACE; } } STDMETHODIMP CVP2PCtrl::XObjectSafety::SetInterfaceSafetyOptions( REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) { METHOD_PROLOGUE_EX(CVP2PCtrl, ObjectSafety) OLECHAR szGUID[39]; // What is this interface anyway? // We can do a quick lookup in the registry under HKEY_CLASSES_ROOT\Interface int i = StringFromGUID2(riid, szGUID, 39); if (0 == dwOptionSetMask && 0 == dwEnabledOptions) { // the control certainly supports NO requests through the specified interface // so it's safe to return S_OK even if the interface isn't supported. return S_OK; } // Do we support the specified interface? if (NULL == pThis->GetInterface(&riid)) { TRACE1("%s is not support.\n", szGUID); return E_FAIL; } if (riid == IID_IDispatch) { TRACE("Client asking if it's safe to call through IDispatch.\n"); TRACE("In other words, is the control safe for scripting?\n"); if (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions) { return S_OK; } else { return E_FAIL; } } else if (riid == IID_IPersistPropertyBag || riid == IID_IPersistStreamInit || riid == IID_IPersistStorage || riid == IID_IPersistMemory) { TRACE("Client asking if it's safe to call through IPersist*.\n"); TRACE("In other words, is the control safe for initializing from persistent data?\n"); if (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask && INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions) { return NOERROR; } else { return E_FAIL; } } else { TRACE1("We didn't account for the safety of %s, and it's one we support...\n", szGUID); return E_FAIL; } } STDMETHODIMP_(ULONG) CVP2PCtrl::XObjectSafety::AddRef() { METHOD_PROLOGUE_EX_(CVP2PCtrl, ObjectSafety) return (ULONG)pThis->ExternalAddRef(); } STDMETHODIMP_(ULONG) CVP2PCtrl::XObjectSafety::Release() { METHOD_PROLOGUE_EX_(CVP2PCtrl, ObjectSafety) return (ULONG)pThis->ExternalRelease(); } STDMETHODIMP CVP2PCtrl::XObjectSafety::QueryInterface( REFIID iid, LPVOID* ppvObj) { METHOD_PROLOGUE_EX_(CVP2PCtrl, ObjectSafety) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } LONG CVP2PCtrl::GetCtrlInfo(BSTR * bstrIP) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加调度处理程序代码 CString strIP; m_talk.GetIP(strIP); // strIP="ddddddddddddddddddddddd"; *bstrIP = strIP.AllocSysString(); // *nPort=1; // *nUdpPort=2; return 0; } BSTR CVP2PCtrl::GetstrIP(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strResult; m_talk.GetIP(strResult); // TODO: 在此添加调度处理程序代码 //strResult = "127.0.0.1"; return strResult.AllocSysString(); } LONG CVP2PCtrl::GetnTcpPort(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加调度处理程序代码 return m_talk.GetListenPort(); return 0; } void CVP2PCtrl::SetnTcpPort(LONG newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加属性处理程序代码 //SetModifiedFlag(); } LONG CVP2PCtrl::GetnUdpPort(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加调度处理程序代码 return m_talk.GetRecSocket()->GetListenPort(); return 0; } void CVP2PCtrl::SetnUdpPort(LONG newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: 在此添加属性处理程序代码 //SetModifiedFlag(); }