COM Component Design and Application 15-connection point (vc6.0)

Source: Internet
Author: User

 

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 ;}

15. Correct Errors in the code generated by IDE. You don't have to memorize the error points. An error will be reported after compilation. Generally, two bugs may occur in the code generated by vc6. First, open the header file, find the connection point, and modify the macro as follows:

Begin_connection_point_map (cdispconnect)Connection_point_entry (diid _ idispconnectevents)// Change iid_xxxx to diid_xxxxend_connection_point_map ()

This error is simply hateful. Since we are using a dual-interface connection point, the code generated by it will not be judged? Another possible error may occur in the fire_xxxx () function of the proxy class. In the fire_result () function code in the example program, you can read it by yourself. In short, it means to cyclically obtain the interface pointer of each connected object (the object represented by each cookie) with yourself, (For automated interfaces, obtain the idispatch interface pointer again) and then call the event function. You don't understand that it doesn't have much to do with it now, but in the second example, the code it generates is incorrect and we need to modify it. This is coming soon.

IV. Implementation of callers (1)

1. Create an MFC project ). The project name in the sample project 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, stdmethodimp csink: getidsofnames (const struct _ guid &, unsigned short **, unsigned int, unsigned long, long *) {return e_notimpl;} // is not required, 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 certain interval of milliseconds ". To add the second connection point, manually modify the IDL file.

...... Library multconnectlib {importlib ("stdole32.tlb"); importlib ("stdole2.tlb ");...... // first, the ATL framework gives us the generated connection point interface description by default.[// You need to manually add a second or more connection points UUID (F81DB93F-4F63-4A55-8114-A32BC78466D3), // CLSID can be used guidgen. EXE to generate helpstring ("_ idispconnectevents2 interface")] dispinterface _ idispconnectevents2 {properties: Methods :};[UUID (9461be82-0d64-4e3b-b0db-2306d1bfe3f0), // This is the Type Library ID of the sample program. It must be different from what you have generated. helpstring ("dispconnect class")] coclass dispconnect {[Default] interface idispconnect; [default, source] dispinterface _ idispconnectevents;[Source] dispinterface _ idispconnectevents2; // do not forget, there is a line here};};

Okay, just like in the previous method, add interface functions, compile IDL files, 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) {ccomvariant varresult; T * PT = static_cast (this); int nconnectionindex; ccomvariant * pvars = new ccomvariant [1]; int nconnections = m_vec.getsize (); for (nconnectionindex = 0; nconnectionindex <nconnections; nconnectionindex ++) {pt-> lock (); ccomptr
  SP = m_vec.getat (nconnectionindex); Pt-> unlock (); idispatch * pdispatch = reinterpret_cast (sp. p); If (pdispatch! = NULL) {variantclear (& varresult );// Original code. pvars [0] = & vardata? Stupid! You have to modify pvars [0] = vardate by yourself;Dispparams disp = {pvars, null, 1, 0}; pdispatch-> invoke (0x1, iid_null, locale_user_default, dispatch_method, & disp, & varresult, null, null) ;}} Delete [] pvars; return varresult. scode ;}

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.
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 workspace)
2. Create an ATL Project in the workspace ). In the example program, the project name is simple15. All default options are accepted.
3. In classview, run the right-click menu command new ATL object... to add the alt class.
4. Select objects for category on the left and simpleobject for objects on the right (which is actually the default project ).
5. Enter the component name in the name card. In this example, dispconnect is used.

6. In the attribute attributes card, the interface type is dual. Be sure to select support connection points to support connection points.

7. In classview, select the interface (idispconnect) and right-click the menu to add the function add method...

8. Add a function. Like the program in the previous response, an interface function compute addition is added, but the calculation result is returned through the connection point interface.

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

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

11. Switch to the FileView card and compile the IDL file. Of course, you can also compile all the projects directly. In fact, the purpose of compilation is to generate a TLB file from the IDL file, because the vc ide environment can generate the following "event proxy program code" only after knowing TLB ".

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

13. 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 example 2, we need to implement two connection points. At that time, you need to select two)

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

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.