C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

リッチテキストボックスでカラー情報をコピーする方法 [1]

[トピック内 29 記事 (21 - 29 表示)]  << 0 | 1 >>

■90002 / inTopicNo.21)  Re[13]: リッチテキストボックスでカラー情報をコピーする方法
  
□投稿者/ イエメン (13回)-(2019/01/29(Tue) 12:45:09)

Clipboard.Clear()
の前に入れたところ、
1回目で文字列は代入されるようになったのですが、
カラーフォントなどがペーストされず、書式無しの文字列になってしまいます。

そして2回目ペーストすると今度はなぜかうまくいくのですが・・・
一体なぜでしょうか?
引用返信 編集キー/
■90004 / inTopicNo.22)  Re[13]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2030回)-(2019/01/29(Tue) 13:11:26)
No90001 (イエメン さん) に返信
> コピーすることで、Excel上でセルを選択している表示は解除されることを確認できました。
> しかし、Excel上でペーストしてもデータが代入されません、

Excel に対する CutCopyMode のキャンセル処理と
RichTextBox からのコピー処理を、
同じイベント内に続けて記載していませんか?

メッセージループが回らないと、クリップボードは処理されませんので、
CutCopyMode を操作するためのボタンだけを、単独で配置してみてください。


一回のボタン操作で行われるようにしたいのなら、
CutCopyMode を操作した後のクリップボード処理を遅延実行させてみてください。

たとえば Application.Idle イベントで処理させるようにするとか、
Control.BeginInvoke なり Task.ContinueWith メソッドなりに分けるとか。
引用返信 編集キー/
■90005 / inTopicNo.23)  Re[14]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (14回)-(2019/01/29(Tue) 14:02:16)
ありがとうございます。

Thread.Sleep(100)
を入れるとうまくいきました。

ただ、文字列のサイズによっては100 msecでは足りない時があるかも知れません。

ちなみになのですが

たとえば Application.Idle イベントで処理させるようにするとか、
Control.BeginInvoke なり Task.ContinueWith メソッドなりに分けるとか。

これらはどのようにして使用するものなのでしょうか?
この方法なら、操作が終わるまで待機するようなことが可能なのでしょうか?

引用返信 編集キー/
■90006 / inTopicNo.24)  Re[15]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2031回)-(2019/01/29(Tue) 14:24:48)
2019/01/29(Tue) 14:28:45 編集(投稿者)

No90005 (イエメン さん) に返信
> Thread.Sleep(100)
> を入れるとうまくいきました。

UI スレッドで Sleep を呼びだすことは避けてください。



> これらはどのようにして使用するものなのでしょうか?

たとえば BeginInvoke ならこうかな。
掲示板に直接書いたので未検証ですけど。


Private Sub ButtonX_Click(…
 Dim oldCursor = Cursor.Current
 Cursor.Current = Cursors.WaitCursor

 Dim xlApp As Object = Nothing
 Try
  xlApp = GetObject(, "Excel.Application")
  CallByName(xlApp, "CutCopyMode", CallType.Let, False)
 Catch
 Finally
  If xlApp IsNot Nothing AndAlso Marshal.IsComObject(xlApp) Then Marshal.ReleaseComObject(xlApp)
 End Try
 BeginInvoke(Sub()
  Try
   Clipboard.Clear()
   RichTextBox1.Copy()

   Dim wApp As Object = Nothing
   '中略
   Try
    wApp = CreateObject("Word.Application")
    '中略
    CallByName(wRng, "Paste", CallType.Method)
    CallByName(wRng, "Copy", CallType.Method)
   Catch
   Finally
    '中略
   End Try
  Catch
  Finally
   Cursor.Current = oldCursor
  End Try
 End Sub)
End Sub
引用返信 編集キー/
■90007 / inTopicNo.25)  Re[16]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (15回)-(2019/01/29(Tue) 14:44:40)
ありがとうございます。

以下のようにしてみましたが、やはり1回目ではうまくいかず2回ペーストする必要があります。

BeginInvokeは非同期でバックグラウンドプロセスからフォアグラウンドプロセスに指令を投げるものだと思いますが、
GUIから使っても良いのでしょうか?
そして、それで遅延が発生するのでしょうか?

            Dim oldCursor = Cursor.Current
            Cursor.Current = Cursors.WaitCursor

            Dim xlApp As Object = Nothing
            Try
                xlApp = GetObject(, "Excel.Application")
                CallByName(xlApp, "CutCopyMode", CallType.Let, False)
            Catch
            Finally
                If xlApp IsNot Nothing AndAlso Marshal.IsComObject(xlApp) Then Marshal.ReleaseComObject(xlApp)
            End Try
            BeginInvoke(Sub()

                            Clipboard.Clear()
                            RichTextBox1.Copy()


                            ' Excel 書式を維持するため、Word 経由で複写
                            Dim wApp As Object = Nothing
                            Dim wDocs As Object = Nothing
                            Dim wDoc As Object = Nothing
                            Dim wRng As Object = Nothing

                            Try

                                wApp = CreateObject("Word.Application")
                                wDocs = CallByName(wApp, "Documents", CallType.Get)
                                wDoc = CallByName(wDocs, "Add", CallType.Method)
                                wRng = CallByName(wDoc, "Range", CallType.Method)
                                CallByName(wRng, "Paste", CallType.Method)
                                CallByName(wRng, "Copy", CallType.Method)
                            Catch
                            Finally
                                If wRng IsNot Nothing AndAlso Marshal.IsComObject(wRng) Then Marshal.ReleaseComObject(wRng)
                                If wDoc IsNot Nothing AndAlso Marshal.IsComObject(wDoc) Then Marshal.ReleaseComObject(wDoc)
                                If wDocs IsNot Nothing AndAlso Marshal.IsComObject(wDocs) Then Marshal.ReleaseComObject(wDocs)
                                If wApp IsNot Nothing AndAlso Marshal.IsComObject(wApp) Then
                                    CallByName(wApp, "Quit", CallType.Method, False)
                                    Marshal.FinalReleaseComObject(wApp)
                                End If
                            End Try

                            Cursor.Current = oldCursor

                        End Sub)

引用返信 編集キー/
■90008 / inTopicNo.26)  Re[17]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2032回)-(2019/01/29(Tue) 15:57:06)
No90002 (イエメン さん) に返信
> 1回目で文字列は代入されるようになったのですが、
> カラーフォントなどがペーストされず、書式無しの文字列になってしまいます

うまくいかない「1 回目」の時に、クリップボード内に
"HTML Format" なデータは含まれていましたか?


"HTML Format" が含まれていない場合は、Debug.WriteLine 等を仕込んで、
Word 側の呼び出しコードが呼び出されているかどうかを確認してみてください。


"HTML Format" が含まれているのに、それでも正しく受け渡せないなら、
クリップボードの格納順や内容が、1 回目と 2 回目でどのように変化しているか
確認してみてください。


ひとまず Sleep や DoEvents を入れた方が安定するのなら、
幾許かの待機処理は入れておいた方が良いのかも。



No90007 (イエメン さん) に返信
> やはり1回目ではうまくいかず2回ペーストする必要があります。

何も貼れないときは、クリップボード操作がエラーになっているのかな…。

Word を操作しても "HTML Format" が含まれていないようなら、
Word 側へのペースト&コピーが失敗して Catch 句を通過していないかをチェックしてみてください。
※例: ExternalException (0x800401D0 = CLIPBRD_E_CANT_OPEN)

もしエラーになるようなら、引数 4 個な Clipboard.SetDataObject メソッドの実装のように、
失敗時に一定間隔で再試行するような実装を設ける必要があるかもしれません。


# 今ちょっと、試せる環境が手元に無い…。
引用返信 編集キー/
■90011 / inTopicNo.27)  Re[18]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (16回)-(2019/01/30(Wed) 12:30:38)
また、お時間ある時に試していただけないでしょうか?
宜しくお願いいたします。



引用返信 編集キー/
■90086 / inTopicNo.28)  Re[19]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (17回)-(2019/02/07(Thu) 13:26:16)
ちなみに、この方法だとフォントサイズをコピーすることができないのですが、
なぜでしょうか?
Excel→Word→Excelだと
うまくサイズも移行できるのですが。

引用返信 編集キー/
■90087 / inTopicNo.29)  Re[20]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (18回)-(2019/02/07(Thu) 13:28:34)
気のせいでした
うまくいきました

引用返信 編集キー/

このトピックをツリーで一括表示

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ