none
RichTextBoxに読み込んだrtfファイル内画像の編集について RRS feed

  • 質問

  • RichTextBoxにペーストした画像をダブルクリックするとペイントが開き、編集でき、閉じるとRichTextBoxへ反映されます。
    この画像編集を、rtfファイル保存、再読み込み後も行いたいのですが、うまくいきません。

    1.ペイント等に開いた画像の一部を選択、コピーしたものをRichTextBoxへペースト
    2.SaveFile("test.rtf") でrtfファイル保存
    3.LoadFile("test.rtf") でRichTextBoxへ表示(別のRichTextBoxでも同じものでも同様)
    4.画像をダブルクリック
      →ペイントが起動して編集できる
    5.ペイントを閉じる
      →編集した内容がRichTextBox上へ反映されていない

    もう一度ダブルクリックしてペイント上で見ると、編集した内容がそのままあります。
    閉じるとやはり反映されていません。

    試しにそのrtfファイルを直接Word(2013)で開き、何もせず保存すると
    その後は何度SaveFileしてもLoadFileしても画像編集内容が反映されるようになります。

    他、試したこと
    ・SaveFileやLoadFileの第2引数へRichTextBoxStreamType.RichTextを指定
    ・LoadFile前後にRefresh
    (3/14追記)
    ・rtfファイルではなくMemoryStreamでSaveFile、LoadFile
    ・Word.Applicationを使用してrtfファイルSave
     →LoadFile後に画像編集できたが、時間がかかるため現実的でない

    Windows10 x64
    VS2017 VB .NETFramework4.7.1を使用しています。

    何か方策はありませんでしょうか。

    よろしくお願いいたします。

    • 編集済み 502town0155 2019年3月14日 0:20 他、試したことへ追記
    2019年3月5日 2:29

回答

  • 一つワークアラウンドが見つかりましたので、共有します。

    App.configに以下のノードを追記する事で、RichTextの作成が .NET Framework 4.6.2 までと同様になり、動きが改善しました。

      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Windows.Forms.DoNotLoadLatestRichEditControl=true"/>
      </runtime>

    • 回答としてマーク 502town0155 2019年4月8日 23:58
    2019年4月8日 8:33

すべての返信

  • Hi,

    You mean you can't save after editing the rtf file?

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年3月7日 6:36
  • Alex, thank you for your comment.
    I tried my best in English translation ...

    A: Double click the image pasted in RichTextBox to open the mspaint for editing. Edit content is reflected to RichTextBox when mspaint is closed.
    B: Save it as an rtf file (RichTextBox.SaveFile("test.rtf")), reload it into RichTextBox (RichTextBox.LoadFile("test.rtf")), and execute A again, the edited result will not be reflected.

    Best Regards

    2019年3月12日 0:17
  • 502town0155 さま よろしく。

    .rtf 内の画像では無く、.jpg 画像そのもののオープンに関して、類似の経験があります。
    ファイルオープンで、ファイルのハンドルをアプリが保持している場合、
    編集上書きは受け入れられません。

    オープン時に、IO.FileStream を使い、さっさと閉じてしまう事です。
    以下のコードでは如何でしょうか?。 .jpg を .rtf に読み替えて下さい。

    	Dim fn As String = "ほにゃらら.jpg"
    	Dim fs As IO.FileStream
    	fs = New IO.FileStream(fn, IO.FileMode.Open, IO.FileAccess.Read)

    手前みその参考投稿: https://shiroyuki-mot-says.blogspot.com/2015/09/vb-picturebox-image-overwrite.html


    • 編集済み ShiroYuki_Mot 2019年3月13日 8:01 リンク不正を訂正
    2019年3月12日 6:28
  • 502town0155さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    編集した画像をどのようにリッチテキストに読み込みますか。これが私のやり方です:

    Public Class Form1

        Dim filename As String = "D:\test.jpg"

        Dim bmp As Bitmap

        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        End Sub

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            If filename Is Nothing OrElse filename.Trim().Length = 0 Then Return

            Try

                bmp = New Bitmap(filename)

                Clipboard.SetDataObject(bmp)

                Dim dataFormat As DataFormats.Format = DataFormats.GetFormat(DataFormats.Bitmap)

                If RichTextBox1.CanPaste(dataFormat) Then RichTextBox1.Paste(dataFormat)

            Catch exc As Exception

                MessageBox.Show("fail" & exc.Message, "warning", MessageBoxButtons.OK, MessageBoxIcon.Information)

            End Try

        End Sub

        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

            RichTextBox1.SaveFile("D:\test.rtf")

        End Sub

        Private Sub RichTextBox1_DoubleClick(sender As Object, e As EventArgs) Handles RichTextBox1.DoubleClick

            Dim process As System.Diagnostics.Process = New System.Diagnostics.Process()

            process = System.Diagnostics.Process.Start("mspaint.exe", filename)

            bmp.Dispose()

        End Sub

        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        End Sub

    End Class

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2019年3月12日 7:56
    モデレータ
  • ShiroYuki_Motさん、Harukaさん
    コメントありがとうございます。

    画像の読み込みといいますか、
    埋め込み画像が含まれたrtfファイルの読み込みをリッチテキストボックスのAPIで行います。

    Button1_Click:
    リッチテキスト1へ入力された文字、ペーストされた画像をrtfファイルへ保存

    Button2_Click:
    リッチテキスト2へ保存したファイルを読み込む

    その後、リッチテキスト2の画像をダブルクリックして編集し、ペイントを閉じるとリッチテキスト上に編集が反映されていない
    となります。

    この投稿後、.NET Framework4.7.2が入ったWindows7上で動作させてみたり
    ターゲットフレームワークを3.5にしてみたところ問題なく、
    何か処理が足りないのか?何が違うのか?と思っているのですが、

    画像部分のダブルクリックでペイントが勝手に起動するところが違うのでしょうか。

    Public Class Form1
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'Save
    
            RichTextBox1.SaveFile("test.rtf")
    
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'Load->2
    
            RichTextBox2.LoadFile("test.rtf")
    
        End Sub
    
    End Class


    よろしくお願いいたします。



    2019年3月13日 0:37
  • 502town0155 さま 拝見しました。

    PictureBox にファイルから貼り付けたケースも同様な事が起こります。
    これは、.FromFile でオープンすると、そのアプリがファイルを解放するまで、
    ハンドルを保持しているからです。
    その結果、自分でも他のアプリでも、上書きは受け付けられません。
    .rtf から 既定のアプリで、画像部分を開く動作が、ご質問の状況でしょうね。
    開く時は、Read モードですから、開けてしまうのが、混乱されている原因でしょう。

                'Me.PictureBox1.Image = Image.FromFile(fn) 
                'Image.FromFile で開くと、Image.Save で GDI+ が Error を吐く

    PS: 前の返信で URL が間違っていました。  訂正済みです。

    何度も書きますが、 Stream で開かれては如何でしょう?。


    • 編集済み ShiroYuki_Mot 2019年3月13日 8:28 ファイルを画像部分に訂正
    2019年3月13日 8:12
  • ShiroYuki_Motさん アドバイスありがとうございます。URLもありがとうございました。

    RichTextBox2.LoadFile("test.rtf")
    としていたところを、下記のように変更してみましたが、状況変わらずでした。

            Dim fileReader As StreamReader
            fileReader = My.Computer.FileSystem.OpenTextFileReader("test.rtf")
    
            Dim stringReader As String
            stringReader = fileReader.ReadToEnd()
    
            fileReader.Close()
            fileReader.Dispose()
    
            RichTextBox2.Rtf = stringReader

    2019年3月14日 1:21
  • 502town0155 さま 拝見しました。

    一番最初にも書いてあるのですが、試していないのですね?。

    では、これでは?。

    Using reader As New StreamReader(New FileStream(fn, FileMode.Open, FileAccess.Read))
     Do Until reader.EndOfStream
      
     Loop
     ' Set Data To the Control
    
    End Using

    2019年3月14日 3:01
  • ShiroYuki_Motさん アドバイスありがとうございます。

    FileStreamは試していませんでした。
    下記のように変更してみましたが、状況変わらずでした。
    不備がありましたらご指摘ください。

            Using reader As New StreamReader(New FileStream("test.rtf", FileMode.Open, FileAccess.Read))
                Dim stringReader As String = String.Empty
    
                Do Until reader.EndOfStream
                    stringReader = reader.ReadToEnd()
                Loop
                ' Set Data To the Control
                RichTextBox2.Rtf = stringReader
    
            End Using

    また、なるほどハンドルか、と思い、
    試しにLoadFile後に同rtfファイルを直接開き(Word)、画像部分の編集をしてみるとできましたので、
    ハンドル問題ではない気がします。

    よろしくお願いいたします。

    2019年3月14日 4:58
  • 502town0155 さま 拝見しました。

    てっきり、ハンドルと思っていたのですが、違う様ですね。  失礼致しました。

    後は、メインのプロセスから起動される画像編集ソフトのプロセルを監視し、それが閉じられるのを掴んで、ファイル等を読み直しするのでしょうかね?。

    自動起動される画像編集のプロセスを、反映出来ていないのは、VS 側の片手落ちの気もしますが。

    画像を開いているのがファイルなのかストリームなのかで、対応は変わる気もしますが。 難問ですね。

    2019年3月14日 7:19
  • 一つワークアラウンドが見つかりましたので、共有します。

    App.configに以下のノードを追記する事で、RichTextの作成が .NET Framework 4.6.2 までと同様になり、動きが改善しました。

      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Windows.Forms.DoNotLoadLatestRichEditControl=true"/>
      </runtime>

    • 回答としてマーク 502town0155 2019年4月8日 23:58
    2019年4月8日 8:33
  • 朴様

    投稿ありがとうございます。
    こちらでも試してみたところうまく行きました!

    ターゲットフレームワークは4.7.1のままで
    RichTextは.NET Framework 4.6.2までと同様の動きとなれば、現状問題ありませんので
    大変助かりました。

    ありがとうございました。


    2019年4月8日 23:57