描述:
此问题我已卡住很多天了,VCKbase,微软新闻组都问过了,仍没有解决!
环境:
工具:VC.net
项目类型:支持MFC的动态链接库
功能:
首次加载此DLL时会注册一个窗口类,并且负责管理此窗口类的消
息。
目的:
1、我要在这个窗口类的某条消息中创建FLASH动画
通常方法:
1、网上有人提供了MFC下的CShockwareFlash类,在MFC应用程序下
很好用,但是用在此项目中会出错误。是容器错误。
2、Win32应用程序下可以使用一个CAxWindow的东西,也很简单好
用,但在此项目中失败。
请高人指点迷津,卡住很多天了。最好能告诉我如何不用MFC或者
什么容器之类的东西就能实现的方式。能不能通过查找注册表查看
用户安装的FLASH版本及其相应的文件位置,然后加载那个ocx文件
我自己调用里面的函数这样从最原始的方式创建FLASH?
现在我直接用控件里的CShockwareFlash类实现FLASH出错:
/**********************堆栈:
>mfc71d.dll!CWnd::InvokeHelper(long dwDispID=142, unsigned short wFlags=1, unsigned short vtRet=0, void * pvRet=0x00000000, const unsigned char * pbParamInfo=0x1003a944, ...) 行374 + 0x3 C++
Really.dll!CShockwaveFlash::LoadMovie(long layer=0, const char * url=0x10034ad4) 行317 + 0x21 C++
Really.dll!CReallyApp::Add_Flash(tagPOINT pt={...}) 行674 C++
Really.dll!CReallyApp::WndProc(HWND__ * hWnd=0x000506f6, unsigned int message=273, unsigned int wParam=32772, long lParam=0) 行493 C++
/**********************出错的OLE代码:
//////////////////////////////////////////
// CWnd invoke helpers for OLE Control wrappers
void AFX_CDECL CWnd::InvokeHelper(DISPID dwDispID, WORD wFlags, VARTYPE vtRet,
void* pvRet, const BYTE* pbParamInfo, ...)
{
ASSERT(m_pCtrlSite != NULL); // not an OLE control (not yet, at least)
if (m_pCtrlSite == NULL)
return;
va_list argList;
va_start(argList, pbParamInfo);
m_pCtrlSite->InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo,
argList);
va_end(argList);
}
/**********************异常提示:
DllTestSdk.exe 中的 0x7c239fd7 (mfc71d.dll) 处未处理的异常: 0xC0000005: 读取位置 0x00000050 时发生访问冲突 。
/**********************输出:
Warning: constructing COleException, scode = DISP_E_MEMBERNOTFOUND ($80020003).
DllTestSdk.exe 中的 0x77e53887 处最可能的异常: Microsoft C++ exception: COleException @ 0x0012e59c 。
Warning: constructing COleException, scode = DISP_E_MEMBERNOTFOUND ($80020003).
DllTestSdk.exe 中的 0x77e53887 处最可能的异常: Microsoft C++ exception: COleException @ 0x0012e59c 。
DllTestSdk.exe 中的 0x7c239fd7 (mfc71d.dll) 处最可能的异常: 0xC0000005: 读取位置 0x00000050 时发生访问冲突 。
DllTestSdk.exe 中的 0x7c239fd7 (mfc71d.dll) 处未处理的异常: 0xC0000005: 读取位置 0x00000050 时发生访问冲突 。
我需要一个安全的可以在只有一个HWND的情况下可以使用FLASH的方法,谢谢!
解决方案1:
看有用没有
com的优越就不多说,使用atl开发com方便而快捷,并且具有size小,dependency少的特点。vc++的import 编译支持更是对com开发的巨大支持。闲话休说,这就开始吧。
一.flash组件
1.atl com appwizard创建新项目"atlflash",选择dll类型。
2.加入atl object "flash"
insert -> new atl object
选择object中的simple object,
short name:“flash”
3.接口添加method “play”
参数为:[in]bstr bstrfile,[in]long hinstance,[in]long hwnd
4.在cflash类中加入:
private:
hwnd m_hwnd;//视频窗口句柄
5. 实现play方法。
stdmethodimp cflash::play(bstr bstrfile, long hinstance, long hwnd)
{
try{
m_hmciwnd=(hwnd)hwnd;
_bstr_t file(bstrfile);
m_hmciwnd=::mciwndcreate((hwnd)hwnd,(hinstance)hinstance,
ws_popup¦ws_visible¦
mciwndf_noplaybar¦
mciwndf_nomenu,
(char *)file);
rect rect;
int sx,sy;
::getwindowrect(m_hmciwnd,&rect);
sx=(::getsystemmetrics(sm_cxscreen)
-rect.right+rect.left)/2;
sy=(::getsystemmetrics(sm_cyscreen)
-rect.bottom+rect.top)/2;
//窗口居中
::setwindowpos(m_hmciwnd,hwnd_topmost,sx,
sy,0,0,swp_showwindow¦swp_nosize);
g_nlength=mciwndgetlength(m_hmciwnd);
mciwndplay(m_hmciwnd);
settimer(m_hmciwnd,1,50,timerproc);
}catch(...)
{
atltrace("error:%ul",::getlasterror());
}
return s_ok;
}
6.flash.cpp中实现timerproc,用于关闭视频窗口。
long g_nlength;
void callback timerproc(
hwnd hw