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

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.