Callback Interface functions NOT being Called

D

Devansh

Hello All,
I have a office outlook ATL-COM addin.
In the main class I am implementing
IRibbonExtensibility and
a callback interface interface ICallbackInterface which implements the
callback functions of the buttons I create in Ribbon interface.
My interface MAP looks like this

BEGIN_COM_MAP(CConnect)
COM_INTERFACE_ENTRY2(IDispatch, IRibbonExtensibility)
COM_INTERFACE_ENTRY(AddInDesignerObjects::IDTExtensibility2)
COM_INTERFACE_ENTRY(IRibbonExtensibility)
COM_INTERFACE_ENTRY(ICallbackInterface)
COM_INTERFACE_ENTRY_IID(IID_IExchExt, IExchExt)
COM_INTERFACE_ENTRY_IID(IID_IExchExtSessionEvents,
IExchExtSessionEvents)
COM_INTERFACE_ENTRY_IID(IID_IExchExtMessageEvents,
IExchExtMessageEvents)
END_COM_MAP()

The problem which I am facing is,
When I click on the button in Ribbon Interface callback function is
not being called at all!!

The error which outlook is giving me is,

"The Callback function "ButtonClicked" was not found."

In my IDL file I have included ICallbackInterface properly in the
component class.
Registration of component class is proper.
Type libraries corresponding to IRibbonExtensibility etc are included
properly.
Code is building properly.

I do not know where exactly the problem is lying.
I want to make this callback work to proceed my work.

Kindly let me know if you have any suggestions.

Thanks,
Devansh
 
S

SvenC

Hi Devansh,
Hello All,
I have a office outlook ATL-COM addin.
In the main class I am implementing
IRibbonExtensibility and
a callback interface interface ICallbackInterface which implements the
callback functions of the buttons I create in Ribbon interface.
My interface MAP looks like this

The ribbon callbacks use IDispatch, always, so you must return
the "correct IDispatch" implementation
BEGIN_COM_MAP(CConnect)
COM_INTERFACE_ENTRY2(IDispatch, IRibbonExtensibility)

You need COM_INTERFACE_ENTRY2(IDispatch, ICallbackInterface)

BUT: you are violating COM rules by having two distinct implementations
of the same interface in one object, IDispatch in your case. You should
create a new coclass which implements ICallbackInterface so that a unique
IDispatch implementation exists for that object. Store that instance as
member in your CConnect class and hand it as callback interface to the
ribbon. That extra object might need a simple C++ callback mechanism to
communicate back to your CConnect instance.
 
D

Devansh

Hi Devansh,


The ribbon callbacks use IDispatch, always, so you must return
the "correct IDispatch" implementation


You need COM_INTERFACE_ENTRY2(IDispatch, ICallbackInterface)

BUT: you are violating COM rules by having two distinct implementations
of the same interface in one object, IDispatch in your case. You should
create a new coclass which implements ICallbackInterface so that a unique
IDispatch implementation exists for that object. Store that instance as
member in your CConnect class and hand it as callback interface to the
ribbon. That extra object might need a simple C++ callback mechanism to
communicate back to your CConnect instance.

Hello SvenC,
I modified my code. Now my interface map looks like this,

BEGIN_COM_MAP(CConnect)
COM_INTERFACE_ENTRY2(IDispatch, ICallbackInterface)
COM_INTERFACE_ENTRY(AddInDesignerObjects::IDTExtensibility2)
COM_INTERFACE_ENTRY(IRibbonExtensibility)
COM_INTERFACE_ENTRY(ICallbackInterface)
COM_INTERFACE_ENTRY_IID(IID_IExchExt, IExchExt)
COM_INTERFACE_ENTRY_IID(IID_IExchExtSessionEvents,
IExchExtSessionEvents)
COM_INTERFACE_ENTRY_IID(IID_IExchExtMessageEvents,
IExchExtMessageEvents)
END_COM_MAP()

My callback function "ButtonClicked" is still NOT being called.
Outlook is not able to find it.

As you said, that in this implementation I am violating COM rules by
having two distinct implementations of the same interface in one
object i.e. IDispatch,
so my question here is, where am I implementing it twice. I could see
only one implementation, the one which is associated with
ICallbackInterface in
COM_INTERFACE_ENTRY2(IDispatch, ICallbackInterface)

In fact similar kind of application was working for me but in this new
application I am not able to make the callback function work, I do not
know why..

Kindly help me.

Thanks,
Devansh
 
S

SvenC

Hi Devansh,
My callback function "ButtonClicked" is still NOT being called.
Outlook is not able to find it.

Please show your ICallbackInterface definition in your IDL file.

Is your typelib registered?

Try to debug your code by setting a breakpoint in IDispatchImpl on the
IDispatch methods: GetIdsFromNames and Invoke. Use Find in Files to
find the methods in the atl sources.

Check if you get any helpful HRESULTs returned, like member not found
or typelib not registered.
 
D

Devansh

Hi Devansh,



Please show your ICallbackInterface definition in your IDL file.

Is your typelib registered?

Try to debug your code by setting a breakpoint in IDispatchImpl on the
IDispatch methods: GetIdsFromNames and Invoke. Use Find in Files to
find the methods in the atl sources.

Check if you get any helpful HRESULTs returned, like member not found
or typelib not registered.

Hi Devansh,



Please show your ICallbackInterface definition in your IDL file.

Is your typelib registered?

Try to debug your code by setting a breakpoint in IDispatchImpl on the
IDispatch methods: GetIdsFromNames and Invoke. Use Find in Files to
find the methods in the atl sources.

Check if you get any helpful HRESULTs returned, like member not found
or typelib not registered.

Hello SvenC,

I put up the brake points in IDispatchImpl class in GetIdsFromNames
and Invoke methods, then I came to know that I am getting error in

hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);

funtion and the error code first returned was "member not found" i.e.
(ButtonClicked)

then I checked into the registry for the typlib and DLL's path was NOT
entered into it so I entered it,

BUT, now I am getting following error as per the winerror.h

//
// MessageId: TYPE_E_CANTLOADLIBRARY
//
// MessageText:
//
// Error loading type library/DLL.
//
#define TYPE_E_CANTLOADLIBRARY
_HRESULT_TYPEDEF_(0x80029C4AL)

This error was coming to me even before in the very beginning in
DLLRegisterServer() code that time I had commented following line and
had some entries manually.

HRESULT hr = _AtlModule.DllRegisterServer();

Now when I have uncommented it again then I am getting the same error
on running regsvr32 on my DLL.

RegSvr32
---------------------------
DllRegisterServer in C:\Program Files\Oasys\Mail Manager
\MMApplication.dll failed.
Return code was: 0x80029c4a
---------------------------
OK
---------------------------

My IDL file is as follows,

// AddIn.idl : IDL source for AddIn
//

// This file will be processed by the MIDL tool to
// produce the type library (AddIn.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";


[
object,
uuid(7338E006-B473-44D6-8083-2FBD051CC7E6),
dual,
nonextensible,
helpstring("ICallbackInterface Interface"),
pointer_default(unique)
]
interface ICallbackInterface : IDispatch{
[id(1), helpstring("method ButtonClicked")] HRESULT
ButtonClicked([in] IDispatch* RibbonControl);
};
[
uuid(D6D02DAD-0E3A-4E3F-B1F4-221E8517E570),
version(1.0),
helpstring("MMApplicationCOM 1.0 Type Library")
]
library MMApplicationCOMLib
{
importlib("stdole2.tlb");
[
uuid(37FFBA96-C7C4-4FC7-941A-FB65C2074822),
helpstring("Connect Class")
]
coclass Connect
{
[default] interface IUnknown;
interface ICallbackInterface;
};

/*[
uuid(FF674466-71DC-40B2-BEEA-1A6D8B002DF6),
helpstring("CallbackInterface Class")
]
coclass CallbackInterface
{
[default] interface ICallbackInterface;
};*/
};


I had also tried to put up ICallbackInterface in a difference coclass
but implementing in the same class, that also did not work.

Kindly help me.

Thanks,
Devansh
 
S

SvenC

Hi Devansh,

please try to minimze the posts by quoting only relevant parts. Avoid
full quotes with bottom posts.
BUT, now I am getting following error as per the winerror.h

#define TYPE_E_CANTLOADLIBRARY
_HRESULT_TYPEDEF_(0x80029C4AL) ....
Now when I have uncommented it again then I am getting the same error
on running regsvr32 on my DLL.

RegSvr32

Please open the dll in Visual Studio with the resource editor and check
if you see a TYPELIB resource with ID 1. If not, then you miss to
include the type library into your dll.

The IDL looked OK for me.

Did you create the project with a wizard of a current VS version like
2005 oder 2008 or did you manually "migrate" an older project to a
newer VS project format?
 
D

Devansh

Hi Devansh,

please try to minimze the posts by quoting only relevant parts. Avoid
full quotes with bottom posts.






Please open the dll in Visual Studio with the resource editor and check
if you see a TYPELIB resource with ID 1. If not, then you miss to
include the type library into your dll.

The IDL looked OK for me.

Did you create the project with a wizard of a current VS version like
2005 oder 2008 or did you manually "migrate" an older project to a
newer VS project format?

Thanks a lot !!
It worked!!

I had created this project by manually migrating old code. So in the
resource file I was missing exactly the same thing which you pointed
out.
if you see a TYPELIB resource with ID 1. If not, then you miss to
include the type library into your dll.

Thanks a lot.

Devansh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top