BUG: Visual Studio .NET 2003에서 Office 이벤트에 대한 취소 매개 변수가 무시됩니다.

기술 자료 번역 기술 자료 번역
기술 자료: 830519 - 이 문서가 적용되는 제품 보기.
이 문서가 보관되었습니다. "그대로" 제공되었으며, 업데이트가 되지 않을 것입니다.
모두 확대 | 모두 축소

이 페이지에서

요약

Microsoft Visual Studio .NET 2003을 함께 작업할 때 Microsoft Word, Microsoft Excel 또는 Microsoft Outlook 발생한 COM 이벤트 Cancel 매개 변수를 사용할 때 문제가 발생할 수 있습니다. COM 이벤트 코드를 받고 코드를 그에 따라 매개 변수를 설정할 수 있지만 COM 이벤트 취소되지 않습니다. COM Interop를 사용하면 관리되는 클라이언트 (예: Microsoft Visual C# 또는 Microsoft Visual Basic .NET) 및 Microsoft .NET Framework 버전 1.1 또한 사용할 경우 이 문제가 발생합니다.

원인

.NET Framework 1.1 COM 구성 요소와 상호 작용하는 때 형식 안정성을 향상시키기 위해 보안 변경 사항이 도입되었습니다. .NET Framework 1.1 구성 요소의 형식 라이브러리의 마샬링 정보를 사용하여 형식 안전성을 향상시킵니다. 관리되는 클라이언트에서 Word나 Excel, Outlook 자동화할 때 IA (COM Interop 어셈블리) 또는 Microsoft Office XP용 주 Interop 어셈블리 (PIA) 이벤트를 처리하기 위해 Microsoft Office 형식 라이브러리에 저장된 형식 정보를 사용합니다. 기존 버전과 [in] 매개 변수로 라이브러리와 Excel 형식 라이브러리를 Outlook 형식 라이브러리 표시를 Cancel 매개 변수 입력합니다. 공용 언어 런타임에서 이 제한을 적용하고 호출자에게 반환되는 에서 관리되는 코드를 변경한 내용이 방지할 수 있도록 취소 매개 변수가 [in] 매개 변수로 표시되어 있습니다. 따라서, 관리되는 코드 IA (또는 PIA) 이벤트를 취소할 수 없습니다.

해결 방법

Microsoft Office 2003에서 이 버그가 수정되었습니다.

해결 과정

이전 버전의 Word나 Excel 이전 버전의 이전 버전의 Outlook 사용하는 경우, 관리되는 코드에서 직접 연결 지점 싱크를 설정해야 합니다. 사용자 지정 처리기를 형식 라이브러리 종속성 및 일반적으로 적용되는 강제로 형식 보호 피할 수 있습니다. 따라서 인수는 다시 호출자에게 전달할 수 있습니다.

Microsoft는 묵시적인 보증 없이 목적으로만 프로그래밍 예제를 제공합니다. 이 포함되지만, 상품성 또는 특정 목적에의 적합성에 대한 묵시적인된 보증이 제한되지 않습니다. 이 문서에서는 만들려면 및 프로시저를 디버깅하는 데 사용되는 도구 및 여기서 설명하는 프로그래밍 언어에 익숙한 사용자를 대상으로 합니다. Microsoft 지원 엔지니어는 사용자에게 도움이 되도록 특정 절차에 대한 기능을 설명할 수 있지만 추가 기능을 제공하거나 특정 요구 사항에 맞도록 프로시저를 구성하지는 이 예제를 수정하지 않습니다.

도우미 클래스 생성

직접 이벤트를 Visual C# 에서 싱크할 수, 사용자 고유의 dispinterface 정의를 만들고 도우미 클래스 이벤트 코드를 구현하려면 또한 만들어야 합니다. 전역 고유 식별자 (GUID) 및 이벤트 싱크 Office 개체를 예상한 이벤트 싱크 디스패치 식별자 (DISPID) dispinterface 정의와 일치해야 합니다. 어떻게 이러한 값을 파악하는 데 다음 방법 중 하나를 사용하십시오.
  • Visual Studio .NET 2003 Professional Edition 함께 포함된 OLE/COM 개체 뷰어 사용
  • Platform SDK 사용할 수 있습니다. Platform SDK에 [NULL]에 대한 자세한 내용은 다음 Microsoft 웹 사이트를 방문하십시오.

    http://www.microsoft.com/msdownload/platformsdk/sdkupdate
GUID 및 해당 DISPID를 알고 나면 Visual Basic .NET에서 또는 Visual C# dispinterface 정의의 정의를 작성할 수 있습니다.

이 문서에서는 이 문제를 해결하려면 사용자가 사용자 지정 연결을 사용하는 방법을 보여 주는 두 예제를 가리킨 제공합니다. 첫 번째 예제에서는 Word 2000 응용 프로그램 개체의 이벤트를 싱크할 사용자가 문서를 닫을 수 없습니다. 있도록 DocumentBeforeClose 이벤트 취소하는 방법을 보여 줍니다. 두 번째 예제에서는 응용 프로그램에서 보내기 작업을 취소할 수 있도록 Outlook 2002 ItemSend 이벤트 싱크의.

예제 1: 취소 DocumentBeforeClose 이벤트

  1. Visual Studio .NET 2003 시작하십시오. 새 프로젝트를 시작하십시오. 선택 Visual C# 프로젝트 형식. 선택한 Windows 응용 프로그램 서식 파일로. 프로젝트 이름을 MyWordEventTest, 다음 확인 을 클릭합니다.

    기본적으로 Form1이 만들어집니다.
  2. 프로젝트 메뉴에서 추가 참조. 대화 상자에서 선택한 Microsoft Word 9.0 개체 라이브러리에 대한 참조를 추가하려면 선택 [COM] 탭을 클릭한 다음 대화 상자를 닫으려면 확인 을 클릭합니다.

    사용자 지정 IA 자동으로 생성됩니다.
  3. 프로젝트 메뉴에서 클래스 추가 클릭하십시오. 코드 파일 을 선택하고 클래스 이름을 Word9EventHelper.cs. 파일을 생성하려면 확인 을 클릭하십시오.
  4. 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. Form1에 다시 전환한 다음 명령 단추를 추가하십시오. Form1.cs에 대한 코드 창이 표시되는 명령 단추를 두 번 클릭하십시오. 또는 보기 메뉴에서 Form1.cs에 대한 코드 창이 나타나도록 하려면 코드 클릭합니다. 다음 코드를 단추 처리기에 대한 Click 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. 단추 처리기에 전에 Form1 클래스에 다음 코드를 추가하여:
    Word.Application m_oApp;
    WordAppEvents9.WordAppEventHelper m_oAppEvents;
    
  7. 빌드 메뉴에서 눌러 빌드 솔루션 프로젝트를 만듭니다. 디버그 를 클릭한 다음 응용 프로그램을 실행하려면 시작 을 클릭하십시오.

    응용 프로그램이 시작될 때 명령 단추를 클릭한 다음 Word 나타납니다. 응용 프로그램을 닫을 때까지 Word 창을 닫을 수 없습니다.

    유사한 코드를 Excel에 대한 이벤트를 처리할 수 있습니다.

예제 2: 취소 ItemSend 이벤트

  1. Visual Studio .NET 2003 시작하십시오. 새 프로젝트를 시작하십시오. 선택 Visual C# 프로젝트 형식. 선택한 Windows 응용 프로그램 서식 파일로. 프로젝트 이름을 MyOutlookEventTest, 다음 확인 을 클릭합니다.

    기본적으로 Form1이 만들어집니다.
  2. 프로젝트 메뉴에서 추가 참조. 대화 상자에서 Microsoft Outlook 10.0 개체 라이브러리 를 선택한 것에 대한 참조를 추가하려면 선택 [COM] 탭을 클릭한 다음 대화 상자를 닫으려면 확인 을 클릭합니다.

    사용자 지정 IA 자동으로 생성됩니다.
  3. 프로젝트 메뉴에서 클래스 추가 클릭하십시오. 코드 파일 을 선택하고 클래스 이름을 Outlook10EventHelper.cs. 파일을 생성하려면 확인 을 클릭하십시오.
  4. 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. 그렇지 않으면, 이벤트를 취소할 수 없습니다.
  5. Form1에 다시 전환한 다음 명령 단추를 추가하십시오. Form1.cs에 대한 코드 창이 표시되는 명령 단추를 두 번 클릭하십시오. 또는 보기 메뉴에서 Form1.cs에 대한 코드 창이 나타나도록 하려면 코드 클릭합니다. 경우 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. 단추 처리기에 전에 Form1 클래스에 다음 코드를 추가하여:
    Outlook.Application m_oApp;
    OutlookAppEvents10.OutlookAppEventHelper m_oAppEvents;
    
  7. 빌드 메뉴에서 눌러 빌드 솔루션 프로젝트를 만듭니다. 디버그 를 클릭한 다음 응용 프로그램을 실행하려면 시작 을 클릭하십시오.

    응용 프로그램이 시작될 때 명령 단추를 클릭한 다음 Outlook 나타납니다. 새 전자 메일 초안 자동으로 만들어집니다. 받는 사람 줄에 입력 및 보내기 를 클릭하십시오. 대화 ItemSend 이벤트 취소 여부를 묻는 팝업을 메시지가 표시됩니다. 취소하고 .

    유사한 코드를 Excel에 대한 이벤트를 처리할 수 있습니다.

현재 상태

Microsoft 문제는 이 문서의 시작 부분에 나열한 제품에서 문제를 확인했습니다.

참조

Visual Studio에서 Office 자동화하는 방법에 대한 자세한 내용은 .NET, Microsoft 기술 자료의 다음 문서를 참조하십시오.
311452Visual Studio.NET에서 솔루션을 Office 개발
317109Visual Studio .NET 클라이언트에서 자동화 후에 Office 응용 프로그램 끝내기 있지 않습니다.

속성

기술 자료: 830519 - 마지막 검토: 2014년 2월 27일 목요일 - 수정: 3.5
본 문서의 정보는 다음의 제품에 적용됩니다.
  • 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
  • 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
키워드:?
kbnosurvey kbarchive kbmt kbnofix kbbug KB830519 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

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