在MFC中使用纯COM方式来操纵Flash OCX
发布时间:2020-12-15 06:33:10 所属栏目:百科 来源:网络整理
导读:1. MFC中的控件(OCX)包装类 在VC++环境中,使用OCX会变得比较简单和快捷。 在Dialog中插入ActiveX,如:Shockwave Flash Object。 在建立了Dialog的类之后,为刚才插入的 Flash 控件添加变量, MFC会自动帮我们生成两个文件:CShockwaveFlash1.h和CShockwa
1. MFC中的控件(OCX)包装类 在VC++环境中,使用OCX会变得比较简单和快捷。 MIDL SWF.IDL /tlb SWF.tlb,即可生成tlb文件。 如果生成过程有错,提示“error MIDL2110 : end of file found in string”,可以这样做:将前面打开的界面中(“View Type Information”)的内容拷贝,然后手动新建一个SWF.IDL的文件,将拷贝的内容粘贴入,再次执行MIDL命令。 接下来在你的VC++项目中:#import "SWF.tlb",编译之,即会在debug或者release 目录下面生成tlh(头文件,header)和tli文件(实现文件,implementation)。 注意,在tlh文件的末尾处已经包含了tli文件。 当然也可以采用下面叙述的方式生成。 3. 相关概念 多数情况下,生成的com组件DLL/EXE/OCX已经包含了类型库信息(type information),但当你的com程序足够大,可能需要分离类型库信息,此时考虑生成tlb[/B]文件,单独存放类型库。 此时使用:#import "XXX.tlb",然后编译之,也会在debug或者release下面产生 XXX.tli和XXX.tlh文件。 tlh和tli文件实际上是对com接口及其属性方法的封装类,其中tlh[/B]相当于类型申明(头文件),tli相当于定义实现(CPP文件),这里的实现完全是封装方法的实现,而不是com接口方法的实现。 如下例: 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的真正实现实际上在XXX.ocx或者XXX.dll中。 4. 开始创建IShockwaveFlash
为了简单起见,就不使用那么麻烦的方法了,直接这样:
#import "C:WINDOWSsystem32Macromed FlashFlDbg9f.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什么, 很方便。 接下来,构造、析构: CFlashHelper::CFlashHelper(void) { if(FAILED(CoInitialize(NULL))) { AfxMessageBox(L"CoInitialize Failed!rn"); return; } isf=NULL; ivo=NULL; } CFlashHelper::~CFlashHelper(void) { CoUninitialize(); } 其中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("n "),hr); return hr;} 这里还要使用一点点ATL,ATL做COM这方面的工作在行些。 故,要在工程属性中,设置“动态使用ATL”,在这个cpp文件中,包含如下头文件: #include <atlbase.h> #include <atlcom.h> #include <atlctl.h> 上面的代码中还采用了一种比较简单的方法,即: AtlAxAttachControl(isf,NULL); 传统的做法是先用CAxWindow创建窗口,然后采用其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来创建窗口,所以采用MFC来建立的Dialog, 然后AtlAxAttachControl(isf,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 这样编译的时候就会出现如下的错误: 错误 8 error C2440: “初始化”: 无法从“int”转换为“unsigned long *” c:program filesmicrosoft visual studio 9.0vcatlmfcincludeatlwin.h 523 LEDEngine 错误 9 error C2664: “GlobalAlloc”: 不能将参数 2 从“unsigned long *”转换为“SIZE_T” c:program filesmicrosoft visual studio 9.0vcatlmfcincludeatlwin.h 570 LEDEngine 其实是因为ULONG_PTR这个数据类型,这个东西在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+ 好了,这个话题就说到这里。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |