0
点赞
收藏
分享

微信扫一扫

com连接点方式的向导实现

Alex富贵 2022-07-27 阅读 62


李国帅 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 条评论