共用方式為


從數學輸入控制項接收輸入

本節說明如何使用 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不同。