10
votes

Découvrez quelles interfaces sont requises pour un objet COM?

Je travaille avec la bibliothèque COM ArcObjects d'Esri, j'essaye vraiment de savoir quel type "sélectionné" doit être:

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


0 commentaires

7 Réponses :


0
votes

Essayez sélectionné.getType (). Tostring ();

Il devrait donner le type d'objet que c'est.


1 commentaires

"Système .__ ComObject" Je reçois cela.



0
votes

essayez de lire les docs. Si le SDK n'aident pas, essayez de lire la bibliothèque de types de l'utilitaire OLEVIEW expédiée avec Windows Resource Kit et Visual C ++.


0 commentaires

8
votes

Après avoir lu votre question, les réponses et les commentaires, vous devrez peut-être écrire un utilitaire pour trouver la réponse de la force brute.

Utilisez la réflexion pour gratter une liste d'interfaces hors de votre assemblage Interop, puis simplement boucle Sur cette liste et voir si votre objet prend en charge chaque interface à tour de rôle. p>

update stry> p>

Quelques échantillons de code: P>

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


6 commentaires

Dans votre code, inconnu.getype () retournera toujours Système .__ ComObject car il s'agit du wrapper géré .NET autour de iunknown . Donc, d'un point de vue «type de type» .NET », System .__ ComObject n'entre pas vraiment aucune des interfaces COM que nous sommes intéressés.


@Nicolas tu as tout à fait raison. J'ai mis à jour le code avec "Marshal.getCommerfaceforObject" à la place.


Eh bien, cela fonctionne Cependant, aucune de leurs interfaces publiques ne semble fonctionner pour cela. Donc, je suppose que c'est quelque chose de soupir interne seulement.


Il se peut que l'interface est située dans un autre assemblage?


Un peu tard, mais juste une pensée: vous pouvez obtenir une liste de iid S à partir de hkey_classes_root \ interface . Pourriez-vous donc boucler sur tous les IID S, requête pour chacun et renvoyer chaque interface prise en charge?


Cela devrait exclure les génériques (par exemple où (t => t.isinterface &&! T.isgenerictype) ). De plus, vous pouvez obtenir une liste de tous les assemblages actifs à itérer avec AppDomain.CurrentDomaine.GetAssemblages () .



0
votes

J'aime l'attaquant Il n'y a aucun moyen de répertorier les interfaces implémentées par un objet COM. Cependant, vous pouvez toujours la force brute en l'interrogeant sur une liste d'interface qui vous intéresse.

EDIT:

Quelques codes Peut aider: xxx


0 commentaires

0
votes

(aurait ajouté cela comme un commentaire, mais je suis un noob et mon représentant est insuffisant)

Cela fait longtemps que j'ai travaillé avec ArcObjects, mais je me souviens que le modèle d'objet était ridiculement grand et mal documenté. Cela dit, NON IMXDOCUMENT.SelectedItem ne se réfère pas à l'élément sélectionné dans le contrôle de Toc / calques? Si oui, cela ne retournerait-il pas une instance d'IMAP ou d'ILayer?


1 commentaires

C'était ce que je m'attendrais à ce que cela fasse. Mais c'est ce que ESRI nous a signalés vers. Nous savons que "quelque chose" est stocké dans des articles sélectionnés. Si nous faisons une carte vide, pas de couches. Rien de sélectionné == null, sélectionnez un outil == quelque chose.



9
votes

Je ne suis pas au courant de cette bibliothèque, mais je peux donner quelques suggestions. Une fois que vous regardez le problème du point de vue de COM, vous verrez qu'il n'y a pas de réponse simple.

(gardez à l'esprit que ce COM tous les objets ne sont que des objets, et que la seule exigence est qu'il doit prendre en charge IUnKnown (et éventuellement d'autres interfaces). La réponse à la question « quel type d'objet il est » peut souvent avoir plus d'une réponse.)

La chose importante à retenir est que dans COM la liste des interfaces pour un objet est définie dans aucune sorte de méta-données comme il est dans .NET (sauf qu'une bibliothèque fournit généralement une option bibliothèque de type comme une forme de documentation pour les outils de développement -. plus que dans une minute)

La liste des interfaces est officiellement définie que par les résultats de l'appel méthode QueryInterface () de IUnKnown -. Qui est, elle est définie entièrement par le résultat de l'exécution du code

Quelques fois la liste peut être codée en dur. Souvent, la liste pourrait ne pas être connu avant l'exécution, et il pourrait même ne pas être connu jusqu'à ce que quelqu'un demande . La seule règle est que la liste des interfaces doit être stable et ce que j'appelle raisonnable : la liste ne peut pas changer au fil du temps pour une instance donnée d'un objet; il doit prendre en charge IUnKnown, qui parfois les gens oublient; s'il supporte une interface dérivée, il doit prendre en charge sa base; et deux ou trois autres, je suis sûr que je suis oublier.

Ce dernier point est essentiel à votre problème: COM ne sait pas a priori quelles interfaces sont pris en charge par un objet quelconque. Le moteur d'exécution .NET ne sait pas non plus - pas de COM de toute façon. La seule façon pour .NET à savoir serait si la bibliothèque de types pour l'objet dit que l'objet retourné est d'une interface spécifique. Manquant que, tout ce que vous avez est un pointeur IUnknown et vous devez demander des interfaces spécifiques via le code et voir si vous obtenez une réponse autre que NULL.

Étant donné que le type de SelectedItem propery est objet, cela signifie que la bibliothèque de type dit simplement « le type de retour est un pointeur d'interface de type IUnKnown » (il pourrait être Idispatch, mais les peuplements principaux ). Le type exact dépend évidemment des circonstances d'exécution -. « Ce qui se passe à choisir en ce moment »

(Dans .NET, le type de retour est en fait System .__ ComObject parce que vous ne recevez pas un pointeur d'interface nue, mais une enveloppe COM callable un proxy .NET à l'objet)

Vous êtes à la merci de la documentation (mauvaise?) De la bibliothèque pour obtenir un indice sur les types d'interfaces l'objet retourné peuvent prendre en charge. À défaut, le code comme celui Chibacity pourrait vous obtenir une liste partielle et (je ne l'ai pas revu ce code). En fin de compte, vous voulez probablement utiliser ce code pour obtenir une liste des interfaces candidats au cours du débogage.

Une fois que vous savez quelques possibilités qui vous intéressent, vous pouvez vous épargner quelques problèmes de frappe en utilisant simplement le C # comme opérateur (ce qui provoque l'emballage COM appelable à délivrer les sorts COM correspondants contre le natif objet).


0 commentaires

1
votes

Je suis agité que la documentation manque à certains endroits, mais l'aide est assez spécifique dans votre cas:

remarques

Cette propriété renvoie une référence à l'élément actuellement sélectionné dans la table des matières. Le retour est un iunknown parce qu'il sont plusieurs objets possbiles l'élément sélectionné peut être.

Lorsque vous travaillez dans l'onglet Affichage, la référence pourrait être une carte Objet Si vous avez une image de données sélectionnée, l'une des objets calque (FeatureLayer, FdographicSlayer, etc.) Si vous avez un calque sélectionné, ou un LEGENDGROUP Si vous avez une valeur unique ou une rubrique sélectionnée.

Dans l'onglet Source, la référence peut être à l'un des objets ci-dessus. Plus une table , FeatureDaTaset ou Espace de travail .

Dans le cas où plus d'un élément est sélectionné, la référence est de un objet objet.

http: // aide. arcgis.com/fr/sdk/10.0/arcObjects_net/componententhelp/index.html#/SelectedItem_Property/000v00000124000000/


0 commentaires