Получение входных данных из элемента управления математическими входами
В этом разделе объясняется, как получить разметку MathML из элемента управления математическими входными данными с помощью библиотеки активных шаблонов (ATL) и компонентной объектной модели (COM).
Чтобы получить распознанное математическое уравнение из элемента управления математическими входными данными, можно переопределить поведение, которое происходит при нажатии кнопки вставки. Для этого необходимо настроить обработчик событий, который реализует различные события, поддерживаемые интерфейсом _IMathInputControlEvents . Настройка обработчика событий включает выполнение следующих действий для событий, которые вы хотите поддерживать (в этом случае вставка).
- Создание класса шаблона, содержащего приемники событий
- Настройка обработчиков событий
- Наследование класса обработчика событий в классе main
- Инициализация класса для наследования приемников событий
Создание класса шаблона, содержащего приемники событий
При реализации приемника событий, использующего элемент управления математическими входами, необходимо сначала указать идентификатор приемника. Затем необходимо создать класс шаблона, который наследует от интерфейсов событий события, обработчика элемента управления событиями и математического ввода. В следующем коде показано, как задать идентификатор приемника и создать такой класс шаблона 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;
}
};
Наследование класса обработчика событий в классе main
После реализации класса шаблона необходимо наследовать его в класс, в который будет настраиваться элемент управления математическим вводом. Для целей этого руководства этот класс является диалоговым окном, 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, будет отличаться, если вы не назвали класс таким же, как в примере.
Инициализация класса для наследования приемников событий
Настроив класс для наследования от класса шаблона, вы можете настроить его для обработки событий. Это будет состоять из инициализации класса , чтобы иметь дескриптор для элемента управления математическими входами и вызывающего класса. Кроме того, элемент управления математическими входными данными для обработки событий из должен отправляться в метод DispEventAdvise, наследуемый примером класса CMathInputControlEventHandler. Следующий код вызывается из метода 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 в этом примере, будет отличаться, если вы не назвали класс таким же, как в примере.