2009-07-17 7 views
1

リッチテキストボックス内のOLEオブジェクトの管理に関する質問があります。リッチテキストボックスからの画像の削除(または更新)

私が今までに見つけたのは多くの情報ですが、私が必要とするものではありませんので、まずは簡単に紹介します。

私がこれまで知っている何

1.

まず第一に、私は、リッチテキストボックスに画像(または任意のActiveX)を挿入するOLEを使用しています。これは、クリップボードが含まれていないので、それを行う "正しい方法"であると考えられており、必要なActiveXコントロールを挿入することができます。

P/Invokeを使用して、OleCreateFromFile関数をole32.dllからインポートしてOLEを作成する方法を説明しているCodeProject(MyExtRichTextBox)に関する記事があります(完全なソースコードを参照)。イメージファイルからのオブジェクト。

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; 

そして最後構造をIRichEditOle.InsertObjectを使用して、リッチテキストボックスに渡される:

int hresult = OleCreateFromFile(...); 

関数は、REOBJECT構造体によって参照されなければならないIOleObjectインスタンスを返します。 IRichEditOleは、P/Invokeを使用してインポートされたCOMインターフェイスです。

オブジェクトの「id」を使用すると、挿入されたオブジェクトのリストを繰り返し処理することができます。 IRichEditOle.GetObjectを使用すると、挿入された各オブジェクトを取得し、dwUserフィールドをチェックして、idが一致するかどうかを確認できます。

2.問題

今すぐ質問に来る:

a)まず問題が挿入された画像を更新しています。私は、必要に応じて(または変更して)特定の画像を「リフレッシュ」できるようにしたい。私は今それをやっている方法は、このようなものです:

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)もう1つの問題は、挿入の瞬間(IRichEditOle.InsertObject)に、処理できない例外が発生することです(Paint Shop Proが機能しなくなりました)。 OpenまたはEditのシェルコマンドにはファイルの関連付けはありませんが、OLEオブジェクトを挿入するとこのアプリケーションが起動するようです。

これを引き起こしている可能性があり、その防止方法を知っている人はいますか?

[編集]

私はちょうど別のアイデアを得た - 私は、画像の更新の世話をするだろう、私のカスタムActiveXコントロールを作成することができます。その場合、私はRichTextBoxのその部分を無効にする必要があります(CodeProject記事の作者に似ています)。しかし、これは少し複雑になります(.NetクラスをCOMに公開し、埋め込み前に登録する必要があります)。

答えて

0

.NET/OLE/ActiveXなどについてはあまりよく分かりませんが、GUIをプログラミングするときには、スレッドをウィンドウから変更/更新しないようにしてください。

私はC++で同様の経験がありました。スレッドを使用してウィンドウを変更するのではなく、タイマーのようなものを使用する必要があります。

+1

私が言ったように、私は* Gui *スレッドから更新しています。 – Groo

関連する問題