转载自:
http://blog.csdn.net/tttyd/article/details/5258096
源代码下载
http://files.cnblogs.com/tttyd/Activex.rar
由于在博主的博客中没有讲明工程的创建过程与最后插件的注册方法,我在另一篇文章中作了补充:
用ATL写简单的ActiveX控件
介绍:
如今在许多流媒体视频网站(youku,tudou......)我们都会发现,观看视频之前都会有一段时间的广告,甚至在观看视频途中也会插入一些广告。实现这个效果的可以有多种技术。使用Javascript就可以实现,只需要在同一个位置分别创建两个Object,一个嵌入Flash插件,一个嵌入 WMP插件,然后切换显示这两个控件即可。
使用COM/Activex技术也可以在同一个控件中实现这样的功能。
插件功能描述:
上周在某个公司碰到这么一个问题,它们需要创建一个插件,内部嵌入一个Flash插件和Windows Media Player插件。然后写一个Web测试页面测试此Activex页面。页面上有三个输入框和一个按钮(Play)。第一个输入框输入falsh URL(.swf),第二个输入框输入.swf播放时间长度(秒),即视频广告时间,第三个输入框输入.wmv URL。点击Play按钮后,页面按钮将三个参数传递给控件,控件优先播放.swf,要布满整个控件的大小。.swf播放指定的时间之后,然后播放.wmv,wmv也要布满整个控件。
容器-插件基础:
为在一个窗口中嵌入一个Activex的话,就需要创建一个Container Window,
然后创建被嵌入的Activex,
然后通过上述的接口建立容器与Activex直接的联系。
在ATL中使用CAxHostWindow封装了Activex容器,并进一步使用CAxWindow类来简化控件容器的操作。
因为用到Flash的操作接口 IShockwaveFlash,所以在工程中导入flash的组件:
#import "C:\WINDOWS\system32\Macromed\Flash\Flash32_11_3_300_257.ocx" \ no_namespace raw_interfaces_only raw_native_types \ named_guids exclude("IServiceProvider")
因为用到Medial Player的接口IWMPPlayer,所以在工程中导入WMP的组件:
#import "C:\\WINDOWS\\system32\\wmp.dll" no_namespace \ raw_interfaces_only raw_native_types named_guids
LRESULT CEmbed::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { RECT rc; GetWindowRect(&rc); rc.right -= rc.left; rc.bottom -= rc.top; rc.top = rc.left = 0; //对于ATL3.0 必须调用AtlAxWinInit,否则Create会调用失败 AtlAxWinInit(); //初始化容器窗口的注册类 RECT rect = rc; //创建Shock wave flash控件播放Flash TCHAR* controlName = L"ShockwaveFlash.ShockwaveFlash"; m_FlashWin.Create(m_hWnd, rect, controlName, WS_CHILD | WS_VISIBLE, 0, ID_FLASHCTRL ); DWORD error = ::GetLastError(); CComPtr< IAxWinAmbientDispatch > ambient; m_FlashWin.QueryHost( &ambient ); CComPtr<IAxWinHostWindow> hostwin; m_FlashWin.QueryHost(&hostwin); hostwin->QueryControl(__uuidof(IDispatch),(void**)&m_ptrFlash.p); CComQIPtr<IShockwaveFlash> ptrFlash = m_ptrFlash; ptrFlash->put_BackgroundColor(RGB( 0, 0, 0 ) ); //创建Windows Media Play控件播放.wmv文件 controlName = L"WMPlayer.OCX"; //CLSID cld; //::CLSIDFromProgID(controlName,&cld); m_WmvWin.Create(m_hWnd, rect,controlName,WS_CHILD, 0,ID_WMPCTRL); if(hostwin) hostwin.Release(); m_WmvWin.QueryHost(&hostwin); hostwin->QueryControl(__uuidof(IDispatch),(void**)&m_ptrWmv.p); return 0; }
HRESULT CEmbed::SetObjectRects(LPCRECT prcPos,LPCRECT prcClip) { IOleInPlaceObjectWindowlessImpl<CEmbed>::SetObjectRects(prcPos, prcClip); int cx, cy; cx = prcPos->right - prcPos->left; cy = prcPos->bottom - prcPos->top; RECT rect; GetClientRect( &rect ); rect.top = 0; rect.left = 0; if(m_FlashWin) m_FlashWin.MoveWindow(&rect ); if(m_FlashWin) m_WmvWin.MoveWindow(&rect ); return S_OK; }
4、1 在测试代码中根据CLASSID获得此ID的对象playobj,但如果在没有注册此ActiveX控件的电脑上该怎么办呢?
此时得通过来在HTML文件中指定codebase="http://url-to-my-server/myactivex.cab"寻找安装文件。
4、2 注册的dll文件中的接口只有四个,但 在script脚本函数中palyobj.SetJmpTimer(parseInt(obj.value));函数没没有出现在此DLL里。
<HTML> <HEAD> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"/> <TITLE>内嵌Activex的Activex插件测试页</TITLE> </HEAD> <BODY> <OBJECT ID="Play" CLASSID="CLSID:62762BB2-C5D5-4CAC-A17C-CABC660678F2" width=700 height=400 ></OBJECT> <br>Flash URL:<input type=text size=45 id="urlflash" value="http://www.atfriday.com/GameZone/200471922656/20047198816907.swf"> Time:<input type=text size=3 id="elapse" value=5> <br>WMV URL: <input type=text size=45 id="wmvflash" value="D://test//Embed//Embed//wmp.wmv"> <input type=button value="Play" onclick="play()"> <script language="javascript" type="text/javascript"> function play() { var obj; var palyobj = document.getElementById("Play"); obj = document.getElementById("urlflash"); palyobj.LoadFlashMovie(obj.value); obj = document.getElementById("wmvflash"); palyobj.LoadWmvMovie(obj.value); obj = document.getElementById("elapse"); palyobj.SetJmpTimer(parseInt(obj.value)); palyobj.Play(); } <script> </BODY> </HTML>