Winapi 我如何接受MathML?

Winapi 我如何接受MathML?,winapi,windows-7,mathml,Winapi,Windows 7,Mathml,我今天发现Windows7附带了一个非常令人印象深刻的MathPanel实用程序,用于执行方程式的手写识别: 这很好。(这里我输入了sRGB颜色空间伽马转换部分的公式) 但现在我似乎什么都做不了 有一个插入按钮。我假设单击Insert会将其插入到其后面活动的应用程序中(与屏幕键盘的工作原理非常相似): 除非我假设它将作为粘贴操作运行 我在帮助中找不到有关应用程序运行所需的信息。没有提到某些软件必须支持的任何特殊API 我在MSDN上也找不到任何关于接受公式插入所需的特殊API的信息 为了接收

我今天发现Windows7附带了一个非常令人印象深刻的MathPanel实用程序,用于执行方程式的手写识别:

这很好。(这里我输入了sRGB颜色空间伽马转换部分的公式)

但现在我似乎什么都做不了

有一个插入按钮。我假设单击Insert会将其插入到其后面活动的应用程序中(与屏幕键盘的工作原理非常相似):

除非我假设它将作为粘贴操作运行

我在帮助中找不到有关应用程序运行所需的信息。没有提到某些软件必须支持的任何特殊API

我在MSDN上也找不到任何关于接受公式插入所需的特殊API的信息

为了接收MathPanel输入,我必须实现什么API、注册、回调、侦听器、消息、COM对象

我提到MathML的唯一原因是因为以下问题的答案:

理论上,任何支持MathML(数学标记语言)的应用程序都可以与Windows 7数学输入面板一起使用。“数学输入”面板仅适用于支持MathML的程序。这里有一些这样的应用程序:StarOffice、OpenOffice、Opera和Maple

那么如何使我的程序支持MathML呢

据我所知,MathML是一种标记语言;不是Windows API。这就像说,“我如何使我的程序支持HTML?”HTML是文本,你可以将它粘贴到任何地方

除非我“支持”MathML,否则MathPad拒绝粘贴


更新

单击“插入”后,检查剪贴板上的
IDataObject
,我看到两种可用格式(都不是文本,这解释了为什么我没有得到任何标记):

格式1:

     CLIPFORMAT cfFormat: "MathML Presentation" (49839)
PDVTargetDevice ptd:      0x00000000
          DWORD dwAspect: DVASPECT_CONTENT
          DWORD lindex:   -1
          DWORD tymed:    1  (TYMED_HGLOBAL)
格式2:

     CLIPFORMAT cfFormat:"MathML" (49838)
PDVTargetDevice ptd:      0x00000000
          DWORD dwAspect: DVASPECT_CONTENT
          DWORD lindex:   -1
          DWORD tymed:    1  (TYMED_HGLOBAL)
所以至少现在我有了一些剪贴板格式:

Handle CF_MathML_Presentation = RegisterClipboardFormat("MathML Presentation");
Handle CF_MathML_Content = RegisterClipboardFormat("MathML Content");
Handle CF_MathML = RegisterClipboardFormat("MathML");
  • “MathML演示文稿”
  • “MathML”

我仍然无法在MSDN上找到任何有关剪贴板格式的信息。

监视发送到我的窗口的消息,看起来
数学输入面板
应用程序发送了一个
Ctrl+V

  • WM_键控(0x11)
    VK_控制
  • WM_向下键(0x56)
    V
  • WM_CHAR(0x16)
  • WM\U键控(0x11)
    VK\U控制
  • WM_键向上(0x56)
    V
因此,您需要识别有人试图按Ctrl+V键,然后必须提取内容

首先注册三种剪贴板格式:

Handle CF_MathML_Presentation = RegisterClipboardFormat("MathML Presentation");
Handle CF_MathML_Content = RegisterClipboardFormat("MathML Content");
Handle CF_MathML = RegisterClipboardFormat("MathML");
注意:记录要注册的Windows剪贴板格式名称:

  • 通用MathMLWindows剪贴板名称:
    MathML
  • Presentation MathMLWindows剪贴板名称:
    MathML Presentation
  • Content-MathMLWindows剪贴板名称:
    MathML-Content
然后在剪贴板中获取
IDataObject
的句柄:

IDataObject dataObject;
OleGetClipboard(dataObject);
然后列举所有格式,寻找您喜欢的格式:

IEnumFORMATETC enum;
dataObject.EnumFormatEtc(DATADIR_GET, out enum);

String mathXml = "";

foreach (FormatEtc format in enum)
{
    if (format.cfFormat = CF_MathML_Presentation) ||
       (format.cfFormat = CF_MathML_Content) ||
       (format.cfFormat = CF_MathML)
    {
        //We know how to handle these formats:
        STGMEDIUM medium;
        dataObject.GetData(format.cfFormat, out medium);

        mathXml = GetStringFromStorageMedium(medium); //handles all the nasty HGlobal/IStream/IStorage nonsense
    }
}

ShowMessage(mathXml); //tada!

Microsoft还允许您:

然后可以创建接收通知事件的对象:

class MathEvents : _IMathInputControlEvents
{
    public HRESULT Insert(String mathXml)
    {
       //Notifies the event handler when the Insert button is clicked.
       MessageBox.Show(mathXml);
       return S_OK;
    }

    public HRESULT Clear()
    {
       //Notifies the event handler when the Clear button is clicked.      
       return S_OK;
    }

    public HRESULT Close()
    {
       //Notifies the event handler when the Close button is clicked.
       return S_OK;
    }

    public HRESULT PaintHRESULT Paint(LONG_PTR hdc, LONG Left, LONG Top, LONG Right, LONG Bottom, LONG Element, LONG State)
    {
       //Notifies the event handler when the buttons and background of the control require painting.
       return S_OK;           
    }
缺少的部分是如何为回调对象提供
mathInputControl
引用

这是超级机密的复杂COM代码,涉及
ConnectionPointContainer和
advice`,不能从C#中完成


但是你不需要,你只需要使用
Ctrl+V

我认为它被正式称为“数学输入面板”(MIP)。MathType产品支持它,并提供一个菜单项来运行它。正如这里的其他回复所提到的,单击MIP的Insert按钮会向它下面的窗口发送一个Ctrl-V。如果该窗口支持该键盘快捷键并处理MathML,那么它将工作

虽然MathML剪贴板格式是在粘贴时处理MathML输入的推荐方式,但如果您在应用程序中实现MathML支持,您也应该接受作为CF_UNICODETEXT提供的MathML文本。有些应用程序支持将MathML复制到剪贴板,但似乎不知道MathML剪贴板格式。当然,粘贴代码必须嗅探文本以识别MathML,而不是常规的非MathML文本。你也应该考虑接受拖放和粘贴。 Math输入控件是一个相关但略有不同的MIP配置。如果我没记错的话,它缺少MIP的历史和其他一些功能。我们开始为MathType使用它,并很快意识到它没有任何优势。您应该忽略它,只支持MathML的粘贴和拖放。如果对应用程序有意义,请添加数学输入面板菜单项。

剪贴板格式的“MathML演示文稿”实际上包含文本;在使用Windows API GetClipboardData()之前,我已经尝试过这个方法

此外,如果您将MathML片段作为纯文本(例如,CF_text)复制到剪贴板,然后将其粘贴到Word文档,您也将获得纯文本,即Word不会将其解释为演示MathML


要让Word这样做,您必须将其复制为CF_文本和“MathML演示文稿”。要获得后者的ID,请尝试按照Ian Boyd的建议将“MathML演示文稿”注册为剪贴板格式。Windows将返回其剪贴板格式ID;将此ID与SetClipboardData()一起使用。

看起来是应用程序负责注册剪贴板更新,然后将“MathML”条目提取为XML;