Ricezione dell'input dal controllo Input matematico
Questa sezione illustra come recuperare il markup MathML dal controllo di input matematico usando Active Template Library (ATL) e il modello a oggetti componente (COM).
Per recuperare l'equazione matematica riconosciuta dal controllo di input matematico, è possibile eseguire l'override del comportamento che si verifica quando viene premuto il pulsante di inserimento. A tale scopo, sarà necessario configurare un gestore eventi che implementa i vari eventi supportati dall'interfaccia _IMathInputControlEvents . La configurazione del gestore eventi comporta l'esecuzione della procedura seguente per gli eventi che si desidera supportare (inserire in questo caso).
- Creare una classe modello che contiene sink di eventi
- Configurare i gestori eventi
- Ereditare la classe del gestore eventi nella classe principale
- Inizializzare la classe per ereditare i sink di eventi
Creare una classe modello che contiene sink di eventi
Quando si implementa un sink di eventi che usa il controllo di input matematico, è prima necessario specificare un ID sink. È quindi necessario creare una classe modello che eredita dall'evento, dal gestore del controllo eventi e dalle interfacce eventi di controllo dell'input matematico. Il codice seguente illustra come impostare un ID sink e creare tale classe modello, CMathInputControlEventHandler, che eredita dalle interfacce necessarie. Questa classe modello è configurata anche per avere un puntatore dell'interfaccia sconosciuto privato che verrà usato per passare il controllo di input matematico a esso sull'inizializzazione e il membro m_ulAdviseCount per contare il numero di chiamate da consigliare/non consigliate.
#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;
Nota
Il membro m_pMain deve essere diverso nell'implementazione se non si usa una finestra di dialogo.
Dopo aver creato la classe modello di base, è necessario fornire una dichiarazione di inoltro per i gestori eventi che verranno sottoposti a override e quindi configurare una mappa sink per gli eventi che verranno gestiti. Il codice seguente illustra come configurare gestori eventi per il metodo Insert , chiamato quando un utente fa clic sul pulsante insert sul controllo di input matematico e il metodo Close , chiamato quando un utente fa clic sul pulsante Annulla sul controllo di input matematico.
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()
Poiché si lavora con il controllo di input matematico, sarà utile impostare un riferimento interno all'interfaccia pertinente. La funzione di utilità seguente viene creata nella classe di esempio per impostare questo riferimento.
HRESULT Initialize(IUnknown *pUnknown, CDialog *pMain)
{
m_pMain = pMain;
m_pUnknown = pUnknown;
m_ulAdviseCount = 0;
return S_OK;
}
Configurare i gestori eventi
Dopo aver configurato i sink eventi, sarà necessario creare le implementazioni dei sink eventi. In entrambi i metodi nell'esempio di codice seguente, i sink eventi recuperano un handle all'interfaccia del controllo di input matematico. Nella funzione Inserisci viene visualizzato il risultato del riconoscimento come MathML e il controllo è nascosto. Nella funzione Close il controllo di input matematico è nascosto.
// 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;
}
};
Ereditare la classe del gestore eventi nella classe principale
Dopo aver implementato la classe modello, sarà necessario ereditarla nella classe in cui verrà configurato il controllo di input matematico. Ai fini di questa guida, questa classe è una finestra di dialogo, CMIC_TEST_EVENTSDlg. Nell'intestazione della finestra di dialogo è necessario includere le intestazioni necessarie e la classe modello creata deve essere ereditata. La classe ereditata all'interno e i gestori eventi devono avere dichiarazioni di inoltro in modo che il modello possa essere implementato. Nell'esempio di codice seguente viene illustrato come eseguire questa operazione.
#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
Nota
Il tipo di modello, CMIC_TEST_EventsDlg, sarà diverso a meno che non sia stata denominata la classe uguale all'esempio.
Inizializzare la classe per ereditare i sink di eventi
Dopo aver configurato la classe per ereditare dalla classe modello, è possibile configurarla per gestire gli eventi. Ciò consiste nell'inizializzare la classe per avere un handle per il controllo di input matematico e la classe chiamante. Inoltre, il controllo di input matematico per gestire gli eventi da deve essere inviato al metodo DispEventAdvise ereditato dalla classe di esempio CMathInputControlEventHandler. Il codice seguente viene chiamato dal metodo OnInitDialog nella classe di esempio per eseguire queste azioni.
// 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();
}
}
}
}
}
Nota
Il tipo di modello, CMIC_TEST_EventsDlg in questo esempio, sarà diverso a meno che non sia stata denominata la classe uguale all'esempio.