Is <OBJECT> the only way in IE for an ActiveX control to sink events

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by David Chin » Wed, 07 Mar 2007 09:20:32


Hello,

I am creating a Vista Sidebar gadget that depends on an ActiveX control. I
have gotten it to work if the ActiveX control is specified by an <OBJECT>
tag within HTML. I can write JScript to sink events OK.

Ideally, I'd like to create the ActiveX control with

new ActiveXObject()

instead, because this will let me register the ActiveX control prior to
instantiating it. (The <OBJECT> tag tries only once when the page loads to
instantiate the control, and since the page itself has script to register
the control, this is too early.)

However, it seems an object created with "new ActiveXObject()" can't sink
events. At least I haven't found a way for it to.

Is there a way to

a) dynamically create an ActiveX object
b) that sinks events
c) in JScript
d) that runs in IE

I think it's possible if the script host is Wscript or CScript, but not IE.
This is maddening!! :-O


Thanks,
David
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by Igor Tande » Wed, 07 Mar 2007 09:29:45


As far as I can tell, this is correct.


To the best of my knowledge, no.


Quite.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925

 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by MV » Wed, 07 Mar 2007 10:35:07


Unless you use a 3rd party helper component like ScriptX (in the free
feature set)...



--
Michael Harris
Microsoft.MVP.Scripting
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by Anthony Jo » Wed, 07 Mar 2007 18:20:03


I
<snip>

Is this control something you have written? If so what language?
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by Dave Methv » Thu, 08 Mar 2007 22:48:12

> Is there a way to

Can you dynamically insert the OBJECT tag into the document, then use
.readyState in a setTimeout to wait until it's loaded?

It may help that there is a special syntax for event handlers in IE:

function myobject::myevent() { ... }

The double-colon syntax was documented in one MSDN article and I can't find
it at the moment.
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by MV » Fri, 09 Mar 2007 10:27:34

> It may help that there is a special syntax for event handlers in IE:

Scripting Events
< http://www.yqcomputer.com/ ;

--
Michael Harris
Microsoft.MVP.Scripting
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by David Chin » Sat, 10 Mar 2007 05:22:08


Thank you, this works for objects created with <OBJECT> tag but not for
objects created with

new ActiveXObject()

This is because the functions are parsed when the page is loaded, and the
object created with "new ActiveXObject" does not get created until the
script starts running. Therefore, the parser has no way of knowing the name
of the object.

BTW, the '::' method was the only way that I could sink events in IE at all,
and that only works for <OBJECT>. It's really stupid. Whoever invented
this COM thing should have made sure the same methods worked for all clients
so we don't have this hodge podge of methods that work with "this host but
not that one". I guess that's why we have .NET now so that everything is
uniform.

-- David (MVP - Visual C++)
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by David Chin » Sat, 10 Mar 2007 05:23:18


Yes, the ActiveX control is my own and was created in C++/ATL.

-- David
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by David Chin » Sat, 10 Mar 2007 05:33:08


Thanks for all the replies! I appreciate them very much.

After a few days of fiddling with this, I came up with a solution. Since
the "new ActiveXObject" could not sink events, I was stuck using the
<OBJECT> tag. So I wrote script that registers the COM object (if not
already registered) and then reloads the page so that the <OBJECT> tag is
reparsed and the object can then be created after the control has been
registered. Here's the script:

<SCRIPT language=JSCRIPT>
function main()
{
if ( ctl && ctl.object ) // already registered -- thanks to Igor
Tandetnik for providing this technique
{
ctl.Init(); // Inititalize it
}
else
{
window.setTimeout("DoRegister()", 500); // timeout fixes gadget
appears in offset position sometimes
}
}

function DoRegister()
{
// Register the COM object, then reload the page so the COM object
can be instantiated now that it's
// registered.
RegisterCOMObject();
window.location.reload();
}
</script>


function RegisterCOMObject()
{
// COM Object registration is from
http://www.yqcomputer.com/
// Register the COM object under the Current User registry key
var wshShell = new ActiveXObject("WScript.Shell");

wshShell.RegWrite(root + "\\Software\\Classes\\" + progID + "\\",
"");
wshShell.RegWrite(root + "\\Software\\Classes\\" + progID +
"\\CLSID\\", clsID);

...
}

<body onload="JSCRIPT:main();">
<OBJECT ID="ctl"
CLASSID="CLSID:475C0DF3-4CA5-4D22-9ACE-F80FAB36B4F0"></OBJECT>

<script>
function ctl::OnKeyDown(vkKey, repeat, locked)
{
// Sink event from my ActiveX control
...
}
</script>
</body>


-- David (MVP - Visual C++)
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by Ayus » Sat, 10 Mar 2007 07:07:27

David Ching wrote ::


Change the classid of Object tag with script to update the object when the
control is registered.

Good Luck, Ayush.
--
Setup Outlook Express to read MS Newsgroups :
http://www.yqcomputer.com/
 
 
 

Is <OBJECT> the only way in IE for an ActiveX control to sink events

Post by Anthony Jo » Sat, 10 Mar 2007 18:55:45


In that case an alternative to an event is to pass into your control a
JScript function:-
CComPtr<IDispatch> m_pOnSomeEvent;

STDMETHODIMP CYourClass::putref_onsomevent(LPDISPATCH newVal)
{
m_pOnSomeEvent = newVal;
return S_OK;
}

void CYourClass::raiseSomeEvent(ULONG SomeValue)
{
HRESULT hr;
if(m_pOnSomeEvent==NULL)
{
return;
}

DISPID dispid;
OLECHAR FAR* szMember = L"call";
DISPPARAMS dispparams;
VARIANTARG * pvarg = NULL;

hr = m_pOnSomeEvent->GetIDsOfNames(IID_NULL, &szMember, 1,
LOCALE_SYSTEM_DEFAULT, &dispid );
if (SUCCEEDED(hr))
{
pvarg = new VARIANTARG[2];
dispparams.rgvarg=pvarg;
dispparams.rgvarg[0].vt= VT_I4;
dispparams.rgvarg[0].intVal = SomeValue;
dispparams.rgvarg[1].vt= VT_DISPATCH;
this->QueryInterface(IID_IDispatch,
(void**)&dispparams.rgvarg[1].pdispVal);
dispparams.cArgs=2;
dispparams.cNamedArgs = 0;
hr =
m_pOnSomeEvent->Invoke(dispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD
,&dispparams, NULL, NULL, NULL);

delete(pvarg);
}
}

Now in your JScript code like this should work:-

var o = new ActiveXObject("YourLib.YourClass")
o.onsomeevent = fnOnSomeEvent

function fnOnSomeEvent(Value)
{
alert('Some Event value is :" + Value.toString())
}

Ok so it's not really an event, you can't use attachEvent but it ought to
work for what you seem to need.

Anthony.