2009-09-16 9 views
13

私は現在、WatiNと協力しており、素晴らしいWebブラウジングオートメーションツールであると考えています。しかし、最後のリリースでは、画面キャプチャ機能が不足しているようです。私はcode by Charles Petzoldに加えて、画面からスクリーンショットをキャプチャするための実行可能なソリューションを用意しました(独立してthis StackOverflow questionに似たコードを生成しています)。残念ながら、コンポーネントがありません:実際のウィンドウはどこですかNativeMethodsのないhWndを指定したウィンドウの位置/場所を見つけるにはどうすればよいですか?

// browser is either an WatiN.Core.IE or a WatiN.Core.FireFox... 
IntPtr hWnd = browser.hWnd; 
string filename = "my_file.bmp"; 
using (Graphics browser = Graphics.FromHwnd(browser.hWnd)) 
using (Bitmap screenshot = new Bitmap((int)browser.VisibleClipBounds.Width, 
             (int)browser.VisibleClipBounds.Height, 
             browser)) 
using (Graphics screenGraphics = Graphics.FromImage(screenshot)) 
{ 
    int hWndX = 0; // Upper left of graphics? Nope, 
    int hWndY = 0; // this is upper left of the entire desktop! 

    screenGraphics.CopyFromScreen(hWndX, hWndY, 0, 0, 
          new Size((int)browser.VisibileClipBounds.Width, 
            (int)browser.VisibileClipBounds.Height)); 
    screenshot.Save(filename, ImageFormat.Bmp); 
} 

成功:

WatiNは、便利なブラウザのあなたにhWndので、私たちは(この単純な例で)そうのように、画面から画像をコピーするように設定することができますを提供しています!スクリーンショットを取得しますが、その問題があります:hWndXhWndYは、コピー元のウィンドウの位置ではなく、画面の左上の最上部のコーナーを常に指しています。

私はControl.FromHandleを調べましたが、作成したフォームでのみ動作するようです。このメソッドは、hWndを渡すとnullポインタを返します。

さらに、私の検索条件を切り替えるために私を導きます...私は、ほとんどの人が実際にウィンドウの「位置」を求めているときに、「ウィンドウの位置」を探していました。これはこれについて話したanother SO questionにつながりましたが、その答えはネイティブメソッドを使用することでした。

したがって、hWnd(好ましくは.NET 2.0時代のライブラリのみ)を指定したネイティブのC#のウィンドウの位置はありますか?

答えて

29

私はちょうどプロジェクトでこれを行って、管理されたC#の方法を見つけることができませんでした。

は/リードの答えPに追加呼び出すためのコードは次のとおりです。

[DllImport("user32.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); 
[StructLayout(LayoutKind.Sequential)] 
private struct RECT 
{ 
    public int Left; 
    public int Top; 
    public int Right; 
    public int Bottom; 
    } 

は、としてそれを呼び出します。

RECT rct = new RECT(); 
    GetWindowRect(hWnd, ref rct); 
+0

ありがとう!それがそうするように見えます。 –

+0

こんにちはRobert、 あなたは完全なソリューションを投稿できますか? firefoxや他のブラウザ(chrome)にscreencapture機能を追加したいと思います。 ありがとうございます! イエロー(リードdevi WatiN) –

+0

ちょっと!確かに、行うことができます。 –

6

いいえ - フォームを作成していない場合は、GetWindowRectをP/Invokeする必要があります。私は、管理された等価物があるとは思わない。

4

答えは、他の人が述べたように、おそらく「いいえ、あなたが取ることができないですネイティブメソッドのないhwndからのランダムウィンドウのスクリーンショットです。 "私はそれを表示する前に警告のカップル:

事前警告:このコードを使用したい人のため

、VisibleClipBoundsから与えられた大きさだけ内部のウィンドウであり、かつないをないことに注意してください境界線またはタイトルバーを含めます。それはdrawable領域です。もしあなたがそれを持っていれば、あなたはp/invokeなしでこれを行うことができるかもしれません。

(ブラウザウィンドウの境界線を計算できる場合は、VisibleClipBoundsを使用できます。SystemInformationオブジェクトを使用してBorder3DSizeなどの重要な情報を取得するか、ダミーを作成して計算することができますフォームとderiving the border and title bar height from thatしかし、すべてがバグが作られている黒い魔法のように聞こえる。)

これは、ウィンドウのCtrl + Printscreenと同じです。これは、ブラウザをスクロールしてページ全体のイメージを撮るなど、WatiNのスクリーンショット機能が果たしている細かいことをするものでもありません。これは私のプロジェクトには適していますが、あなたのためではないかもしれません。

強化:

私はデフォルト(あなたは.NET 3にし、アップ土地ならこれは拡張メソッドに変更することができ、画像の種類のオプションはかなり簡単に追加することができこの例ではImageFormat.Bmp)。

コード:

using System.Drawing; 
using System.Drawing.Imaging; 
using System.Runtime.InteropServices; 

public class Screenshot 
{ 
    class NativeMethods 
    { 
     // http://msdn.microsoft.com/en-us/library/ms633519(VS.85).aspx 
     [DllImport("user32.dll", SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); 

     // http://msdn.microsoft.com/en-us/library/a5ch4fda(VS.80).aspx 
     [StructLayout(LayoutKind.Sequential)] 
     public struct RECT 
     { 
      public int Left; 
      public int Top; 
      public int Right; 
      public int Bottom; 
     } 
    } 
    /// <summary> 
    /// Takes a screenshot of the browser. 
    /// </summary> 
    /// <param name="b">The browser object.</param> 
    /// <param name="filename">The path to store the file.</param> 
    /// <returns></returns> 
    public static bool SaveScreenshot(Browser b, string filename) 
    { 
     bool success = false; 
     IntPtr hWnd = b.hWnd; 
     NativeMethods.RECT rect = new NativeMethods.RECT(); 
     if (NativeMethods.GetWindowRect(hWnd, ref rect)) 
     { 
      Size size = new Size(rect.Right - rect.Left, 
           rect.Bottom - rect.Top); 
      // Get information about the screen 
      using (Graphics browserGraphics = Graphics.FromHwnd(hWnd)) 
      // apply that info to a bitmap... 
      using (Bitmap screenshot = new Bitmap(size.Width, size.Height, 
                browserGraphics)) 
      // and create an Graphics to manipulate that bitmap. 
      using (Graphics imageGraphics = Graphics.FromImage(screenshot)) 
      { 
       int hWndX = rect.Left; 
       int hWndY = rect.Top; 
       imageGraphics.CopyFromScreen(hWndX, hWndY, 0, 0, size); 
       screenshot.Save(filename, ImageFormat.Bmp); 
       success = true; 
      } 
     } 
     // otherwise, fails. 
     return success; 
    } 
} 
関連する問題