DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C#での画面ハードコピー

分類:[.NET]

はじめまして。いつも拝見させていただいております。Odagirizmと申します。

私は今、C#で一定時間ごとに画面のキャプチャをとるというアプリの作成途中なのですが、行き詰まってしまいました。
そこで皆様の知恵をお貸しいただきたく書き込みいたしました。

画面のハードコピーを取る方法はSendKeys.Send("%{PRTSC}")で実行しています。
以下、ソース中心部分です。
このソースはTimer_Tickの中で一定時間ごとに行われるようにしています。

// [Alt] + [PrintScreen]キーを押す
SendKeys.Send("%{PRTSC}");
Application.DoEvents();

IDataObject changedData = Clipboard.GetDataObject();

/*
* ここの処理が正しく行われないことがあるのです
* */
Image captureImage = (Image)changedData.GetData(DataFormats.Bitmap, true);

この処理を実行すると最初の数回はただしくキャプチャできているのですが、最初の数回を過ぎるとコメント部分のGetDataメソッドが正しく行われずにnullが吐き出されてしまいます。
Windowsのクリップブックを見ながら確認してみるとキャプチャが正しく行われなくなった時クリップブックには「クリップブックでは現在の形式の情報は表示されないか、またはメモリ不足のため情報が表示されません。」的なメッセージが表示されていました。

クリップボードからデータが正常に取得できなくなる理由をご存知の方、
もしくは「画面のハードコピーならこんな方法でできるよ」という方がいましたら
ぜひ教えてください。よろしくお願いします。
もうしわけございません。
環境を書き忘れておりました。
Visual Studio2002
Windows 2000 Server
.NET Framework 1.1
です。
■No448に返信(Odagirizmさんの記事)

SendKeysを使った方法は分からないのですが、画面ハードコピーということでは、次のページのサンプルが参考になりそうです。

C# Corner - Screen Capture Utility in C# and .NET
http://www.c-sharpcorner.com/Code/2002/April/ScreenCaptureUtility.asp
> /*
> * ここの処理が正しく行われないことがあるのです
> * */
> Image captureImage = (Image)changedData.GetData(DataFormats.Bitmap, true);

このcaptureImageという変数はこの後、どのように扱っているのですか?
PictureBoxのImageプロパティに設定しているのでしょうか??
そうだとすれば、前回設定してあったImageプロパティのImageオブジェクト
はDisposeしていますか?

> Windowsのクリップブックを見ながら確認してみるとキャプチャが正しく行われなくなった時クリップブックには「クリップブックでは現在の形式の情報は表示されないか、またはメモリ不足のため情報が表示されません。」的なメッセージが表示されていました。

その説明通りの状況になっているように思います。
  • 題名: 解決しました。ありがとうございます。
  • 著者: Odagirizm
  • 日時: 2003/08/25 22:31:51
  • ID: 457
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
管理人様、よねKEN様、ありがとうございます。
恥ずかしながらDisposeメソッドのことなど一度本で読んだだけで、すっかり記憶の彼方でございました。
こんな基本のことも知らずに申し訳ない限りです。

なお、私のメソッドではこの後ImageクラスはSaveメソッドでJPG書き出しを行っています。
そこで書き出し後やイメージ取得直後など色んなところにDisposeメソッドを置いてみたところ、それでもやはり状況は改善されませんでした。

管理人様に教えていただいたサイトの該当ソースを貼り付けてみたら無事動きました。
・・・が、「何してるのか知らないけど、うまく動いて結果オーライ」のままでは良くないですね。
やっぱりWindowsプログラミングを勉強するうえでWindowsのAPIからは逃げられないものなんでしょうか。
これから機会を見つけて勉強してみたいと思います。

では失礼いたします。これからまたお世話になることもあるかと思いますが、何とぞよろしくお願いします。
解決済み!
■No453に返信(よねKENさんの記事)
私が思うに、
SendKeys.Send("%{PRTSC}");
の後すぐに
IDataObject changedData = Clipboard.GetDataObject();
としているところが怪しいのではないかと思うのですが。つまりその前に、クリップボードに確実にイメージデータが入るまでループするといった処理が必要となるような気がしますが、どうでしょう?
■No458に返信(管理人さんの記事)
> IDataObject changedData = Clipboard.GetDataObject();
> としているところが怪しいのではないかと思うのですが。つまりその前に、クリップボードに確実にイメージデータが入るまでループするといった処理が必要となるような気がしますが、どうでしょう?

たびたびありがとうございます。

Getがうまくいくまでdo-whileループでまわしてみたことはあったんですけど、
いざ実行したらずっとループから抜けず、私の額からイヤな汗が垂れたぐらいでした。
SendKeys.Sendメソッドを見ていただければ分かるかもしれませんが、PrintScreenキーの対応状況だけ微妙なとこでして、そこで何かが起きているかもしれません。

DOBON.NET | プログラミング道 | プログラミング掲示板