"Reprint" COM Component design and application (16)--Connection point (vc.net)

Source: Internet
Author: User

Original: http://vckbase.com/index.php/wv/1257.html

First, preface

The last book introduced the callback interface, on the basis of which we understand the connection point is much easier.

Second, the principle

Diagram One, the connection point component schematic diagram. Left side is client, right side is service side (Component object)

It looks so complicated ... Oh, in fact, simple tight: (Note 1)

1, a COM component that allows multiple connection point objects (IConnectionPoint).

This means that there can be multiple sources of "events" happening. There are 3 points of connection;

2. The interface for managing these connection points is called a "Connection point container" (IConnectionPointContainer).

The connection point container interface is particularly simple, because there are only 2 functions, one is FindConnectionPoint (), which means finding the connection point you want, and the other is EnumConnectionPoints (), which indicates that all the connection points are listed, and then you choose which one to use. In practical applications, the lookup method uses the most, accounting for 90%, while the enumeration method uses only 10%, generally in support of third-party plug-ins (Plug in). (Do you want to write a plugin for IE?) We'll talk about it later.)

3, each connection point, can be multiple clients of the receiver (Sink) connection;

We are familiar with this, remember we in the last book in order to manage multiple callback interface, using a cookie way to make a difference?!

III. Realization of components (I.)

1, establish a blank solution.

2. In the solution, add the ATL project. The project name in the sample program is called SIMPLE16, and be careful not to select the "Attributed Programming" method.

3. Add an ATL class. Select simple objects for ATL.

4. In the name card, enter the component name. The sample program is Dispconnect.

5, option card, interface type Select Dual interface. Note Be sure to select the connection point.

6, add the interface function. As with the previous program, add a method to calculate the integer addition, and return the calculation result by the connection point.

7, the following should increase the "event" function. Select the event interface (_idispconnectevents) and add the function.

8. The function is used to return the calculation result of the ADD () function.

9. Generate Event proxy class program code. Select Component Class object (Cdispconnect), perform the right mouse button menu "Add Connection Point"

10. Select the agent code that you want the IDE to help you build which connection point. We have only one connection point for this component, so we have to choose it. (In the program of example two, we implemented two connection points, then you have to choose two interfaces)

11, to this, the VC IDE finally help us to complete all the framework, the following we write the real task code.

STDMETHODIMP Cdispconnect::add (Long N1, long N2) {Long nval = n1 + n2; Fire_result (nval);//Call the IDE to help us generate the proxy function code, issue the event return S_OK;}

  

Iv. Implementing the Caller (i)

1, set up an MFC project. The name in the sample program is called use.

2, according to the knowledge we learned before, add #import, AfxOleInit () 、...... Not much waste of tongue. If you do not, then please re-read it again from "fourth back". (Note 2)

3. Here are just a few highlights. We need to add the "sink" object in the caller's project. Remember the way you added the callback receiver object to the last book? On the last, our callback interface was inherited from IUnknown. In this case, because our component is a dual interface (Dual), the connection point is also a dual interface, so this time our receiver will be derived from IDispatch.

4, complete the CSink class interface function (virtual function)

STDMETHODIMP Csink::queryinterface (const struct _GUID &iid,void * * PPV) {*ppv=this;return S_OK;} ULONG __stdcall csink::addref (void) {return 1;} Just make a fake, because this object will not quit before the program ends. ULONG __stdcall Csink::release (void) {return 0;} Make a fake, because this object will not exit before the end of the program Stdmethodimp csink::gettypeinfocount (unsigned int *) {return E_NOTIMPL;} Do not have to implement, anyway do not stdmethodimp csink::gettypeinfo (unsigned int,unsigned long,struct ITypeInfo *) {return E_NOTIMPL;} Do not have to implement, anyway do not stdmethodimp Csink::getidsofnames (<span style= "color: #0000ff;" >const</span> IID &,lpolestr *,uint,lcid,dispid *) {return E_NOTIMPL;} Do not have to implement, anyway do not stdmethodimp Csink::invoke (long dispid,const struct _guid &,unsigned long,unsigned short,struct Tagdispparams * pparams,struct tagvariant *,struct tagexcepinfo *,unsigned int *) {//Just implement this is enough switch (DISPID)// Depending on the DispID, complete the different callback function {case 1:......//here to receive the event that COM emitted break;case 2:......//event code DISPID is actually the ID of the connection point function in the IDL file (n) The number Break;default:break;} return S_OK;}

  

Five , Example (ii)

The 2nd component in the sample program (Multconnect), we add one more connection point (_IDISPCONNECTEVENTS2). This interface object is responsible for the completion of a clock, each interval of a certain Hao seconds to the caller issued a "clock event." Adding a second connection point is to manually modify the IDL file

..... library Multconnectlib{importlib ("Stdole2.tlb"); ...//First connection point. It is the <b>[   //2nd connection point that ATL helped us generate, and we need to add the UUID (e3330ae1-2b1d-42e6-a8e0-a9cb0d1ac74c) manually,//CLSID can be used with GUIDGEN. EXE generates helpstring ("_idispconnect event Interface")]dispinterface _idispconnectevents2{properties:methods:};</b> [UUID ( 4B0FDB44-BAF2-4F25-A2B0-B5ECD5CD440E),//This is the type library ID of the sample program, certainly and you produce a different helpstring ("Dispconnect Class")]coclass Dispconnect{[default] Interface idispconnect;[ Default, source] dispinterface _idispconnectevents; <b>[source] dispinterface _idispconnectevents2; Don't forget, there's another line </b>};

  

Well, as in the previous way, add interface functions, let the IDE help us implement proxy class code, enter program code, and modify the bug in the framework code. In the example, our event function is called HRESULT Timer ([in] VARIANT Vardata), which passes information about a time type (Vt_data) in Vardata (note 3). Let's take a look at the error in the proxy class code:

HRESULT Fire_timer (VARIANT  vardate) {HRESULT hr = S_OK;  T * PThis = static_cast (this); int cconnections = M_vec.  GetSize ();    for (int iconnection = 0; iconnection < cconnections; iconnection++) {Pthis->lock (); CComPtr punkconnection = M_vec.    GetAt (iconnection);    Pthis->unlock ();    IDispatch * pconnection = static_cast (PUNKCONNECTION.P);      if (pconnection) {ccomvariant avarparams[1];    <b>//Original: avarparams[0] = VARDATE;AVARPARAMS[0].VT = Vt_variant;      //But unfortunately this is wrong, because avarparams[0] = vardate; the assignment has been done correctly  //And then the AVARPARAMS[0].VT assignment, which is the reference way to do so.  avarparams[0] = vardate;//This is the right operation </b>   CComVariant Varresult;       Dispparams params = {avarparams, NULL, 1, 0};       hr = Pconnection->invoke (1, Iid_null, Locale_user_default, dispatch_method,¶ms, &varresult, NULL, NULL); }} return hr;

  

In terms of writing caller client code, if you need to receive clock events, you can emulate the example to derive a clock sink from IDispatch repeatedly. We download the case program code, which contains a wealth of explanatory information.

Vi. Summary

Connection points, especially the two-interface connection points, are less efficient to run on a remote (DCOM) environment. If you only want to complete the simple "notifications" feature, then the callback interface in the previous one is a sensible scenario and can be run on a DCOM environment. Connection point scenarios are of course also important because many Microsoft applications (IE, Office ...) All support connection points, and ActiveX can only provide "events" functionality through the connection point interface. So, we are all in good hands. Good and good ...

Note 1: Jin Yong's martial arts novels, always use "xx tight" to express "very xx." I also learn to learn, hehe.

NOTE 2: If you have seen it several times, your ladyship will not be able to do so. Don't learn it first. 5555

Note The 3:data type is a 8-byte double, and its integer portion represents the total number of days starting December 30, 1899, and the fractional part indicates how many points of the day the day has elapsed. This time type, represented by a variant, is the vt_date type, which is represented by COleDateTime in MFC. There is a demonstration of this type of operation in the sample program.

"Reprint" COM Component design and application (16)--Connection point (vc.net)

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.