2008年1月25日金曜日

画面をキャプチャする(C#) その2

前回の最後で、
「何らかの方法でアクティブなウィンドウの左上隅の座標とウィンドウの大きさを
取得すれば、"CopyFromScreen"メソッドが利用できる。」
と話しましたが、もちろんできます。


前回のソースをそのまま改変していきます。
(新たにプロジェクトを作成する場合は、"button1"をダブルクリックする所まで
 進めて下さい。)

まずは、長方形を表す構造体を宣言します。
("using"ディレクティブを用いて、"System.Runtime.InteropServices"名前
 空間の修飾省略定義を行って下さい。)

/*** Form1.cs ***/
public partial class Form1 : Form
{
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
(省略)
}

構造体"RECT"は長方形の左上隅と右下隅とで、長方形の形を定義します。

左上隅に (x, y) = (RECT.left, RECT.top)
右上隅に (x, y) = (RECT.right, RECT.bottom)
が入ります。

続いて、「アクティブなウィンドウを取得する」メソッドと、
「ウィンドウの長方形座標を取得する」メソッドを"user32.dll"より呼び出します。

// 現在ユーザーが作業しているウィンドのハンドルを返します。
[DllImport("user32")]
private static extern IntPtr GetForegroundWindow();

// 指定されたウィンドウ左上端と右下端の座標をスクリーン座標で取得します。
[DllImport("user32")]
private static extern int GetWindowRect(IntPtr hWnd, ref RECT lpRect);

"GetWindowRect"の第一引数には、もちろん座標を取得したいウィンドウのハンドルが入ります。

第二引数に渡した変数に対して、取得された座標が代入されます。

このとき、"ref"がついてることがポイントです。

値渡しと参照渡し
引数の渡し方は2種類あります。1つは"値渡し"、もう1つは"参照渡し"です。

値渡しはメソッドを呼び出すときに、値のコピーを渡す方式です。
メソッド内で、引数の値に対して操作を行った場合でも、元の値には影響しません

参照渡しはメソッドを呼び出すときに、値の参照を渡す方式です。
メソッド内で、引数の値に対して操作を行うと、元の値にも影響します

C#ではメソッドの引数は基本的には値渡しです。
参照渡しにする時は、開発者が"ref"を用いて明示的に示さなければなりません。
この"ref"は引数の宣言の時にも、渡す時にも必要になります。


実装は以下の通りです。

/*** Form1.cs ***/
private void button1_Click(object sender, EventArgs e)
{
// アクティブなウィンドウのデバイスコンテキストを取得
IntPtr hWnd = GetForegroundWindow();

// ウィンドウの大きさを取得
RECT wRect = new RECT();
GetWindowRect(hWnd, ref wRect);

int width = wRect.right - wRect.left;
int height = wRect.bottom - wRect.top;

Bitmap bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(new Point(wRect.left, wRect.top), new Point(0, 0), bmp.Size);
}

this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
this.pictureBox1.Image = bmp;
}

実行します。




















参照:
Capture a Screen Shot - Developer Fusion

1 件のコメント:

Merusaia さんのコメント...
このコメントはブログの管理者によって削除されました。