ActiveX calling javascript functions
-
10. května 2012 20:30
I have seen questions similar to mine out there but I'm not running into the same problems. Here are the steps I followed in hopes someone could point me to my error.
1. ATL Project (called Sample)
2. Add class (ATL Simple Object) called Dog
3 Checked connection points & IObjectwithSite
4. Added a method to the events, my .idl file:
import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(D3299028-F05E-4341-A686-AB2DBC844DF5), dual, nonextensible, helpstring("IDog Interface"), pointer_default(unique) ] interface IDog : IDispatch{ }; [ uuid(48BE55E1-A592-43BF-89CD-E4A8A45F8988), version(1.0), helpstring("Sample 1.0 Type Library") ] library SampleLib { importlib("stdole2.tlb"); [ uuid(E6BA2F52-0796-4446-8EED-1D00E353F647), helpstring("_IDogEvents Interface") ] dispinterface _IDogEvents { properties: methods: [id(1), helpstring("method bark")] void bark(); }; [ uuid(3C47225F-64EF-4343-B649-12CB510FEF50), helpstring("Dog Class") ] coclass Dog { [default] interface IDog; [default, source] dispinterface _IDogEvents; }; };5. Add/Implement Connection Point (_IDogEvents), my _IDOGEvents_CP.h:
#pragma once template<class T> class CProxy_IDogEvents : public IConnectionPointImpl<T, &__uuidof(_IDogEvents)> { public: HRESULT Fire_bark() { HRESULT hr = S_OK; T * pThis = static_cast<T *>(this); int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++) { pThis->Lock(); CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection); pThis->Unlock(); IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p); if (pConnection) { DISPPARAMS params = { NULL, NULL, 0, 0 }; hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); } } return hr; } };
6 Added IProvideClassInfo2Impl & IObjectSafetyImpl to the class and added IProvideClassInfo,IProvideClassInfo2, IObjectSafety to the COM Map
My Dog.h file:
#pragma once #include "resource.h" // main symbols #include "Sample_i.h" #include "_IDogEvents_CP.h" class ATL_NO_VTABLE CDog : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CDog, &CLSID_Dog>, public IConnectionPointContainerImpl<CDog>, public CProxy_IDogEvents<CDog>, public IObjectWithSiteImpl<CDog>, public IProvideClassInfo2Impl<&CLSID_Dog, &__uuidof(_IDogEvents), &LIBID_SampleLib>, public IObjectSafetyImpl<CDog,INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>, public IDispatchImpl<IDog, &IID_IDog, &LIBID_SampleLib, 1, 0> { public: CDog() { MessageBoxA(NULL,"Dog init","1",MB_ICONINFORMATION); Fire_bark(); } DECLARE_REGISTRY_RESOURCEID(IDR_DOG) BEGIN_COM_MAP(CDog) COM_INTERFACE_ENTRY(IDog) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IConnectionPointContainer) COM_INTERFACE_ENTRY(IObjectWithSite) COM_INTERFACE_ENTRY(IObjectSafety) COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2) END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(CDog) CONNECTION_POINT_ENTRY(__uuidof(_IDogEvents)) END_CONNECTION_POINT_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } public: }; OBJECT_ENTRY_AUTO(__uuidof(Dog), CDog)
Html file
<html> <body> <script type="text/javascript"> function mydog::bark() { alert("ruff ruff"); } </script> <object id="mydog" width=10 height=10 border=1 classid="CLSID:3C47225F-64EF-4343-B649-12CB510FEF50"> </body> </html>
There doesnt seem to be a connection established. Anytime a Fire_xxx event is called the m_vec.GetSize(); returns 0 and nothing will get invoked by the dispatch. What am I missing?
Všechny reakce
-
10. května 2012 20:37
-
10. května 2012 20:55
Igor,
I tried to call a javascript event to cause the DLL to do something and then make a call to fire the event
<html> <script type="text/javascript"> function addSomething() { var d = document.getElementById("mydog"); d.Add(); } function mydog::bark() { alert("ruff ruff"); } </script> <body> <a href=javascript:addSomething()>addSomething</a> <br><br> <object id="mydog" width=10 height=10 border=1 classid="CLSID:3C47225F-64EF-4343-B649-12CB510FEF50"> </body> </html>
Dog.cpp
// Dog.cpp : Implementation of CDog #include "stdafx.h" #include "Dog.h" CDog::CDog() { MessageBoxA(NULL,"Dog init","1",MB_ICONINFORMATION); } STDMETHODIMP CDog::Add() { MessageBoxA(NULL,"Add","1",MB_ICONINFORMATION); Fire_bark(); return 0; }
In this case I get the same thing, no connections. Should I create a thread and try this same sort of thing?
-
10. května 2012 21:54
On 5/10/2012 4:55 PM, hapyfishrmn wrote:
In this case I get the same thing, no connections.
On a hunch, try placing the <script> tag below <object> tag.
Igor Tandetnik
- Označen jako odpověď hapyfishrmn 11. května 2012 19:56
-
11. května 2012 13:27Same as before no connections
-
11. května 2012 16:52
-
11. května 2012 20:01
Igor many thanks to you,
For those who come later there where 2 problems:
1) no closing </object>
2)if you are using the notation in Javascript "mydog::bark" then the script must be below the <object>
using the notation: "mydog::bark"
<html> <body> <a href=javascript:addSomething()>addSomething</a> <br><br> <object id="mydog" width=10 height=10 border=1 classid="CLSID:3C47225F-64EF-4343-B649-12CB510FEF50"></object> <script type="text/javascript"> function addSomething() { var d = document.getElementById("mydog"); d.Add(); } function mydog::bark() { alert("ruff ruff"); } </script> </body> </html>
You can alternatively use the "for" "event" notation before the <object> if you need
<html> <body> <a href=javascript:addSomething()>addSomething</a> <br><br> <script for="mydog" event="bark()"> alert("ruff ruff"); </script> <script type="text/javascript"> function addSomething() { var d = document.getElementById("mydog"); d.Add(); } </script> <object id="mydog" width=10 height=10 border=1 classid="CLSID:3C47225F-64EF-4343-B649-12CB510FEF50"></object> </body> </html>
both worked. Thanks again Igor
- Upravený hapyfishrmn 11. května 2012 20:38
- Označen jako odpověď hapyfishrmn 11. května 2012 20:38
-
4. prosince 2012 22:20I have tried this and it doesn't work for me. The first error I get is that there is no "Add()" method on mydog. What is the purpose of this add_something method and the call to Add?