none
クリップボードの値を取得して、後でその値をクリップボードに戻す処理 RRS feed

  • 質問

  • クリップボードの値を取得して、後でその値をクリップボードに戻す処理を行おうとしています。

     

    クリップボードの値が 以下のコードを実行すると消えてしまいます。

    修正点がわかれば 宜しく教えてください。

     

    例えば何か文字列などをコピーした後に、下記のコード実行すると、コピーした文字列が消えています。

     

    '=================================

    'クリップボードのデータを取得
            Dim ClipBoardValue As IDataObject
            ClipBoardValue = Clipboard.GetDataObject()

    'クリップボードにデータをSet
            Clipboard.SetDataObject(ClipBoardValue, True)

    '======================================
    2007年9月5日 13:40

すべての返信

  • '内容がテキストの場合
            Dim ClipBoardValue As IDataObject
            Dim ClipBoardString As String
            'クリップボードのデータを取得()
            ClipBoardValue = Clipboard.GetDataObject
            ClipBoardString = ClipBoardValue.GetData(DataFormats.Text).ToString
            'クリップボードにデータをSet出来たか確認するために、一旦クリアします。
            Clipboard.Clear()
            'クリップボードにデータをSet
            Clipboard.SetDataObject(ClipBoardString, True)

     

     

     '内容がビットマップの場合
            Dim ClipBoardValue As IDataObject
            Dim ClipBoardBitmap As Bitmap
            'クリップボードのデータを取得()
            ClipBoardValue = Clipboard.GetDataObject
            ClipBoardBitmap = CType(ClipBoardValue.GetData(DataFormats.Bitmap), Bitmap)
            'クリップボードにデータをSet出来たか確認するために、一旦クリアします。
            Clipboard.Clear()
            'クリップボードにデータをSet
            Clipboard.SetDataObject(ClipBoardBitmap, True)

     

    これでいいのかな???

    2007年9月6日 8:03
  • ご回答有難う御座います。参考になります。

     

    クリップボードに入っているデータは特定のものではなくて、あらゆるデータが想定される場合で、

    クリップボードの全てのデータ、全てのデータ型に対応する方法を探しているのですが、そういう方法はないでしょうか。

     

     

    2007年9月6日 11:58
  • IDataObjectをDataObjectに変更した、以下のコードで試すと、ピクチャオブジェクトもテキストも クリップボードに戻せたのですが、2回実行するとエラーが発生します。

    どこに問題があるか判れば教えてください。

     

    '===================================

        Dim ClipBoardValue As DataObject

            ClipBoardValue = Clipboard.GetDataObject()

     

            'クリップボードにデータをSet出来たか確認するために、一旦クリアします。
            Clipboard.Clear()

            'この下のコードで、2回目の実行時にエラー発生

            Clipboard.SetDataObject(ClipBoardValue, True)

    '=====================================

     

    ーーーーーエラー内容詳細ーーーーーーーーー

    System.Runtime.InteropServices.ExternalException はハンドルされませんでした。
      ErrorCode=-2147221036
      Message="要求されたクリップボード操作に成功しませんでした。"
      Source="System.Windows.Forms"
      StackTrace:
           場所 System.Windows.Forms.Clipboard.ThrowIfFailed(Int32 hr)
           場所 System.Windows.Forms.Clipboard.SetDataObject(Object data, Boolean copy, Int32 retryTimes, Int32 retryDelay)
           場所 System.Windows.Forms.Clipboard.SetDataObject(Object data, Boolean copy)
           場所 CallExcelAddinTest1.Form1.Button2_Click(Object sender, EventArgs e) 場所 E:\IsentrisDev\ExportStToExcel\CallExcelAddinTest2\CallExcelAddinTest1\CallExcelAddinTest1\Form1.vb:行 88
           場所 System.Windows.Forms.Control.OnClick(EventArgs e)
           場所 System.Windows.Forms.Button.OnClick(EventArgs e)
           場所 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           場所 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           場所 System.Windows.Forms.Control.WndProc(Message& m)
           場所 System.Windows.Forms.ButtonBase.WndProc(Message& m)
           場所 System.Windows.Forms.Button.WndProc(Message& m)
           場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           場所 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           場所 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           場所 System.Windows.Forms.Application.Run(ApplicationContext context)
           場所 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
           場所 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
           場所 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
           場所 CallExcelAddinTest1.My.MyApplication.Main(String[] Args) 場所 17d14f5c-a337-4978-8281-53493378c1071.vb:行 81
           場所 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           場所 System.Threading.ThreadHelper.ThreadStart()
    ーーーーーエラー内容詳細 終ーーーーーーーーー

    2007年9月6日 12:51
  •  

    IDataObjectは、データ オブジェクトとデータ転送を仲介するインターフェース。
    DataObjectは、IDataObjectを実装した、データ転送を実現するクラス。
    これらを使って、クリップボードからデータを取得するのであって、これらをクリップボードに貼り付けても仕方がないと思います。
    クリップボードに貼り付けられているデータの種類は、ContainsAudio、ContainsFileDropList、FileDrop、ContainsImage、ContainsText、で調べられますが、カスタムデータの場合は、ContainsDataに引数を渡して、調べるので、何を取得したいか分からない場合には、調べられません。
    クリップボードは基本的に自分の使用したいデータを取得するもので、貼り付ける側は、相手が、取得しやすいように、データを複数の形式で格納しておくことができます。
    エラーの件は、おそらく、自分のDataObjectが、クリップボードを使用中なので、発生したのではないかと思います。
    たまたま、クリップボードをいじっていただけで、実は、あまり詳しくないので、上記の内容は、間違っているかもしれません。
    すみません。
    2007年9月7日 4:49
  • しかし、下記のコードを2回実行するとエラーが出てしまいますが、下記のコードは全ての種類のオブジェクトを取り扱う事ができます。なぜ1回目だけ正常に実行されるかが不明です。

    何かコピーする>下記のコードをボタンクリックイベントの中にいれて2回実行する>1回目の実行では正常。クリップボードの値も残っている>2回目の実行では例外エラー

     

    ClipBoardValue = Clipboard.GetDataObject() の 部分は オブジェクトのコピーではなく、参照になると思うのですが、なぜか一回目は正常に実行されます。 このコードをオブジェクトのコピーに変更すればうまいくのかもしれません。どなたかアイディアがあれば教えてください。

     

     

    '===================================

        Dim ClipBoardValue As DataObject

            ClipBoardValue = Clipboard.GetDataObject()

     

            'クリップボードにデータをSet出来たか確認するために、一旦クリアします。
            Clipboard.Clear()

            'この下のコードで、2回目の実行時にエラー発生

            Clipboard.SetDataObject(ClipBoardValue, True)

    '=====================================

     

    2007年9月8日 0:40
  • しかし、下記のコードを2回実行するとエラーが出てしまいますが、下記のコードは全ての種類のオブジェクトを取り扱う事ができます。なぜ1回目だけ正常に実行されるかが不明です。

     

    まず、System.Windows.Forms.Clipboardでは全ての種類のオブジェクトを取り扱うことはできません。

    .Netのオブジェクトなら、すべてのオブジェクトを入れてみることはできますが、

    いつまで有効かどうかはオブジェクト次第です。

     

    クリップボードの値を取得して、後でその値をクリップボードに戻す処理を行おうとしています。

     

    GetDataObjectで取得したIDataObjectSetDataObjectで設定する、

    という使い方は見たことがありません。

    私はあまり詳しくないですし、調べてもいませんが、

    動かなくても当然かなと思います。

     

    IDataObjectは「クリップボードの中身と通信してデータを取得するのを助けるためのオブジェクト」です。

    実際のデータを中に含んでるわけではありません。

    (含んでる場合もあるが、含んで無い場合もある)

    実際にはCOMオブジェクトで、それをIDataObjectにマーシャリングし、DataObjectでラップしています。

    前のコードを2回実行すると、元のデータが複数回マーシャリングされたりラップされたりしますので、

    その辺でうまく動かないんでは無いでしょうか?

     

    クリップボードは一度コピーしても消えません。

    ですので、「全く同じものを入れなおす」ことはありません。

    その場合は何もいじらなければいいだけです。

     

    「ちょっと違うものを入れなおす」のであれば、

    データを全て取得し、必要な変更を加え、それらを全てDataObjectに登録し、

    そのDataObjectをクリップボードに登録します。

    2007年9月9日 7:42
  • クリップボードのデータ経由である外部アプリケーションにデータを送る必要があり、本件を聞いています。

    元のクリップボード内のデータを失わないように、以下のスキームを考えています。

     

    元のクリップボードのデータを変数内に保存 > クリップボードに、別の特定のデータをコピー > 外部アプリケーションに別の特定のデータをペースト>変数内の元のクリップボードのデータを、クリップボード内に戻す。

     

    オブジェクトのCloneメソッドやシリアライズなどを考えましたがが、良い方法が見つかりません。

    2007年9月9日 13:06
  •  tanaka333 さんからの引用

    クリップボードのデータ経由である外部アプリケーションにデータを送る必要があり、本件を聞いています。

    元のクリップボード内のデータを失わないように、以下のスキームを考えています。

     

    元のクリップボード内のデータの種類がテキストやビットマップなど、.Netで扱えるオブジェクトの場合は可能です。

    そうで無い場合は.Netだけで実装するのは無理です。

     

    クリップボードはシステムで一つだけですので、もともとその方法には無理があります。

    他の方法を考えたほうがいいと思います。

    2007年9月10日 5:54
  •  tanaka333 さんからの引用

    しかし、下記のコードを2回実行するとエラーが出てしまいますが、下記のコードは全ての種類のオブジェクトを取り扱う事ができます。なぜ1回目だけ正常に実行されるかが不明です。

    何かコピーする>下記のコードをボタンクリックイベントの中にいれて2回実行する>1回目の実行では正常。クリップボードの値も残っている>2回目の実行では例外エラー

     

    ClipBoardValue = Clipboard.GetDataObject() の 部分は オブジェクトのコピーではなく、参照になると思うのですが、なぜか一回目は正常に実行されます。 このコードをオブジェクトのコピーに変更すればうまいくのかもしれません。どなたかアイディアがあれば教えてください。

    '===================================

        Dim ClipBoardValue As DataObject

            ClipBoardValue = Clipboard.GetDataObject()

     

            'クリップボードにデータをSet出来たか確認するために、一旦クリアします。
            Clipboard.Clear()

            'この下のコードで、2回目の実行時にエラー発生

            Clipboard.SetDataObject(ClipBoardValue, True)

    '=====================================

     

    私の環境(Vista Home Premium)では上記コードを実行しても例外エラーはでませんでした。

    その代わり、クリップボードの中身も消えてしまっていました。

    (文字列のみ確認)

    2007年9月12日 15:00