特定ウインドウの画面キャプチャが取りたかったので調べました。
以下の2点に注意が必要ですが気を付ければ問題ないと思います。
- 最小化や他ウインドウの後ろに隠れていると意図した画像が取得できない
- 同名のウインドウを複数立ち上げていると一意に特定できない
実装は以下の通りです。
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
namespace test
{
class CapTest
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
public static Bitmap Capture()
{
Process[] proc = GetProcessesByWindowTitle("ウインドウタイトル");
if (proc.Length != 1)
{
MessageBox.Show("指定ウインドウが起動されていません。");
return null;
}
IntPtr handle = proc[0].MainWindowHandle;
// ウィンドウサイズ取得
GetWindowRect(handle, out RECT rect);
int rectWidth = rect.right - rect.left;
int rectHeight = rect.bottom - rect.top;
//Bitmapの作成(画面全体のサイズでBitmapを作成)
Bitmap bmp = new Bitmap(rectWidth, rectHeight);
//Graphicsの作成
Graphics g = Graphics.FromImage(bmp);
//画面全体をコピーする
g.CopyFromScreen(new System.Drawing.Point(rect.left, rect.top), new System.Drawing.Point(0, 0), bmp.Size);
//解放
g.Dispose();
return bmp;
}
public static Process[] GetProcessesByWindowTitle(string windowTitle)
{
System.Collections.ArrayList list = new System.Collections.ArrayList();
//すべてのプロセスを列挙する
foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
{
//指定された文字列がメインウィンドウのタイトルに含まれているか調べる
if (p.MainWindowTitle == windowTitle)
{
//含まれていたら、コレクションに追加
list.Add(p);
}
}
//コレクションを配列にして返す
return (System.Diagnostics.Process[])list.ToArray(typeof(System.Diagnostics.Process));
}
}
}


コメント