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.
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
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:
Nası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
Proje) menüsünde Add Class ' ı tıklatın. Genel C++ sınıfı, şablonlar listesinden seçin ve Aç ' ı tıklatın.
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.
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.
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;
}
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;
}
}
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();
}
Aşağıdaki kod CWordEvents1Dlg::OnInitDialog Wordevents1dlg.cpp içinde ekleme:
Oluşturmak ve bu programı çalıştırmak için F5 tuşuna basın.
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.
Olay işleyicilerini sınayın. Bunu yapmak için şu adımları izleyin:
Herhangi bir belgede çift tıklatın.
Herhangi bir belge içinde sağ tıklatın.
Belgeyi kaydedin.
Belgeyi kapatın.
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:
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:
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.
Teşekkürler! Görüşleriniz, destek içeriğimizi geliştirmemize yardımcı olmak için kullanılmaktadır. Diğer yardım seçenekleri için, lütfen Yardım ve Destek Giriş Sayfasını ziyaret edin.