BUG: Il parametro Cancel per gli eventi di Office viene ignorata in Visual Studio .NET 2003

Traduzione articoli Traduzione articoli
Identificativo articolo: 830519 - Visualizza i prodotti a cui si riferisce l?articolo.
Questo articolo Ŕ stato archiviato. L?articolo, quindi, viene offerto ?cosý come Ŕ? e non verrÓ pi¨ aggiornato.
Espandi tutto | Chiudi tutto

In questa pagina

Sommario

Quando si lavora con Microsoft Visual Studio .NET 2003, potrebbero verificarsi problemi quando si utilizza il parametro Cancel di un evento COM che viene generato da Microsoft Word, Microsoft Excel o Microsoft Outlook. Sebbene il codice riceve l'evento di COM e il codice Ŕ possibile impostare il parametro di conseguenza, il COM evento non viene annullato. Questo problema si verifica quando si utilizza l'interoperabilitÓ COM da un client gestito (ad esempio Microsoft Visual C# o Microsoft Visual Basic. NET) e si utilizza la versione 1.1 di Microsoft .NET Framework.

Cause

.NET Framework 1.1 ha introdotto modifiche della protezione per migliorare l'indipendenza dai tipi quando si interagisce con un componente COM. .NET Framework 1.1 migliora l'indipendenza dai tipi base alle informazioni marshalling nella libreria dei tipi del componente. Quando si automatizza Word, Excel o Outlook da un client gestito, l'assembly di interoperabilitÓ COM (IA) o il assembly di interoperabilitÓ primario (PIA) per Microsoft Office XP utilizza le informazioni di tipo memorizzati in librerie dei tipi Microsoft Office per gestire gli eventi. Versioni esistenti di Word digitare raccolte, le librerie dei tipi Excel e il segno di librerie di tipo Outlook il parametro Cancel come un parametro [in] . Il parametro Cancel Ŕ contrassegnato come parametro [in] , in modo che common language runtime impone questa restrizione e impedisce tutte le modifiche apportate dal codice gestito la restituzione al chiamante. Di conseguenza, Ŕ Impossibile annullare l'evento da un IA (o PIA) di codice gestito.

Risoluzione

Questo errore Ŕ stato corretto in Microsoft Office 2003.

Workaround

Se si utilizza una versione precedente di Word, una versione precedente di Excel o una versione precedente di Outlook, Ŕ necessario stabilire il proprio sink di punto di connessione nel codice gestito. Un gestore personalizzato Ŕ possibile evitare la dipendenza di libreria dei tipi e la protezione di tipo applicato in genere applicabili. Di conseguenza, l'argomento pu˛ essere passato al chiamante.

Microsoft fornisce esempi di programmazione a scopo puramente illustrativo, senza alcuna garanzia espressa o implicita. Questo include, ma non Ŕ limitato a, le garanzie implicite di commerciabilitÓ o idoneitÓ per uno scopo specifico. Questo articolo si presuppone che conosca il linguaggio di programmazione in questione e gli strumenti utilizzati per creare ed eseguire il debug di procedure. Tecnici del supporto Microsoft possono spiegare la funzionalitÓ di una particolare procedura, ma in nessun sono caso a modificare questi esempi per fornire funzionalitÓ aggiuntive o creare procedure per soddisfare specifiche esigenze.

Generazione di una classe di supporto

Per direttamente elaborare gli eventi da Visual C#, Ŕ necessario creare una definizione di interfaccia dispatch personalizzata ed Ŕ anche necessario creare una classe di supporto per implementare il codice di evento. La definizione di interfaccia dispatch deve corrispondere l'identificatore univoco globale (GUID) e gli identificatori di attivitÓ (o DISPID) per sink di evento Ŕ previsto dall'oggetto di Office che si desidera elaborare gli eventi per. Per sapere quali sono questi valori, Ŕ possibile utilizzare uno dei seguenti metodi:
  • ╚ possibile utilizzare il Visualizzatore di oggetti OLE/COM Ŕ incluso in Visual Studio .NET 2003 Professional Edition
  • ╚ possibile utilizzare Platform SDK. Per ulteriori informazioni su Platform SDK, visitare il sito di Web di Microsoft:

    http://www.microsoft.com/msdownload/platformsdk/sdkupdate
Dopo aver individuato il GUID e i DISPID, Ŕ possibile creare una definizione personalizzata della definizione di interfaccia dispatch in Visual Basic .NET o in Visual C#.

Questo articolo vengono fornite due di esempi che mostrano l'utilizzo di connessione personalizzata in che si sceglie per aggirare il problema. Il primo viene illustrato come sink di eventi dell'oggetto Application per Word 2000 e quindi annullare l'evento DocumentBeforeClose , in modo che l'utente non Ŕ possibile chiudere il documento. Nel secondo esempio sink l'evento ItemSend per Outlook 2002, in modo che Ŕ possibile annullare l'operazione di invio nell'applicazione.

Esempio 1: evento Annulla DocumentBeforeClose

  1. Avviare Visual Studio .NET 2003. Avviare un nuovo progetto. Selezionare Visual C# come tipo di progetto. Selezionare Windows Application come il modello. Denominare il progetto MyWordEventTest e quindi fare clic su OK .

    Per impostazione predefinita, verrÓ creato Form1.
  2. Scegliere dal menu progetto , Aggiungi riferimento . Nella casella finestra di dialogo, selezionare Microsoft Word 9.0 Object Library nella scheda COM fare clic su Seleziona per aggiungere un riferimento e quindi fare clic su OK per chiudere la finestra di dialogo.

    Un IA personalizzato viene generato automaticamente per l'utente.
  3. Nel menu progetto , fare clic su Aggiungi una classe . Selezionare File di codice e classe il nome Word9EventHelper.cs . Fare clic su OK per generare il file.
  4. Aggiungere il codice riportato di seguito per la finestra del codice per 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();}
    	}
    }
  5. Tornare a Form1 e aggiungere un pulsante di comando. Fare doppio clic sul pulsante comando per visualizzare la finestra codice per Form1.cs vengono visualizzati. In alternativa, dal menu Visualizza , fare clic su codice per la finestra di codice per Form1.cs verranno visualizzati. Aggiungere il codice riportato di seguito al gestore del pulsante per il documento di 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;
    
  6. Aggiungere il codice riportato di seguito alla classe Form1 prima di gestore del pulsante:
    Word.Application m_oApp;
    WordAppEvents9.WordAppEventHelper m_oAppEvents;
    
  7. Scegliere dal menu Genera , Genera soluzione per rendere il progetto. Fare clic su debug e quindi fare clic su Start per eseguire l'applicazione.

    Avvio dell'applicazione, Ŕ possibile scegliere il pulsante di comando e viene quindi visualizzato Word. Impossibile chiudere la finestra di Word fino alla chiusura dell'applicazione.

    ╚ possibile utilizzare codice simile per gestire gli eventi di Excel.

Esempio 2: Annulla ItemSend evento

  1. Avviare Visual Studio .NET 2003. Avviare un nuovo progetto. Selezionare Visual C# come tipo di progetto. Selezionare Windows Application come il modello. Denominare il progetto MyOutlookEventTest e quindi fare clic su OK .

    Per impostazione predefinita, verrÓ creato Form1.
  2. Scegliere dal menu progetto , Aggiungi riferimento . Nella casella finestra di dialogo, selezionare Microsoft Outlook 10.0 Object Library nella scheda COM fare clic su Seleziona per aggiungere un riferimento e quindi fare clic su OK per chiudere la finestra di dialogo.

    Un IA personalizzato viene generato automaticamente per l'utente.
  3. Nel menu progetto , fare clic su Aggiungi una classe . Selezionare File di codice e classe il nome Outlook10EventHelper.cs . Fare clic su OK per generare il file.
  4. Aggiungere il codice riportato di seguito la finestra del codice per 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. In caso contrario, l'evento non pu˛ essere annullato.
  5. Tornare a Form1 e aggiungere un pulsante di comando. Fare doppio clic sul pulsante comando per visualizzare la finestra codice per Form1.cs vengono visualizzati. In alternativa, dal menu Visualizza , fare clic su codice per la finestra di codice per Form1.cs verranno visualizzati. Aggiungere il codice riportato di seguito al gestore del pulsante per l'articolo 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);
  6. Aggiungere il codice riportato di seguito alla classe Form1 prima di gestore del pulsante:
    Outlook.Application m_oApp;
    OutlookAppEvents10.OutlookAppEventHelper m_oAppEvents;
    
  7. Scegliere dal menu Genera , Genera soluzione per rendere il progetto. Fare clic su debug e quindi fare clic su Start per eseguire l'applicazione.

    Avvio dell'applicazione, Ŕ possibile scegliere il pulsante di comando e viene quindi visualizzato Outlook. Viene creata automaticamente una nuova bozza di posta elettronica. Input di un destinatario nella riga a e quindi fare clic su Invia . VerrÓ visualizzata una finestra di dialogo che chiede se si desidera annullare l'evento ItemSend popup. Fare clic su per annullare.

    ╚ possibile utilizzare codice simile per gestire gli eventi di Excel.

Status

Microsoft ha confermato che questo problema riguarda i prodotti sono elencati nella sezione "Si applica a" di questo articolo.

Riferimenti

Per ulteriori informazioni sull'automazione di Office da Visual Studio. NET, fare clic sul seguente numero per visualizzare l'articolo della Microsoft Knowledge Base riportato di seguito:
311452Sviluppo di Microsoft Office soluzioni con Visual Studio .NET
317109Applicazione di Office non viene chiuso dopo l'automazione da un client di Visual Studio .NET

ProprietÓ

Identificativo articolo: 830519 - Ultima modifica: giovedý 27 febbraio 2014 - Revisione: 3.5
Le informazioni in questo articolo si applicano a:
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Word 2002 Standard Edition
  • Microsoft Outlook 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Outlook 2000 Standard Edition
  • Microsoft .NET Framework 1.1
  • Microsoft Visual Studio .NET 2003 Professional Edition
  • Microsoft Visual Studio .NET 2003 Enterprise Architect
  • Microsoft Visual Studio .NET 2003 Academic Edition
Chiavi:á
kbnosurvey kbarchive kbmt kbnofix kbbug KB830519 KbMtit
Traduzione automatica articoli
Il presente articolo Ŕ stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non Ŕ sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, pi¨ o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non Ŕ la sua. Microsoft non Ŕ responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 830519
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

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