IDispatch & default method - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

IDispatch & default method

emperoremperor Posts: 59Member
Hey there, I'm fairly new to COM/ActiveX etc, and I have a question which is probably quite easy. First off, I'm using Visual C++ and the app I am writing has a WebBrowser control embedded in a dialog box. What I want to do is suppress the right-click menu in the WebBrowser window, and I got as far as finding the "oncontextmenu" property of IHTMLElement2. Thing is, according to MSDN, the put_oncontextmenu() function needs to be passed a "VARIANT of type VT_DISPATCH that specifies the IDispatch interface of an object with a default method that is invoked when the event occurs."

All I want is to give put_oncontextmenu() a function which does nothing, but it wants all this IDispatch stuff which seems awfully complicated (I know it's necessary but it's a pain in C++). I know how to use VARIANT but I don't know anything about IDispatch, or how to pass put_oncontextmenu() an IDispatch which does nothing.

Any help appreciated!

Comments

  • oded_sharonoded_sharon Posts: 1Member
    Ok.. I'm a newbie to ATL, but I am currently writing a small project to learn the basics. So in any case I can't vouch for the quality of the code, but here is the simplest example I can think of that would get the job done:

    I use the attribute feature, since it really is a time saver in terms of managing files:

    So first you need an interface with a default method. As far as I could figure out giving the id DISPID_VALUE (0) makes it the default method called

    [
    object,
    uuid("XXX-XXX-XXX"),
    dual, helpstring("IElementOnPropertyChangeOverride Interface"),
    pointer_default(unique)
    ]
    __interface IElementOnPropertyChangeOverride : IDispatch
    {
    [id(DISPID_VALUE)] HRESULT OnPropertyChange();
    };

    Next you need to implement the interface it is easiet to let ATL implement the IDispatch interface

    [
    coclass,
    default(IElementOnPropertyChangeOverride),
    noncreatable,
    threading(apartment),
    vi_progid("???.????"), progid("???.???.1"),
    version(1.0),
    uuid("XXXX-XXXX"),
    helpstring("ElementOnPropertyChangeOverride Class")
    ]
    class ATL_NO_VTABLE CElementOnPropertyChangeOverride :
    public IElementOnPropertyChangeOverride
    {
    public:
    CElementOnPropertyChangeOverride() {}
    DECLARE_PROTECT_FINAL_CONSTRUCT()
    HRESULT FinalConstruct() {return S_OK;}
    void FinalRelease() {}

    public:
    STDMETHODIMP OnPropertyChange()
    {
    MessageBox(NULL, L"Hello", L"World!", MB_OK);
    return S_OK;
    }

    };

    Finally in your code you need to put this COM object in a Variant and pass it to an HTML Element

    It should probably look something like this

    //access the IHTMLElement2 inteface from a pointer to a DOMElement
    CComPtr spHTMLElement2;
    HRESULT hr = pDOMPtr->QueryInterface(&spHTMLElement2);
    if (FAILED(hr))
    return hr;

    //override function
    CComObject* newMethod(NULL);
    CComObject::CreateInstance(&newMethod);

    CComVariant newPropertyChange(newMethod);
    hr = spHTMLElement2->put_onpropertychange(newPropertyChange);
    return hr;

    I hope this helps.
Sign In or Register to comment.