COM Component Design and Application (16)

Source: Internet
Author: User
Connection Point (vc.net)

Author: Instructor Yang

Download source code

I. Preface

The callback interface is introduced in the previous response. On this basis, it is much easier to understand the connection points.

Ii. Principles


Figure 1. Schematic diagram of the connection point component. Client on the left and server on the right (Component Object)

Look complicated... haha, actually simple: (Note 1)
1. a COM component allows multiple connection point objects (iconnectionpoint ).
That is to say, there can be multiple sources where "events" occur. There are three connection points;
2. The interface for managing these connection points is called the "connection point container" (iconnectionpointcontainer ).
The connection point container interface is very simple, because there are only two functions, one is findconnectionpoint (), which indicates to find the desired connection point; the other is enumconnectionpoints (), which indicates to list all the connection points, then you can select which one to use. In actual applications, the lookup method is used most, accounting for 90%, while the enumeration method only accounts for 10%. It is generally used only when third-party plug-ins (plug in) are supported. (Do you want to write an IE Plug-in? We will talk about it later)
3. Each connection point can be connected by the receivers of multiple clients;
We are familiar with this. Do you still remember that we used cookies to manage multiple callback interfaces in the previous response ?!

Iii. Implementation components (I)

1. Create a blank solution.
2. Add an ATL Project in the solution. In the example program, the project name is simple16. Be sure not to select the "attribute-based programming" method.
3. Add the ATL class. Select "Simple Object of ATL ".
4. Enter the component name in the name card. In this example, dispconnect is used.

5. In the tab, select "double interface" for the interface type. Be sure to select "connection points ".

6. added interface functions. Like the program of the previous book, add a method to calculate the integer addition, and return the calculation result through the connection point.

7. Add the "event" function below. Select the event interface (_ idispconnectevents) and add the function.

8. This function is used to return the calculation result of the add () function.

9. Generate the event proxy program code. Select the component class Object (cdispconnect) and right-click it and choose "add connection point"

10. Select the proxy code at which point you want the IDE to generate for you. We have only one connection point for this component, so we have to choose it. (In the example 2 program, we have implemented two connection points, so you have to select two interfaces)

11. At this point, VC's ide finally helped us complete all the frameworks. Now let's write our own task code.

Stdmethodimp cdispconnect: add (long N1, long N2) {long nval = N1 + N2; fire_result (nval); // call the Agent Function Code that IDE generates for us, send event return s_ OK ;}

IV. Implementation of callers (1)

1. Create an MFC project. The name in the sample program is use.
2. Add # import, afxoleinit (),... according to our previous knowledge. If you still don't know, read it again from the fourth round. (Note 2)
3. Here we will only introduce the key parts. We need to add the "receiver" object in the caller project. Do you still remember the method for adding the "Callback receiver" object in the previous response? In the previous process, our callback interface was inherited from iunknown. In this return, because our components are dual interfaces and the connection points are also dual interfaces, our receiver needs to be derived from idispatch this time.

4. Complete csink class interface functions (virtual functions)

Stdmethodimp csink: QueryInterface (const struct _ guid & IID, void ** NPV) {* GMM = This; return s_ OK;} ulong _ stdcall csink: addref (void) {return 1;} // you can make a false one, because this object will not exit ulong _ stdcall csink: release (void) before the end of the program) {return 0;} // make a false statement, because the object will not exit before the end of the program. stdmethodimp csink: gettypeinfocount (unsigned int *) {return e_notimpl ;} // no implementation is required. stdmethodimp csink: gettypeinfo (unsigned int, unsigned long, struct itypeinfo **) {return e_notimpl;} // no implementation is required, you do not need to use stdmethodimp csink: getidsofnames (const IID &, lpolestr *, uint, lcid, dispid *) {return e_notimpl;} // or stdmethodimp csink :: invoke (long dispid, const struct _ guid &, unsigned long, unsigned short, struct tagdispparams * pparams, struct tagvariant *, struct taginterval info *, unsigned int *) {// you only need to implement this. Switch (dispid) // depending on different dispid, complete different callback functions {Case 1 :...... // here we can receive the event break issued by com; Case 2 :...... // The Event code dispid is actually the break number of the connection point function ID (n) In the IDL file; default: break;} return s_ OK ;}

V., Example (2)

In the example program's 2nd components (multconnect), we add another connection point (_ idispconnectevents2 ). This interface object is responsible for completing a clock, and sends a "clock event" to the caller every interval of seconds ". To add the second connection point, manually modify the IDL file.

...... Library multconnectlib {importlib ("stdole2.tlb"); ...... // The first connection point. It was generated by ATL.[// 2nd connection points, we need to manually add UUID (E3330AE1-2B1D-42E6-A8E0-A9CB0D1AC74C), // CLSID can use guidgen. EXE generates helpstring ("_ idispconnect event interface")] dispinterface _ idispconnectevents2 {properties: Methods :};[UUID (random), // This is the Type Library ID of the sample program. It must be a different helpstring ("dispconnect class")] coclass dispconnect {[Default] interface idispconnect; [default, source] dispinterface _ idispconnectevents;[Source] dispinterface _ idispconnectevents2; // do not forget that there is another line.};};

Okay, just like in the previous method, add interface functions, and let ide help us implement proxy code, input program code, and modify bugs in framework code. In the example, our event function is hresult timer ([in] variant vardata), and vardata transmits a time type (vt_data) Information (note 3 ). Let's take a look at the errors in the proxy 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];// Original: avarparams [0] = vardate; avarparams [0]. vt = vt_variant; // It is a pity that this is incorrect, because avarparams [0] = vardate; has been correctly assigned a value // then avarparams [0]. VT Value assignment: this operation can be performed only by reference. Avarparams [0] = vardate; // This is the correct operation.Ccomvariant varresult; dispparams Params = {avarparams, null, 1, 0}; HR = pconnection-> invoke (1, iid_null, locale_user_default, dispatch_method, interval ms, & varresult, null, null) ;}} return hr ;}

To write the caller's client code, if you need to receive clock events, you can repeatedly derive a clock receiver from idispatch, as shown in the following example. You can download the sample code, which contains a wealth of comments.

Vi. Summary

Connection points, especially double interface connection points, are less efficient in remote (DCOM) environments. If you only want to complete the simple "notification" function, the "Callback interface" in the previous one is a wise solution and can run in the DCOM environment. The connection point solution is also very important, because many Microsoft applications (ie, office...) support connection points, and ActiveX can only provide the "event" function through the connection point interface. Therefore, we can still master it as good. Shanzai, Shanzai ......

NOTE 1: In the martial arts novels of Mr. Jin Yong, "XX is always used to express" XX ". I also want to learn.
NOTE 2: If you have read it several times, you will not be able to do so. 5555
Note 3: The data type is an 8-byte double. The integer part indicates the total number of days since January 1, December 30, 1899, and the decimal part indicates the number of minutes that have passed the day. This time type is represented by variant, that is, vt_date, and coledatetime in MFC. The example program demonstrates this type of operation.

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.