How to find out which interfaces are requested for a COM object?

I work with ESRI ArcObjects COM Library, I try very hard to figure out what type should be "selected":

IMxDocument doc = m_application.Document as IMxDocument; object selected = doc.SelectedItem; 

SelectedItem returns a Not Null, typically representing the selected data type. However, I have no idea what type I should give it to. When I debug it, I really don't see anything useful:

http://imgur.com/Yfo6G

(monitor debugging after setting value)

The ESRI ArcObjects library is huge and pretty poorly documented, I just can't understand it. I even got to the point of manually checking about 50 interfaces, which I thought should be.

Does anyone have any ideas how I can figure this out?

EDIT To clarify their documentation, absolutely no help nor their forums.

+6
c # com
source share
7 answers

After reading your question, answers and comments, you may need to write a utility to find the answer by brute force.

Use reflection to clear the list of interfaces from your interop assembly, and then just loop into that list and see if your object supports each interface.

Update

Code example:

  object unknown = //your com object... Type someComObjectType = typeof(ExampleTypeInInteropAssembly); Assembly interopAssembly = someComObjectType.Assembly; Func<Type, bool> implementsInterface = iface => { try { Marshal.GetComInterfaceForObject(unknown, iface); return true; } catch (InvalidCastException) { return false; } }; List<Type> supportedInterfaces = interopAssembly. GetTypes(). Where(t => t.IsInterface). Where(implementsInterface). ToList(); if (supportedInterfaces.Count > 0) { supportedInterfaces.ForEach(Console.WriteLine); } else { Console.WriteLine("No supported interfaces found :("); } 
+5
source share

I am not familiar with this library, but I can give some suggestions. When you look at a problem from a COM perspective, you will see that there is no simple answer.

(Keep in mind that in COM all objects are just objects, and the only condition is that it must support IUNKNOWN (and possibly other interfaces). Thus, the answer to the question "what type of object is it", often may have more than one answer.)

It is important to remember that in COM the list of interfaces for an object is not defined in any metadata, as in .NET (except that the library usually provides an additional type library as a form of documentation for development tools - more on that in a minute).

The list of interfaces is officially determined only by the results of calling the IUNKNOWN QueryInterface () method, that is, it is completely determined by the result of the code execution.

Several times the list can be hard-coded. Often the list may not be known until runtime, and it may not even be known until someone asks . The only rule is that the list of interfaces must be stable and what I call reasonable: the list cannot change over time for a given instance of the object; he must support IUNKNOWN, which is sometimes forgotten by people; if it supports a derived interface, it must support its base; and a couple of others, I'm sure I forget.

This last point is crucial for your problem: COM does not know a priori which interfaces are supported by any object. .NET runtime knows neither one nor the other. The only way for .NET to know would be if the type library for the object says that the returned object has a specific interface. If this is not the case, all you have is an IUNKNOWN pointer, and you need to set specific interfaces through code and see if you have a non-NULL answer.

Since the type of the SelectedItem property is an object, this means that the type library simply says: "The return type is an interface pointer of type IUNKNOWN" (this may be IDISPATCH, but the principle is worth it). The exact type obviously depends on the execution conditions - β€œwhat will be chosen right now”.

(In .NET, the return type is actually System.__ComObject , because you are not getting a bare pointer to the interface, but a COM calling shell on which the .NET proxy is based on an object)

You are at the mercy of the documentation of the (poor?) Library to get an idea of ​​what types of interfaces the returned object can support. The disadvantage of this code, for example, Chibacity, can lead to you a partial list (I have not looked at this code yet). Ultimately, you probably want to use this code to get a list of candidate interfaces during debugging.

Once you find out a few features that interest you, you can save on some typing problems by simply using the C # as operator (which forces the COM calling shell to issue appropriate COM spells against its own object).

+7
source share

I claim that the documentation is not enough in certain places, but the help is quite specific in your case:

Notes

This property returns a link to the currently selected item in the table of contents. Return is IUnknown because there are several possible objects that can be selected by the selected item.

When working on the "Screen" tab, a link can be to a Map object if you have selected a data frame, one of the Layer objects (FeatureLayer, FDOGraphicsLayer, etc.), If you have a layer selected, or LegendGroup , if you selected a unique value or headline.

On the Source tab, a link can be associated with any of the above objects plus a Table , FeatureDataset, or Workspace .

In the case when more than one item is selected, a link to a Set .

http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#/SelectedItem_Property/000v00000124000000/

+1
source share

try selected.GetType (). ToString ();

It must indicate the type of object that it is.

0
source share

Try reading the docs. If the SDK does not help, try reading the type library in the OLEView utility that ships with the Windows Resource Kit and Visual C ++.

0
source share

I am afraid that there is no way to list the interfaces implemented by the com object. However, you can still overdo it by querying it against the list of interface that interests you.

Edit:

Some code that might help:

 foreach(Type comInterfacType in comInterfaceTypesIAmInterestedIn) { IntPtr comInterface = Marshal.GetComInterfaceForObject(o, comInterfaceType); if(comInterface != IntPtr.Zero) { Console.WriteLine("o implements " + comInterfaceType); Marshal.ReleaseComObject(o); } } 
0
source share

(I would add this as a comment, but I'm noob, and my reputation is insufficient)

Some time has passed since I worked with ArcObjects, but I remember that the object model was ridiculously large and poorly documented. However, is not IMxDocument.SelectedItem related to the item selected in the TOC / layers control? If so, will it return an instance of IMap or ILayer?

0
source share

All Articles