轉載自:
http://blog.csdn.net/tttyd/article/details/5258096
源代碼下載
http://files.cnblogs.com/tttyd/Activex.rar
由於在博主的博客中沒有講明工程的創建過程與最后插件的注冊方法,我在另一篇文章中作了補充:
介紹:
如今在許多流媒體視頻網站(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類來簡化控件容器的操作。
Activex嵌入主要代碼
1、環境設置。
因為用到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
- #import "C:\\WINDOWS\\system32\\wmp.dll" no_namespace \
- raw_interfaces_only raw_native_types named_guids
2.內嵌Activex的創建
- 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;
- }
3.設置內嵌Activex控件的大小位置
- 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.測試代碼
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>
擴展學習:網頁調用ActivX中的方法的第二種方式