Using the ATL library to develop COM components Frequently Asked Questions (ie does not respond to events and solves tragedies ).

Source: Internet
Author: User

 

When using ATL to develop COM components, there are several problems that may occur frequently. If you do not know, it is difficult to find a solution. I have seen that some people have also asked the same questions on csdn, but few have provided satisfactory answers. Therefore, I will write These FAQs below to avoid repeated efforts by others.

I. Q: When calling a widget on a webpage, the IE browser always prompts: "The Interaction Between ActiveX controls on this page and other parts on this page may be insecure. do you want to allow this interaction?" How can I remove this prompt.

A: Add the following processing to your control. In the class definition section of your control, another parent class is inherited.

Public iobjectsafetyimpl <ccommunicationslink, interfacesafe_for_untrusted_caller | interfacesafe_for_untrusted_data>

At the same time, add one more sentence in interface ing:
Begin_com_map (CXXX)
........
Com_interface_entry (IObjectSafety)
End_com_map ()

If the preceding processing is performed, ie will not be prompted.

Ii. Q: Can I use the control written in the ATL library of VC and VB to receive events, but I still cannot receive events on IE web pages?

A: There are several reasons:
The first is that IE browser can only support single-Suite mode. Your control can only be single-suite, not multi-suite.

The second is that IE does not take the initiative to call advise and other registration event interfaces. Therefore, the class definition of your control must inherit the following parent classes.

Public
Iprovideclassinfo2impl <& clsid_test, & diid _ itesteven ts, & libid_testlib, 1, 0>

Add the following processing to the interface ing.
Begin_com_map (ctest)
// Used to query interface class information
Com_interface_entry (iprovideclassinfo)
Com_interface_entry (iprovideclassinfo2)
End_com_map ()

In this way, ie can register and prepare to receive events.
Reference http://support.microsoft.com/default.aspx? SCID = KB; en-US; 200839

The third is the statement that activates the event in the control (like the place where fire_event is called). If it is not in the main thread but activated in another thread, it must be processed. The specific processing steps are mentioned in the Microsoft Knowledge Base. The URL is

Http://support.microsoft.com/kb/q280512/

You need to download a file atlcpimplmt. H on the webpage. In the file implemented by the control event, perform the following processing: Include the file and add some minor modifications. The sample code is as follows:

# Include "atlcpimplmt. H" // contains this sentence
 
// Note that the inheritance class in the following sentence is changed from iconnectionpointimpl to iconnectionpointimplmt.
Template <class T>
Class cproxy_itesteven ts: Public iconnectionpointimplmt <t, & diid _ itesteven ts, ccomdynamicunkarray>
{
// Warning this class may be recreated by the wizard.
Public:
Hresult fireevents (dispid p_dispid, ccomvariant * p_pvars, long p_lparnum)
{
Ccomvariant varresult;
T * PT = static_cast <t *> (this );
Int nconnectionindex;
Int nconnections = m_vec.getsize ();

For (nconnectionindex = 0; nconnectionindex <nconnections; nconnectionindex ++)
{

// Disable the three statements generated by the wizard.
// Pt-> lock ();
// Ccomptr <iunknown> sp = m_vec.getat (nconnectionindex );
// Pt-> unlock ();

// Replace the following two statements
Ccomptr <iunknown> sp;
Sp. Attach (getinterfaceat (nconnectionindex ));

Idispatch * pdispatch = reinterpret_cast <idispatch *> (sp. P );
If (pdispatch! = NULL)
{
Variantclear (& varresult );
Dispparams disp = {p_pvars, null, p_lparnum, 0 };
Pdispatch-> invoke (p_dispid, iid_null, locale_user_default, dispatch_method, & disp, & varresult, null, null );
}
}
Return varresult. scode;
}

Of course, there are methods such as sending messages to the main thread and setting columns between threads. However, I think this operation is simpler. After the above processing, the IE web page will be able to receive events.

The syntax for receiving events on a webpage is roughly as follows:
 
In vbs
 
Sub control id_on event function name (parameter)
............
End sub
 
JS
<Script for = "Control ID" event = "event function name (parameter)">
............
</SCRIPT>

3. Q: I have safearray-type data in the control. How can I transmit the data to IE web pages or vbprograms through events?

A: For example, your IDL definition is as follows:
Dispinterface _ itesteven TS
{
Properties:
Methods:
[ID (1), helpstring ("datareceived")]
Hresult datareceived ([in] safearray (unsigned char) * data );
};
If the data is received, the data needs to be transmitted through the event. The event processing functions are defined as follows:
Hresult fire_datareceived (safearray ** data)

You will find that the code generated by the ATL Wizard cannot transmit the safearray data. In fact, you can modify the code generated by the wizard.

// Pvars [0] = data;

Pvars [0]. Vt = vt_array | vt_byref | vt_ui1;
Pvars [0]. pparray = data;

Block the original pvars [0] = data; and replace it with the following two sentences. Note that vt_ui1 is of the same type as safearray data before sending events. For example, you can use the following function to organize data.
Safearraycreate (vt_ui1, 1, psaB );
It is vt_ui1. If it is another type, it must be matched at the same time.

When using ATL to develop COM components, there are several problems that may occur frequently. If you do not know, it is difficult to find a solution. I have seen that some people have also asked the same questions on csdn, but few have provided satisfactory answers. Therefore, I will write These FAQs below to avoid repeated efforts by others.

I. Q: When calling a widget on a webpage, the IE browser always prompts: "The Interaction Between ActiveX controls on this page and other parts on this page may be insecure. do you want to allow this interaction?" How can I remove this prompt.

A: Add the following processing to your control. In the class definition section of your control, another parent class is inherited.

Public iobjectsafetyimpl <ccommunicationslink, interfacesafe_for_untrusted_caller | interfacesafe_for_untrusted_data>

At the same time, add one more sentence in interface ing:
Begin_com_map (CXXX)
........
Com_interface_entry (IObjectSafety)
End_com_map ()

If the preceding processing is performed, ie will not be prompted.

Ii. Q: Can I use the control written in the ATL library of VC and VB to receive events, but I still cannot receive events on IE web pages?

A: There are several reasons:
The first is that IE browser can only support single-Suite mode. Your control can only be single-suite, not multi-suite.

The second is that IE does not take the initiative to call advise and other registration event interfaces. Therefore, the class definition of your control must inherit the following parent classes.

Public
Iprovideclassinfo2impl <& clsid_test, & diid _ itesteven ts, & libid_testlib, 1, 0>

Add the following processing to the interface ing.
Begin_com_map (ctest)
// Used to query interface class information
Com_interface_entry (iprovideclassinfo)
Com_interface_entry (iprovideclassinfo2)
End_com_map ()

In this way, ie can register and prepare to receive events.
Reference http://support.microsoft.com/default.aspx? SCID = KB; en-US; 200839

The third is the statement that activates the event in the control (like the place where fire_event is called). If it is not in the main thread but activated in another thread, it must be processed. The specific processing steps are mentioned in the Microsoft Knowledge Base. The URL is

Http://support.microsoft.com/kb/q280512/

You need to download a file atlcpimplmt. H on the webpage. In the file implemented by the control event, perform the following processing: Include the file and add some minor modifications. The sample code is as follows:

# Include "atlcpimplmt. H" // contains this sentence
 
// Note that the inheritance class in the following sentence is changed from iconnectionpointimpl to iconnectionpointimplmt.
Template <class T>
Class cproxy_itesteven ts: Public iconnectionpointimplmt <t, & diid _ itesteven ts, ccomdynamicunkarray>
{
// Warning this class may be recreated by the wizard.
Public:
Hresult fireevents (dispid p_dispid, ccomvariant * p_pvars, long p_lparnum)
{
Ccomvariant varresult;
T * PT = static_cast <t *> (this );
Int nconnectionindex;
Int nconnections = m_vec.getsize ();

For (nconnectionindex = 0; nconnectionindex <nconnections; nconnectionindex ++)
{

// Disable the three statements generated by the wizard.
// Pt-> lock ();
// Ccomptr <iunknown> sp = m_vec.getat (nconnectionindex );
// Pt-> unlock ();

// Replace the following two statements
Ccomptr <iunknown> sp;
Sp. Attach (getinterfaceat (nconnectionindex ));

Idispatch * pdispatch = reinterpret_cast <idispatch *> (sp. P );
If (pdispatch! = NULL)
{
Variantclear (& varresult );
Dispparams disp = {p_pvars, null, p_lparnum, 0 };
Pdispatch-> invoke (p_dispid, iid_null, locale_user_default, dispatch_method, & disp, & varresult, null, null );
}
}
Return varresult. scode;
}

Of course, there are methods such as sending messages to the main thread and setting columns between threads. However, I think this operation is simpler. After the above processing, the IE web page will be able to receive events.

The syntax for receiving events on a webpage is roughly as follows:
 
In vbs
 
Sub control id_on event function name (parameter)
............
End sub
 
JS
<Script for = "Control ID" event = "event function name (parameter)">
............
</SCRIPT>

3. Q: I have safearray-type data in the control. How can I transmit the data to IE web pages or vbprograms through events?

A: For example, your IDL definition is as follows:
Dispinterface _ itesteven TS
{
Properties:
Methods:
[ID (1), helpstring ("datareceived")]
Hresult datareceived ([in] safearray (unsigned char) * data );
};
If the data is received, the data needs to be transmitted through the event. The event processing functions are defined as follows:
Hresult fire_datareceived (safearray ** data)

You will find that the code generated by the ATL Wizard cannot transmit the safearray data. In fact, you can modify the code generated by the wizard.

// Pvars [0] = data;

Pvars [0]. Vt = vt_array | vt_byref | vt_ui1;
Pvars [0]. pparray = data;

Block the original pvars [0] = data; and replace it with the following two sentences. Note that vt_ui1 is of the same type as safearray data before sending events. For example, you can use the following function to organize data.
Safearraycreate (vt_ui1, 1, psaB );
It is vt_ui1. If it is another type, it must be matched at the same time.

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.