• <strike id="wwm2q"></strike>
  • <strike id="wwm2q"></strike>
    <strike id="wwm2q"></strike>
    
    
  • <ul id="wwm2q"></ul>
  • <ul id="wwm2q"></ul><strike id="wwm2q"></strike>
  • 在MFC中使用純COM方式來操縱Flash OCX (IShockwaveFlash)
    2008-12-15
    5130
    小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝,小小貝

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

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

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

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

    MFC會自動幫我們生成兩個文件:CShockwaveFlash1.h和CShockwaveFlash1.cpp有了這兩個文件,就可以很容易控制Flash了。

    2. 通過MIDL生成TLB文件

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

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

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

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

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

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

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

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

    當然也可以采用下面敘述的方式生成。

    3. 相關概念

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

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

    tlh和tli文件實際上是對com接口及其屬性方法的封裝類,其中tlh[/B]相當于類型申明(頭文件),tli相當于定義實現(xiàn)(CPP文件),這里的實現(xiàn)完全是封裝方法的實現(xiàn),而不是com接口方法的實現(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;
    }


    其中get_Quality的真正實現(xiàn)實際上在XXX.ocx或者XXX.dll中。

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

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

    #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 */ 


    如前述會自動在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是一個宏:

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


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

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

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


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

    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;
    }


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

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

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

    5. 其他要注意

    如果你同時在使用GDI+,那么可能會要加入如下代碼:

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


    這樣編譯的時候就會出現(xiàn)如下的錯誤:

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

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

    9.0vcatlmfcincludeatlwin.h 570 LEDEngine

    其實是因為ULONG_PTR這個數(shù)據(jù)類型,這個東西在ATL中也有定義,而且在altwin.h中使用了,但是其實在ATL中:

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

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

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

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


    好了,這個話題就說到這里。

     

    關鍵字:MFC中使用純COM方式來操縱Flash,OCX,貝一科技知識庫
    主站蜘蛛池模板: 亚洲精品国产成人片| 99精品一区二区三区无码吞精 | 精品亚洲欧美无人区乱码| 国产精品区一区二区三在线播放| 巨大黑人极品VIDEOS精品| 中文字幕精品一区二区日本| 国产女主播精品大秀系列| 亚洲国产精品一区二区第一页| 精品视频久久久久| 国产色婷婷精品综合在线| 亚洲国产综合91精品麻豆| 国产精品久久久久久| 国产成人精品无码一区二区| 少妇伦子伦精品无码STYLES| 四虎影院国产精品| 久久这里只有精品视频99| 国产精品日日摸夜夜添夜夜添1国产精品va欧美精 | 国产精品无码AV一区二区三区| 欧美亚洲日本久久精品| 国模精品一区二区三区| 国产精品亚洲产品一区二区三区| 四虎永久在线精品国产免费| 97久久精品人妻人人搡人人玩| 日本伊人精品一区二区三区| 亚洲国产一成人久久精品| 中文字幕一区二区三区日韩精品| 四虎成人精品国产永久免费无码| 精品人妻伦一二三区久久 | 精品人妻中文字幕有码在线 | 91精品国产麻豆国产自产在线| 国产精品久久亚洲不卡动漫| 国产精品特级毛片一区二区三区| 欧美精品一区二区蜜臀亚洲| 无码精品A∨在线观看中文| 亚洲日韩精品一区二区三区| 中文字幕无码精品亚洲资源网久久| 亚洲精品无码久久久| 中文精品久久久久人妻| 无码国产乱人伦偷精品视频| 精品无码一区二区三区爱欲| 69久久夜色精品国产69 |