Internet Explorer ATL ActiveX event not firing (IConnectionPointContainerImpl Advise not called on time)

by APIJunkie 25. January 2008 10:54

This is a heads up for people developing ActiveX  controls for IE. The problem was demonstrated on IE 7 but might be true on other browser versions.

If you embed an ATL based ActiveX control inside a web page and try to send/fire events to the script and find out that the events are not generated then you might have the following problem.

As a simple debug trace can demonstrate initiation of ActiveX controls and script on a web page is done synchronically by one thread.

At first, objects are created, then any global script code gets executed and only after that IConnectionPointContainerImpl Advise gets called to establish a connection between the connection point and a sink.

Now the problem is that if you call a member function of the ActiveX object in the global script and this function tries to generate events those events will never be generated since the advise function was not called yet.

A simple solution to the problem, although a little bit of a hack, is to make sure you never call ActiveX functions when the page initializes.

Instead you can use a timer event handler function and call the ActiveX functions from inside the timer event handler this will insure that advise gets called to register the event handlers before you call any ActiveX member functions.

Example:

Lets assume we have a init function in the JavaScript script that does some ActiveX initialization.

function InitActiveX()

{

MyActiveXObj.Myfunction(parameters);

}

//InitActiveX(); //-> PRB: un remarking this line will cause the advise function not to get called on time!!

var timerId = setTimeout('InitActiveX',1000); // this works because the advise function will get called before the timer event handler function gets executed!!

Note that even a time delay of 0 works because it still makes sure the function is not called directly from the global script.

 

Tags:

C++ | PRB | ActiveX | ATL

Comments

1/25/2008 11:06:11 AM #

trackback

Trackback from DotNetKicks.com

Internet Explorer ATL ActiveX events not firing

DotNetKicks.com

1/26/2008 2:08:03 AM #

Momcilo

Can you please post the simple HTML example for active X initialization?

Momcilo Serbia

1/26/2008 9:20:36 AM #

APIJunkie

Hi Momcilo,

Its basically what you can see in the example above.

Here it is with the enclosing script tags:

<script language="javascript">
<!--

function InitActiveX()
{

MyActiveXObj.Myfunction(parameters);

}

//InitActiveX(); //-> PRB: un remarking this line will cause the advise function not to get called on time!!

var timerId = setTimeout('InitActiveX',1000); // this works because the advise function will get called before the timer event handler function gets executed!!

//-->
</script>

APIJunkie United States

1/26/2008 9:34:01 AM #

APIJunkie


Here is a more complete example of an HTML page with an ActiveX control and the script:

<html>
<head>
<title>New Page 1</title>
</head>
<body>
<OBJECT id="MyActiveXObj" codeBase="MyObj.cab#Version=1,0,0,1" height="1" width="1" data="data:application/x-oleobject;base64,...objx64data..."
  classid="CLSID:763E8FEF-1EA9-12CF-A3DB-080236F32652" name="MyActiveXObj" VIEWASTEXT>
</OBJECT>
<script language="javascript">
<!--

function InitActiveX()
{

MyActiveXObj.Myfunction(parameters);

}

//InitActiveX(); //-> PRB: un remarking this line will cause the advise function not to get called on time!!

var timerId = setTimeout('InitActiveX',1000); // this works because the advise function will get called before the timer event handler function gets executed!!

//-->
</script>

</body>

</html>

APIJunkie United States

1/28/2008 2:31:42 AM #

Momcilo

I've tried to reproduce this, but failed.

I have ActiveX object which spawns several working threads. Each of these threads generates events, which are submitted to dispatching queue (thread safe). The dispatching thread invokes event handlers.

The ActiveX has the following logic:

Connect();

CatchEvents_IN_JavaScriptEventHandlers();

Disconnect();

Connect and Disconnect generate Connection events like Connecting, Connected, Disconnecting, Disconnected, Aborted


While debugging ActiveX, I've noticed that call to pConnection->Invoke (inside generated wrapper), returns S_UNEXPECTED, while the ActiveX connect. As soon as I call Disconnect, the same code manages to call the event handlers in ActiveX.

Do you have any clues?

Btw: In your example setTimeout should pass function name with parameter list like:
var timerId = setTimeout('InitActiveX()',1000);

Momcilo Serbia

1/29/2008 12:09:39 AM #

Momcilo

I've figured out what was the issue. The activex control was set to apartement. The events were triggered by background worker thread, which caused IE to reject marshaling of the events. I've changed it to free, and it works.

Thank you for the help.

Momcilo Serbia

Comments are closed

About the author

Name of author

I was first wounded by x86 assembly, recovered and moved on to C. Following a long addiction to C++ and a short stint at rehab I decided to switch to a healthier addiction so I am now happily sniffing .NET and getting hooked on Silverlight.

I am mainly here to ramble about coding, various API’s, Junkies(me especially) and everything else that happens between coders and their significant other.

  James Bacon