2009-07-17 45 views
1

我有一個問題涉及到在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,然後在嵌入之前註冊它)。

回答

0

我對.NET/OLE/ActiveX等知之甚少,但在編程GUI時,應該避免從線程修改/刷新窗口。

我有類似的C++經驗。而不是使用線程來修改你的窗口,你應該使用類似計時器的東西。

+1

正如我所說,我正在從* Gui *線程更新。 – Groo 2009-07-17 11:27:54