Non-exposed interfaces
-
Could someone tell me what on Earth are 'non-exposed interfaces' ? All I know is that a COM object can have interfaces, which can be accessed by using
QueryInterface
, for example. I would assume that an interface needs to be exposed by the object in order forQueryInterface
to be able to retrieve it. This problem relates to the Microsoft Knowledge Base Article Q281417 (Found here[^]) and the ability to accomplish the same on Visual C++. Even if I queried for any interface on the object, then queried for IUnknown and queried for the target interface, it always fails withE_NOINTERFACE
. Any ideas, suggestions or other ? -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible. -
Could someone tell me what on Earth are 'non-exposed interfaces' ? All I know is that a COM object can have interfaces, which can be accessed by using
QueryInterface
, for example. I would assume that an interface needs to be exposed by the object in order forQueryInterface
to be able to retrieve it. This problem relates to the Microsoft Knowledge Base Article Q281417 (Found here[^]) and the ability to accomplish the same on Visual C++. Even if I queried for any interface on the object, then queried for IUnknown and queried for the target interface, it always fails withE_NOINTERFACE
. Any ideas, suggestions or other ? -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.I had gone thru Q281417. The term
non-exposed
they used in the sensenon-creatable
. That means u can not sayPrivate Obj As new IMsTscNonScriptable
Only thing u can do is to get a reference to an existingIMsTscNonScriptable
object in the terminal server client connection activex. ie,Private Obj As IMsTscNonScriptable set obj = MsTscAx1.Object
If u chk the IDL of the activex u can see the "noncreatable
" keyword in the attribute section ofIMsTscNonScriptable
declaration. Thisnoncreatable
attribute will prevent a client from queryinterfacing that interface. rgds..mil10 -
I had gone thru Q281417. The term
non-exposed
they used in the sensenon-creatable
. That means u can not sayPrivate Obj As new IMsTscNonScriptable
Only thing u can do is to get a reference to an existingIMsTscNonScriptable
object in the terminal server client connection activex. ie,Private Obj As IMsTscNonScriptable set obj = MsTscAx1.Object
If u chk the IDL of the activex u can see the "noncreatable
" keyword in the attribute section ofIMsTscNonScriptable
declaration. Thisnoncreatable
attribute will prevent a client from queryinterfacing that interface. rgds..mil10Thank you for the swift answer. The next logical question is naturally: how to get this interface in the VC++ side. I tried looking for the ActiveX control in the Running Object Table, but it doesn't register itself there.. Also, using this method also requires you to use QueryInterface, which will result in a failure.. -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.
-
Thank you for the swift answer. The next logical question is naturally: how to get this interface in the VC++ side. I tried looking for the ActiveX control in the Running Object Table, but it doesn't register itself there.. Also, using this method also requires you to use QueryInterface, which will result in a failure.. -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.
Antti.... As per the MSDN sample code in vb we can get an existing
IMsTscNonScriptable
pointer as follows:Private Obj As IMsTscNonScriptable set obj = MsTscAx1.Object
So the VC++ equivalent of the above code is:CComPtr<IMsTscNonScriptable> pIMsTscNonScriptable; m_MsTscAx1.Object( reinterpret_cast<void**>(&pIMsTscNonScriptable) )
Here i assume u will insert the activex control into ur app and will add a member variable to it namedm_MsTscAx1
. Unfrntly i don't have that ocx installed on my mechine. So i am not sure whethr it is a moniker provider and is supposed to be in the ROT. hope this will help... rgds...mil10. -
Antti.... As per the MSDN sample code in vb we can get an existing
IMsTscNonScriptable
pointer as follows:Private Obj As IMsTscNonScriptable set obj = MsTscAx1.Object
So the VC++ equivalent of the above code is:CComPtr<IMsTscNonScriptable> pIMsTscNonScriptable; m_MsTscAx1.Object( reinterpret_cast<void**>(&pIMsTscNonScriptable) )
Here i assume u will insert the activex control into ur app and will add a member variable to it namedm_MsTscAx1
. Unfrntly i don't have that ocx installed on my mechine. So i am not sure whethr it is a moniker provider and is supposed to be in the ROT. hope this will help... rgds...mil10.The ActiveX control was added to the dialog template, and I used 'Add Member Variable' to add a control variable into it. Visual Studio automatically generated the IDispatch wrapper class for the object. However, looking at the class declaration, it's derived from CWnd. Thus, the member variable doesn't have a function called 'Object'. I tried attaching the CComPtr object into the m_MsTscAx1, and although this compiled properly, the attempt to call any methods resulted in an assertion. Any more suggestions ? -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.
-
The ActiveX control was added to the dialog template, and I used 'Add Member Variable' to add a control variable into it. Visual Studio automatically generated the IDispatch wrapper class for the object. However, looking at the class declaration, it's derived from CWnd. Thus, the member variable doesn't have a function called 'Object'. I tried attaching the CComPtr object into the m_MsTscAx1, and although this compiled properly, the attempt to call any methods resulted in an assertion. Any more suggestions ? -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.
Problem solved. As the m_MsTscAx1 is derived from
CWnd
, it also has a method calledCWnd::GetControlUnknown
, which returns a pointer to the existingIUnknown
interface of the object. This interface pointer can be used to query for other existing interfaces on the object. Even those interfaces that are marked as 'non-creatable' can be accessed in this way, because querying for the interfaces doesn't create new interface objects. The pointer returned byGetControlUnknown
must not be released, as that might terminate the object (all interfaces released). However, all interfaces queried from here on should be released in the normal way. The key issue here is thatQueryInterface
only casts the givenIUnknown
pointer to the target interfaces, while adding the reference count at the same time. -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible. -
Problem solved. As the m_MsTscAx1 is derived from
CWnd
, it also has a method calledCWnd::GetControlUnknown
, which returns a pointer to the existingIUnknown
interface of the object. This interface pointer can be used to query for other existing interfaces on the object. Even those interfaces that are marked as 'non-creatable' can be accessed in this way, because querying for the interfaces doesn't create new interface objects. The pointer returned byGetControlUnknown
must not be released, as that might terminate the object (all interfaces released). However, all interfaces queried from here on should be released in the normal way. The key issue here is thatQueryInterface
only casts the givenIUnknown
pointer to the target interfaces, while adding the reference count at the same time. -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.its cooool man.. so u did it. ur correct,
noncreatable
does not prevent from queryinterfacing an interface. More specificallynoncreatable
attribute is for a coclass, not for an interface. It just prevents that coclass from being instantiated. Also, if u r able to queryinterface that interface from the activex IUnknown, then that terminal cleint interface is not a separate coclass and notnoncreatable
attributed. I revoked the defenition i had given for a non exposed interface. I rephrase it as just another interfaec under the activex coclass, apart from the activexdispinterface
and its eventdispinterface
. What exactly it means is Scripting engins like Vbs need at least one IDsipatch derived interface. So normally COM servers that expect scripting engins as clients will always derive interfaces from IDispatch. But the limitation of COM is that a coclass can have only one IDispatch implimented interface.(Well,COM_INTERFACE_ENTRY2
is there to specify which Idispatch is 2 b considered) So if we need to have more than one interface in a coclass, then the remaining interfaces shud b iunknown derived (to make it compliant with vbs like apps). And As far as vb is concerned these IUnknown derived interfaces are "non exposed
". That means vbs like clients can't get it directly, but they can queryinterface the IDispatch. If ur familiar with vb, u cud catch it easly. Or more clearly u can leave that term, it is specificaly for vb programmers we can say. BTWGetControlUnknown
is just an alternative to invoke mthds on an activex. As per the msdn sample the vb code gets the terminal cleint interface thru theobject
method. if such a method is there in the activex, then ofcource that method will be there in the wrapper class also. coz, as u said wrapper class is just an idispatch wrapper for invoking methods on the activex. So it will contain all the methods in the activex. if u do a search for "object" in the wrapper class header file, it will be there. if it is not there, then that msdn sample code is wrong. i don't have that control installed on my mechine. generate the idl of that ocx and chk for "object" in the idl. rgds...mil10