NASıL YAPıLıR: Visual C++ .NET ve MFC kullanarak Word olayları tanıtıcı.

Makale numarası: 309294 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Bu Sayfada

Not Microsoft Visual C++ .NET (2002), Microsoft .NET Framework tarafından sağlanan bir yönetilen kod model hem de yerel Microsoft Windows kod modeli yönetilmeyen destekler. Bu makaledeki bilgiler yalnızca yönetilmeyen Visual C++ kod uygulanır.

Özet

Bu adım adım makalede, Visual C++ .NET ile Microsoft Foundation Classes (MFC) kullanarak oluşturulan bir Otomasyon istemciden Word'deki olayları işlemek açıklamaktadır. Makaleyi geleneksel COM gösterir sinking olay.

Microsoft Word, olayları işlemek için bir C++ Otomasyon istemcisinin oluşturma

  1. Temel bir otomasyon istemci oluşturmak için aşağıdaki Microsoft Bilgi Bankası makalesinde "Bir otomasyon istemci oluşturma" bölümündeki adımları izleyin:
    307473Nasıl YAPıLıR: Visual C++ .NET'den Office Otomasyonu için bir tür kitaplığı kullanın.
    1. Adımda WordEvents1 projenin adını yazın.

    3. Adımda, ilk düğmeyi KIMLIĞINI ID_STARTSINKBaşlat'ı olay havuzu için başlık olarak değiştirin. Ikinci bir düğme eklemek ve ikinci düğmeyi KIMLIĞINI ID_STOPSINK ve resim yazısı Durdur, olay havuzu değiştirin.

    4. Adımda, Word Tür Kitaplığı'nı kullanın ve aşağıdaki Word arabirimleri seçin:
    • _Application
    • _Document
    • Belgeleri
    • Seçimi
    • Pencere
  2. Proje) menüsünde Add Class ' ı tıklatın. Genel C++ sınıfı, şablonlar listesinden seçin ve ' ı tıklatın.
  3. Genel C++ sınıf Sihirbazı iletişim kutusunda, CAppEventListener, sınıfın adını yazın... ıdispatch için bir temel sınıf yazın ve sonra da <a2>son</a2>'u tıklatın.
  4. Tüm Appeventslistener.h kodu aşağıdaki ile Değiştir:
    #pragma once
    #include "oaidl.h"
    #include "CApplication.h"
    #include "CDocument0.h"
    #include "CDocuments.h"
    #include "CSelection.h"
    #include "CWindow0.h"
    
    const IID IID_IApplicationEvents2 = 
    {0x000209fe,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
    // Parsed UUID for WordApplicationEvents2 dispinterface.
    class CAppEventListener : public IDispatch
    {
    private:
       int m_refCount;
    
    public:
       //Constructor.
       CAppEventListener();
       //Destructor
       ~CAppEventListener();
    
       /***** IUnknown Methods *****/ 
       STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObj);
       STDMETHODIMP_(ULONG) AddRef();
       STDMETHODIMP_(ULONG) Release();
    
       /***** IDispatch Methods *****/ 
       STDMETHODIMP GetTypeInfoCount(UINT *iTInfo);
       STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, 
          ITypeInfo **ppTInfo);
       STDMETHODIMP GetIDsOfNames(REFIID riid,  
          OLECHAR **rgszNames, 
          UINT cNames,  LCID lcid,
          DISPID *rgDispId);
       STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
          WORD wFlags, DISPPARAMS* pDispParams,
          VARIANT* pVarResult, EXCEPINFO* pExcepInfo,
          UINT* puArgErr);
    
       // The following three examples are patterns for the
       //  declaration, definition, and implementation of
       //  event handler methods.
       STDMETHODIMP WindowSelectionChange(CSelection* Sel);
       STDMETHODIMP WindowBeforeRightClick(CSelection* Sel,
          VARIANT_BOOL* Cancel);
       STDMETHODIMP WindowDeactivate(IUnknown* Doc, 
          CWindow0* Wn);
       // End of examples.
    };
    						
    Not: IID_IApplicationEvents2 değişken değeri, Word Nesne Kitaplığı ' türetilmiştir. Daha fazla bilgi için "Word uygulama olaylar" bölümüne bakın.
  5. Tüm Appeventlistener.cpp kodu aşağıdaki kodla değiştirin:
    #include "stdafx.h"
    #include "AppEventListener.h"
    
    //Constructor.
    CAppEventListener::CAppEventListener()
    {
       m_refCount = 0;
    }
    
    //Destructor.
    CAppEventListener::~CAppEventListener()
    {}
    
    /******************************************************************************
    *   IUnknown Interfaces -- All COM objects must implement, either 
    *  directly or indirectly, the IUnknown interface.
    ******************************************************************************/ 
    
    /******************************************************************************
    *  QueryInterface -- Determines if this component supports the 
    *  requested interface, places a pointer to that interface in ppvObj if it is 
    *  available, and returns S_OK. If not, sets ppvObj to NULL and returns 
    *  E_NOINTERFACE.
    ******************************************************************************/ 
    STDMETHODIMP CAppEventListener::QueryInterface(REFIID riid, void ** ppvObj)
    {
       if (riid == IID_IUnknown){
          *ppvObj = static_cast<IUnknown*>(this);
       }
    
       else if (riid == IID_IDispatch){
          *ppvObj = static_cast<IDispatch*>(this);
       }
    
       else if (riid == IID_IApplicationEvents2){
          *ppvObj = static_cast<IDispatch*>(this);
       }
    
       else{
          *ppvObj = NULL;
          return E_NOINTERFACE;
       }
    
       static_cast<IUnknown*>(*ppvObj)->AddRef();
       return S_OK;
    }
    
    /******************************************************************************
    *  AddRef() -- In order to allow an object to delete itself when 
    *  it is no longer needed, it is necessary to maintain a count of all 
    *  references to this object.  When a new reference is created, this function 
    *  increments the count.
    ******************************************************************************/ 
    STDMETHODIMP_(ULONG) CAppEventListener::AddRef()
    {
       return ++m_refCount;
    }
    
    /******************************************************************************
    *  Release() -- When a reference to this object is removed, this 
    *  function decrements the reference count.  If the reference count is 0, 
    *  this function deletes this object and returns 0.
    ******************************************************************************/ 
    STDMETHODIMP_(ULONG) CAppEventListener::Release()
    {
       m_refCount--;
    
       if (m_refCount == 0)
       {
          delete this;
          return 0;
       }
       return m_refCount;
    }
    
    /******************************************************************************
    *   IDispatch Interface -- This interface allows this class to be used as an
    *   Automation server, allowing its functions to be called by other COM
    *   objects.
    ******************************************************************************/ 
    
    /******************************************************************************
    *   GetTypeInfoCount -- This function determines if the class supports type 
    *   information interfaces or not. It places 1 in iTInfo if the class supports
    *   type information and 0 if it does not.
    ******************************************************************************/ 
    STDMETHODIMP CAppEventListener::GetTypeInfoCount(UINT *iTInfo)
    {
       *iTInfo = 0;
       return S_OK;
    }
    
    /******************************************************************************
    *   GetTypeInfo -- Returns the type information for the class. For classes 
    *   that do not support type information, this function returns E_NOTIMPL;
    ******************************************************************************/ 
    STDMETHODIMP CAppEventListener::GetTypeInfo(UINT iTInfo, LCID lcid, 
                                                ITypeInfo **ppTInfo)
    {
       return E_NOTIMPL;
    }
    
    /******************************************************************************
    *   GetIDsOfNames -- Takes an array of strings and returns an array of DISPIDs
    *   that correspond to the methods or properties indicated. If the name is not 
    *   recognized, it returns DISP_E_UNKNOWNNAME.
    ******************************************************************************/ 
    STDMETHODIMP CAppEventListener::GetIDsOfNames(REFIID riid,  
                                                  OLECHAR **rgszNames, 
                                                  UINT cNames,  LCID lcid,
                                                  DISPID *rgDispId)
    {
       return E_NOTIMPL;
    }
    
    /******************************************************************************
    *   Invoke -- Takes a dispid and uses it to call another of the methods of this 
    *   class. Returns S_OK if the call was successful.
    ******************************************************************************/ 
    STDMETHODIMP CAppEventListener::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
                                           WORD wFlags, DISPPARAMS* pDispParams,
                                           VARIANT* pVarResult,
                                           EXCEPINFO* pExcepInfo,
                                           UINT* puArgErr)
    {
       //Validate arguments.
       if ((riid != IID_NULL))
          return E_INVALIDARG;
    
       HRESULT hr = S_OK;  // Initialize.
    
       switch(dispIdMember){
          case 0x00000001:  //Startup(); Word is started before this is fired.
             OutputDebugString("Startup\n");
             break;
          case 0x00000002:  //Quit();
             OutputDebugString( "Quit\n");
             break;
          case 0x00000003:  //DocumentChange();
             OutputDebugString( "DocumentChange\n");
             break;
          case 0x00000004:  //DocumentOpen([in] Document* Doc);
             OutputDebugString( "DocumentOpen\n");
             break;
          case 0x00000005:  // No dispID
             OutputDebugString( "No dispID yields 00005. This is wierd!\n");
             break;
          case 0x00000006:  // DocumentBeforeClose([in] Document* Doc, [in] VARIANT_BOOL* Cancel);
             OutputDebugString( "DocumentBeforeClose\n");
             break;
          case 0x00000007:  // DocumentBeforePrint([in] Document* Doc, [in] VARIANT_BOOL* Cancel);
             OutputDebugString( "DocumentBeforePrint\n");
             break;
          case 0x00000008:  // DocumentBeforeSave([in] Document* Doc, [in] VARIANT_BOOL* SaveAsUI, [in] VARIANT_BOOL* Cancel);
             OutputDebugString( "DocumentBeforeSave\n");
             break;
          case 0x00000009:  // NewDocument([in] Document* Doc);
             OutputDebugString( "New Document\n");
             break;
          case 0x0000000a:  // WindowActivate([in] Document* Doc, [in] Window* Wn);
             OutputDebugString( "WindowActivate\n");
             break;
    
             // Next 3 illustrate passing parameters to real event handler functions.
    
          case 0x0000000b:  // WindowDeactivate([in] Document* Doc, [in] Window* Wn);
             // The client(in this case, Word) sends arguments to INVOKE
             // in a parameter array, stacked in reverse order, but you
             // need to send them to the called function in not-reverse order.
             if(pDispParams->cArgs!=2)
                return E_INVALIDARG;
             else
             {
                if(pDispParams->rgvarg[0].vt & VT_BYREF)
                {
                   if(pDispParams->rgvarg[0].vt & VT_BYREF)
                   {
                      WindowDeactivate(*(pDispParams->rgvarg[1].ppunkVal),
                         ((CWindow0*)*(pDispParams->rgvarg[0].ppunkVal)));
                   }
                   else
                   {
                      WindowDeactivate(*(pDispParams->rgvarg[1].ppunkVal),
                         ((CWindow0*)(pDispParams->rgvarg[0].punkVal)));
                   }
                }
                else
                {
                   if(pDispParams->rgvarg[0].vt & VT_BYREF)
                   {
                      WindowDeactivate((pDispParams->rgvarg[1].punkVal),
                         ((CWindow0*)*(pDispParams->rgvarg[0].ppunkVal)));
                   }
                   else
                   {
                      WindowDeactivate((pDispParams->rgvarg[1].punkVal),
                         ((CWindow0*)(pDispParams->rgvarg[0].punkVal)));
                   }
    
                }
             }
             break;
          case 0x0000000c:  // WindowSelectionChange([in] Selection* Sel);
             if (pDispParams->cArgs != 1)
                return E_INVALIDARG;
             else{
                if (pDispParams->rgvarg[0].vt & VT_BYREF)
                   WindowSelectionChange( ((CSelection*)*(pDispParams->rgvarg[0].ppunkVal)) );
                else
                   WindowSelectionChange((CSelection*) pDispParams->rgvarg[0].punkVal );
             }
             break;
          case 0x0000000d:  // WindowBeforeRightClick([in] Selection*  Sel, [in] VARIANT_BOOL* Cancel);
             if(pDispParams->cArgs !=2)
                return E_INVALIDARG;
             else
             {
                if(pDispParams->rgvarg[1].vt & VT_BYREF) // The pointer to bool is always by reference.
                {
                   WindowBeforeRightClick( // call the function
                      ((CSelection*)*(pDispParams->rgvarg[1].ppunkVal)),
                      pDispParams->rgvarg[0].pboolVal);
                }
                else
                {
                   WindowBeforeRightClick(  // Call the function.
                      ((CSelection*)(pDispParams->rgvarg[1].punkVal)),
                      pDispParams->rgvarg[0].pboolVal);
                }
             }
             break;
          case 0x0000000e:  // WindowBeforeDoubleClick([in] Selection*  Sel, [in] VARIANT_BOOL* Cancel);
             OutputDebugString( "WindowBeforeDoubleClick\n");
             break;
          default:
             OutputDebugString( "An event with a dispID above 000e\n");
             break;
       }
       return hr;
    }
    
    /************************************************************************************
    *       Sample event handler functions, called from the above switch.
    *       Fill each with the code needed to handle the event according to
    *       the needs and design of your application.
    ************************************************************************************/ 
    STDMETHODIMP CAppEventListener::WindowSelectionChange(CSelection* Sel)
    {
       OutputDebugString("WindowSelectionChange\n");
       return S_OK;
    }
    STDMETHODIMP CAppEventListener::WindowBeforeRightClick(CSelection* Sel, VARIANT_BOOL* Cancel)
    {
       OutputDebugString("WindowBeforeRightClick\n");
       return S_OK;
    }
    STDMETHODIMP CAppEventListener::WindowDeactivate(IUnknown* Doc, CWindow0* Wn)
    {
       OutputDebugString("WindowDeactivate\n");
       return S_OK;
    }
    					
  6. Iletişim kutunuz ID_STARTSINK denetimi çift tıklatın ve CWordEvents1Dlg::OnBnClickedStartsink için aşağıdaki kodu ekleyin:
    void CWordEvents1Dlg::OnBnClickedStartsink()
    {
       // Common OLE-variants. These are easy variants to use for calling arguments.
       COleVariant
          covTrue((short)TRUE),
          covFalse((short)FALSE),
          covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
       COleException e;
    
       CDocuments oDocs;  // oDocs is the Documents Collection.
       CDocument0 oDoc;  // oDoc is the Document object.
       CString str;
       HRESULT hr = S_OK;
    
       try
       {
          // Start Word and get an Application object.
          if(!m_wordApplication.CreateDispatch("Word.Application", &e))
          {
             str.Format("Problem instantiating Word. Error is %ld <0x%08lx>", e.m_sc, e.m_sc);
             AfxMessageBox(str,MB_SETFOREGROUND);
             return;
          }
          else // Success.
          {
             //Make the application visible. 
             m_wordApplication.put_Visible(TRUE);
          }
    
          oDocs = m_wordApplication.get_Documents();
          oDoc = oDocs.Add(covOptional,covOptional,covOptional,covTrue);
    
          //Do not try to hook up more than once.
          if (m_pAppEventListener != NULL)
             return;
    
          // Get IConnectionPointContainer interface for the server.
          IConnectionPointContainer *pConnPtContainer= NULL;
          hr = m_wordApplication.m_lpDispatch->QueryInterface(
             IID_IConnectionPointContainer,
             (void **)&pConnPtContainer );
          if (SUCCEEDED(hr)){
    
             // Find the connection point for events that you are interested in.
             hr = pConnPtContainer->FindConnectionPoint(
                IID_IApplicationEvents2,
                &m_pConnectionPoint
                );
             if (SUCCEEDED(hr)){
    
                //Create a new CAppEventListener.
                m_pAppEventListener = new CAppEventListener();
                m_pAppEventListener->AddRef();
    
                // Set up advisory connection.
                hr = m_pConnectionPoint->Advise(m_pAppEventListener, 
                   &m_dwConnectionCookie);
    
                // Release the IConnectionPointContainer interface.
                pConnPtContainer->Release(); 
             }
          }
       }
       catch(COleException* e)
       {
          str.Format("Error in Try..Catch was 0x%08lx", e->m_sc);
          AfxMessageBox(str, MB_SETFOREGROUND);
          return;
       }
    }
    					
  7. Iletişim kutunuz ID_STOPSINK denetimi çift tıklatın ve CWordEvents1Dlg::OnBnClickedStopsink için aşağıdaki kodu ekleyin:
    void CWordEvents1Dlg::OnBnClickedStopsink()
    {
       //If the connection point has been advised, unadvise it and clean up.
       if (m_pConnectionPoint != NULL){
          m_pConnectionPoint->Unadvise( m_dwConnectionCookie );
          m_dwConnectionCookie = 0;
          m_pConnectionPoint->Release();
          m_pConnectionPoint = NULL;
       }
    
       if (m_pAppEventListener != NULL){
          m_pAppEventListener->Release();
          m_pAppEventListener = NULL;
       }
    
       m_wordApplication.ReleaseDispatch();
    }
    					
  8. Aşağıdaki kod CWordEvents1Dlg::OnInitDialog Wordevents1dlg.cpp içinde ekleme:
        m_pAppEventListener = NULL;
        m_pConnectionPoint = NULL;
        m_dwConnectionCookie = 0;
    					
  9. Aşağıdakiler için Wordevents1dlg.h dahil ekleyin:
    #include "AppEventListener.h"
    					
  10. Wordevents1dlg.h dosyasında aşağıdaki CWordEvents1Dlg //Implementation bölümünde korumalı bir değişken eklemek:
       CApplication m_wordApplication;
       CAppEventListener* m_pAppEventListener;
       IConnectionPoint* m_pConnectionPoint;
       DWORD m_dwConnectionCookie;
    					

Uygulama sınayın.

  1. Oluşturmak ve bu programı çalıştırmak için F5 tuşuna basın.
  2. Word'Ü başlatın, yeni bir Word belgesi oluştur ve olay işleyicileri ayarlamak için formda Olay havuzu olan Başlat'ı tıklatın.
  3. Olay işleyicilerini sınayın. Bunu yapmak için şu adımları izleyin:
    1. Herhangi bir belgede çift tıklatın.
    2. Herhangi bir belge içinde sağ tıklatın.
    3. Belgeyi kaydedin.
    4. Belgeyi kapatın.
    5. Visual Studio'da, Görünüm menüsünde Diğer Windows seçin ve çıktı penceresini görüntülemek için Çıkış ' ı seçin. Izleme sırası yan? s?ra, olayları ele işlenmiş olayların Output penceresi görüntüler:
      DocumentChange
      WindowActivate
      WindowBeforeDoubleClick
      WindowSelectionChange
      WindowSelectionChange
      WindowBeforeRightClick
      DocumentBeforeSave
      DocumentBeforeClose
      WindowDeactivate
      DocumentChange
      						
  4. Word olayları işlemeyi durdurmak için Durdur, olay havuzu seçeneğini tıklatın.
  5. Programınızı kapatın ve sonra da Word'nden çıkın.

Uygulama olaylar? word

Bir dizi Word olayları için evrensel benzersiz tanımlayıcı (UUID) doğrulamak için şu adımları izleyin:
  1. Visual Studio. NET'te Araçlar menüsünden OLE/COM nesnesi Görüntüleyicisi ' ni tıklatın.
  2. Tür kitaplıkları</a0> düğümünü genişletin.
  3. Microsoft Word your version nesne kitaplığı, tür kitaplıkları listede çift tıklatın.
  4. Word nesne kitaplığına görüntülenen ıtypelib görüntüleyiciyi oturum açtığında, Uygulama coClass düğümünü genişletin. Uygulama coClass düğümünde ApplicationEvents ve ApplicationEvents2 bakın. Word 2002 nesne kitaplığına görüntülüyorsanız, ApplicationEvents3 bakın.
  5. ApplicationEvents2</a1> çift tıklatın.
  6. ıtypelib görüntüleyicinin sağ bölmede, aşağıdaki UUID bulun:
    uuid(000209FE-0000-0000-C000-000000000046)
    bu UUID Appeventlistener.h içinde bildirilen değişkenin IID_ApplicationEvents2 karşılık gelir.

Referanslar

Word otomatikleştirme hakkında daha fazla bilgi için Microsoft Knowledge Base'deki makaleleri görüntülemek üzere aşağıdaki makale numaralarını tıklatın:
301659Nasıl YAPıLıR: Microsoft Word, Visual C# .NET adres mektup birleştirme gerçekleştirmek otomatikleştirme
285333BILGI: Word 2002 adres mektup birleştirme olay kodu tanıtım
Daha fazla bilgi için aşağıdaki Microsoft Developer Network (MSDN) Web sitesine bakın:
Visual Studio ile Microsoft Office geliştirme
http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx
(c) Microsoft Corporation 2001, tüm hakları saklıdır. Katkıyı Jensen Chris, Microsoft Corporation.

Özellikler

Makale numarası: 309294 - Son Gözden Geçirme: 29 Haziran 2007 Cuma - Gözden geçirme: 8.3
Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft Visual C++ .NET 2002 Standard Edition
  • Microsoft Office Word 2003
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
Anahtar Kelimeler: 
kbmt kbautomation kbhowtomaster KB309294 KbMttr
Otomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:309294

Geri Bildirim Ver