1

I need to create a COM object which is callable from Javascript. I've been told that to do this, you need a COM object which also implements a class factory and it was suggested here that I try ATL. Someone pointed me to a Code Project ATL sample, however that doesn't cover the class factory.

I'm able to build a small ATL project with a simple object, but am unable to instantiate it, presumable because I haven't provided the class factory.

So, does anyone have experience building a simple COM object in VS2010 via ATL which can be called from Javascript?

EDIT: well, in reading the documentation for the DECLARE_CLASSFACTORY_EX it sounds like a default class factory IS provided. So now I'm not sure what's missing. What is needed to instantiate and invoke the class from Javascript?

EDIT: Also, to clarify, the Javascript where I'm calling the object from is in an HTML page being shown in the IE ActiveX control in an MFC dialog app. So that's the context in which the Javascript will run.

2 Answers 2

4

First of all, I believe you mean MS-specific JScript for Internet Explorer, because other browsers might not support COM/ActiveX.

You don't have to implement class-factory explicitly, because ATL framework already provides it. Just run ATL wizard: View --> Class view; in Class view right-click project root --> Add --> Class --> ATL Simple Object; set class name, and leave the defaults for all the rest. The wizard will define the following main things:

  1. Interface and co-class that implements it, in IDL file.
  2. C++ class, which would be the actual implementation of the above co-class. Pay attention to OBJECT_ENTRY_AUTO macro in the header file: it "connects" between your class and the ATL framework class-factory.
  3. *.rgs file, which is used to register your co-class in Windows registry.

Now you can add some methods to this newly created class - by means of wizard (right-click on class --> Add --> Add Function...), or manually.

Besides, in order to avoid security issues with your component, you have to implement IObjectSafety in your class: just inherit the c++ class from public IObjectSafetyImpl<CYourClass, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>, and add COM_INTERFACE_ENTRY(IObjectSafety) to the interface map.

Now your class is ready for use from within JScript. In the script you can either create it statically, using object tag, or dynamically, using new ActiveX() statement. If your object has connection-points (i.e. fires events) and you don't want to be too tricky, you have to use the former approach.

Sign up to request clarification or add additional context in comments.

4 Comments

yes, this is Javascript running in an HTML page which will be presented in IE, specifically, the IE ActiveX control. Supporting other browsers is not necessary in this case. It'll be an MFC dialog with the IE control so the trick is being able to do stuff in Javascript, like handle a button click and get that through to the C++ code in the dialog which means going through an ActiveX object. I'll give what you've suggested a try and see if I can get it working.
For me in VS2008 the step "Now you can add some methods to this newly created class - by means of wizard (right-click on class --> Add --> Add Function...)" was not working. Method was added to class but not exposed via COM interface. What worked was R-Click newly created interface-->Add-->Add method. This added method to both the interface and the class.
@farfareast yes, you're right. But anyway, in a real project, after it grows a bit, the wizard fails to add anything :).
OBJECT_ENTRY_AUTO saved me from wasting another one more day by looking into other places, thanks a lot !
1

I published sample code project earlier in response to another question: Exposing COM events to VBScript (ATL). It uses VBS and I assume JS conversion is an easy thing.

Code: SVN, Browser Friendly.

Another related sample: SVN, Browser Friendly + blog post explain things going on: Three ways to implement VBScript (VB6, VBA) callback from C++/ATL class.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.