问题描述
我正在尝试使用 mathinputcontrol 的 LoadInk 方法,但我不知道从哪里创建 IIDispInk 对象,因为它只是一个接口.
I'm trying to use use the LoadInk method of an mathinputcontrol but I can't figure out where to create the IIDispInk object from, as it just appears to be an interface.
http://msdn.microsoft.com/en-us/library/dd372605(VS.85).aspx
任何指导将不胜感激.
谢谢:)
为清楚起见,这是我到目前为止的代码(感谢 Hans Passant)
for clarity, here is my code so far [edit 2: by "so far", I mean of what's been added. Pretty much all the rest of my code can be found on SO under how to create the MIC in C#] (thanks to Hans Passant)
MSINKAUTLib.InkDispClass loadInkTest = new MSINKAUTLib.InkDispClass();
Stream stream = File.Open("C:\Tim\bytes.isf", FileMode.Open);
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
loadInkTest.Load(bytes);
ctrl.LoadInk((micautLib.IInkDisp)loadInkTest);
不幸的是,这会引发完全相同的异常
Unfortunately this throws exactly the same exception
灾难性故障(HRESULT 异常:0x8000FFFF (E_UNEXPECTED))
C:Timytes.isf 包含从 InkPicture 控件保存的字节,该控件可以加载并保存此文件文件 OK,所以我假设因为 loadInkTest.Load() 方法没有抛出异常(通常它不害羞这样做),它加载数据OK.如果有关于更好(或更明显)获取字节的位置的建议,请告诉我.
C:Timytes.isf contain bytes saved from an InkPicture control which loads and saves this file file OK, so I assume that because the loadInkTest.Load() method did not throw an exception (normally it is not shy to do so) that it loaded the data OK. If there is a suggestion on a better (or more obvious) place to get the bytes, please let me know.
推荐答案
使用项目+添加引用,浏览选项卡.导航到 c:program filescommon filesmicrosoft sharedink 并选择 InkObj.dll.您现在可以创建 MSINKAUTLib.InkDispClass 的实例.它实现了 IInkDisp 并具有 Save 和 Load 方法.
Use Project + Add Reference, Browse tab. Navigate to c:program filescommon filesmicrosoft sharedink and select InkObj.dll. You can now create an instance of MSINKAUTLib.InkDispClass. It implements IInkDisp and has Save and Load methods.
您必须将对象转换为 micautLib.IInkDisp,接口来自不同的类型库.关键是,在使用 LoadInk() 之前,您必须先调用 MathInputControl 的 Show() 方法.报错很惨,一切都是E_UNEXPECTED.我开始工作的代码:
You will have to cast the object to micautLib.IInkDisp, the interfaces come from different type libraries. And the clincher, you have to call the MathInputControl's Show() method first before using LoadInk(). Error reporting is miserable, everything is E_UNEXPECTED. The code I got to work:
var ctl = new micautLib.MathInputControl();
var ink = new MSINKAUTLib.InkDisp();
ink.Load(System.IO.File.ReadAllBytes("c:\temp\test.isf"));
var iink = (micautLib.IInkDisp)ink;
ctl.Show();
ctl.LoadInk(iink);
插入和关闭事件的附加事件处理程序.以及将窗户固定在正确位置的胶水.
Plus event handlers for the Insert and Close event. And the glue to get the window in the right place.
还要注意 micautLib 类型库依赖于机器的位数.麻烦的是 SetOwnerWindow() 方法,您真的想使用它来防止对话框消失在另一个窗口后面.它的参数声明为 LONG_PTR,在 32 位操作系统上为 32 位,在 x64 上为 64 位.窗把手.当您使用 Visual Studio 时,您将始终获得该方法的 32 位版本,因为 VS 是一个 32 位程序.
Also beware that the micautLib type library has a dependency on the bit-ness of the machine. The troublemaker is the SetOwnerWindow() method, you really want to use it to prevent the dialog from disappearing behind another window. Its argument is declared as LONG_PTR, a type that is 32-bits on a 32-bit operating system, 64-bits on x64. The window handle. When you use Visual Studio, you will always get the 32-bit version of that method since VS is a 32-bit program.
如果您计划支持 64 位操作系统,那么您必须构建一个单独的程序版本.首先运行 64 位版本的 Tlbimp.exe(不是 Visual Studio)来创建互操作包装器.这样参数将是一个 64 位的值,并且与您传递给该方法的窗口句柄兼容.
If you plan on supporting 64-bit operating systems then you will have to build a separate version of your program. Starting with running the 64-bit version of Tlbimp.exe (not Visual Studio) to create the interop wrapper. So that the argument will be a 64-bit value and compatible with the window Handle you pass to the method.
啊,COM的乐趣.这不是由 Microsoft.Ink.dll 包装的,这并不是真正的意外 :)
Ah, the joys of COM. No real accident that this wasn't wrapped by Microsoft.Ink.dll :)
这篇关于将墨水加载到 C# 中的 MathInputControl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!