我今天发现 Windows 7 带有一个非常令人印象深刻的 MathPanel 实用程序,用于执行方程的手写识别:
这很好。 (这里我已经输入了 sRGB 颜色空间 Gamma 转换部分的公式)
但现在我似乎无法用它做任何事情。
有一个 插入 按钮。我会假设单击 插入 会将其插入到其后面处于事件状态的应用程序中(很像屏幕键盘的工作原理):
除了我假设它会作为粘贴操作运行。
我在帮助中找不到关于应用程序需要什么才能使其工作的信息。没有提到某些软件必须支持的任何特殊 API。
我也无法在 MSDN 上找到有关接受方程插入所需的特殊 API 的任何信息。
我必须实现哪些 API、注册、回调、监听器、消息、COM 对象才能接收 MathPanel 输入?
我提到 MathML 的唯一原因是因为 SuperUser mentioned MathML 的答案:
那么如何让我的程序支持 MathML?
据我所知 MathML 是一种标记语言;不是 Windows API。这就像在说,“我如何让我的程序支持 HTML?” Html 是文本,您可以将其粘贴到任何地方。
MathPad 拒绝粘贴,除非我“支持”MathML?
更新
单击 后检查剪贴板上的 IDataObject
插入 ,我看到两种可用格式(都不是文本,这解释了为什么我没有得到任何标记):
格式一:
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)
所以至少现在我有一些剪贴板格式:
我仍然无法在 MSDN 上找到任何关于剪贴板格式的信息。
最佳答案
监视发送到我的窗口的消息,看起来 Math Input Panel
应用程序发送了 Ctrl+V
:
VK_CONTROL
V
key VK_CONTROL
V
key 所以你需要认识到有人试图按下 Ctrl+V。然后您必须提取内容。
首先注册三种剪贴板格式:
Handle CF_MathML_Presentation = RegisterClipboardFormat("MathML Presentation");
Handle CF_MathML_Content = RegisterClipboardFormat("MathML Content");
Handle CF_MathML = RegisterClipboardFormat("MathML");
然后获取剪贴板中
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 还允许您 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
提供对回调对象的引用。这是 super secret 的复杂COM代码,涉及
ConnectionPointContainer, and
Advise`,which不能从C#中完成。但是你不需要,你可以使用
Ctrl+V
。关于winapi - 我如何接受 MathML?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9364890/