2010-12-02 84 views
6

我與ESRI公司的ArcObjects COM庫工作,我真的已經很努力弄清楚「選擇了」是什麼類型應該是:找出哪些接口可以查詢COM對象?

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

的SelectedItem返回comobject(NOT NULL),通常表示爲數據類型當前選中。然而,我不知道我應該把它投入什麼類型。當我調試它,我實在看不出任何有用的東西:

http://imgur.com/Yfo6G

(手錶調試值設置後)

ESRI公司的ArcObjects庫是巨大的,是記錄非常糟糕,我只是無法弄清楚。我甚至竟然手動檢查了大約50個我認爲應該是的接口。

有沒有人有任何想法我可以弄清楚這一點?

編輯澄清他們的文件是絕對沒有幫助,他們的論壇也沒有幫助。

回答

5

在閱讀完您的問題,答案和評論之後,您可能需要編寫一個實用程序以通過強力找到答案。

使用反射來從您的互操作程序集中提取接口列表,然後簡單地遍歷此列表並查看您的對象是否支持每個接口。

更新

一些示例代碼:

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 :("); 
    } 
+0

我不認爲`IsAssignableFrom`在這種情況下工作。 – 2010-12-02 20:35:06

+0

@Nicolas你確定嗎? – 2010-12-02 20:36:50

0

try selected.GetType()。ToString();

它應該給出它的類型。

+1

「系統.__ ComObject」 我得到這個。 – UberJumper 2010-12-02 19:45:09

0

嘗試閱讀文檔。如果SDK不起作用,請嘗試閱讀隨Windows資源工具包和Visual C++附帶的OLEView實用程序中的類型庫。

0

我'affraid是沒有辦法中列出了一個COM對象實現的接口。但是,你仍然可以蠻力它通過查詢這對你有興趣在界面的列表

編輯:

一些代碼,可以幫助:

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

(會已添加此作爲評論,但我是一個noob和我的代表是不夠的)

這已經有一段時間,因爲我已經與ArcObjects合作,但我記得對象m奧德爾是荒謬的大和文件記錄不佳。也就是說,不是IMxDocument.SelectedItem引用在TOC /圖層控件中選擇的項目?如果是這樣,是不是會返回IMap或ILayer的實例?

7

我對圖書館並不熟悉,但我可以提出一些建議。一旦你從COM的角度來看問題,你會發現沒有簡單的答案。 (請記住,在COM中,所有對象都只是對象,唯一的要求是它必須支持IUNKNOWN(可能還有其他接口)。因此,對於「它是什麼類型的對象」 「通常可以有多個答案。)

要記住的重要一點是,在COM中,對象的接口列表沒有在任何類型的元數據中定義,例如它在.NET中(除了通常的庫提供了一個可選的類型庫作爲開發工具的文檔形式 - 更多內容在一分鐘內)。

接口列表僅由調用IUNKNOWN的QueryInterface()方法的結果正式定義 - 也就是說,它完全由執行代碼的結果定義。

某些時候,列表可能是硬編碼的。通常情況下,列表可能不會在運行時才知道,甚至可能不知道,直到有人詢問。唯一的規則是接口列表需要穩定,我稱之爲合理:對於給定的對象實例,列表不能隨時間變化;它必須支持有時讓人忘記的IUNKNOWN;如果它支持派生接口,它必須支持它的基礎;和其他一些我確定我忘了。

最後一點對您的問題至關重要:COM不知道先驗什麼對象支持哪些接口。 .NET運行時並不知道 - 無論如何都不是。 .NET知道的唯一方法就是如果對象的類型庫聲明返回的對象是特定的接口。缺乏這一點,你所擁有的只是一個IUNKNOWN指針,你必須通過代碼請求特定的接口,看看你是否得到了一個不是NULL的答案。

由於SelectedItem propery的類型是object,這意味着類型庫只是簡單地說「返回類型是IUNKNOWN類型的接口指針」(它可能是IDISPATCH,但原理是stand)。確切的類型顯然取決於運行時環境 - 「現在選擇什麼」。

(在.NET中,返回類型實際上是System.__ComObject,因爲你沒有得到一個裸體的接口指針但COM調用包裝它基於.NET代理的對象)

你是在憐憫庫的(poor?)文檔來獲取返回對象可能支持的接口類型。缺乏這一點,像Chibacity的代碼也可能會給你一個部分列表(我還沒有審查過這個代碼)。最終,您可能希望在調試期間使用該代碼獲取候選接口列表。只要使用C#as運算符(這會導致COM可調用包裝器針對本機對象發出相應的COM法術),您可以節省一些打字的麻煩。

1

我aggree該文件缺乏在某些地方,但幫助你的情況很特殊:

備註

此屬性 將返回到當前所選項目的引用目錄。回報是IUnknown,因爲 是所選項目可以包含的幾個可能的對象。

在顯示選項卡工作時,參考可以是到一個地圖 對象如果有一個數據幀中選擇,所述層的一個對象 (FeatureLayer,FDOGraphicsLayer等)如果有一個層選擇或 a LegendGroup如果您選擇了唯一值或標題。

在源選項卡,該參考可以是任何上述目的 的外加爲FeatureDataset,或工作區

在選擇多個項目的情況下,參考爲 a 設置對象。

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