IDispEventSimpleImpl 사용
이벤트를 처리하는 데 사용할 IDispEventSimpleImpl
경우 다음을 수행해야 합니다.
IDispEventSimpleImpl에서 클래스를 파생시킵니다.
클래스에 이벤트 싱크 맵을 추가합니다.
이벤트를 설명하는 _ATL_FUNC_INFO 구조를 정의합니다.
SINK_ENTRY_INFO 매크로를 사용하여 이벤트 싱크 맵에 항목을 추가합니다.
처리에 관심이 있는 메서드를 구현합니다.
이벤트 원본을 조언하고 프로비전 해제합니다.
예시
아래 예제에서는 Word의 Application 개체에서 DocumentChange
발생한 이벤트를 처리하는 방법을 보여줍니다. 이 이벤트는 dispinterface의 ApplicationEvents
메서드로 정의됩니다.
이 예제는 ATLEventHandling 샘플에서 가져옵니다.
[ uuid(000209F7-0000-0000-C000-000000000046), hidden ]
dispinterface ApplicationEvents {
properties:
methods:
[id(0x00000001), restricted, hidden]
void Startup();
[id(0x00000002)]
void Quit();
[id(0x00000003)]
void DocumentChange();
};
이 예제에서는 Word의 형식 라이브러리에서 필요한 헤더 파일을 생성하는 데 사용합니다 #import
. 다른 버전의 Word에서 이 예제를 사용하려면 올바른 mso dll 파일을 지정해야 합니다. 예를 들어 Office 2000은 mso9.dll을 제공하고 OfficeXP는 mso.dll을 제공합니다. 이 코드는 pch.h(Visual Studio 2017 이하의 stdafx.h)에서 간소화됩니다.
#pragma warning (disable : 4146)
// Paths to required MS OFFICE files (replace "MSO.DLL" and "MSWORD.OLB" with the actual paths to those files...)
#define _MSDLL_PATH "MSO.DLL"
// Delete the *.tlh files when changing import qualifiers
#import _MSDLL_PATH rename("RGB", "MSRGB") rename("DocumentProperties", "WordDocumentProperties") raw_interfaces_only
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" raw_interfaces_only
#define _MSWORDOLB_PATH "MSWORD.OLB"
#import _MSWORDOLB_PATH rename("ExitWindows", "WordExitWindows") rename("FindText", "WordFindText") raw_interfaces_only
#pragma warning (default : 4146)
이 예제에서 실제로 사용되는 형식 라이브러리의 유일한 정보는 Word Application
개체의 CLSID와 인터페이스의 ApplicationEvents
IID입니다. 이 정보는 컴파일 시간에만 사용됩니다.
다음 코드는 Simple.h에 표시됩니다. 관련 코드는 주석으로 기록됩니다.
// Note declaration of structure for type information
extern _ATL_FUNC_INFO OnDocChangeInfo;
extern _ATL_FUNC_INFO OnQuitInfo;
class ATL_NO_VTABLE CSimple :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSimple, &CLSID_Simple>,
public IDispatchImpl<ISwitch, &IID_ISwitch, &LIBID_ATLEVENTHANDLINGLib>,
// Note inheritance from IDispEventSimpleImpl
public IDispEventSimpleImpl</*nID =*/ 1, CSimple, &__uuidof(Word::ApplicationEvents)>
{
public:
CSimple()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLE)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSimple)
COM_INTERFACE_ENTRY(ISwitch)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
CComPtr<Word::_Application> m_pApp;
// Event handlers
// Note the __stdcall calling convention and
// dispinterface-style signature
void __stdcall OnQuit()
{
Stop();
}
void __stdcall OnDocChange()
{
ATLASSERT(m_pApp != NULL);
// Get a pointer to the _Document interface on the active document
CComPtr<Word::_Document> pDoc;
m_pApp->get_ActiveDocument(&pDoc);
// Get the name from the active document
CComBSTR bstrName;
if (pDoc)
pDoc->get_Name(&bstrName);
// Create a display string
CComBSTR bstrDisplay(_T("New document title:\n"));
bstrDisplay += bstrName;
// Display the name to the user
USES_CONVERSION;
MessageBox(NULL, W2CT(bstrDisplay), _T("IDispEventSimpleImpl : Active Document Changed"), MB_OK);
}
// Note the mapping from Word events to our event handler functions.
BEGIN_SINK_MAP(CSimple)
SINK_ENTRY_INFO(/*nID =*/ 1, __uuidof(Word::ApplicationEvents), /*dispid =*/ 3, OnDocChange, &OnDocChangeInfo)
SINK_ENTRY_INFO(/*nID =*/ 1, __uuidof(Word::ApplicationEvents), /*dispid =*/ 2, OnQuit, &OnQuitInfo)
END_SINK_MAP()
// ISwitch
public:
STDMETHOD(Start)()
{
// If we already have an object, just return
if (m_pApp)
return S_OK;
// Create an instance of Word's Application object
HRESULT hr = m_pApp.CoCreateInstance(__uuidof(Word::Application), NULL, CLSCTX_SERVER);
if (FAILED(hr))
return hr;
ATLASSERT(m_pApp != NULL);
// Make the Word user interface visible
m_pApp->put_Visible(true);
// Note call to advise
// Forge a connection to enable us to receive events
DispEventAdvise(m_pApp);
return S_OK;
}
STDMETHOD(Stop)()
{
// Check we have an object to unadvise on
if (!m_pApp)
return S_OK;
// Note call to unadvise
// Break the connection with the event source
DispEventUnadvise(m_pApp);
// Release the Word application
m_pApp.Release();
return S_OK;
}
};
다음 코드는 Simple.cpp의 코드입니다.
// Define type info structure
_ATL_FUNC_INFO OnDocChangeInfo = {CC_STDCALL, VT_EMPTY, 0};
_ATL_FUNC_INFO OnQuitInfo = {CC_STDCALL, VT_EMPTY, 0};
// (don't actually need two structure since they're the same)