수학 입력 컨트롤에서 입력 수신
이 섹션에서는 ATL(활성 템플릿 라이브러리) 및 COM(구성 요소 개체 모델)을 사용하여 수학 입력 컨트롤에서 MathML 태그를 검색하는 방법을 설명합니다.
수학 입력 컨트롤에서 인식된 수학 수식을 검색하려면 삽입 단추를 누를 때 발생하는 동작을 재정의할 수 있습니다. 이렇게 하려면 _IMathInputControlEvents 인터페이스에서 지원하는 다양한 이벤트를 구현하는 이벤트 처리기를 설정해야 합니다. 이벤트 처리기를 설정하려면 지원하려는 이벤트에 대해 다음 단계를 수행해야 합니다(이 경우 삽입).
이벤트 싱크를 포함하는 템플릿 클래스 만들기
수학 입력 컨트롤을 사용하는 이벤트 싱크를 구현하는 경우 먼저 싱크 ID를 지정해야 합니다. 그런 다음, 이벤트, 이벤트 제어 처리기 및 수학 입력 컨트롤 이벤트 인터페이스에서 상속되는 템플릿 클래스를 만들어야 합니다. 다음 코드에서는 싱크 ID를 설정하고 필수 인터페이스에서 상속되는 CMathInputControlEventHandler 템플릿 클래스를 만드는 방법을 보여 줍니다. 또한 이 템플릿 클래스는 초기화 시 수학 입력 컨트롤을 전달하는 데 사용되는 프라이빗 알 수 없는 인터페이스 포인터와 조언할 호출 수를 계산하는 m_ulAdviseCount 멤버를 사용하도록 설정됩니다.
#pragma once
static const int MATHINPUTCONTROL_SINK_ID = 1 ;
template <class T>
class ATL_NO_VTABLE CMathInputControlEventHandler :
public IDispEventSimpleImpl<MATHINPUTCONTROL_SINK_ID, CMathInputControlEventHandler<T>, &__uuidof(_IMathInputControlEvents)>
{
private:
IUnknown *m_pUnknown;
ULONG m_ulAdviseCount;
CDialog *m_pMain;
참고
대화 상자를 사용하지 않는 경우 구현에서 멤버 m_pMain 달라야 합니다.
이제 기본 템플릿 클래스가 있으므로 재정의할 이벤트 처리기에 대해 정방향 선언을 제공하고 처리할 이벤트에 대한 싱크 맵을 설정해야 합니다. 다음 코드에서는 사용자가 수학 입력 컨트롤에서 삽입 단추를 클릭할 때 호출되는 Insert 메서드와 사용자가 수학 입력 컨트롤에서 취소 단추를 클릭할 때 호출되는 Close 메서드에 대한 이벤트 처리기를 설정하는 방법을 보여 줍니다.
public:
static const _ATL_FUNC_INFO OnMICInsertInfo; // = {CC_STDCALL, VT_I4, 1, {VT_BSTR}};
static const _ATL_FUNC_INFO OnMICCloseInfo; // = {CC_STDCALL, VT_I4, 0, {VT_EMPTY}};
BEGIN_SINK_MAP(CMathInputControlEventHandler)
SINK_ENTRY_INFO(MATHINPUTCONTROL_SINK_ID, __uuidof(_IMathInputControlEvents), DISPID_MICInsert, OnMICInsert, const_cast<_ATL_FUNC_INFO*>(&OnMICInsertInfo))
SINK_ENTRY_INFO(MATHINPUTCONTROL_SINK_ID, __uuidof(_IMathInputControlEvents), DISPID_MICClose, OnMICClose, const_cast<_ATL_FUNC_INFO*>(&OnMICCloseInfo))
END_SINK_MAP()
수학 입력 컨트롤을 사용하므로 관련 인터페이스에 대한 내부 참조를 설정하는 것이 유용합니다. 다음 유틸리티 함수는 이 참조를 설정하기 위해 예제 클래스에 만들어집니다.
HRESULT Initialize(IUnknown *pUnknown, CDialog *pMain)
{
m_pMain = pMain;
m_pUnknown = pUnknown;
m_ulAdviseCount = 0;
return S_OK;
}
이벤트 처리기 설정
이벤트 싱크를 설정한 후에는 이벤트 싱크의 구현을 만들어야 합니다. 다음 코드 예제의 두 메서드에서 이벤트 싱크는 수학 입력 컨트롤 인터페이스에 대한 핸들을 검색합니다. Insert 함수에서 인식 결과가 MathML로 표시되고 컨트롤이 숨겨집니다. Close 함수에서 수학 입력 컨트롤은 숨겨집니다.
// Methods
HRESULT __stdcall OnMICInsert( BSTR bstrRecoResult)
{
CComQIPtr<IMathInputControl> spMIC(m_pUnknown);
HRESULT hr=S_OK;
if (spMIC)
{
MessageBox(NULL,bstrRecoResult,L"Recognition Result",MB_OK);
hr = spMIC->Hide();
return hr;
}
return E_FAIL;
}
HRESULT __stdcall OnMICClose()
{
CComPtr<IMathInputControl> spMIC;
HRESULT hr = m_pUnknown->QueryInterface<IMathInputControl>(&spMIC);
if (SUCCEEDED(hr))
{
hr = spMIC->Hide();
return hr;
}
return hr;
}
};
기본 클래스에서 이벤트 처리기 클래스 상속
템플릿 클래스를 구현한 후에는 수학 입력 컨트롤을 설정할 클래스로 상속해야 합니다. 이 가이드의 목적을 위해 이 클래스는 CMIC_TEST_EVENTSDlg 대화 상자입니다. 대화 머리글에서 필수 헤더를 포함해야 하며 만든 템플릿 클래스를 상속받아야 합니다. 템플릿을 구현할 수 있도록 내에서 상속하는 클래스와 이벤트 처리기에는 전달 선언이 있어야 합니다. 다음 코드 예제에서는 이 작업을 수행하는 방법을 보여줍니다.
#pragma once
#include <atlbase.h>
#include <atlwin.h>
// include for MIC
#include "micaut.h"
// include for event sinks
#include <iacom.h>
#include "mathinputcontroleventhandler.h"
class CMIC_TEST_EVENTSDlg;
const _ATL_FUNC_INFO CMathInputControlEventHandler<CMIC_TEST_EVENTSDlg>::OnMICInsertInfo = {CC_STDCALL, VT_I4, 1, {VT_BSTR}};
const _ATL_FUNC_INFO CMathInputControlEventHandler<CMIC_TEST_EVENTSDlg>::OnMICCloseInfo = {CC_STDCALL, VT_I4, 0, {VT_EMPTY}};
// CMIC_TEST_EVENTSDlg dialog
class CMIC_TEST_EVENTSDlg : public CDialog,
public CMathInputControlEventHandler<CMIC_TEST_EVENTSDlg>
{
public:
CComPtr<IMathInputControl> m_spMIC; // Math Input Control
참고
CMIC_TEST_EventsDlg 템플릿 형식은 클래스의 이름을 예제와 동일하게 지정하지 않는 한 다릅니다.
이벤트 싱크를 상속하도록 클래스 초기화
템플릿 클래스에서 상속하도록 클래스를 설정하면 이벤트를 처리하도록 설정할 준비가 된 것입니다. 이는 수학 입력 컨트롤 및 호출 클래스에 대한 핸들을 갖도록 클래스를 초기화하는 것으로 구성됩니다. 또한 에서 이벤트를 처리하는 수학 입력 컨트롤은 CMathInputControlEventHandler 예제 클래스가 상속하는 DispEventAdvise 메서드로 보내야 합니다. 다음 코드는 예제 클래스의 OnInitDialog 메서드에서 호출되어 이러한 작업을 수행합니다.
// includes for implementation
#include "micaut_i.c"
// include for event handler
#include "mathinputcontroleventhandler.h"
...
OnInitDialog{
...
// TODO: Add extra initialization here
CoInitialize(NULL);
HRESULT hr = g_spMIC.CoCreateInstance(CLSID_MathInputControl);
if (SUCCEEDED(hr)){
hr = CMathInputControlEventHandler<CMIC_TEST_EVENTSDlg>::Initialize(m_spMIC, this);
if (SUCCEEDED(hr)){
hr = CMathInputControlEventHandler<CMIC_TEST_EVENTSDlg>::DispEventAdvise(m_spMIC);
if (SUCCEEDED(hr)){
hr = m_spMIC->Show();
}
}
}
}
}
참고
이 예제에서 CMIC_TEST_EventsDlg 템플릿 형식은 클래스 이름을 예제와 동일하게 지정하지 않는 한 다릅니다.