2009-09-03 20 views
5

私は、クリップボードを使用する必要がある小さなアプリケーションをいくつかの機能のために作成しようとしています。現在クリップボードにあるユーザーのデータを上書きしたくないので、私はそれをメモリに保存し、仕事をしてからそれを書き返すことに決めました。以下のコードは、私がしようとしているもののベアボーンの例であるコンソールアプリケーションです。クリップボードアクセスの不自然さ

私が抱えている問題は、状態を復元することです。アプリケーションを実行する前に何かをVisual Studioからクリップボードにコピーすると、クリップボードには合計6つのオブジェクト(さまざまな文字列形式とロケール)がキャッシュに入れられます。ロケールだけがクリップボードにあり、SetData()の各呼び出しが最後のものを上書きするように見えますが、それらを復元すると、 (ちなみに、SetDataObjectはGetDataObjectの逆ではないので、私はそれを使うことはできません)

どのようにしてクリップボードの状態を保存して後で復元できますか?

[STAThread] 
    static void Main(string[] args) 
    { 
     //Store the old clipboard data 
     Dictionary<string, object> clipboardCache = new Dictionary<string, object>(); 

     IDataObject clipboardData = Clipboard.GetDataObject(); 

     foreach (string format in clipboardData.GetFormats()) 
     { 
      clipboardCache.Add(format, clipboardData.GetData(format)); 
     } 

     Clipboard.SetText("Hello world!"); 

     string value = Clipboard.GetText(); 

     Console.WriteLine(value); 

     //Clear the clipboard again and restore old data 
     Clipboard.Clear(); 

     foreach (KeyValuePair<string, object> valuePair in clipboardCache) 
     { 
      Clipboard.SetData(valuePair.Key, valuePair.Value); 
      Thread.Sleep(100); 
     } 

     Console.ReadLine(); 
    } 
+0

あなたはClipXのような任意の複数のオブジェクト・クリップボードのプラグインを使用している:私はあなたはそれがあまりにも複雑作っているとあなたのコードは、このようなものであるべきだと思いますか? – TheVillageIdiot

+0

コードスニペットは実際に私の問題を完全に解決しましたが、あなたのものとはまったく異なりますが、ここでGoogleを紹介しますので、ここで詳しく説明します:コンソールアプリケーションからWindowsクリップボードにアクセスするのに問題がある人は、 "[STAThread]"属性を持つメソッド! :D – BrainSlugs83

答えて

5

Windowsクリップボードには、一度に1つのオブジェクトしか表示されません。しかし、その1つのオブジェクトから複数のフォーマット(RTF、テキスト、HTMLなど)が利用可能です。

//Store the old clipboard data 
IDataObject clipboardData = Clipboard.GetDataObject(); 

Clipboard.SetText("Hello world!"); 

string value = Clipboard.GetText(); 
Console.WriteLine(value); 

//Clear the clipboard again and restore old data 
Clipboard.Clear(); 
Clipboard.SetDataObject(clipboardData); 

Console.ReadLine(); 
+1

私は私の質問では、IDataObjectを受け入れてクリップボードを空のままにしていないため、SetDatObjectが動作しているとは思わなかった、 しかし、私は間違っていました。デフォルトでは、アプリケーションは終了するまでデータをクリップボードに保持します。ラウンドを少し読んだ後、あなたのコードがSetDataObject(clipboardData)をSetDataObject(clipboardData、true)に置き換えて動作することがわかりました。ありがとうございました - 私は単純だと思った。 –

1

マーティンあなたのコードを試しました。私はClipXを私のシステムにインストールしています。私はあなたのコードを実行するときに実行すると、私はClipXのキャッシュにそこに多くの項目を取得します。しかし、Clipboard.GetDataObject()コールは、最新のオブジェクトのみを返します。それはClipX内のすべてのオブジェクトの形式を返しますので、実際には、このループを実行しているとき

IDataObject clipboardData = Clipboard.GetDataObject(); 

によって返されたデータを変換

foreach (string format in clipboardData.GetFormats()) 
{ 
    clipboardCache.Add(format, clipboardData.GetData(format)); 
} 

:だから何が起こるかは、あなたがこのループを呼び出すときということです

foreach (KeyValuePair<string, object> valuePair in clipboardCache) 
{ 
    Clipboard.SetData(valuePair.Key, valuePair.Value); 
    Thread.Sleep(100); 
} 

クリップボードに設定されているオブジェクトは1つだけです。

第2に、古いオブジェクトを新しいオブジェクトで上書きする場合は、通常の動作ではなく通常の動作です。複数のエントリクリップボードを構築する場合は、システムコールのコピーと貼り付けを傍受し、オブジェクトをプログラムのメモリまたはディスクに保持する必要があります。あなたはデフォルトのクリップボードに頼ることはできません。

+1

応答をありがとう。私はすべてのクリップボード拡張を使用していないと私は1つの項目を保存するために探していますが、Visual Studio(例えば)からテキストをコピーする場合、クリップボードに格納されている複数のアイテム - テキストの文字列表現、 RTFバージョン、ロケール - 合計で私のclipboardDataには6つのフォーマットがあり、6つのオブジェクトすべてをクリップボードに戻したいと思います。 Visual Studioからテキストをコピーできますか? clipboardData.GetFormats()からいくつの結果を取得しますか? –

+1

ちょうど追加する - 私はあなたもクリップボードに1つのアイテムを格納することができたと思ったが、それはあなたが1つのアイテム*を*の形式を持つことができますそれを今日混乱から。私はこれについて正しいのではないかどうかを知ることにも興味があります... –

関連する問題