com连接点方式的向导实现

李国帅 2009

使用连接点添加com控件事件的例子

1、控件类声明
// CTopseePlayer.h : 由 Microsoft Visual C++ 创建的 ActiveX 控件包装类的声明

#pragma once

/////
// CTopseePlayer

class CTopseePlayer : public CWnd
{

protected:
    DECLARE_DYNCREATE( CTopseePlayer )
    //IMPLEMENT_DYNCREATE(CTopseePlayer, CWnd)

public:
    CLSID const& GetClsid()
    {
        static CLSID const clsid
        = { 0x2C8548DD, 0x829D, 0x473C, { 0x9C, 0xF4, 0xBB, 0xA2, 0x3E, 0x12, 0xA6, 0x2B } };
        return clsid;
    }

    virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle,
                         const RECT& rect, CWnd* pParentWnd, UINT nID,
                         CCreateContext* pContext = NULL )
    {
        return CreateControl( GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID );
    }

    BOOL Create( LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
                 UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE,
                 BSTR bstrLicKey = NULL )
    {
        return CreateControl( GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
                              pPersist, bStorage, bstrLicKey );
    }

// 操作

public:

    void Play()
    {
        InvokeHelper( 0x1, DISPATCH_METHOD, VT_EMPTY, NULL, NULL );
    }

    void Stop()
    {
        InvokeHelper( 0x2, DISPATCH_METHOD, VT_EMPTY, NULL, NULL );
    }

    CString GetURL()
    {
        CString result;
        InvokeHelper( 0x3, DISPATCH_PROPERTYGET, VT_BSTR, ( void* )&result, NULL );
        return result;
    }

    void PutURL( LPCTSTR newValue )
    {
        static BYTE parms[] = VTS_BSTR ;
        InvokeHelper( 0x3, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue );
    }

...

    void MonitorChange()
    {
        InvokeHelper(0x32, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
    }
    BOOL CheckFullScreen()
    {
        BOOL result;
        InvokeHelper(0x33, DISPATCH_METHOD, VT_BOOL, (void*)&result, NULL);
        return result;
    }

public:
    int PointInRect( POINT pt, CRect &rect );
    void DrawWhiteRect( CRect rect );
    void DrawRedRect( CRect rect );

    DECLARE_MESSAGE_MAP()

    virtual BOOL PreTranslateMessage( MSG* pMsg );
    CTopseePlayer();

// 属性

public:
   BOOL m_bQuery;  //是否按下查询录象
    //static BOOL m_bFullScreen;   //视频显示整个屏幕
    static BOOL m_bLogin;
    //static BOOL m_bDraw;
    BOOL m_bLock;

};
2、控件事件头文件
#pragma once
#include "oaidl.h"

class CEventSink :
    public IDispatch
{
public:
    CEventSink(CWnd* pParent = NULL);
    ~CEventSink(void);
    CWnd* m_pParent;
public:
    //void SetResultWnd(CEdit * pEdit);
// IUnknown
    STDMETHOD(QueryInterface)(const struct _GUID &iid,void ** ppv);
    ULONG __stdcall AddRef(void);
    ULONG __stdcall Release(void);
// IDispatch
    STDMETHOD(GetTypeInfoCount)(unsigned int *);
    STDMETHOD(GetTypeInfo)(unsigned int,unsigned long,struct ITypeInfo ** );
    STDMETHOD(GetIDsOfNames)(const IID &,LPOLESTR *,UINT,LCID,DISPID *);
    STDMETHOD(Invoke)(long dispID,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS * pParams,struct tagVARIANT *,struct tagEXCEPINFO *,unsigned int *);
};
3、控件事件定义文件
#include "StdAfx.h"
#include ".\eventsink.h"

//#include "MultiViewer.h"

//class CMainFrame;

CEventSink::CEventSink(CWnd* pParent){    m_pParent = pParent;}

CEventSink::~CEventSink(void){}
// STDMETHODIMP 是宏,等价于 long __stdcall
STDMETHODIMP CEventSink::QueryInterface(const struct _GUID &iid,void ** ppv)
{
    *ppv = this;
    return S_OK;
}

ULONG __stdcall CEventSink::AddRef(void){    return 1;    }    // 做个假的就可以,因为反正这个对象在程序结束前是不会退出的

ULONG __stdcall CEventSink::Release(void){    return 0;    }    // 做个假的就可以,因为反正这个对象在程序结束前是不会退出的

STDMETHODIMP CEventSink::GetTypeInfoCount(unsigned int *){    return E_NOTIMPL;    }    // 不用实现,反正也不用

STDMETHODIMP CEventSink::GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** ){    return E_NOTIMPL;    }    // 不用实现,反正也不用

STDMETHODIMP CEventSink::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *){    return E_NOTIMPL;    }    // 不用实现,反正也不用

STDMETHODIMP CEventSink::Invoke(
                long dispID,
                const struct _GUID &,
                unsigned long,
                unsigned short,
                struct tagDISPPARAMS * pParams,
                struct tagVARIANT *,
                struct tagEXCEPINFO *,
                unsigned int *)
{                            // 只需要实现这个就足够啦
//    CMainFrame* pMainFrame = (CMainFrame*)m_pParent;
//    CWorkStat* pStat = (CWorkStat*)m_pParent;

    switch(dispID)//获取事件的id号,回调其他类的处理函数进行处理
    {
    case 1:    //Alarm
        //if (pParams[0].cArgs != 3)
        //    TRACE0("Arg Num is Error\n");
        //TRACE3("Channel %d, Sub %d, Alarm Type %d\n", pParams->rgvarg[2].lVal, pParams->rgvarg[1].lVal, pParams->rgvarg[0].lVal);
        //pStat->OnAlarm(pParams->rgvarg[2].lVal, pParams->rgvarg[1].lVal, pParams->rgvarg[0].lVal);

        break;
    case 2:  // PlayBegin(LONG Channel, LONG SubChannel)
        TRACE1("channel %d play begin\n", pParams->rgvarg[1].lVal);
        //pStat->OnPlayBegin(pParams->rgvarg[1].lVal, pParams->rgvarg[0].lVal);
        //((CWorkStat*)m_pParent)->m_Info[pParams->rgvarg[1].lVal].SetPlayStat(TRUE);
        break;
    case 3: // PlayStop(LONG Channel, LONG SubChannel)
        TRACE1("channel %d play stop\n", pParams->rgvarg[1].lVal);
        //pStat->OnPlayStop(pParams->rgvarg[1].lVal, pParams->rgvarg[0].lVal);
        //((CWorkStat*)m_pParent)->m_Info[pParams->rgvarg[1].lVal].SetPlayStat(FALSE);
        break;
    case 4: // SaveBegin(LONG Channel, LONG SubChannel)
        //pStat->OnSaveBegin(pParams->rgvarg[1].lVal, pParams->rgvarg[0].lVal);
        //((CWorkStat*)m_pParent)->m_Info[pParams->rgvarg[1].lVal].SetSaveStat(TRUE);
        break;
    case 5: // SaveStop(LONG Channel, LONG SubChannel)
        //pStat->OnSaveStop(pParams->rgvarg[1].lVal, pParams->rgvarg[0].lVal);
//        ((CWorkStat*)m_pParent)->m_Info[pParams->rgvarg[1].lVal].SetSaveStat(FALSE);
        break;
.....
    default:
        TRACE0( "怎么可能,根本就没有这个号码的函数呀\n" );
        break;
    }
    return S_OK;
}
4、控件调用头文件
// MainFrm.h : CMainFrame 类的接口
#pragma once

#include "CTopseePlayer.h"
#include "EventSink.h"

class CMainFrame : public CFrameWnd
{

public:
    CMainFrame();
protected:
    DECLARE_DYNAMIC(CMainFrame)

// 重写
public:
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);

// 实现
public:
    virtual ~CMainFrame();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif
// 属性
public:

public://    CChildView    m_wndView;
    CTopseePlayer *pDisplay;
    CEventSink* pEvent;
    IConnectionPoint* m_pConPoint;
    DWORD m_dwAdvise;

// 生成的消息映射函数
protected:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnSetFocus(CWnd *pOldWnd);
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnMove(int x, int y);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnOpenFile();
    afx_msg void OnOpenUrl();
};
5、事件的具体调用
//
// MainFrm.cpp : CMainFrame 类的实现

#include "stdafx.h"
#include "TSPlayer.h"

#include "MainFrm.h"
#include ".\mainfrm.h"
#include "openurldlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_WM_SETFOCUS()
    ON_WM_MOVE()
    ON_WM_SIZE()
    ON_COMMAND(ID_OPEN_FILE, OnOpenFile)
    ON_COMMAND(ID_OPEN_URL, OnOpenUrl)
END_MESSAGE_MAP()

// CMainFrame 构造/析构

CMainFrame::CMainFrame()
{
    // TODO: 在此添加成员初始化代码
    pDisplay = new CTopseePlayer();
    //pEvent = new CEventSink();
}

CMainFrame::~CMainFrame()
{
    if (pEvent != NULL)
        delete pEvent;
    if (pDisplay != NULL)
        delete pDisplay;
}


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;


    RECT rcClient;
    GetClientRect(&rcClient);

    if (!pDisplay->Create(_T(""), WS_VISIBLE|WS_CHILD, CRect(rcClient.left, rcClient.top, rcClient.right, rcClient.bottom), this, 100)) {
        MessageBox(_T("Display control initialize failed, program exit now!"));
        PostMessage(WM_CLOSE);
        return FALSE;
    }
    pDisplay->PutRunMode(0);
    pDisplay->PutShowControls(true);


    m_pConPoint = NULL;
    pEvent = new CEventSink(this);
    IConnectionPointContainer * pContainer;
    IUnknown* pDisplayUnk = ((CMainFrame*)theApp.GetMainWnd())->pDisplay->GetControlUnknown();

    GUID IID_ITopseePlayerEvents = { 0x22143EA9, 0x10C5, 0x43A6, 0xA0, 0x6C, 0x20, 0xE7, 0x87, 0x8B, 0x1C, 0xB8 };

    if (pDisplayUnk) {
        pDisplayUnk->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pContainer);
        pDisplayUnk->Release();
        if (pContainer) {
            pContainer->FindConnectionPoint(IID_ITopseePlayerEvents, &m_pConPoint);
            pContainer->Release();
            if (m_pConPoint) {
                m_pConPoint->Advise(pEvent, &m_dwAdvise);
            }
        }
    }


    return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
    // 样式

    cs.cx = 360;
    cs.cy = 360;
    //cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
    //cs.lpszClass = AfxRegisterWndClass(0);
    return TRUE;
}


// CMainFrame 诊断

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
    CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
    CFrameWnd::Dump(dc);
}

#endif //_DEBUG


// CMainFrame 消息处理程序

void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
    // 将焦点前移到视图窗口
//    m_wndView.SetFocus();
    if (pDisplay != NULL)
        pDisplay->SetFocus();
}

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
    // 让视图第一次尝试该命令
//    if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
//        return TRUE;

    // 否则,执行默认处理
    return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

void CMainFrame::OnMove(int x, int y)
{
    CFrameWnd::OnMove(x, y);

    CRect rtRect;
    GetClientRect(&rtRect);
    if (pDisplay != NULL)
        pDisplay->MoveWindow(&rtRect);
}


void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
    CFrameWnd::OnSize(nType, cx, cy);

    CRect rtRect;
    GetClientRect(&rtRect);
    if (pDisplay != NULL)
        pDisplay->MoveWindow(&rtRect);

}

void CMainFrame::OnOpenFile()
{
    TCHAR resultFile[MAX_PATH] = {'\0'};

    OPENFILENAME fileName;
    ZeroMemory(&fileName, sizeof(OPENFILENAME));

    fileName.lStructSize = sizeof(OPENFILENAME);
    fileName.hwndOwner = m_hWnd;
    //fileName.hInstance = 0; // ZeroMemory does the work.
    fileName.lpstrFilter = _T("All Files (*.asf)\0*.asf\0\0");
    fileName.lpstrCustomFilter = NULL;
    //fileName.nMaxCustFilter = 0; // ZeroMemory does the work.
    fileName.nFilterIndex = -1;
    fileName.lpstrFile = resultFile;
    fileName.nMaxFile = MAX_PATH;
    fileName.lpstrInitialDir = NULL;
    fileName.lpstrTitle = _T("Select Open File");
    fileName.Flags = OFN_EXPLORER + OFN_ENABLESIZING + OFN_HIDEREADONLY;// | extraFlags;

    if (GetSaveFileName(&fileName))
    {
        pDisplay->PutRunMode(2);
        pDisplay->PutFileName(resultFile);
        pDisplay->PlayFile();
    }
}

void CMainFrame::OnOpenUrl()
{
    COpenUrlDlg dlg;
    if (dlg.DoModal() == IDOK) {
        if (dlg.m_Url.GetLength() == 0)
            return;
        pDisplay->PutRunMode(0);
        pDisplay->PutURL(dlg.m_Url);
        if (dlg.m_User.GetLength() != 0)
            pDisplay->PutUserName(dlg.m_User);
        if (dlg.m_Passwd.GetLength() != 0)
            pDisplay->PutPasswd(dlg.m_Passwd);
        pDisplay->Play();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微澜-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值