Re: ATL/COM: Interface as property of another interface
Hello Roman, thnaks for the answer.
About the internal interface:
The problem creating the interface is that I need a function with a pointer
to a class (TJName*). When I do an import or include of the class file into
the interface (in the IDL file), then I receive n compile errors from MIDL.
interface IInterName : IUnknown
{
STDMETHOD(SetForNode)(TJName* name);
STDMETHOD(SetToNull)();
}
I found some MACROS to create an interface outside the IDL file, for
example, in the Header file of the COM-Class that should implement the
interface. My interface is now like this:
static const IID IID_INewName = { 0xa1e5b58f, 0xf15d, 0x49ad, { 0xb5, 0xaa,
0xc6, 0xa0, 0x29, 0x56, 0xac, 0x37 } };
#undef INTERFACE
#define INTERFACE INewName
interface DECLSPEC_UUID("00A58F61-D52E-43f8-A083-35A7AF5C1757") INewName :
public IUnknown
{
BEGIN_INTERFACE
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
STDMETHOD(SetForNode)(THIS_ TJName* name) PURE;
STDMETHOD(SetToNull)(THIS) PURE;
END_INTERFACE
};
At least, it compiles.
About the implementation of the interface:
I could find how to implement the new created interface in a COM-Class
already generated with the wizard. I did it and overrode the two methods of
the new created interface (SetToNull and SetforNode) and in the
FinalConstructor of the class I do all what I described in my last post. It
compiles without errors or warnings, but when I try to get the new interface
pointer with a QueryInterface, it fails with then error: E_NOINTERFACE.
class ATL_NO_VTABLE CPCJName :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CPCJName, &CLSID_PCJName>,
public IDispatchImpl<IPCJName, &IID_IPCJName, &LIBID_PCJ, /*wMajor =*/ 1,
/*wMinor =*/ 0>,
public INewName
{
public:
CPCJName() : m_objName()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_PCJNAME)
BEGIN_COM_MAP(CPCJName)
COM_INTERFACE_ENTRY(IPCJName)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(INewName)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
SetForNode(NULL);
return S_OK;
}
void FinalRelease()
{
}
public:
STDMETHOD(SetForNode)(THIS_ TJName* name);
STDMETHOD(SetToNull)(THIS);
//---------------------------------------------------------------------------
The FinalConstructor of the Node Class is like this now:
HRESULT FinalConstruct()
{
HRESULT hR;
hR = CoCreateInstance(CLSID_PCJName,NULL, CLSCTX_INPROC_SERVER,
IID_IPCJName,(void**)&m_objName);
if(SUCCEEDED(hR))
{
INewName *temp;
// Hier will fail with E_NONINTERFACE
//
hR = m_objName->QueryInterface(IID_INewName,(void**)&temp);
if(SUCCEEDED(hR))
{
temp->SetForNode(&m_objNode.Name);
return S_OK;
}
m_objName->Release();
}
return hR;
}
void FinalRelease()
{
HRESULT hR;
INewName *temp;
hR = m_objName->QueryInterface(IID_INewName,(void**)&temp);
if(SUCCEEDED(hR))
{
temp->SetToNull();
temp->Release();
}
m_objName->Release();
}
//----------------------------------------------------
any Idea why it does not works?
"Roman Ryl..." <ryltsov@gmail.com> schrieb im Newsbeitrag
news:60558fcb-3703-4b1e-8075-bbd8cd2ea3ea@40g2000prx.googlegroups.com...
Hi Keneth,
QUESTIONS:
- How can I create/define an Interface just for internal uses?
Just the same way you define public interfaces. You can not include
the interface into library section of IDL and not reference the
interface in the coclass section as implemented by class and this way
your private interface won't be visible on the type library and will
be only for your private use.
- How can I implement that interface in an already created ATL/COM class?
Well if stated exactly the way you did - then you cannot. But if your
question is how you can dynamically decide on adding implementation of
certain interface in your code, then you have a number of options.
1. Aggregation
2. Tear off interfaces
3. Fully implement certain interface but on runtime return
E_NOINTERFACE for particular IID if you want to hide this interface.
All the options affect your COM_MAP where you need to add certain
macros or code to achieve desired implementation.
Roman