【问题标题】:How do i accept MathML?我如何接受 MathML?
【发布时间】:2012-02-20 16:45:42
【问题描述】:

我今天发现 Windows 7 带有一个令人印象深刻的 MathPanel 实用程序,用于执行方程式的手写识别:

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

但现在我似乎无法用它任何事情。

有一个插入按钮。我会假设单击 Insert 会将其插入到其后面处于活动状态的应用程序中(很像屏幕键盘的工作原理):

除了我认为它会作为粘贴操作进行操作。

我在帮助中找不到有关应用程序需要什么才能使其工作的信息。没有提及某些软件必须支持的任何特殊 API。

我在 MSDN 上也找不到任何关于接受插入方程式需要什么特殊 API 的信息。

我必须实现哪些 API、注册、回调、侦听器、消息、COM 对象才能接收 MathPanel 输入?

我提到MathML的唯一原因是因为SuperUser mentioned MathML上的答案:

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

那么我如何让 my 程序支持 MathML?

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

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


更新

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

格式一:

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

格式二:

     CLIPFORMAT cfFormat:"MathML" (49838)
PDVTargetDevice ptd:      0x00000000
          DWORD dwAspect: DVASPECT_CONTENT
          DWORD lindex:   -1
          DWORD tymed:    1  (TYMED_HGLOBAL)

所以至少现在我有一些剪贴板格式:

  • “MathML 演示”
  • “MathML”

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

【问题讨论】:

标签: winapi windows-7 mathml


【解决方案1】:

监视发送到我窗口的消息,看起来Math Input Panel 应用程序发送了Ctrl+V

  • WM_KEYDOWN (0x11) VK_CONTROL
  • WM_KEYDOWN (0x56) V
  • WM_CHAR (0x16)
  • WM_KEYUP (0x11) VK_CONTROL
  • WM_KEYUP (0x56) V

因此,您需要识别出有人在尝试按 Ctrl+V。然后你必须提取内容。

先注册三种剪贴板格式:

Handle CF_MathML_Presentation = RegisterClipboardFormat("MathML Presentation");
Handle CF_MathML_Content = RegisterClipboardFormat("MathML Content");
Handle CF_MathML = RegisterClipboardFormat("MathML");

注意: Appendix B of the W3C's Mathematical Markup Language (MathML) Version 3.0 记录了要注册的 Windows 剪贴板格式名称:

  • 通用 MathML Windows 剪贴板名称:MathML
  • Presentation MathML Windows 剪贴板名称:MathML Presentation
  • Content MathML Windows 剪贴板名称: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!

微软还允许你program the Math Input COM object:

//Create the COM object
IMathInputControl mathInputControl = CreateComObject(CLSID_MathInputControl);
mathInputControl.Show();

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

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, andAdvise`,which不能用C#完成。

但你不需要,你可以使用Ctrl+V

【讨论】:

    【解决方案2】:

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

    虽然推荐使用 MathML 剪贴板格式来处理粘贴时的 MathML 输入,但如果您在应用中实现 MathML 支持,您还应该接受作为 CF_UNICODETEXT 提供的 MathML 文本。一些应用程序支持将 MathML 复制到剪贴板,但似乎不知道 MathML 剪贴板格式。当然,您的粘贴代码必须嗅探文本以识别 MathML,而不是常规的非 MathML 文本。您还应该考虑接受拖放和粘贴。

    数学输入控件是一个相关但略有不同的 MIP 配置。如果我没记错的话,它缺少 MIP 的历史和其他一些功能。我们开始为 MathType 使用它,并很快意识到它没有任何优势。你应该忽略它,只支持 MathML 的粘贴和拖放。如果对您的应用有意义,请添加数学输入面板菜单项。

    【讨论】:

      【解决方案3】:

      剪贴板格式“MathML Presentation”实际上包含文本;在使用 Windows API GetClipboardData() 之前,我已经尝试过了。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多