用ATL实现无窗口(Windowless)的Flash播放器
来源:互联网 发布:危险化学品查询软件 编辑:程序博客网 时间:2024/05/21 02:13
用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"");
以上代码因为是取的程序中的关键代码,所以不保证能够编译通过。
- 用ATL实现无窗口(Windowless)的Flash播放器
- SL - 无窗口模式(windowless)
- ATL窗口实现的学习
- 透明、无窗口的Flash
- WindowLess RichEdit 实现QQ聊天窗口的气泡效果,设计思路和方法。
- 跨平台Flash(RTMP)播放器的实现(一)
- 在ATL中实现窗口(精)
- 用WTL实现播放器的控制窗口
- 用WTL实现播放器的控制窗口
- python实现的dos窗口播放器
- flash 满窗口播放
- 用来实现MSN7中的传情动漫,无窗口的Flash的Demo
- 无窗口软件的实现
- 用VC 6.0写flash播放器——2、为作为主窗口的对话框添加状态栏
- ATL窗口(2)
- ATL窗口(初学者)
- 在ATL中实现窗口
- ATL窗口继承实现机制
- 对 android app in billing 网上现有材料的简单总结。(附原帖地址)
- richeidt 控件開發(四)
- js 正则表达式 验证方法
- 内存究竟有多快?
- 【BAT教程】实例及学习【入门篇】
- 用ATL实现无窗口(Windowless)的Flash播放器
- ios 编程: ipad 和 iphone开发中使用 UIWebView 来播放视频的时候,在页面切换时 停止播放
- js身份证验证
- 8个美白小锦囊 不知不觉中白起来
- How to export/import data with LOB type from one user/schema to another
- TortoiseGit + GitHub 使用指南
- Java实现给图片添加水印
- 磁盘监控报警-nagios
- Xcode4.2 EXC_BAD_ACCESS