https://www.fenet.jp/dotnet/column/language/4633/
アクティブウィンドウをキャプチャするコードをありがたく使わせてもらいます。
ただ、実際動かしてみるとキャプチャボタンを押すとアクティブウィンドウがC#で作成したフォーム自身になってしまうので、任意のウィンドウをキャプチャすることは出来ませんでした。
そうなると、現在実行中のプロセスの一覧から目的のウィンドウを選びフォーカスを移動するルーチンを組むのが良いかと思いましたが、UIを含めて作るのが面倒です。ということでキャプチャ用のボタンを押してから3秒ほど非同期にTask.Delay()することで、その間にキャプチャしたいウィンドウを選択するようにしてみました。
using System.Runtime.InteropServices;
namespace WindowCapture;
public partial class Form1 : Form
{
[StructLayout(LayoutKind.Sequential)]
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")]
static extern IntPtr GetForegroundWindow();
readonly int _sec = 3;
FlowLayoutPanel _basePanel = new()
{
Dock = DockStyle.Fill,
};
PictureBox _picbox = new()
{
SizeMode = PictureBoxSizeMode.Zoom,
Size = new Size(720, 360),
};
Button _captureButton = new()
{
AutoSize = true,
};
public Form1()
{
InitializeComponent();
_captureButton.Text = $"{_sec}秒後キャプチャ";
this.Load += Form1_Load;
}
void Form1_Load(Object? s, EventArgs e)
{
_basePanel.Controls.AddRange(new Control[]
{
_picbox,
_captureButton,
});
_basePanel.SetFlowBreak(_picbox, true);
this.Controls.Add(_basePanel);
_captureButton.Click += async (s, e) =>
{
await Task.Delay(_sec * 1000);
Rect rect;
IntPtr window = GetForegroundWindow();
GetWindowRect(window, out rect);
var rectangle = new Rectangle(rect.left, rect.top, (rect.right - rect.left), (rect.bottom-rect.top));
var bitmap = new Bitmap(rectangle.Width, rectangle.Height);
using var graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(new Point(rectangle.X, rectangle.Y), new Point(0, 0), rectangle.Size);
_picbox.Image?.Dispose();
_picbox.Image = bitmap;
};
_picbox.MouseDown += (s, e) =>
{
if (_picbox.Image == null) return;
var bitmap = (Bitmap)_picbox.Image;
var path = Path.GetTempFileName() + ".png";
bitmap.Save(path, System.Drawing.Imaging.ImageFormat.Png);
var effect = DragDropEffects.Copy | DragDropEffects.Move;
string[] files = {path};
var data = new DataObject(DataFormats.FileDrop, files);
var result = _picbox.DoDragDrop(data, effect);
};
}
}
コメント