BOGUE : paramètre Cancel pour les événements d'Office est ignorée dans Visual Studio .NET 2003

Traductions disponibles Traductions disponibles
Numéro d'article: 830519 - Voir les produits auxquels s'applique cet article
Cet article a été archivé. Il est proposé « en l'état » et ne sera plus mis à jour.
Agrandir tout | Réduire tout

Sommaire

Résumé

Lorsque vous travaillez avec Visual Studio .NET 2003, vous pouvez rencontrer des problèmes lorsque vous utilisez le paramètre Cancel dans un événement COM qui est généré par Microsoft Word, par Microsoft Excel ou Microsoft Outlook. Bien que le code reçoit l'événement COM et le code peut définir le paramètre en conséquence, le COM événement n'est pas annulé. Ce problème se produit lorsque vous utilisez l'interopérabilité COM à partir d'un client géré (tel que Microsoft Visual C# ou Microsoft Visual Basic .NET), et que vous utilisez également version 1.1 de Microsoft .NET Framework.

Cause

Le .NET Framework 1.1 a introduit des modifications de sécurité pour améliorer la sécurité de type lors de l'interaction avec un composant COM. Le .NET Framework 1.1 améliore la sécurité de type en utilisant les informations marshaling de la bibliothèque de type du composant. Lorsque vous automatisez Word, Excel ou Outlook à partir d'un client géré, l'assembly de l'interopérabilité COM (IA) ou le PIA (Primary Interop Assembly) pour Microsoft Office XP utilise les informations type stockées dans les bibliothèques de types Microsoft Office pour gérer les événements. Versions existantes de la Word tapez bibliothèques, les bibliothèques de types Excel et la marque de bibliothèques de type Outlook le paramètre Cancel comme paramètre [en] . Le paramètre Cancel est marqué comme paramètre [en] de sorte que le common language runtime impose cette restriction et empêche les modifications apportées par le code géré d'être renvoyé à l'appelant. Par conséquent, l'événement ne peut pas être annulé à partir d'un IA du code managé (ou PIA).

Résolution

Ce problème a été corrigé dans Microsoft Office 2003.

Contournement

Si vous utilisez une version antérieure de Word, une version antérieure d'Excel ou une version antérieure d'Outlook, vous devez établir votre propre récepteur de point de connexion dans votre code géré. Un gestionnaire personnalisé peut éviter le type-bibliothèque dépendance et la protection appliquée-type qui s'appliquent généralement. Par conséquent, l'argument peut être transmis à l'appelant.

Microsoft fournit des exemples de programmation pour illustration uniquement, sans garantie explicite ou implicite. Cela inclut, mais n'est pas limité aux garanties implicites de qualité marchande ou d'adéquation à un usage particulier. Cet article suppose que vous êtes familiarisé avec le langage de programmation présenté et les outils qui sont utilisés pour créer et déboguer des procédures. Les techniciens du support technique Microsoft peuvent vous expliquer les fonctionnalités d'une procédure particulière, mais ils ne sont pas modifier les exemples en vue de fournir des fonctionnalités supplémentaires ou de créer des procédures répondant à vos besoins spécifiques.

Génération d'une classe d'assistance

Pour directement recevoir des événements à partir de Visual C#, vous devez créer votre propre définition dispinterface et vous devez également créer une classe d'assistance pour implémenter votre code d'événement. La définition de la dispinterface doit correspondre à l'identificateur global unique (GUID) et les identificateurs d'affectation (DISPID) d'au récepteur d'événement est attendu par l'objet d'Office que vous souhaitez recevoir des événements pour. Pour savoir comment ces valeurs sont, vous pouvez utiliser une des méthodes suivantes :
  • Vous pouvez utiliser l'Observateur d'objet OLE/COM inclus avec Visual Studio .NET 2003 Professional Edition
  • Vous pouvez utiliser le Kit de développement Platform SDK. Pour plus d'informations sur le Kit de développement Platform SDK, reportez-vous au site de Web Microsoft suivant :

    http://www.microsoft.com/msdownload/platformsdk/sdkupdate
Une fois que vous connaissez le GUID et le DISPID, vous pouvez créer votre propre définition de la définition de dispinterface dans Visual Basic .NET ou dans Visual C#.

Cet article fournit deux exemples qui vous indiquent comment utiliser connexion personnalisée vous pointez sur contourner ce problème. Le premier exemple montre comment récepteur d'événements application objet pour Word 2000 et ensuite annuler l'événement DocumentBeforeClose afin que l'utilisateur ne peut pas fermer le document. Le deuxième exemple récepteurs l'événement ItemSend pour Outlook 2002, afin que vous pouvez annuler l'opération d'envoi dans votre application.

Exemple 1: Annuler DocumentBeforeClose , événement

  1. Démarrez Visual Studio .NET 2003. Démarrer un nouveau projet. Sélectionnez Visual C# comme le type de projet. Sélectionnez Windows Application en tant que le modèle. Nommez le projet MyWordEventTest , puis cliquez sur OK .

    Par défaut, Form1 est créé.
  2. Dans le menu projet , cliquez sur Ajouter référence . Dans la boîte de dialogue, sélectionnez bibliothèque d'objets Microsoft Word 9.0 cliquez sur Sélection pour ajouter une référence de l'onglet COM, puis cliquez sur OK pour fermer la boîte de dialogue.

    Un IA personnalisé est généré automatiquement pour vous.
  3. Dans le menu projet , cliquez sur Ajouter une classe . Sélectionner le fichier de code , puis puis nommez la classe Word9EventHelper.cs . Cliquez sur OK pour générer le fichier.
  4. Ajoutez le code suivant dans la fenêtre de code système Word9EventHelper.cs:
    using System;
    using System.Runtime.InteropServices;
    using Word; // The default name for a custom Word IA.
    // If you use Office XP and you have the PIAs
    // referenced in your project, you must change the previous line to read:
    // using Word = Microsoft.Office.Interop.Word;
    
    namespace WordAppEvents9
    {
    	[InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
    	GuidAttribute("000209FE-0000-0000-C000-000000000046")]
    	public interface DWordApplicationEvents9
    	{
    		[DispId(0x00000001)] void Startup();
    		[DispId(0x00000002)] void Quit();
    		[DispId(0x00000003)] void DocumentChange();
    		[DispId(0x00000004)] void DocumentOpen(Word.Document doc);
    		[DispId(0x00000006)] void DocumentBeforeClose(Word.Document doc, ref bool Cancel);	
    		[DispId(0x00000007)] void DocumentBeforePrint(Word.Document doc, ref bool Cancel);
    		[DispId(0x00000008)] void DocumentBeforeSave(Word.Document doc, ref bool SaveAsUI, ref bool Cancel);
    		[DispId(0x00000009)] void NewDocument(Word.Document doc);
    		[DispId(0x0000000a)] void WindowActivate(Word.Document doc, Word.Window wn);
    		[DispId(0x0000000b)] void WindowDeactivate(Word.Document doc, Word.Window wn);
    		[DispId(0x0000000c)] void WindowSelectionChange(Word.Selection sel);
    		[DispId(0x0000000d)] void WindowBeforeRightClick(Word.Selection sel, ref bool Cancel);
    		[DispId(0x0000000e)] void WindowBeforeDoubleClick(Word.Selection sel, ref bool Cancel);
    	}
    
    
    	public class WordAppEventHelper : DWordApplicationEvents9, IDisposable
    	{
    		public WordAppEventHelper()
    		{
    			m_oConnectionPoint = null;
    			m_Cookie = 0;
    		}
    
    		public void Startup()
    		{System.Diagnostics.Debug.WriteLine("Startup");}
    
    		public void Quit()
    		{System.Diagnostics.Debug.WriteLine("Quit");}
    
    		public void DocumentChange()
    		{System.Diagnostics.Debug.WriteLine("DocumentChange");}
    
    		public void DocumentOpen(Word.Document doc)
    		{System.Diagnostics.Debug.WriteLine("DocumentOpen");}
    
    		public void DocumentBeforeClose(Word.Document doc, ref bool Cancel)
    		{
    			System.Diagnostics.Debug.WriteLine("DocumentBeforeClose");
    			Cancel = true; // Cancel the close!
    		}
    
    		public void DocumentBeforePrint(Word.Document doc, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("DocumentBeforePrint");}
    
    		public void DocumentBeforeSave(Word.Document doc, ref bool SaveAsUI, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("DocumentBeforeSave");}
    
    		public void NewDocument(Word.Document doc)
    		{System.Diagnostics.Debug.WriteLine("NewDocument");}
    
    		public void WindowActivate(Word.Document doc, Word.Window wn)
    		{System.Diagnostics.Debug.WriteLine("WindowActivate");}
    
    		public void WindowDeactivate(Word.Document doc, Word.Window wn)
    		{System.Diagnostics.Debug.WriteLine("WindowDeactivate");}
    
    		public void WindowSelectionChange(Word.Selection sel)
    		{System.Diagnostics.Debug.WriteLine("WindowSelectionChange");}
    
    		public void WindowBeforeRightClick(Word.Selection sel, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("WindowBeforeRightClick");}
    
    		public void WindowBeforeDoubleClick(Word.Selection sel, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("WindowBeforeDoubleClick");}
    
    		private UCOMIConnectionPoint m_oConnectionPoint;
    		private int m_Cookie;
    
    		public void SetupConnection(Word.Application app)
    		{
    			if (m_Cookie != 0) return;
    
    			// GUID of the DIID_ApplicationEvents dispinterface.
    			Guid guid = new Guid("{000209FE-0000-0000-C000-000000000046}");
    
    			// QI for IConnectionPointContainer.
    			UCOMIConnectionPointContainer oConnPointContainer = (UCOMIConnectionPointContainer)app;
    
    			// Find the connection point and then advise.
    			oConnPointContainer.FindConnectionPoint(ref guid, out m_oConnectionPoint);
    			m_oConnectionPoint.Advise(this, out m_Cookie);
    		}
    
    		public void RemoveConnection()
    		{
    			if (m_Cookie != 0)
    			{
    				m_oConnectionPoint.Unadvise(m_Cookie);
    				m_oConnectionPoint = null;
    				m_Cookie = 0;
    			}
    		}
    
    		public void Dispose(){RemoveConnection();}
    	}
    }
    oConnPointContainer.FindConnectionPoint (guid de référence des m_oConnectionPoint); m_oConnectionPoint.Advise (, m_Cookie sortant);} RemoveConnection() public void {si (m_Cookie! = 0) {m_oConnectionPoint.Unadvise(m_Cookie) ; m_oConnectionPoint = null ; m_Cookie = 0;}} public void Dispose(){RemoveConnection();}}}
  5. Revenez à Form1 et puis ajoutez un bouton de commande. Double-cliquez sur le bouton de commande pour la fenêtre code de Form1.cs s'affichent. Ou, dans le menu Affichage , cliquez sur code pour rendre la fenêtre de code de Form1.cs s'affichent. Ajouter le code suivant au gestionnaire de bouton pour le document event:
    Word.Document doc;
    Object missing = System.Reflection.Missing.Value;
    
    // Create a new instance of Word and then set up the event handler.
    m_oApp = new Word.ApplicationClass();
    m_oAppEvents = new WordAppEvents9.WordAppEventHelper();
    m_oAppEvents.SetupConnection(m_oApp);
    
    // Make Word visible and then display a new document to test close.
    m_oApp.Visible = true;
    doc = m_oApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);
    doc.UserControl = true;
    doc.Content.Text = "Try to close the document";
    
    // You only have to do this one time in this sample.
    button1.Enabled = false;
    
    Button1.Enabled = false ;
  6. Ajoutez le code suivant à la classe Form1 avant le gestionnaire de bouton :
    Word.Application m_oApp;
    WordAppEvents9.WordAppEventHelper m_oAppEvents;
    
  7. Dans le menu Générer , cliquez sur Créer solution pour rendre le projet. Cliquez sur débogage , puis cliquez sur Démarrer pour exécuter l'application.

    Lorsque l'application démarre, vous pouvez cliquer sur le bouton de commande et Word s'affiche. Vous ne pouvez pas fermer la fenêtre Word jusqu'à ce que vous fermiez votre application.

    Vous pouvez utiliser un code similaire pour gérer les événements pour Excel.

Exemple 2: Annuler ItemSend événement

  1. Démarrez Visual Studio .NET 2003. Démarrer un nouveau projet. Sélectionnez Visual C# comme le type de projet. Sélectionnez Windows Application en tant que le modèle. Nommez le projet MyOutlookEventTest , puis cliquez sur OK .

    Par défaut, Form1 est créé.
  2. Dans le menu projet , cliquez sur Ajouter référence . Dans la boîte de dialogue, sélectionnez bibliothèque d'objets Microsoft Outlook 10.0 cliquez sur Sélection pour ajouter une référence de l'onglet COM, puis cliquez sur OK pour fermer la boîte de dialogue.

    Un IA personnalisé est généré automatiquement pour vous.
  3. Dans le menu projet , cliquez sur Ajouter une classe . Sélectionner le fichier de code , puis puis nommez la classe Outlook10EventHelper.cs . Cliquez sur OK pour générer le fichier.
  4. Ajoutez le code suivant dans la fenêtre de code pour système Outlook10EventHelper.cs:
    using System;
    using System.Runtime.InteropServices;
    //using Outlook; // The default name for a custom Word IA.
    // If you use Office XP and you have the PIAs
    // referenced in your project, you must change the previous line to read:
    using Outlook = Microsoft.Office.Interop.Outlook;
    using System.Windows.Forms;
    
    namespace OutlookAppEvents10
    {
    	[InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
    	GuidAttribute("0006300E-0000-0000-C000-000000000046")]
    	public interface DOutlookApplicationEvents_10
    	{
    		void ItemSend(object Item, ref bool Cancel);
    		void NewMail();
    		void Reminder(object Item);
    		void OptionsPagesAdd(Outlook.PropertyPages Pages);
    		void Startup();
    		void Quit();
    		void AdvancedSearchComplete(Outlook.Search SearchObject);
    		void AdvancedSearchStopped(Outlook.Search SearchObject);
    		void MAPILogonComplete();
    	}
    
    	public class OutlookAppEventHelper : IDisposable
    	{
    		public OutlookAppEventHelper()
    		{
    			m_oConnectionPoint = null;
    			m_Cookie = 0;
    		}
    
    		private UCOMIConnectionPoint m_oConnectionPoint;
    		private int m_Cookie;
    
    		public void SetupConnection(Outlook.Application app)
    		{
    			if (m_Cookie != 0) return;
    			// GUID of the DIID_ApplicationEvents dispinterface.
    			Guid guid = new Guid("{0006300E-0000-0000-C000-000000000046}");
    
    			// QI for IConnectionPointContainer.
    			UCOMIConnectionPointContainer oConnectionPointContainer = (UCOMIConnectionPointContainer)app;
    
    			// Find the connection point and then advise.
    			oConnectionPointContainer.FindConnectionPoint(ref guid, out m_oConnectionPoint);
    			m_oConnectionPoint.Advise(this, out m_Cookie);
    		}
    
    		public void RemoveConnection()
    		{
    			if (m_Cookie != 0)
    			{
    				m_oConnectionPoint.Unadvise(m_Cookie);
    				m_oConnectionPoint = null;
    				m_Cookie = 0;
    			}
    		}
    
    		#region IDisposable Members
    
    		public void Dispose()
    		{
    			RemoveConnection();
    		}
    
    		#endregion
    
    		//#region DOutlookApplicationEvents_10 Members
    
    		[DispId(0x0000F002)]
    		public void ItemSend(object Item, ref bool Cancel)
    		{
    			DialogResult result;
    			result = MessageBox.Show("Do you want to cancel the ItemSend event?","",MessageBoxButtons.YesNo);
    			if(result == DialogResult.Yes)
    			{
    				System.Diagnostics.Debug.WriteLine("Cancelling Message");
    				Cancel = true;	
    			}
    			else
    			{
    				System.Diagnostics.Debug.WriteLine("Passing Message");
    				Cancel = false;
    			}
    		}
    
    		[DispId(0x0000F003)]
    		public void NewMail()
    		{
    			MessageBox.Show("NewMail");
    		}
    
    		[DispId(0x0000F004)]
    		public void Reminder(object Item)
    		{
    			MessageBox.Show("Reminder");
    		}
    
    		[DispId(0x0000F005)]
    		public void OptionsPagesAdd(Microsoft.Office.Interop.Outlook.PropertyPages Pages)
    		{
    			MessageBox.Show("OptionsPagesAdd");
    		}
    
    		[DispId(0x0000F006)]
    		public void Startup()
    		{
    			MessageBox.Show("Startup");
    		}
    
    		[DispId(0x0000F007)]
    		public void Quit()
    		{
    			MessageBox.Show("Quit");
    		}
    
    		[DispId(0x0000FA6A)]
    		public void AdvancedSearchComplete(Microsoft.Office.Interop.Outlook.Search SearchObject)
    		{
    			MessageBox.Show("AdvancedSearchComplete");
    		}
    
    		[DispId(0x0000FA6B)]
    		public void AdvancedSearchStopped(Microsoft.Office.Interop.Outlook.Search SearchObject)
    		{
    			MessageBox.Show("AdvancedSearchStopped");
    		}
    
    		[DispId(0x0000FA90)]
    		public void MAPILogonComplete()
    		{
    			MessageBox.Show("MAPILogonComplete");
    		}
    		//#endregion
    	}
    }
    Note You need to place the [DispId(#)] attribute on the methods. Dans le cas contraire, l'événement ne peut pas être annulé.
  5. Revenez à Form1 et puis ajoutez un bouton de commande. Double-cliquez sur le bouton de commande pour la fenêtre code de Form1.cs s'affichent. Ou, dans le menu Affichage , cliquez sur code pour rendre la fenêtre de code de Form1.cs s'affichent. Ajoutez le code suivant au gestionnaire de bouton pour l'article cliquez sur event:
    Outlook.MailItem item;
    
    if (m_oApp == null)
    {
    	// Create a new instance of Outlook and then set up the event handler.
    	m_oApp = new Outlook.ApplicationClass();
    	m_oAppEvents = new OutlookAppEvents10.OutlookAppEventHelper();
    	m_oAppEvents.SetupConnection(m_oApp);
    } 
    
    // Make Outlook visible and then display a new message to test send.
    item = (Outlook.MailItem)m_oApp.CreateItem(Outlook.OlItemType.olMailItem);
    item.Subject = "The Subject!";
    item.Body = "Try sending the message.";
    item.Display(m_oApp);
    élément = (Outlook.MailItem)m_oApp.CreateItem(Outlook.OlItemType.olMailItem) ; item.Subject = « l'objet! »; item.Body = « tentative de l'envoi du message. »; item.Display(m_oApp) ;
  6. Ajoutez le code suivant à la classe Form1 avant le gestionnaire de bouton :
    Outlook.Application m_oApp;
    OutlookAppEvents10.OutlookAppEventHelper m_oAppEvents;
    
  7. Dans le menu Générer , cliquez sur Créer solution pour rendre le projet. Cliquez sur débogage , puis cliquez sur Démarrer pour exécuter l'application.

    Lorsque l'application démarre, vous pouvez cliquer sur le bouton de commande et Outlook s'affiche. Un brouillon de message électronique nouveau est automatiquement créé. Entrée d'un destinataire dans la ligne À , puis cliquez sur Envoyer . Vous obtiendrez un pop boîte de dialogue vous demandant si vous souhaitez annuler l'événement ItemSend. Cliquez sur Oui pour l'annuler.

    Vous pouvez utiliser un code similaire pour gérer les événements pour Excel.

Statut

Microsoft a confirmé qu'il s'agit d'un problème les produits Microsoft répertoriés au début de cet article produits.

Références

Pour plus d'informations sur l'automatisation d'Office à partir de Visual Studio .NET, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
311452 Développement Microsoft Office solutions avec Visual Studio .NET
317109 Application Office ne se termine pas après l'automatisation du client de Visual Studio .NET

Propriétés

Numéro d'article: 830519 - Dernière mise à jour: jeudi 27 février 2014 - Version: 3.5
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Excel 2002
  • Microsoft Word 2002 Standard Edition
  • Microsoft Outlook 2002 Standard
  • Microsoft Excel 2000 Standard
  • Microsoft Word 2000 Standard Edition
  • Microsoft Outlook 2000 Standard
  • Microsoft .NET Framework 1.1
  • Microsoft Visual Studio .NET 2003 Professional
  • Microsoft Visual Studio .NET 2003 Enterprise Architect
  • Microsoft Visual Studio .NET 2003 Éducation
Mots-clés : 
kbnosurvey kbarchive kbmt kbnofix kbbug KB830519 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 830519
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com