#1
  1. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2002
    Location
    Seattle WA
    Posts
    863
    Rep Power
    14

    [VC++] Having a Function implement IDispatch


    I'm trying to use IHTMLElement2::attachEvent(BSTR, IDispatch*, VARIANT_BOOL*) in my code. The interface parameter is a pointer to the function I want to attach to the event.

    It's trivial in scripting languages...jscript somehow wraps each function and exposes an interface for each function.

    How though, to to this in C++? I'm quite familiar with interfaces in that I have numerous classes that expose them, but for a function? Anyone ever do this?

    I'm trying to get an html page displayed in my program to call some class members when various DHTML events are fired.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    Microsoft Platform SDK, "Implementing the IDispatch Interface":

    http://msdn.microsoft.com/library/de...chap5_34f9.asp

    i did transfer this to delphi successfully (i had some more docs ;) )- if you have further questions, maybe i can help too...
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2002
    Location
    Seattle WA
    Posts
    863
    Rep Power
    14
    Thanks for the link, but I'm still at a complete loss on what to do. I pass an IDispatch* to the attachEvent function, but what is done with the interface? How does the browser know what method to call?

    I've found lots of documentation on the attachEvent method, but it's all with respect to scripting languages. I have no idea how to somehow get the browser to invoke a function of an object instantiated in my application. I mean, even if I have a class exposing an interface and pass it to the attachEvent method (not a problem), what does the browser do with the interface to invoke a method?
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    i only used the IDispatch interface for shell extensions. In this case, the explorer calls the function that it it needs.

    i.e. there is a function called similar to "get_thumb_image(HBITMAP *bmp, int width, int height)" that is called when explorer wants the preview image.
    i just implemented this function and explorer calls it when needed.

    it SHOULD work like this, although from my experience with windows programming, it could also work different ;) :
    derive a class from IDispatch ("CmyDispatcher"), then:
    CmyDispatcher disp=new CmyDispatcher();
    ...->attachEvent(... , disp, ...)
    but from reading other posts by you, i guess you know this already.

    if i understand you correctly, you miss the info which functions to implement on the IDispatch interface for having a function called when eg. a JavaScript event occurs. Is this right?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2002
    Location
    Seattle WA
    Posts
    863
    Rep Power
    14
    Originally posted by M.Hirsch
    ...but from reading other posts by you, i guess you know this already.
    Hehe, yup. Thanks for the info though, incase I didn't.
    Originally posted by M.Hirsch
    if i understand you correctly, you miss the info which functions to implement on the IDispatch interface for having a function called when eg. a JavaScript event occurs. Is this right?
    Yup, that's exactly the problem. What method is invoked on the interface when (in this case), Explorer determines the DHTML event has occured.

    I'm about 75% through coding a workaround, which has dropped the whole DHTML event sink strategy. But it would be nice to know for other features I'd like to implement in my code. If you ever find the info, I'd love to have it.

    Thanks!
    -Michael
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    190
    i only read a little about this as i had a similar project on my mind earlier, but i dropped it because my c++ is not that good. where i started:

    http://msdn.microsoft.com/library/de...rials/sink.asp
    has a tutorial about implementing this and
    http://support.microsoft.com/default...;en-us;q194179 shows an example of implementing a dispatch interface the ATL way.

    the method that is invoked by IE seems to be IDispatch::Invoke:
    Code:
    STDMETHODIMP CEventSink::Invoke(DISPID dispidMember,
                                    REFIID riid,
                                    LCID lcid,
                                    WORD wFlags,
                                    DISPPARAMS* pdispparams,
                                    VARIANT* pvarResult,
                                    EXCEPINFO* pexcepinfo,
                                    UINT* puArgErr)
    {
        switch (dispidMember)
        {
            case DISPID_HTMLELEMENTEVENTS2_ONCLICK:
            OnClick();
            break;
    
            default:
            break;
        }
    
        return S_OK;
    }
    where CEventSink is a child class of IDispatch.

    i am not into ATL and i can only read half of the code (a lot seems to be macros). but maybe you can the "valuable" info from there...

    ps. when you got it working, please tell me how. iŽll grab my old sources then and go on too...
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2002
    Location
    Seattle WA
    Posts
    863
    Rep Power
    14
    <irony>That first link you supplied was the original info I found a year ago when I first started looking into the COM...it's a good resource.</irony>

    That code snippet you posted was pretty much the final bit of info I had been looking for, thanks! It made everything 'click.' I have a good idea now of how to implement the event sinks, I'll post a sample project once I try it out. That won't be for a week or so though, this is a weekend hobby project I've been tinkering with for the last year.
    the method that is invoked by IE seems to be IDispatch::Invoke
    That's actually the ultmate case for any method...method names are translated to numeric REFIIDs, and Invoke is called with the appropriate REFIID. All I need to do is track down where the event ids are defined so I can case the right one, and I'm good.

    Beautiful, thanks!

IMN logo majestic logo threadwatch logo seochat tools logo