方法: Visual C++ .NET および MFC を使用して Word のイベントを処理します。

文書翻訳 文書翻訳
文書番号: 309294 - 対象製品
すべて展開する | すべて折りたたむ

目次

メモ Microsoft Visual C++ .NET (2002) は、Microsoft .NET Framework によって提供されるマネージ コード モデルとアンマネージ ネイティブ Windows コード モデルの両方をサポートします。 この資料の情報は、アンマネージ Visual C++ コードのみに適用されます。

概要

このステップ バイ ステップ方法について説明 Microsoft Foundation クラス (MFC) を使用して Visual C++ .NET で作成されたオートメーション クライアントからの Word でイベントを処理します。 説明従来の COM イベントをシンクします。

Word イベントを処理するための C++ オートメーション クライアントを作成します。

  1. 以下の「サポート技術情報」 (Microsoft Knowledge Base) の「オートメーション クライアントの作成」に記載されている手順に従って、基本的なオートメーション クライアントを作成します:
    307473Q307473 HOWTO: Use a Type Library for Office Automation from Visual C++ .NET
    手順 1、 WordEvents1 プロジェクトの名前を入力します。

    手順 3 には最初のボタンの ID を ID_STARTSINK してキャプション イベント シンクの開始 を変更します。 第 2 ボタンを追加して、2 番目のボタンの ID ID_STOPSINK して イベント シンクを停止 するには、キャプション変更します。

    手順 4 で、Word タイプ ライブラリを使用し、次の Word のインターフェイスを選択します。
    • _Application
    • _Document
    • ドキュメント
    • 選択範囲
    • ウィンドウ
  2. [ プロジェクト ] メニューの [ クラスの追加 ] をクリックします。 テンプレートの一覧で、 汎用 C++ クラスを選択し、[ ファイルを開く しています。
  3. 一般 C++ クラス ウィザード ] ダイアログ CAppEventListener クラス名を入力、基本クラスの IDispatch を入力し、 [終了日]
  4. Appeventslistener.h のコードの全体を次に置き換えます:
    #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.
    };
    						
    : IID_IApplicationEvents2 変数の値は、Word オブジェクト ライブラリから派生します。 詳細については、参照、アプリケーション イベントの Word してください。
  5. Appeventlistener.cpp のコードの全体を次のコードに置き換えます:
    #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. ダブルクリック、ダイアログ ボックス [ ID_STARTSINK コントロールし、次のコードを追加 CWordEvents1Dlg::OnBnClickedStartsink :
    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. ダブルクリック、ダイアログ ボックス [ ID_STOPSINK コントロールし、次のコードを追加 CWordEvents1Dlg::OnBnClickedStopsink :
    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. CWordEvents1Dlg::OnInitDialog Wordevents1dlg.cpp 中に次のコードを追加:
        m_pAppEventListener = NULL;
        m_pConnectionPoint = NULL;
        m_dwConnectionCookie = 0;
    					
  9. 次のインクルード Wordevents1dlg.h を追加:
    #include "AppEventListener.h"
    					
  10. CWordEvents1Dlg の//Implementation セクションでプロテクト変数の一覧に、次を Wordevents1dlg.h ファイルで追加:
       CApplication m_wordApplication;
       CAppEventListener* m_pAppEventListener;
       IConnectionPoint* m_pConnectionPoint;
       DWORD m_dwConnectionCookie;
    					

アプリケーションをテストします

  1. F5 キーを押してプログラムをビルドし、実行します。
  2. イベント シンクの開始 、フォームをクリック Word を起動し、新しい Word 文書を作成、イベント ハンドラーを設定します。
  3. イベント ハンドラーをテストします。 これを行うには、次の手順を実行します。
    1. ドキュメントの任意の場所をダブルクリックします。
    2. 右クリック任意の場所のドキュメントします。
    3. 文書を保存します。
    4. 文書を閉じます。
    5. Visual Studio では、[ 表示 ] メニューの 他のウィンドウ の [し、[出力] ウィンドウを表示する 出力 します。 出力ウィンドウに、イベントが処理された順序と同様に処理されたイベントのトレースは表示されます:
      DocumentChange
      WindowActivate
      WindowBeforeDoubleClick
      WindowSelectionChange
      WindowSelectionChange
      WindowBeforeRightClick
      DocumentBeforeSave
      DocumentBeforeClose
      WindowDeactivate
      DocumentChange
      						
  4. Word のイベントの処理を停止する イベント シンクの停止 </a0> をクリックします。
  5. お使いのプログラムを終了し、[Word を終了します。

Word のアプリケーション イベント

ユニバーサル固有識別子 (UUID) を確認する Word のイベントのセットに対してには、次の手順に従います。
  1. [ ツール ] メニューの Visual Studio .NET で [ OLE/COM オブジェクト ビューアー ] をクリックします。
  2. タイプ ライブラリ を展開します。
  3. Microsoft Word your version オブジェクト ライブラリ をダブルクリックして、タイプ ライブラリ] ボックスの一覧。
  4. ITypeLib Viewer は、Word オブジェクト ライブラリの表示とが開いたら、ノードを展開します アプリケーションをコクラス の。 [ アプリケーションのコクラス ] ノード、 ApplicationEvents ApplicationEvents2 表示されます。 Word 2002 オブジェクト ライブラリを表示して場合 ApplicationEvents3 も表示されます。
  5. [ ApplicationEvents2 を] をダブルクリックします。
  6. ITypeLib ビューアーの右のペインで、次の UUID を探します:
    uuid(000209FE-0000-0000-C000-000000000046)
    Appeventlistener.h で宣言した IID_ApplicationEvents2 変数をこの UUID が対応します。

関連情報

Word の自動化については、クリックして、次資料、記事の「サポート技術情報」(Microsoft Knowledge Base) を表示。
301659方法: Visual C# .NET から差し込み印刷を実行するにを自動化します。
285333情報: Word 2002 の差し込み印刷イベントのコードのデモンストレーション
詳細については、以下のマイクロソフト Developer Network (MSDN) Web サイトを参照してください:
Visual Studio で Microsoft Office 開発
http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx
(c) マイクロソフト コーポレーション 2001、予約済みのすべての権限。 "山口良二"子、マイクロソフト株式会社を投稿します。

プロパティ

文書番号: 309294 - 最終更新日: 2007年6月29日 - リビジョン: 8.3
この資料は以下の製品について記述したものです。
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft Visual C++ .NET 2002 Standard Edition
  • Microsoft Office Word 2003
  • Microsoft Word 2002
  • Microsoft Word 2000
キーワード:?
kbhowtomaster kbautomation kbmt KB309294 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:309294
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

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