您的位置:首页 > 其它

WTL8.0 调用 ActiveX 控件 - (调用 Flash 控件,响应 Flash 控件的事件)

2007-11-28 01:02 609 查看
alimama_pid="mm_10785426_825144_3745076";
alimama_titlecolor="0000FF";
alimama_descolor ="000000";
alimama_bgcolor="FFFFFF";
alimama_bordercolor="E6E6E6";
alimama_linkcolor="008000";
alimama_bottomcolor="FFFFFF";
alimama_anglesize="0";
alimama_bgpic="0";
alimama_icon="0";
alimama_sizecode="12";
alimama_width=468;
alimama_height=60;
alimama_type=2;

很久没用WTL了,WTL都升级到8.0了,这两天做了个小例子,WTL调用Flash控件。

目标:使用WTL创建对话框的工程,调用Flash控件播放Flash,并响应Flash控件的事件。

环境:WindowsXP, VC++ 2005, WTL8.0, Flash9

1. 首先用WTL Wizard创建对话框工程,如图:

m_wndFlashPlayer = GetDlgItem(IDC_SHOCKWAVEFLASH1);

// HRESULT hResult = m_wndFlashPlayer.QueryControl(__uuidof(IShockwaveFlash), reinterpret_cast<void**>(&m_FlashPtr));

HRESULT hResult = m_wndFlashPlayer.QueryControl(&m_FlashPtr);

ATLASSERT(hResult == S_OK);

IDC_SHOCKWAVEFLASH1 是ActiveX控件的资源ID, GetDlgItem 根据资源 ID 得到ActiveX控件的窗口对象,然后窗口对象 m_wndFlashPlayer 使用QueryControl方法得到ActiveX控件的COM对象指针。上面代码中,注释掉的方法也是可用的,但没有注释的使用比较简单。

接着装载一个Flash Movie,调用下面的方法,装载一个swf文件,并让它处于停止状态:

hResult = m_FlashPtr->put_Movie(_bstr_t("f:\\flashC.swf"));

ATLASSERT(hResult == S_OK);

hResult = m_FlashPtr->Stop();

ATLASSERT(hResult == S_OK);

这时候,我们可以在对话框上增加一个按钮,在Click事件里添加播放的代码,如下:

到此,我们可以编译一下工程,如果没有意外,程序可以正常运行,点击Play按钮,可以播放Flash文件。

4. 下面我们关注如何响应Flash的事件,我们以FSCommand事件为例。

首先编辑对话框资源,右键单击前面添加的Flash控件,选择Add Event Handler,如图:

BEGIN_COM_MAP(CMainDlg)

END_COM_MAP()

更早些的方法,SINK_MAP 使用 SINK_ENTRY_INFO 的方式映射事件接受函数

BEGIN_SINK_MAP(CMainDlg)

SINK_ENTRY_INFO(SOURCEID, DIID__IShockwaveFlashEvents, 150, OnFSCommand, &FSCommandInfo)

END_SINK_MAP()

其中 FSCommandInfo 的定义如下:

__declspec(selectany) _ATL_FUNC_INFO FSCommandInfo =

{ CC_STDCALL, VT_EMPTY, 2, { VT_BSTR, VT_BSTR } };

这样 CMainDlg 需要这样派生:

class CMainDlg : public CAxDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>,

public CMessageFilter, public CIdleHandler,

public CComObjectRootEx<CComSingleThreadModel>,

public CComCoClass<CMainDlg>,

public IDispEventSimpleImpl<SOURCEID, CMainDlg, &DIID__IShockwaveFlashEvents>

最后说说事件的订阅的方法:

有这么几种:

1. 写一个Sink类,继承 IDispEventImpl,如下:

#pragma once

#define DISPID_ONSTARTADD 1

#define DISPID_ONSTOPADD 2

#define SOURCEID 1

class CTestSink;

typedef IDispEventImpl<SOURCEID,CTestSink,&DIID__ITestOBJEvents,&LIBID_TestCOMLib,1,0> CTestEventSink;

//typedef IDispatchImpl<_ITestOBJEvents, &__uuidof(_ITestOBJEvents), &LIBID_TestCOMLib, /* wMajor = */ 1, /* wMinor = */ 0> CEventSink;

class ATL_NO_VTABLE CTestSink :

public CComObjectRoot,

public CTestEventSink

事件的订阅可以使用如下代码:

ITestOBJPtr m_TestOBJPtr;

HRESULT hResult = m_TestOBJPtr.CreateInstance("TestCOM.TestOBJ");

CTestSink * m_pSink = NULL;

m_pSink = new CComObject<CTestSink>;

m_pSink->AddRef();

m_pSink->DispEventAdvise(m_TestOBJPtr);

// hResult = AtlAdvise(m_TestOBJPtr, (IUnknown *)m_pSink, DIID__ITestOBJEvents, &m_dwCookie);

上面注释的代码也是可以使用的。在最开始的例子里,还有比较简单的事件订阅的方法:

AtlAdviseSinkMap(this, true);

最后记住在合适的时候取消事件订阅:DispEventUnadvise 或者 AtlUnadvise 或者 AtlAdviseSinkMap(this, false)。

以上简单总结了 WTL 使用 ActiveX 控件的相关方法,欢迎拍砖,:-P
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: