a2 Tech blog

試したこと・調べたこと・感じたことを発信するITエンジニアの日記です。仕事とは直接関係ないけど興味あることを模索していきます。

Coded UI Testでアクティブなウィンドウのみ画面キャプチャを撮る

f:id:ninna2:20170411015358j:plain:w360

Coded UI Test の実行エビデンスとして画面キャプチャを残す方法の3回目です。3回も画面キャプチャについて書くとは少し予想外の展開です。今回は、アクティブなウィンドウ、つまりテスト実行中のウィンドウの画面キャプチャのみを撮る方法について記載します。

過去記事は下記ですので、合わせて参照下さい。

ninna2.hatenablog.com

ninna2.hatenablog.com

はじめに

基本的なCoded UI Test についての実施環境が整っていることを前提にしています。導入編を過去に投稿しているので、「UIテストコード化はじめの一歩」を参考に準備して見てください。

ninna2.hatenablog.com

前提となるテストの実行環境は Windows です。Macの方はすいません。同じ方法では出来ません!

アクティブなウィンドウのみ画面キャプチャを撮る

アクティブなウィンドウの画面キャプチャを撮るためには、アクティブなウィンドウの位置と大きさを判別しないといけません。そのために、Windows API(User32.dll)を使っています。

GetForegroundWindow でアクティブなウィンドウのハンドルを取得して、GetWindowRectでそのウィンドウの座標を取得するわけです。

まずは、User32.dllのインポートと宣言です。

 [DllImport("User32.Dll")]
 static extern int GetWindowRect(IntPtr hWnd, out RECT rect);

 [DllImport("user32.dll")]
 extern static IntPtr GetForegroundWindow();

今回の核となる座標の取得部分の実装です。

IntPtr active = GetForegroundWindow();
GetWindowRect(active, out r);
Rectangle rect = new Rectangle(r.left, r.top, r.right - r.left, r.bottom - r.top);

座標さえ取れてしまえば、画面全体で取得する方法で示した座標を置き換えてあげるだけで、その範囲の画面キャプチャーが撮れます。

全体のコードを参考に載せておきます。共通化などは全く考慮してないので、実際に使う際は、utility化して使うのが良いかなと思います。

public partial class UIMap
{

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [DllImport("User32.Dll")]
    static extern int GetWindowRect(IntPtr hWnd, out RECT rect);

    [DllImport("user32.dll")]
    extern static IntPtr GetForegroundWindow();

    /// <summary>
    /// RecordedMethod - このメソッドにパラメーターを渡すには 'RecordedMethodParams' を使用します。
    /// </summary>
    public void RecordedMethod(TestContext testContextInstance)
    {
        // 自動生成処理

        // 画面キャプチャを撮る処理
        RECT r;
        IntPtr active = GetForegroundWindow();
        GetWindowRect(active, out r);
        Rectangle rect = new Rectangle(r.left, r.top, r.right - r.left, r.bottom - r.top);

        using (Bitmap bm = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb))
        {
            using (Graphics gr = Graphics.FromImage(bm))
            {
                gr.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy);
                String testDir = testContextInstance.TestDeploymentDir;
                String testMethodName = testContextInstance.TestName;
                String imageFileName = testMethodName + "任意文字列" + ".png";
                bm.Save(imageFileName, System.Drawing.Imaging.ImageFormat.Png);
            }
        }

        // 自動生成処理(後続処理)
    }
}

これで、アクティブなウィンドウのみのキャプチャ出来ました。UIテストの参考にして下さい。