数式入力コントロールからの入力の受信
このセクションでは、アクティブ テンプレート ライブラリ (ATL) とコンポーネント オブジェクト モデル (COM) を使用して、数式入力コントロールから MathML マークアップを取得する方法について説明します。
数式入力コントロールから認識された数式を取得するには、挿入ボタンが押されたときに発生する動作をオーバーライドできます。 これを行うには、 _IMathInputControlEvents インターフェイスでサポートされているさまざまなイベントを実装するイベント ハンドラーを設定する必要があります。 イベント ハンドラーを設定するには、サポートするイベントに対して次の手順を実行します (この場合は挿入します)。
イベント シンクを含むテンプレート クラスを作成する
数式入力コントロールを使用するイベント シンクを実装する場合は、まずシンク ID を指定する必要があります。その後、イベント、イベント コントロール ハンドラー、および数学入力コントロール イベント インターフェイスから継承するテンプレート クラスを作成する必要があります。 次のコードは、シンク ID を設定し、必要なインターフェイスから継承するこのようなテンプレート クラス CMathInputControlEventHandler を作成する方法を示しています。 このテンプレート クラスは、初期化時に数学入力コントロールを渡すために使用されるプライベートの不明なインターフェイス ポインターと、アドバイス/unadvise の呼び出し数をカウントする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;
Note
ダイアログを使用していない場合は、実装でメンバー 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
Note
テンプレートの種類 (CMIC_TEST_EventsDlg) は、クラスに例と同じ名前を付けない限り、異なります。
イベント シンクを継承するようにクラスを初期化する
テンプレート クラスから継承するようにクラスを設定したら、イベントを処理するように設定する準備が整います。 これは、数学入力コントロールと呼び出し元のクラスへのハンドルを持つクラスを初期化することで構成されます。 さらに、イベントを処理する数式入力コントロールは、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();
}
}
}
}
}
Note
この例CMIC_TEST_EventsDlgテンプレートの種類は、クラスに例と同じ名前を付けない限り、異なります。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示