Recebendo entrada do controle de entrada matemática
Esta seção explica como recuperar a marcação MathML do controle de entrada matemática usando a ATL (Biblioteca de Modelos Ativos) e o COM (Component Object Model).
Para recuperar a equação matemática reconhecida do controle de entrada matemática, você pode substituir o comportamento que acontece quando o botão inserir é pressionado. Para fazer isso, você precisará configurar um manipulador de eventos que implemente os vários eventos compatíveis com a interface _IMathInputControlEvents . A configuração do manipulador de eventos envolve a execução das etapas a seguir para os eventos aos quais você deseja dar suporte (insira neste caso).
- Criar uma classe de modelo que contém coletores de eventos
- Configurar os manipuladores de eventos
- Herdar a classe de manipulador de eventos em sua classe main
- Inicializar sua classe para herdar os coletores de eventos
Criar uma classe de modelo que contém coletores de eventos
Ao implementar um coletor de eventos que usa o controle de entrada matemática, você deve primeiro especificar uma ID do coletor. Em seguida, você deve criar uma classe de modelo que herda do evento, do manipulador de controle de eventos e das interfaces de evento de controle de entrada matemática. O código a seguir mostra como definir uma ID de coletor e criar uma classe de modelo, CMathInputControlEventHandler, que herda das interfaces necessárias. Essa classe de modelo também está configurada para ter um ponteiro de interface desconhecido privado que será usado para passar o controle de entrada matemática para ele na inicialização e o membro m_ulAdviseCount para contar o número de chamadas para aconselhar/cancelar a supervisão.
#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;
Observação
O membro m_pMain deverá ser diferente em sua implementação se você não estiver usando uma caixa de diálogo.
Agora que você tem a classe de modelo básica, deve fornecer uma declaração de encaminhamento para os manipuladores de eventos que você substituirá e, em seguida, deve configurar um mapa de coletor para os eventos que você manipulará. O código a seguir mostra como configurar manipuladores de eventos para o método Insert , chamado quando um usuário clica no botão inserir no controle de entrada matemática e o método Close , chamado quando um usuário clica no botão cancelar no controle de entrada matemática.
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()
Como você trabalhará com o controle de entrada matemática, será útil definir uma referência interna para a interface relevante. A função de utilitário a seguir é criada na classe de exemplo para definir essa referência.
HRESULT Initialize(IUnknown *pUnknown, CDialog *pMain)
{
m_pMain = pMain;
m_pUnknown = pUnknown;
m_ulAdviseCount = 0;
return S_OK;
}
Configurar os manipuladores de eventos
Depois de configurar os coletores de eventos, você precisará criar suas implementações dos coletores de eventos. Em ambos os métodos no exemplo de código a seguir, os coletores de eventos recuperam um identificador para a interface de controle de entrada matemática. Na função Insert , o resultado do reconhecimento é exibido como MathML e o controle está oculto. Na função Fechar , o controle de entrada matemática está oculto.
// 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;
}
};
Herdar a classe de manipulador de eventos em sua classe main
Depois de implementar sua classe de modelo, você precisará herdá-la na classe na qual você configurará o controle de entrada matemática. Para os fins deste guia, essa classe é uma caixa de diálogo, CMIC_TEST_EVENTSDlg. No cabeçalho da caixa de diálogo, os cabeçalhos necessários devem ser incluídos e a classe de modelo que você criou deve ser herdada. A classe na qual você está herdando e os manipuladores de eventos devem ter declarações de encaminhamento para que o modelo possa ser implementado. O exemplo de código a seguir mostra como isso é feito.
#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
Observação
O tipo de modelo, CMIC_TEST_EventsDlg, será diferente, a menos que você tenha nomeado sua classe da mesma forma que o exemplo.
Inicializar sua classe para herdar os coletores de eventos
Depois de configurar sua classe para herdar da classe de modelo, você estará pronto para configurá-la para manipular eventos. Isso consistirá em inicializar a classe para ter um identificador para o controle de entrada matemática e a classe de chamada. Além disso, o controle de entrada matemática para manipular eventos de deve ser enviado para o método DispEventAdvise herdado pela classe de exemplo CMathInputControlEventHandler. O código a seguir é chamado do método OnInitDialog na classe de exemplo para executar essas ações.
// 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();
}
}
}
}
}
Observação
O tipo de modelo, CMIC_TEST_EventsDlg neste exemplo, será diferente, a menos que você tenha nomeado sua classe da mesma forma que o exemplo.