ActiveX calling javascript functions

Answered ActiveX calling javascript functions

  • 10. května 2012 20:30
     
      Obsahuje kód

    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, &params, 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
     
     

    On 5/10/2012 4:30 PM, hapyfishrmn wrote:

        CDog()
        {
             MessageBoxA(NULL,"Dog init","1",MB_ICONINFORMATION);
             Fire_bark();

    That's too early. Your object is just being created - the script couldn't possibly have received its interface pointer yet, let alone advise its event sink to it.


    Igor Tandetnik

  • 10. května 2012 20:55
     
      Obsahuje kód

    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
     
     Odpovědět

    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:27
     
     
    Same as before no connections
  • 11. května 2012 16:52
     
     

    On 5/11/2012 9:27 AM, hapyfishrmn wrote:

    Same as before no connections

    I don't see anything obviously wrong in your code, and similar code worked for me in the past. If you'd like to send a reasonably small sample reproducing the problem to me at itandetnik@mvps.org, I'll look at it.


    Igor Tandetnik

  • 11. května 2012 20:01
     
     Odpovědět Obsahuje kód

    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


  • 4. prosince 2012 22:20
     
     
    I 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?