对于SWE相关COM知识的不解

时间: 14:09 2010-8-19
PAGE:
http://www.codeguru.com/Cpp/COM-Tech/activex/tutorials/article.php/c5567
http://www.codeproject.com/KB/COM/comintro.aspx

感言: COM 很00,很设计模式

COM :
其的接口分离:操作列表
实现:
实现类:
其要求实现接口类,与一些常用的接口.
其是可以通过接口类继承一些接口,然后在实现类当中统一实现。
(SWE是就是这样处理的,如自定义控件,我们能否子类化内置控件呢, 不知道,主要是:内置控件其提供了接口

类,但其没有提供实现类,自定义控件其就提供了相关实现类。
COM 很00,很设计模式: 内置控件其提供了接口,我们能否使用:装饰者模式来添加新功能(如果对于修改控件的

外观,其能够在XAML文件当中实现,但用C++我们还很好的实现,思考。。。)


实现类其一般继承接口类(自定义的)与接口类当中的接口的对应实现类。
如:
interface I a : public Ib
{};

class a : public Ia, b
{

}

COM 的内部类,其是由a 创建。
a 其是由一个工厂函数来创建的。(这种设计思想在MS的SWE当中到处可见)

整个COM 其是放在一个DLL文件当中,
一个DLL文件当中其可以包含多个COM.
DLL 文件当中其就有一个工厂函数.

其一定要创建一个COM CLASS.
然后通过COM CLASS::QueryInterface(IID,PPV)  来查找接口.
QueryInterface其是用来打查找接口的,当要查找接口的时候其就可以使用QueryInterface。
使用COM之前要创建COM对象与查找接口 ,其调用一个工厂函数就能一同实现.

在一个标准的COM,其是有一个IFactoryClass instance ( 工厂类), 注意工厂类其是用于创建其他对象(COM

CLASS),而不是自身对象,
然后COM CLASS 其就可以查找接口.


HRESULT __stdcall CAddFactory::CreateInstance(IUnknown* pUnknownOuter,
                                           const IID& iid,
                                           void** ppv)
    {

 // Create an instance of the component.

 CAddObj* pObject = new CAddObj ;
 if (pObject == NULL)
     {
  return E_OUTOFMEMORY ;
     }
 // Get the requested interface.
 return pObject->QueryInterface(iid, ppv) ;
    }

CLIENT 通过CreateInstance(工厂函数)传入IID,就可以查找到接口。

在SWE当中,其就是以这种思路进行的实现。
其首先要求控件进行注册,==》 建立一个表。
CAddObj * pObject = new CAddObj;
这一步在SWE当中是怎么样实现的.分为两步:
1. new
2.Create ( 因为要LOAD XAML ,查找控件的成员,与对于控件相关成员绑定事件)

最后才是查找接口. 注意其没有使用NEW 而是使用类型转换.

HRESULT __stdcall CAddObj::QueryInterface(
                                    REFIID riid ,
                                    void **ppObj)
    {
    if (riid == IID_IUnknown)
        {
     *ppObj = static_cast<IAdd*>(this) ;
        AddRef() ;
        return S_OK;
        }

    if (riid == IID_IAdd)
     {
     *ppObj = static_cast<IAdd*>(this) ;
        AddRef() ;
        return S_OK;
     }

    if (riid == IID_IFileIO)
     {
     *ppObj = static_cast<IFileIO*>(this) ;
        AddRef() ;
        return S_OK;
     }

    //
    //if control reaches here then , let the client know that
    //we do not satisfy the required interface
    //

    *ppObj = NULL ;
    return E_NOINTERFACE ;
    }

我们存储控件,
我们应该存储哪一个部分呢。是实现类,还是接口

思考:
1.
其为什么只是接口有IID,
而实现类没有IID,( 其对应于CLSID,好像可以有,也可以没有,所以在XAML2CPP.EXE所生成的代码当中,其没有

写)

2.其为什么没有采用这种方式呢,这种形式是什么.
hr = CoCreateInstance ( CLSID_XXX,         // CLSID of coclass
                        NULL,                    // not used - aggregation
                        CLSCTX_INPROC_SERVER,    // type of server
                        IID_IXXXX,          // IID of interface
                        (void**) &pIXX );        // Pointer to our interface pointer

DllGetClassObject ==> 其是在DLL当中有IClassFactory.

CoCreateInstance  其是DLL当中没有IClassFactory的情形,其直接完成IClassFactory的功能.

STDAPI DllGetClassObject(const CLSID& clsid,
                         const IID& iid,
                         void** ppv)
    {
    //
    //Check if the requested COM object is implemented in this DLL
    //There can be more than 1 COM object implemented in a DLL
    //

    if (clsid == CLSID_AddObject)
        {
        //
        //iid specifies the requested interface for the factory object
        //The client can request for IUnknown, IClassFactory,
        //IClassFactory2
        //
        CAddFactory *pAddFact = new CAddFactory;
        if (pAddFact == NULL)
            return E_OUTOFMEMORY;
        else
            {
            return pAddFact->QueryInterface(iid , ppv);
            }
        }
   

    //
    //if control reaches here then that implies that the object
    //specified by the user is not implemented in this DLL
    //

    return CLASS_E_CLASSNOTAVAILABLE;
    }


// 在DLLMAIN.CPP 当中,
其传入CLSID 是CLSID_AddObject,而不是CLSID_FactoryObject,( 因为IFactoryObject 其只是一个接口,而非

实现类)

但其创建的对象:CAddFactory *pAddFact = new CAddFactory;
其的接口IID:IID_IClassFactory OR IID_IUnknown.
PPV: 其是指向 CAddFactory 而不是CAddObject.

==》 以后要调用COM的接口,其要使用调用 CAddFactory::CreateInstance
  然后调用CAddObj::QueryInterface.

 a class ID ,or CLSID ,is  a GUID that names a coclass(short for component object class). an interface ID,or

IID,is a GUID that names an interface.

A COM object is an instance of a coclass in memory

Note that a COM "class" is not the same as a c++ "class"
a COM class 是由A C++ CLASS 实现的。

在程序当中怎么样使用了,使用哪一个 class呢,
如存储

Create A COM OBJECT ,其就是创建一个C++ OBJECT 吗,
将C++ OBJECT 赋值给INTERFACE,其就是INTERFACE 类了吗


every COM interface is derived from IUnkown.
every COM object(C++ 对象) implements IUnkown.

QueryInterface() - Requests an interface pointer from a COM object .You use this when a coclass
implement more than one interface.

一个COM class 其是一个实现了所有接口的C++ CLASS 吗,
一个COM CLASS 其是否允许有多个C++ CLASS呢.

COM 其是采用了很多的设计模式,

面向接口编程,

其之所以能够很自然的这样处理是因为,其采用了接口,这是使用很多设计模式的基础.( 如装饰,适配器)

其当中之所以要引用smartpointer,其就是为了管理new出来的对象,由谁业delete的问题.

smartpointer : smart,pointer.
用户将其当作pointer来进行处理。
smart: 其是用于管理pointer的指针引用 。

对于接口类的使用,其是通过
SmartPointer

原文地址:https://www.cnblogs.com/pengxinglove/p/1809802.html