Question

I'm writing a BHO that exposes a number of methods through COM. Most of them work fine, but the 2 most recently added ones are showing strange behavior.

When called from JavaScript on a page, the newly added methods "return" Undefined, as opposed to throwing an exception that the method or property doesn't exist, so the object at least knows the methods are on it, but never executes them.

bho.h

class ATL_NO_VTABLE CBho :
public IObjectWithSite,
public IDispatchImpl<IBho, &IID_IBho>,
public IOleCommandTarget
{
public:
    STDMETHOD(DeletePreference)(BSTR prefName);
};

bho.cpp:

STDMETHODIMP CBho::DeletePreference(BSTR prefName) {
    //some code that interacts with localStorage
    return S_OK;
}

And my IDL:

[
    object,
    uuid(/*uuid/*),    
    dual,
    nonextensible,
    helpstring("IBho Interface"),
    pointer_default(unique)
]
interface IBho : IDispatch{
    ...
    [id(5), helpstring("method DeletePreference")] HRESULT DeletePreference([in] BSTR prefName);
};

[
    uuid(/*uuid*/),
    version(1.0),
    helpstring("Bho1.0 Type Library")
]
library MyBhoLib
{
    importlib("stdole2.tlb");
    [
        uuid(36BA1FA3-144A-4A1A-BE62-8301C4E4ADEF),     
        helpstring("Bho Class")
    ]
    coclass BhoSite
    {
        [default] interface IBho;
    };
}

I've noticed similar behavior can be created by changing the IDs around, I've tried to "reset" the type library by defining a new interface to implement, changing the guids, incrementing the type library version, etc. All of which resulted in the methods not being callable at all.

As far as I can tell from the research I've spent on this here and on MSDN, I'm on the right track. How do I successfully add new methods to my COM class so they may be called on my BHO object? The BHO has not been released yet, so the interface has not yet been set in stone.

Était-ce utile?

La solution

I was able to resolve this issue, but not in a way I completely understand. It seems the IBho interface only supports 4 methods exposed by the IDL. After that, the methods are visible to the caller, but will not execute. I have no idea why this is, and have yet to find any documentation that addresses this.

To address the issue, I simply created a new COM class intended to manage storage and exposed it to COM through the IDL and registration process. That allowed me to expand the storage related APIs to include the DeletePreference method, as well as add other requested functionality to the BHO. This is probably better coding practice anyway. Here's what this looks like now:

Preferences.h

class CPreferences :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CPreferences, &CLSID_Preferences>,
    public IDispatchImpl<IPreferences , &IID_IPreferences >
{
    ...
    /implementation
};

IDL:

[
    object,
    uuid(/*uuid/*),    
    dual,
    nonextensible,
    helpstring("IBho Interface"),
    pointer_default(unique)
]
interface IBho : IDispatch{
    ...
    [id(4), helpstring("method DoSomeThing")] HRESULT DoSomeThing([in] BSTR prefName);
};

[
    object,
    uuid(/*uuid/*),    
    dual,
    nonextensible,
    helpstring("IPreferences Interface"),
    pointer_default(unique)
]
interface IPreferences : IDispatch{
    ...
    [id(3), helpstring("method DeletePreference")] HRESULT DeletePreference([in] BSTR prefName);
};

[
    uuid(/*uuid*/),
    version(1.0),
    helpstring("Bho1.0 Type Library")
]
library MyBhoLib
{
    importlib("stdole2.tlb");
    [
        uuid(36BA1FA3-144A-4A1A-BE62-8301C4E4ADEF),     
        helpstring("Bho Class")
    ]
    coclass BhoSite
    {
        [default] interface IBho;
    };
    [
        uuid(uuid),     
        helpstring("Preferences Class")
    ]
    coclass Preferences 
    {
        [default] interface IPreferences;
    };
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top