荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Second (石开), 信区: Program
标  题: ATL问题集-#15 ~ #16
发信站: 荔园晨风BBS站 (Fri Jun  1 08:02:02 2001), 转信


#15 在COM/ATL中如何处理错误?

基于Windows的组件都有支持ISupportErrorInof接口,它允许将组件的错误信息返回给
客户端,在VC5以后提供了本地的支持,如下:
_com_error( HRESULT hr, IErrorInfo* perrinfo = NULL ) throw( );
_com_error( const _com_error& that ) throw( );
这个函数检查IErrorInfo接口指针年是否存在,如果存在将抛出_com_error异常对象,
你只要捕获这个_com_error异常对象就要以了,以下是示例代码:
STDMETHODIMP CMessageHandler::NewMessage(BSTR inMessage, BSTR inTo,
                                         BSTR inFrom, BSTR inReply)
{
    HRESULT hr = S_OK;
    try
 {
    ......
    if(FAILED(hr))
        _com_error(hr);
    }
    catch (_com_error& e) {
        hr = Error((BSTR)e.Description(), e.HelpContext(), e.HelpFile(),e.GU
ID(), e.Error());
        ATLTRACE("com error: %d - %s\n", e.Error(), (const char*)e.Descripti
on());
    }
    return hr;
}
至于返回错误信息到客户端,请参阅我的《COM的错误处理》(也在文档中心)。


#16 如何自定义控件的Verbs?
Microsoft标准文档定义了OLE对象从容器中响应消息,在一个对象容器或客户端链接到
对象,通常是调动IOleObject::DoVerb()来响应用户或容器的消息,你可以通过双击对
象或点击鼠标右键的上下文菜单来提供的选择来操作,容器对象装入上下文菜单是通过
调用IOleObject::EnumVerbs().
典型的服务对象或控件是在IOleObject::EnumVerbs()的实现中调用OleRegEnumVerbs()
 ,ATL默认实现了这些功能,但你必须按照以下步骤:
1.首先添加菜单项到.RGS文件中,verb关键字存储在注册,如下:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\Verb
      \1 = <verb1>
      \2 = <verb2>
      \3 =
以下是verb的格式:
Verb_Number = <Verb_String, Menu_Flag, Verb_Flag>
Verb_Number是个枚举类型,Verb_String是有效的字符串,像"属性",Menu_Flag描述如
何调用::AppendMenu,Verb_Flag是OLEVERBATTRIB枚举类型的值之一,如下:
OLEVERBATTRIB_NEVERDIRTIES       = 1,
OLEVERBATTRIB_ONCONTAINERMENU    = 2
所以请修改你的.RGS文件,如下:
   NoRemove CLSID
   {
      ForceRemove {E14A8DEA-8C72-11D1-891C-00C04FA3FB11} = s 'X Class'
      {
         ProgID = s 'X.X.1'
         VersionIndependentProgID = s 'X.X'
         ForceRemove 'Programmable'
...
         'verb'
         {
            '1' = s '&Play,0,2'
'2' = s '&Transpose,0,2'
'3' = s '&Detune,0,2'
'4' = s '&Properties,0,2'
         }
...
      }
   }
当容器检测到作过在对象上的verb操作将调用IOleObject::DoVerb(),在ATL,你需要覆
盖IOleObjectImpl::DoVerb(),如下:
STDMETHOD(DoVerb)(LONG iVerb,
LPMSG lpmsg,
IOleClientSite *pActiveSite,
LONG lindex,
HWND hwndParent,
LPCRECT lprcPosRect)
{
if (iVerb == 1)//The verb number mentioned in the .rgs file
   {
       //Do whatever you want
   }
else if(iVerb == 2)
{
}
?
?
return IOleObjectImpl<ClassName>::DoVerb(iVerb, lpmsg,
    pActiveSite, lindex, hwndParent, lprcPosRect);
}

--
                            既然热爱生命
                            那么,
                            一切都在意料之中。

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.28.190]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店