用ATL实现无窗口(Windowless)的Flash播放器

1 篇文章 0 订阅
1 篇文章 0 订阅
用ATL实现无窗口(Windowless)的Flash播放器
 
首先,说明一点:我不会写文章,如果有表达不清晰的地方,还请各位包涵一二了,可以在评论中告诉我。
 
其次,看这篇文章的至少要对ATL有一定的了解。
 
OK,开始主题,一开始我也是不知道ATL已经有实现windowless容器接口的类,所以我找到了codeproject上一个无窗的实现( http://www.codeproject.com/KB/atl/WindowlessMedia.aspx?msg=2948497#xx2948497xx)。他的标题是说用的ATL,其实不完全是这样,准确的说他是用了WTL。试着运行了他的例子,确实是无窗口显示Flash了。但是,因为我在我的应用里面加了个浏览器“刷新”一样的功能,用户可以按F5重新加载播放器。这时,我Release旧的播放器,再创建一个新的播放器,旧播放器并不能完全Release(也就是旧Flash还在内存中)。
 
后面在某个国外的帖子里面有人回复说可以用CAxHostWindow,于是看了下CAxHostWindow的代码,发现CAxHostWindow确实实现了Windowless容器所需要的接口,废话不多说了,直接上关键代码。

class ATL_NO_VTABLE CFlashWnd :
     public CAxHostWindow,
     public IFlashWindow
{
    DECLARE_NOT_AGGREGATABLE(CFlashWnd);
    DECLARE_WND_CLASS(_T( "FlashWnd"))
    BEGIN_MSG_MAP(CFlashWnd)

         // …………更多自己要处理的消息
         if (uMsg == WM_NCHITTEST)
        {
            m_nHit = DefWindowProc(uMsg, wParam, lParam);
            lResult = m_nHit;
             return TRUE;
        }
        CHAIN_MSG_MAP(CAxHostWindow)
         if (m_nHit == HTCLIENT)
        { // 应用Flash的鼠标光标
            MESSAGE_HANDLER(WM_SETCURSOR, OnWindowMessage)
        }
         if (WM_MOUSEWHEEL == uMsg)
        { // 使Flash可以使用鼠标滚轮
            MESSAGE_HANDLER(WM_MOUSEWHEEL, OnWindowlessMouseMessage)
        }
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
    END_MSG_MAP()
     // create flash init stream,这个函数很关键,szFlashInit的数据是复制了设计器中的Flash控件的资源数据,里面已经设置好WMode为Opaque,这是Flash无窗口的基础。当然这里的做法是一个偷懒的办法,呵呵,因为我完全不了解ActiveX初始数据的组织格式;也没有去寻找其它方式提供初始数据
    HRESULT STDMETHODCALLTYPE CreateStreamInit(IStream * * ppStream)
    {
         static WCHAR szFlashInit[] = { 0x0376, 0x011a, 0x0000,
            0x0000, 0x0000, 0x5567, 0x5566, 0x0900, 0x0000, 0x6775, 0x0000, 0x420b, 
            0x0000, 0x0008, 0x0002, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0008, 
            0x0000, 0x0000, 0x0008, 0x000e, 0x0000, 0x004f, 0x0070, 0x0061, 0x0071, 
            0x0075, 0x0065, 0x0000, 0x0008, 0x0006, 0x0000, 0x002d, 0x0031, 0x0000, 
            0x0008, 0x0006, 0x0000, 0x002d, 0x0031, 0x0000, 0x0008, 0x000a, 0x0000, 
            0x0048, 0x0069, 0x0067, 0x0068, 0x0000, 0x0008, 0x0002, 0x0000, 0x0000, 
            0x0008, 0x0006, 0x0000, 0x002d, 0x0031, 0x0000, 0x0008, 0x0000, 0x0000, 
            0x0008, 0x0002, 0x0000, 0x0000, 0x0008, 0x0010, 0x0000, 0x0053, 0x0068, 
            0x006f, 0x0077, 0x0041, 0x006c, 0x006c, 0x0000, 0x0008, 0x0004, 0x0000, 
            0x0030, 0x0000, 0x0008, 0x0004, 0x0000, 0x0030, 0x0000, 0x0008, 0x0002, 
            0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0008, 0x0002, 0x0000, 0x0000, 
            0x000d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
            0x0008, 0x0004, 0x0000, 0x0031, 0x0000, 0x0008, 0x0004, 0x0000, 0x0030, 
            0x0000, 0x0008, 0x0000, 0x0000, 0x0008, 0x0004, 0x0000, 0x0030, 0x0000, 
            0x0008, 0x0008, 0x0000, 0x0061, 0x006c, 0x006c, 0x0000, 0x0008, 0x000a, 
            0x0000, 0x0074, 0x0072, 0x0075, 0x0065, 0x0000
        };
        HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, sizeof(szFlashInit));
        LPVOID pData = GlobalLock(hMem);
        CopyMemory(pData, szFlashInit, sizeof(szFlashInit));
        GlobalUnlock(hMem);
         return CreateStreamOnHGlobal(hMem, TRUE, ppStream);
    }
    BOOL CreateFlash(HWND hWnd, RECT *pRect, DWORD ws =WS_OVERLAPPEDWINDOW |WS_VISIBLE, DWORD wsEx = 0)
    {
        m_sizeMin.cx = pRect - >right;
        m_sizeMin.cy = pRect - >bottom;
        HMENU hMenu = NULL;
        Create(hWnd, pRect, NULL, ws, wsEx, hMenu);
         // 修正最小窗口大小
        LPSTREAM pStream = NULL;
        HRESULT hr = CreateStreamInit( &pStream);
        CComBSTR bstrLicKey;
        hr = _DialogSplitHelper : :ParseInitData(pStream, &bstrLicKey.m_str);
        BOOL bRet = CreateFlashInstance(pStream); // pStream不为NULL,且WMode的属性必须为Opaque或Transparent,才能实现无窗口的Flash播放器
        pStream - >Release();
         return bRet;
    }
    BOOL CreateFlashInstance(LPSTREAM pStreamInit =NULL)
    {
        HRESULT hr; 
        _bstr_t bStrClsid = L "ShockwaveFlash.ShockwaveFlash.1"
        hr = CreateControl(bStrClsid, m_hWnd, pStreamInit); 
         if(FAILED(hr)) 
        {
            MessageBox(_T( "您没有安装Flash播放器或版本太低,请先安装最新版本Flash播放器"));
            DestroyWindow();
             return FALSE; 
        }
        shwaveflash = NULL;
        hr = QueryControl(__uuidof(IShockwaveFlash), ( void * *) &shwaveflash); 
         if(FAILED(hr)) 
             return FALSE; 
         long lVer = shwaveflash - >FlashVersion();
         if (HIWORD(lVer) < 10 || (HIWORD(lVer) == 10 && LOWORD(lVer) < 2))
        {
            MessageBox(_T( "您的Flash播放器版本太低,请升级到最新版本"));
            DestroyWindow();
             return FALSE;
        }
        IOleWindow * pOleWnd;
         if (shwaveflash - >QueryInterface(IID_IOleWindow, (LPVOID *) &pOleWnd) == S_OK)
        {
            HWND hwnd;
            pOleWnd - >GetWindow( &hwnd);     // 这里是取不到窗口句柄的
            pOleWnd - >Release();
        }
         return TRUE;
    }
     // 销毁Flash
    BOOL DestroyFlash()
    {
         if (shwaveflash != NULL)
        {
            shwaveflash - >Release();
            shwaveflash = NULL;
            
            ReleaseAll();
        }
         return TRUE;
    }
     void LoadUrl(_bstr_t url, _bstr_t flashvars)
    {
        shwaveflash - >put_FlashVars(flashvars);
        bstr_t fullscreen(_T( "true"));
        shwaveflash - >put_AllowFullScreen(fullscreen);
        bstr_t allownet(_T( "all"));
        shwaveflash - >put_AllowNetworking(allownet);
        bstr_t allowscript(_T( "always"));
        shwaveflash - >put_AllowScriptAccess(allowscript);
        shwaveflash - > put_Movie(url); // you have to change the path here 
        shwaveflash - > Play(); 
    }
    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
    {
        DestroyFlash();
        PostQuitMessage( 0);
        bHandled = FALSE;
         return 0;
    }
     // …………省略若干方法
public :
    IShockwaveFlash * shwaveflash;
    LRESULT    m_nHit;
     // …………省略若干变量
};
 
CFlashWnd类的使用方法:
CComObject<CFlashWnd>  flashwnd;
flashwnd.CreateFlash(NULL, NULL);
flashwnd.LoadUrl(L"D:\\test.swf", L"");
 
以上代码因为是取的程序中的关键代码,所以不保证能够编译通过。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值