久久婷婷伊人,91极品视频在线观看,日韩在线不卡视频,久久伊人操,国产精品高清一区二区,在线精品国产91吴梦梦,国产情侣激情在线视频免费看

在MFC中使用純COM方式來操縱Flash OCX (IShockwaveFlash)
2008-12-15
5130
小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝

1. MFC中的控件(OCX)包裝類

在VC++環(huán)境中,使用OCX會(huì)變得比較簡(jiǎn)單和快捷。

在Dialog中插入ActiveX,如:Shockwave Flash Object。

在建立了Dialog的類之后,為剛才插入的Flash 控件添加變量,

MFC會(huì)自動(dòng)幫我們生成兩個(gè)文件:CShockwaveFlash1.h和CShockwaveFlash1.cpp有了這兩個(gè)文件,就可以很容易控制Flash了。

2. 通過MIDL生成TLB文件

MFC包裝類固然簡(jiǎn)單,但很明顯缺乏一些高級(jí)的功能,此時(shí)就需要采用純COM的方式了。

首先使用OLE/COM Object Viewer來找到Shockwave Flash Object,

點(diǎn)擊右鍵“View Type Information”,在彈出的界面中,點(diǎn)擊“save as”將信息保存為 SWF.IDL文件,然后在打開VS提供的工具:“Visual Studio 2008 命令提示”,進(jìn)入DOS界面,切換到SWF.IDL所在的目錄,執(zhí)行如下命令:

MIDL SWF.IDL /tlb SWF.tlb,即可生成tlb文件。

如果生成過程有錯(cuò),提示“error MIDL2110 : end of file found in string”,可以這樣做:將前面打開的界面中(“View Type Information”)的內(nèi)容拷貝,然后手動(dòng)新建一個(gè)SWF.IDL的文件,將拷貝的內(nèi)容粘貼入,再次執(zhí)行MIDL命令。

接下來在你的VC++項(xiàng)目中:#import  "SWF.tlb",編譯之,即會(huì)在debug或者release。

目錄下面生成tlh(頭文件,header)和tli文件(實(shí)現(xiàn)文件,implementation)。

注意,在tlh文件的末尾處已經(jīng)包含了tli文件。

當(dāng)然也可以采用下面敘述的方式生成。

3. 相關(guān)概念

多數(shù)情況下,生成的com組件DLL/EXE/OCX已經(jīng)包含了類型庫信息(type information),但當(dāng)你的com程序足夠大,可能需要分離類型庫信息,此時(shí)考慮生成tlb[/B]文件,單獨(dú)存放類型庫。

此時(shí)使用:#import "XXX.tlb",然后編譯之,也會(huì)在debug或者release下面產(chǎn)生 XXX.tli和XXX.tlh文件。

tlh和tli文件實(shí)際上是對(duì)com接口及其屬性方法的封裝類,其中tlh[/B]相當(dāng)于類型申明(頭文件),tli相當(dāng)于定義實(shí)現(xiàn)(CPP文件),這里的實(shí)現(xiàn)完全是封裝方法的實(shí)現(xiàn),而不是com接口方法的實(shí)現(xiàn)。

如下例:

inline int IShockwaveFlash::GetQuality ( ) {
int _result = 0;
HRESULT _hr = get_Quality(&_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}


其中g(shù)et_Quality的真正實(shí)現(xiàn)實(shí)際上在XXX.ocx或者XXX.dll中。

4. 開始創(chuàng)建IShockwaveFlash 

為了簡(jiǎn)單起見,就不使用那么麻煩的方法了,直接這樣:

#import "C:WINDOWSsystem32MacromedFlashFlDbg9f.ocx"  
raw_interfaces_only, /* Don't add raw_ to method names */
raw_native_types, /* Don't map to DTC smart types */  
named_guids, /* Named guids and declspecs */  
no_namespace /* Don't wrap with C++ name space */ 


如前述會(huì)自動(dòng)在debug目錄下面生成tlh和tli文件,不需要在工程屬性里面加入lib,也不要include什么,很方便。

接下來,構(gòu)造、析構(gòu):


其中isf和ivo是成員變量(在.h中聲明):

IShockwaveFlash * isf;
IViewObject2 * ivo;


再初始化接口:

HRESULT CFlashHelper::Init(BSTR fileName)
{
HRESULT hr;
JIF(CoCreateInstance(__uuidof(ShockwaveFlash),
NULL,CLSCTX_INPROC_SERVER,
__uuidof(IShockwaveFlash),(void **)&isf));
JIF(isf->QueryInterface(__uuidof(IViewObject2),(void **)&ivo));
AtlAxAttachControl(isf,theApp.m_pFlashPlayerDlg->m_hWnd,NULL);
isf->put_Movie(fileName);
return S_OK;
}


其中JIF是一個(gè)宏:

#define JIF(x) if (FAILED(hr=(x)))
{TRACE(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT(" "), hr); return hr;}


這里還要使用一點(diǎn)點(diǎn)ATL,ATL做COM這方面的工作在行些。

故,要在工程屬性中,設(shè)置“動(dòng)態(tài)使用ATL”,在這個(gè)cpp文件中,包含如下頭文件:

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>


上面的代碼中還采用了一種比較簡(jiǎn)單的方法,即:

AtlAxAttachControl(isf,theApp.m_pFlashPlayerDlg->m_hWnd,NULL);


傳統(tǒng)的做法是先用CAxWindow創(chuàng)建窗口,然后采用其QueryControl方法得到IUnknown接口,

再采用其QueryInterface,得到IShockwaveFlash,代碼大概如下:

HRESULT CFlash::Create(LPRECT lpRect) {
HRESULT hr = S_OK;
AtlAxWinInit();
m_pAxWin = new CAxWindow();
m_hwnd = m_pAxWin->Create(NULL, lpRect, g_szCLSID_ShockwaveFlash, 0);
if (!m_hwnd)
{
return E_FAIL;
}
IUnknown *pUk = NULL;
hr = m_pAxWin->QueryControl(&pUk);
if (FAILED(hr))
{
return hr;
}
m_lWidth = lpRect->right-lpRect->left;
m_lHeight = lpRect->bottom - lpRect->top;
hr = pUk->QueryInterface(IID_IShockwaveFlash,(void**)&m_pShockwaveFlash);
pUk->Release();
return hr;
}


但這個(gè)工程既然是MFC的工程,就不想使用CAxWindow來創(chuàng)建窗口,所以采用MFC來建立的Dialog,

然后AtlAxAttachControl(isf,theApp.m_pFlashPlayerDlg->m_hWnd,NULL);就可以了。

通過上面的方法就得到了IShockwaveFlash和IViewObject2了,接下來怎么做就隨你了。

5. 其他要注意

如果你同時(shí)在使用GDI+,那么可能會(huì)要加入如下代碼:

// for GDI+
#include <comdef.h>
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long *
#include "GdiPlus.h"
using namespace Gdiplus;
// end for GDI+
#endif


這樣編譯的時(shí)候就會(huì)出現(xiàn)如下的錯(cuò)誤:

錯(cuò)誤 8 error C2440: “初始化”: 無法從“int”轉(zhuǎn)換為“unsigned long *” c:program filesmicrosoft visual studio 9.0vcatlmfcincludeatlwin.h 523 LEDEngine

錯(cuò)誤 9 error C2664: “GlobalAlloc”: 不能將參數(shù) 2 從“unsigned long *”轉(zhuǎn)換為“SIZE_T” c:program filesmicrosoft visual studio

9.0vcatlmfcincludeatlwin.h 570 LEDEngine

其實(shí)是因?yàn)閁LONG_PTR這個(gè)數(shù)據(jù)類型,這個(gè)東西在ATL中也有定義,而且在altwin.h中使用了,但是其實(shí)在ATL中:

ULONG_PTR是這樣定義的:typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;

在GDI+中式這樣定義的:#define ULONG_PTR unsigned long *

這樣就有沖突了,故如要同時(shí)使用GDI+和ATL,一定要這樣聲明:

// for GDI+
#include <comdef.h>
#include "GdiPlus.h"
using namespace Gdiplus;
// end for GDI+


好了,這個(gè)話題就說到這里。

 

關(guān)鍵字:MFC中使用純COM方式來操縱Flash,OCX,貝一科技知識(shí)庫