我有一个问题涉及到在RichTextBox中管理OLE对象。删除(或更新)RichTextBox中的图像
我到目前为止发现的信息很多,但并不完全是我需要的,所以我会先做一个快速介绍(我也希望有人可能会觉得这很有帮助)。
1.我所知道的,到目前为止
首先,我使用OLE插入图像(或任何ActiveX)到RichTextBox。这应该是“正确的方式”,因为没有剪贴板,你可以插入任何你想要的ActiveX控件。在CodeProject上解释如何(有完整的源代码),这样做,而是使之短的文章(MyExtRichTextBox):
使用P/Invoke,该OleCreateFromFile
功能从OLE32.DLL创建一个OLE进口来自图像文件的对象。
int hresult = OleCreateFromFile(...);
函数返回一个IOleObject
实例,然后必须通过REOBJECT
结构被引用:
REOBJECT reoObject = new REOBJECT();
reoObject.cp = 0; // charated index for insertion
reoObject.clsid = guid; // iOleObject class guid
reoObject.poleobj = Marshal.GetIUnknownForObject(pOleObject); // actual object
// etc. (set other fields
// Then we set the flags. We can, for example, make the image resizable
// by adding a flag. I found this question to be asked frequently
// (how to enable or disable image drag handles).
reoObject.dwFlags = (uint)
(REOOBJECTFLAGS.REO_BELOWBASELINE | REOOBJECTFLAGS.REO_RESIZABLE);
// and I use the `dwUser` property to set the object's unique id
// (it's a 32-bit word, and it will be sufficient to identify it)
reoObject.dwUser = id;
最后的结构被传递的RichTextBox使用IRichEditOle.InsertObject
到。 IRichEditOle
是一个COM接口,也使用P/Invoke导入。
该对象的“id”使我能够遍历插入的对象列表和“do stuff”。使用IRichEditOle.GetObject
我可以获取每个插入的对象并检查dwUser
字段以查看id是否匹配。
2.问题
现在想来问题:
一)第一个问题是更新的插入的图像。我希望能够根据需要“刷新”某些图像(或更改它们)。我现在正在做它的方式是这样的:
if (reoObject.dwUser == id)
{
// get the char index for the "old" image
oldImageIndex = reoObject.cp;
// insert the new image (I added this overload for testing,
// it does the thing described above)
InsertImageFromFile(oldImageIndex, id, filename);
// and now I select the old image (which has now moved by one "character"
// position to the right), and delete it by setting the selection to ""
_richEdit.SelectionStart = oldImageIndex + 1;
_richEdit.SelectionLength = 1;
_richEdit.SelectedText = "";
}
因为我从GUI线程更新,我相信我不应该担心用户这一方法在改变选择,因为OLE嵌入块线程和应用程序正在STA中运行。
但我不知何故觉得可能有更好/更安全的方法来做到这一点?该方法看起来像我应该用[DirtyHack]
属性标记它。
b)另一个问题是,在插入时(IRichEditOle.InsertObject
),我得到一个未处理的异常(Paint Shop Pro已停止工作)。看起来插入OLE对象以某种方式启动这个应用程序,尽管Open或Edit shell命令没有文件关联。
有谁知道什么可能导致这种情况,以及如何防止它?
[编辑]
我刚刚得到一个不同的想法 - 我可以创造我这将需要更新图像照顾自定义ActiveX控件。在这种情况下,我只需要使RichTextBox的那部分无效(与CodeProject文章的作者类似)。但是这会使部署更加复杂一些(我需要将.Net类暴露给COM,然后在嵌入之前注册它)。
正如我所说,我正在从* Gui *线程更新。 – Groo 2009-07-17 11:27:54