我是MFC的com,当处理异常的时候,我希望能抛出异常,让JS可以捕捉的到,但现在很多地方讲到的都是基于ATL的error返回,我查了些资料,
CComQIPtr< ICreateErrorInfo> spCEI;
::CreateErrorInfo( &spCEI ); spCEI->SetGUID( IID_IDeskConsole ); // 发生错误的接口IID
spCEI->SetSource( L"EcmUploadComponent.EcmDfcUpload" ); // ProgID
spCEI->SetDescription( L"cuowuxinxi");
CComQIPtr < IErrorInfo > spErrInfo = spCEI;
if( spErrInfo )
::SetErrorInfo( 0, spErrInfo );
throw _com_error(hr, spErrInfo);
但这样方式的处理还是不能解决问题,直接就出现VC的红叉叉了。不知道可以如何解决
CComQIPtr< ICreateErrorInfo> spCEI;
::CreateErrorInfo( &spCEI ); spCEI->SetGUID( IID_IDeskConsole ); // 发生错误的接口IID
spCEI->SetSource( L"EcmUploadComponent.EcmDfcUpload" ); // ProgID
spCEI->SetDescription( L"cuowuxinxi");
CComQIPtr < IErrorInfo > spErrInfo = spCEI;
if( spErrInfo )
::SetErrorInfo( 0, spErrInfo );
throw _com_error(hr, spErrInfo);
但这样方式的处理还是不能解决问题,直接就出现VC的红叉叉了。不知道可以如何解决
解决方案 »
- MFC~登录框~密码验证
- 水分一万
- CListCtrl里的问题~求助!
- 小菜问问^-^
- 问个老问题,怎么调用选择图标对话框?
- 问:类型库方式和自动化方式的区别
- 请问,我有一行字符串,格式如下,我如何解析它为一个字符串变量,一个字符变量,三个整数变量
- 请问CDC::SetViewportExt(x,y)怎么用啊?它应该是将x,y映射成屏幕上的逻辑点吧,可是我画不出来呀 ???
- 试图在钩子里隐藏即将显示的窗口
- 请问怎么在MSFlexGrid中直接操作数据库啊?
- (递归建立二叉搜索树时错误)Unhandle exception in FaceR.exe(NTDLL.DLL):0XC0000005:Access Violation
- 对了,有个问题我以前通过网络解决了不过没记录现在又忘记了
你的组件不是有方法吗?方法不是返回HRESULT吗?直接返回E_...开头的值就能被JS捕获,只要不是返回S_OK或者S_FALSE就可以了。
我的声明改成DISP_FUNCTION_ID(DeskConsole, "createFolder", dispidcreateFolder, createFolder, VT_HRESULT, VTS_BSTR),怎么就直接执行报错了呢
后来是干脆不用HRESULT 把错误号和描述文本做一个retval参数返回了
不要用智能指针,这样出了作用域话会被释放掉的,你这样试试看行不行.IErrorInfo* pIErrorInfo = NULL;
spCEI->QueryInterface(IID_IErrorInfo, (void**)&pIErrorInfo);
SetErrorInfo(hr, pIErrorInfo);
throw _com_error(hr, pIErrorInfo);
下面是我的代码,我没有在JS下测试过,不过在COM里是可以用的,你可以参考一下!
//-----------------------------------------------------------
// Name : _ComIssueError()
// Desc : Issue COM error information
//-----------------------------------------------------------
void _ComIssueError(HRESULT hr, LPCTSTR pszSource, LPCTSTR pszDescrption,
REFGUID rguid, LPCTSTR pszHelpFile, DWORD dwHelpContext)
{
CComQIPtr<ICreateErrorInfo> pICreateErrorInfo;
IErrorInfo* pIErrorInfo;
if( SUCCEEDED(CreateErrorInfo(&pICreateErrorInfo)) )
{
USES_CONVERSION;
pICreateErrorInfo->SetSource(T2OLE(pszSource));
pICreateErrorInfo->SetDescription(T2OLE(pszDescrption));
if( rguid != GUID_NULL )
pICreateErrorInfo->SetGUID(rguid);
if( pszHelpFile != NULL )
pICreateErrorInfo->SetHelpFile(T2OLE(pszHelpFile));
if( dwHelpContext != 0 )
pICreateErrorInfo->SetHelpContext(dwHelpContext);
if( SUCCEEDED(pICreateErrorInfo->QueryInterface(IID_IErrorInfo, (void**)&pIErrorInfo)) )
{
SetErrorInfo(hr, pIErrorInfo);
throw _com_error(hr, pIErrorInfo);
}
}
}
函数实体HRESULT DeskConsole::createFolder(LPCSTR folderName )这样会不可以呢,把VT_HRESULT改成别的就可以
有一些标准的错误类型,比如E_OUTOFMEMORY,脚本引擎都能识别并抛出对应的异常,如果需要自定义异常,函数返回值应该设置成DISP_E_EXCEPTION,同时在组件的Invoke方法的倒数第二个参数(EXCEPINFO指针指向的结构)中填充自己的内容。MFC有点麻烦,它做了一层封装,隐藏了HRESULT细节,我看看MFC中有没有解决办法。
2、当需要抛出异常时,调用CreateErrorInfo创建一个IErrorInfo,再调用SetErrorInfo,最后返回E_开头的HRESULT。注意不能使用throw语句,这个是用于C++的,不是脚本。
3、在ISupportErrorInfo::InterfaceSupportsErrorInfo实现里判断是否已经设置了错误信息,返回S_OK或者S_FALSE