Detailed description of ATL interface ing macros [7]

Source: Internet
Author: User
7. com_interface_entry_autoaggregate (IID, punk, CLSID) parameter ATL routine commap

Let's take a look at the macro definition:
# Define com_interface_entry_autoaggregate (IID, punk, CLSID )/
{& IID ,/
(DWORD) & _ ccomcachedata </ccomaggregatecreator <_ commapclass, & CLSID> ,/
(DWORD) offsetof (_ commapclass, punk )/
>: Data ,/
_ Cache },
Let's take a look at its typical usage:
Class cautoagg:
Public idispatchimpl,
Public isupporterrorinfo,
Public ccomobjectroot,
Public ccomcoclass
{
......
......
};
Similar to general components.
Class couter:
Public cchainbase,
Public idispatchimpl,
Public ccomcoclass
{
Begin_com_map (couter)
Com_interface_entry_autoaggregate (iid_iautogate, m_punkautoagg.p,
Clsid_cauto)
End_com_map ()
Ccomptr m_punkautoscaling;
};
Unlike the macro com_interface_entry_aggregrate (_), couter does not need to create a cluster in finalconstruct.
Set components. External components are automatically created !!!
1.
Template
_ Atl_cachedata _ ccomcachedata: Data = {dwvar, Creator: creat
Einstance };
2.
Static hresult winapi _ cache (void * PV, refiid IID, void ** ppvobject, dword dw)
{
{
Hresult hres = e_nointerface;
_ Atl_cachedata * PCD = (_ atl_cachedata *) dw;
Iunknown ** pp = (iunknown **) (DWORD) PV + PCD-> dwoffsetvar );
If (* PP = NULL)
Hres = PCD-> pfunc (PV, iid_iunknown, (void **) pp );
If (* PP! = NULL)
Hres = (* PP)-> QueryInterface (IID, ppvobject );
Return hres;
}
3.
Template
Class ccomaggregatecreator
{
Public:
Static hresult winapi createinstance (void * PV, refiid/* riid */, lpvoid * PV
)
{
Atlassert (* GMM = NULL );
Atlassert (Pv! = NULL );
T * P = (T *) PV;
Return cocreateinstance (* pclsid, p-> getcontrollingunknown (),
Clsctx_inproc, iid_iunknown, GMM );
}
};
We have already seen the classes and functions of _ cache, _ ccomcachedata, and ccomaggregatecreator.
I have seen or talked about similar things, so I will not talk about them more. In short, we can see that if m_punkautoagg.p is not empty
Query directly. Otherwise, create a clustering component.
Compared with the macro com_interface_entry_aggregate, this macro seems to be better. It is created only when needed.
Easy to use.

8. com_interface_entry_autoaggregate_blind (punk, CLSID) parameter ATL routine commap

Let's take a look at its definition:
# Define com_interface_entry_autoaggregate_blind (punk, CLSID )/
{Null ,/
(DWORD) & _ ccomcachedata </ccomaggregatecreator <_ commapclass, & CLSID> ,/
(DWORD) offsetof (_ commapclass, punk )/
>: Data ,/
_ Cache },
The macro combines com_interface_entry_autoaggregate () and
The features of com_interface_entry_aggregate_blind () can be created automatically or conveniently
Multiple Interfaces in the aggregation component. No more details !!

9. com_interface_entry_chain (classname) parameter commap

Let's take a look at its definition:
# Define com_interface_entry_chain (classname )/
{Null ,/
(DWORD) & _ ccomchaindata: data ,/
_ Chain },

Typical usage:
Class cchain:
Public idispatchimpl,
Public isupporterrorinfo,
Public ccomobjectroot
Public ccomcoclass
{
........
};
It is similar to a general component.
Class couter:
Class couter:
Public cchain,
....
{
Begin_com_map (couter)
......
Com_interface_entry_chain (cchain)
End_com_map ()
};

We are already familiar with the query process. Let's take a look at the functions of _ chain.
_ Chain () is a member function of ccomobjectrootbase:
Static hresult winapi _ chain (void * PV, refiid IID, void ** ppvobject, dword dw)
{
_ Atl_chaindata * PCD = (_ atl_chaindata *) dw;
Void * P = (void *) (DWORD) PV + PCD-> dwoffset );
Return internalqueryinterface (p, PCD-> pfunc (), IID, ppvobject );
}
Struct _ atl_chaindata
{
DWORD dwoffset;
Const _ atl_intmap_entry * (winapi * pfunc )();
};
};
Let's take a look at the DW section in the macro definition:
Template
_ Atl_chaindata _ ccomchaindata: Data =
{Offsetofclass (base, derived), base: _ getentries };
Basically, we have understood what is going on. Void * P will get the base class pointer, interalqueryinterface
We are already familiar with it. _ chain transfers the base class pointer and the base class interface ing macro to it, which is actually a query.
Base Class interface !!!

Generally, this macro is placed at the end of begin_com_map and end_com_map, which indicates that only when
The interface of the parent class is queried only when the interface cannot be found in the previous class. However, we usually put it first, and then we will first check
Parent class interface. You can check the interface only when the parent class does not implement this interface. In ATL, components are implemented in Multi-inheritance mode.
Currently, ATL defines many classes to implement some common interfaces. These classes are often used as the base classes of components.
Macros are widely used.

We have already talked about all the important macros, and the rest are simple macros.
Next, let's start and end.

10. com_interface_entry_iid (IID, X)
# Define com_interface_entry_iid (IID, x )/
{& IID ,/
Offsetofclass (x, _ commapclass ),/
_ Atl_simplemapentry },

11. com_interface_entry2_iid (IID, X, X2)
# Define com_interface_entry2_iid (IID, X, X2 )/
{& IID ,/
(DWORD) (x *) (X2 *) (_ commapclass *) 8)-8 ,/
_ Atl_simplemapentry },
In terms of definition, these two macros are only compared with com_interface_entry () and com_interface_entry2 ().
An additional "IID ". There is no other benefit, except that the user explicitly specifies the interface IID, instead of the system according to the interface
The name is converted.

12. com_interface_entry_func (IID, DW, func)
# Define com_interface_entry_func (IID, DW, func )/
{& IID ,/
DW ,/
Func },
Do you still remember the code in atlinternalqueryinterface? If we find
If the interface is not of the _ atl_simpleentry type, the function specified in the macro definition is executed.
This macro provides us with the ability to write our own processing functions. This function must be defined as follows:
Hresult winapi func (void * PV, refiid riid, lpvoid * GMM, dword dw );
When atlinternalqueryinterface calls func, related information is transmitted. PV is a pointer to a Class Object, riid
It is the interface to be queried, and bpis the interface pointer to be returned for the query, and DW is the parameter specified in the macro definition.
In addition, if the function does not intend to return an interface pointer, you should assign the BPPV to null and return s_false or
E_nointerface. If s_false is returned, the query will continue. If e_nointerface is returned, the query will be terminated.
If the interface pointer is returned, s_ OK should be returned.

13. com_interface_entry_func_blind (DW, func)
# Define com_interface_entry_func_blind (DW, func )/
{Null ,/
DW ,/
Func },
For the features of the _ blind type, see the previous sections.

14. com_interface_entry_nointerface (X)
# Define com_interface_entry_nointerface (X )/
{& _ Atl_iidof (x ),/
Null ,/
_ Nointerface },
_ Nointerface is a member function of ccomobjectrootbase. Let's take a look at its definition:
Static hresult winapi _ nointerface (...)
{
Return e_nointerface;
}
It only returns e_nointerface and terminates the query.
Haha, it seems that I don't want anyone to check this interface !!!

15th, com_interface_entry_break (X)
# Define com_interface_entry_break (X )/
{& _ Atl_iidof (x ),/
Null ,/
_ Break },
_ Break is also a member function of ccomobjectrootbase. Let's take a look at its definition:
Static hresult winapi _ break (...)
{
IID;
_ Atldumpiid (IID, _ T ("break due to QI for interface"), s_ OK );
Debugbreak ();
Return s_false;
}
If this interface is found, debugbreak () will be called and s_false will be returned to continue the query.
What is debugbreak ()? You can try it on your own. You must be familiar with it.

So far, we have finished all the 15 interface ing macros. Alas, this is really not easy, especially the previous macros and
This is troublesome. Because of the limitation of text, many things are not easy to express clearly. Some names are me.
What you call this may be different from others' habits. No way. You will do it.

--------------- Full text ------------

Note: about the implementation of the class factory in ATL

1. When creating a component, you must first create its class factory and then call createinstance () of the class factory to create the component.
The macro declare_classfactory () is defined in ccomcoclass and contains the class factory object of the component.
_ Classfactorycreatorclass. Its createinstance is used to create the class factory of the component, that is
Ccomcreator <Ccomclassfactory >:: createinstance ();
2. In ccomcoclass, the macro declare_aggregatable () is also defined, including the object _ creatorclass,
This object is actually the component object we want to create (For details, refer to "1"). It also has
Createinstance. This function is used to create this component !! This
To the class factory.
3. After we successfully obtain the class factory object (at this time, the class factory has been created), we will then call the class factory
Createinstance (). In this function, the createinstance of the component is called to create the component.
4. Therefore, three createinstances are involved:
(1) _ classfactorycreatorclass: createinstance () // class factory object used to create components
(2) ccomclassfactory: createinstance () // call _ creatorclass: createinstance
(3) _ creatorclass: createinstance () // used to create a component

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.