【原创翻译】COM入门简介 -- 什么是COM , 怎样使用它 (5)

Introduction to COM - What It Is and How to Use It
By Michael Dunn
From www.codeproject.com

/**********原创翻译,转载请注明出处*********** 新手水平有限,欢迎批评指教 By FreeKid /

COM入门简介 -- 什么是COM , 怎样使用它 (5)

使用多个含有多个接口的COM对象

第二个示例展示了如何对只有一个接口的COM对象使用QueryInterface()函数。代码使用在shell中包含的Shell Link Coclass来创建一个指向当前壁纸文件的快捷方式,壁纸文件名我们是从上一个例子中获得的。

步骤如下:

    1. 初始化COM库。
    2. 创建COM对象以便创建快捷方式,并且获得IShellLink接口。
    3. 调用IShellLink接口的SetPath()方法。
    4. 在COM对象上调用QueryInterface()并获得一个IPersistFIle接口。
    5. 调用IPersistFile接口的Save()方法。
    6. 释放所有接口。
    7. 反初始化COM库。

CString       sWallpaper  =  wszWallpaper;   //  Convert the wallpaper path to ANSI
IShellLink *    pISL;
IPersistFile
*  pIPF;

    
//  1. Initialize the COM library (make Windows load the DLLs). Normally you would
    
//  call this in your InitInstance() or other startup code.  In MFC apps, use
    
//  AfxOleInit() instead.
    CoInitialize ( NULL );

    
2 . Create a COM  object using  the Shell Link coclass provided by the shell.
    
//  The 4th parameter tells COM what interface we want (IShellLink).
    hr  =  CoCreateInstance ( CLSID_ShellLink,
                            NULL,
                            CLSCTX_INPROC_SERVER,
                            IID_IShellLink,
                            (
void ** & pISL );

    
if  ( SUCCEEDED(hr) )
        
{
        
// 3. Set the path of the shortcut's target (the wallpaper file).
        hr = pISL->SetPath ( sWallpaper );

        
if ( SUCCEEDED(hr) )
            
{
            
// 4. Get a second interface (IPersistFile) from the COM object.
            hr = pISL->QueryInterface ( IID_IPersistFile, (void**&pIPF );

            
if ( SUCCEEDED(hr) )
                
{
                
// 5. Call the Save() method to save the shortcut to a file.  The
                
// first parameter is a Unicode string.
                hr = pIPF->Save ( L"C:/wallpaper.lnk", FALSE );

                
// 6a. Release the IPersistFile interface.
                pIPF->Release();
                }

            }


        
// 6b. Release the IShellLink interface.
        pISL->Release();
        }


    
//  Printing of error messages omitted here.

    
//  7. Uninit the COM library.  In MFC apps, this is not necessary since MFC
    
//  does it for us.
    CoUninitialize();


处理HRESULTs

我已经展示了一些使用SUCCEEDED和FAILED宏进行错误处理的简单例子。现在我会进一步说明应当怎样处理从COM方法中返回的HRESULTs类型。

HRESULT是一个32位的有符号整数。非负表示成功,负数则表示失败。HRESULT有三个域(field):the severity bit(用来指明成功或失败),the facility code和 the status code. "facility"指明了HRESULT来自哪个组件或程序。微软把facility codes分配给了不同的组件,比如COM,比如任务调度器(Task Scheduler)等等。这种code是一串16位没有内在含义的数字。它们仅仅是用来在数字和含义之间建立一种随意的联系,就像用GetLastError()的返回值那样。

如果你在winerror.h文件中查看这些错误代码,你会发现那里列出了很多HRESULTs。它们的格式是这样的:[facility]_[severity]_[description].通常的HRESULTs可以不含有facility部分,它们可以被任何组件返回。例如:

    REGDB_E_READREGDB:Facility = REGDV,代表"registry database"; E = error; READREGDB是一种错误的描述(不能读取数据库)
    S_OK:Facility = generic; S = success; OK是一种状态描述(一切正常)

幸运的是,有许多比在winerror.h文件中查看更容易的方式,来弄清楚HRESULT的意思。HRESULTs可以用错误查看工具来进行处理。比如,你忘记了在使用CoCreateInstance()之前调用CoInitialize().CoCreateInstance()将返回错误代码0x800401F0,你可以把这个错误代码输入的错误查看工具中,然后你就会看到描述信息:“CoInitialize没有被调用”

你也可以在调试器中查看HRESULT的描述信息。如果你有一个叫做hres的HRESULT变量,你可以在观察窗口(Watch window)中输入"hres,hr"进行查看。"hr"会告诉VC将hres的值作为一个HRESULT描述信息显示出来。

参考书目:

Essential COM by Don Box, ISBN 0-201-63446-5. Everything you'd ever want to know about the COM spec and IDL (interface definition language). The first two chapters go into great detail about the COM spec and the problems it was designed to solve.

MFC Internals by George Shepherd and Scot Wingo, ISBN 0-201-40721-3. Contains an in-depth look at MFC's COM support.

Beginning ATL 3 COM Programming by Richard Grimes, et al, ISBN 1-861001-20-7. This book goes into depth about about writing your own COM components using ATL.


(全文完)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值