com连接点方式的向导实现
来源:互联网 发布:java thread run 编辑:程序博客网 时间:2024/05/19 03:24
李国帅 2009
使用连接点添加com控件事件的例子
1、控件类声明
// CTopseePlayer.h : 由 Microsoft Visual C++ 创建的 ActiveX 控件包装类的声明#pragma once/////////////////////////////////////////////////////////////////////////////// CTopseePlayerclass 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 __stdcallSTDMETHODIMP 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// CMainFrameIMPLEMENT_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 _DEBUGvoid 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(); }}
阅读全文