從數學輸入控制項接收輸入
本節說明如何使用 Active Template Library (ATL) 和元件物件模型 (COM) ,從數學輸入控制項擷取 MathML 標記。
若要從數學輸入控制項擷取已辨識的數學方程式,您可以覆寫按下插入按鈕時所發生的行為。 若要這樣做,您必須設定事件處理常式,以實作 _IMathInputControlEvents 介面支援的各種事件。 設定事件處理常式牽涉到針對您想要支援 (在此案例中插入的事件執行下列步驟) 。
建立包含事件接收的範本類別
當您實作使用數學輸入控制項的事件接收時,您必須先指定接收識別碼。接著,您必須建立繼承自事件、事件處理常式和數學輸入控制項事件介面的樣板類別。 下列程式碼示範如何設定接收識別碼,並建立繼承自必要介面的樣板類別 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會不同。
初始化類別以繼承事件接收 (s)
設定類別以繼承自範本類別之後,即可設定它來處理事件。 這包含初始化 類別,以擁有數學輸入控制項和呼叫類別的控制碼。 此外,處理 事件的來源數學輸入控制項必須傳送至 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不同。