none
フォームの背面の画面をキャプチャできないでしょうか。 RRS feed

  • 質問

  • はじめまして。

    VS2005+C#でWinアプリを作っています。

    で、その機能の一部として、「自身のフォームの背面をキャプチャしたい」ということになりました。言い換えると「自身のフォームが無いとすると、どう表示されているかを知りたい」のです。

    Graphics.CopyFromScreenメソッドでは当然、自身のフォームもコピーされてしまいます。一度自身のフォームを隠せば期待する画像は取得できるのですが、一瞬チラつきが起こってしまいます。これを自身のフォームを隠さずに実現する方法は無いでしょうか。

    2006年6月19日 9:40

回答

  • スクリーンキャプチャのために自身のフォームを隠す方法ですが、単純に Visible プロパティを false にしてからキャプチャするとフォーカスが移動した画面をキャプチャすることになります。今回のケースでは、これでは不適当かもしれません(button3_Clickメソッド)。さらに、Win32 APIを使うと、なぜか正常に動作しないことがあります(button2_Clickメソッド)。Windows 2000以上限定となりますが、Opacityプロパティを0にする方法で達成できましたが、その場合もApplication.DoEvents()メソッドが必要なようです(button1_Clickメソッド)。



    private void button1_Click(object sender, EventArgs e)
    {
        // 安定 フォーカス正しい
        double opacity = this.Opacity;
        this.Opacity = 0;
        Application.DoEvents(); // 必要
        pictureBox1.Image = new ScreenCapture().CaptureScreen();
            // http://www.developerfusion.co.uk/show/4630/
        // あるいは
        // SendKeys.SendWait("^{PRTSC}");
        // pictureBox1.Image = (Image)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
        this.Opacity = opacity;
    }
    private void button2_Click(object sender, EventArgs e)
    {
        // 不安定 なぜかフォーカス正しい
        bool saveVisible = this.Visible;
        this.Visible = false;
        Application.DoEvents(); // 効果なし
        pictureBox1.Image = new ScreenCapture().CaptureScreen();
            // http://www.developerfusion.co.uk/show/4630/
        this.Visible = saveVisible;
    }
    private void button3_Click(object sender, EventArgs e)
    {
        // 不安定 さらにフォーカスが期待と異なる
        bool saveVisible = this.Visible;
        this.Visible = false;
        SendKeys.SendWait("^{PRTSC}");
        pictureBox1.Image = (Image)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
        this.Visible = saveVisible;
    }



     

    2006年6月20日 17:07

すべての返信

  • こういう要望を検討する場合競合ソフトを調べるといいでしょう。

    調べてみてください。

    2006年6月19日 12:13
  • コメントありがとうございます。

    背面に隠れているデスクトップの状況を得るようなものはありますし、作り方も想像がつくのですが、ちょうど背面となると、なかなか競合となるものが見当たりません。

    なんにせよ。もう少し調べてみることにします。

    2006年6月20日 1:08
  • どちらにしても表に覆っている邪魔なものをどけて(自分自身)、背面のウィンドウをつかさどっているプログラムに描画させなくてはいけないと思います。
    2006年6月20日 1:44
  • そうですね。。やはり一度自身を隠してからキャプチャするように仕様を変更する方向に持っていきます。

    ご回答ありがとうございました!

    2006年6月20日 11:48
  • スクリーンキャプチャのために自身のフォームを隠す方法ですが、単純に Visible プロパティを false にしてからキャプチャするとフォーカスが移動した画面をキャプチャすることになります。今回のケースでは、これでは不適当かもしれません(button3_Clickメソッド)。さらに、Win32 APIを使うと、なぜか正常に動作しないことがあります(button2_Clickメソッド)。Windows 2000以上限定となりますが、Opacityプロパティを0にする方法で達成できましたが、その場合もApplication.DoEvents()メソッドが必要なようです(button1_Clickメソッド)。



    private void button1_Click(object sender, EventArgs e)
    {
        // 安定 フォーカス正しい
        double opacity = this.Opacity;
        this.Opacity = 0;
        Application.DoEvents(); // 必要
        pictureBox1.Image = new ScreenCapture().CaptureScreen();
            // http://www.developerfusion.co.uk/show/4630/
        // あるいは
        // SendKeys.SendWait("^{PRTSC}");
        // pictureBox1.Image = (Image)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
        this.Opacity = opacity;
    }
    private void button2_Click(object sender, EventArgs e)
    {
        // 不安定 なぜかフォーカス正しい
        bool saveVisible = this.Visible;
        this.Visible = false;
        Application.DoEvents(); // 効果なし
        pictureBox1.Image = new ScreenCapture().CaptureScreen();
            // http://www.developerfusion.co.uk/show/4630/
        this.Visible = saveVisible;
    }
    private void button3_Click(object sender, EventArgs e)
    {
        // 不安定 さらにフォーカスが期待と異なる
        bool saveVisible = this.Visible;
        this.Visible = false;
        SendKeys.SendWait("^{PRTSC}");
        pictureBox1.Image = (Image)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
        this.Visible = saveVisible;
    }



     

    2006年6月20日 17:07
  • Kazuya Ujiharaさん。回答ありがとうございます!

    お礼が遅くなって大変申し訳ありませんでした。

    ターゲットはXP限定なので、Opacityでやってみようと思います。

    DoEvents()が必要だったんですね。なぜ必要なのか、もう少し勉強する必要がありそうです。

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

     

    2006年6月27日 12:24