Comment obtenir de manière fiable l’object d’un menu contextuel de contact dans un complément Outlook 2013?

J’ajoute une entrée au menu contextuel pour un contact dans Outlook 2013 en suivant l’exemple de cet article . Voici le XML:

   

L’entrée apparaît correctement dans le menu et lorsque je clique dessus, mon gestionnaire d’événements est exécuté:

 public void OnDoSomething(IRibbonControl control) { object context = control.Context; System.Diagnostics.Debug.WriteLine(context.GetType()); if ((context as IMsoContactCard) != null) System.Diagnostics.Debug.WriteLine("IMsoContactCard"); if ((context as ContactItem) != null) System.Diagnostics.Debug.WriteLine("ContactItem"); if ((context as ContactCard) != null) System.Diagnostics.Debug.WriteLine("ContactCard"); if ((context as _ContactItem) != null) System.Diagnostics.Debug.WriteLine("_ContactItem"); } 

L’ article IMsoContactCard en référence semble indiquer que le contexte devrait être une IMsoContactCard , mais ce n’est pas ce que je reçois. La ligne qui imprime context.GetType() affiche System.__ComObject .

Cet article semble indiquer que je devrais être capable de transformer cet object en quelque chose d’utile, mais toutes les tentatives pour le transformer en quelque chose de logique ( IMsoContactCard , ContactItem , ContactCard , _ContactItem ) ont échoué.

Pour tenter de contourner le problème, j’ai essayé de suivre l’élément actuellement sélectionné, conformément aux instructions de cet article . En fait, cela fonctionne assez bien, avec l’avertissement que l’élément actuellement sélectionné ne correspond pas toujours à l’élément auquel le menu contextuel s’applique.

Pour élaborer, je peux cliquer sur un contact et le mettre en surbrillance. Mon événement de sélection est déclenché. Si je clique avec le bouton droit de la souris sur un autre contact pour afficher le menu contextuel sans cliquer dessus en premier , ce contact sera alors défini mais pas mis en surbrillance, et mon événement de sélection ne sera pas déclenché. Lorsque cela se produit, je finis par appliquer le menu contextuel en cliquant sur le mauvais contact.

Tout conseil ou direction serait apprécié. Merci.


Mise à jour avec une solution basée sur les informations fournies par Eugene Astafiev

Sur la base des informations fournies ci-dessous, j’ai pu déterminer que le Context de ce rappel particulier est de type Microsoft.Office.Interop.Outlook.Selection . Je peux ensuite l’utiliser pour obtenir le ContactItem comme suit:

 private ContactItem GetContactItemFromControlContext(IRibbonControl control) { var selection = control.Context as Selection; if (selection != null && selection.Count == 1) return selection[1] as ContactItem; else return null; } 

Le type de l’object Context dépend de l’endroit où vous avez cliqué et du type de menu contextuel. Pour obtenir le type sous-jacent, vous devez procéder comme suit:

  1. Convertissez l’object dans l’interface IDispatch.
  2. Obtenez l’interface ITypeInfo à l’aide de la méthode GetTypeInfo de l’interface IDispatch.
  3. Obtenez le nom du type à l’aide de la méthode GetDocumentation de l’interface ITypeInfo.

     public static ssortingng GetTypeName(object comObj) { if (comObj == null) return Ssortingng.Empty; if (!Marshal.IsComObject(comObj)) //The specified object is not a COM object return Ssortingng.Empty; IDispatch dispatch = comObj as IDispatch; if (dispatch == null) //The specified COM object doesn't support getting type information return Ssortingng.Empty; ComTypes.ITypeInfo typeInfo = null; try { try { // obtain the ITypeInfo interface from the object dispatch.GetTypeInfo(0, 0, out typeInfo); } catch (Exception ex) { //Cannot get the ITypeInfo interface for the specified COM object return Ssortingng.Empty; } ssortingng typeName = ""; ssortingng documentation, helpFile; int helpContext = -1; try { //resortingeves the documentation ssortingng for the specified type description typeInfo.GetDocumentation(-1, out typeName, out documentation, out helpContext, out helpFile); } catch (Exception ex) { // Cannot extract ITypeInfo information return Ssortingng.Empty; } return typeName; } catch (Exception ex) { // Unexpected error return Ssortingng.Empty; } finally { if (typeInfo != null) Marshal.ReleaseComObject(typeInfo); } } 

    }

Voir HowTo: obtenir le nom du type réel derrière System .__ ComObject avec Visual C # ou VB.NET pour plus d’informations.