/// <summary> /// 設定ウィンドウをキャプチャ保存 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSnapShot_Click(object sender, EventArgs e) { w32.RECT w32Rect = new w32.RECT(); w32.GetWindowRect(this.Handle, ref w32Rect); Rectangle rect = new Rectangle(w32Rect.Left, w32Rect.Top, w32Rect.Right - w32Rect.Left, w32Rect.Bottom - w32Rect.Top); using (Bitmap bmp = new Bitmap(rect.Width, rect.Height)) { using (Graphics g = Graphics.FromImage(bmp)) { IntPtr hDC = g.GetHdc(); w32.PrintWindow(this.Handle, hDC, 0); g.ReleaseHdc(hDC); } string saveFile = string.Format(@"{0}\ジョイパッド設定画面キャプチャ.png", Program.ExecutePath); if (System.IO.File.Exists(saveFile)) { try { System.IO.File.Delete(saveFile); } catch { MessageBox.Show("キャプチャ画像が保存できませんでした"); return; } } try { // PNG形式で保存 bmp.Save(saveFile, System.Drawing.Imaging.ImageFormat.Png); MessageBox.Show(string.Format("この画面のキャプチャを保存しました\n{0}", saveFile)); } catch { MessageBox.Show("キャプチャ画像が保存できませんでした"); } } }
/// <summary> /// 対象のウィンドウをキャプチャ(タイマから実行される) /// </summary> internal static void IntervalCapture(object sender) { // 同時実行数をチェック // asyncCaptureNum = 0 の場合はキャプチャ処理されない (スレッドを生かしたまま止められる) if (nowCapturingNum >= asyncCaptureNum) { //System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss")); return; } Stopwatch sw1 = new Stopwatch(); Stopwatch sw2 = new Stopwatch(); sw1.Start(); nowCapturingNum++; try { IntPtr hWnd = IntPtr.Zero; int pid = 0; if (WindowHandle == IntPtr.Zero) { // TODO: w32.FindWindow に変更するべき foreach (Process process in Process.GetProcesses()) { IntPtr windowHandle = process.MainWindowHandle; if (windowHandle != IntPtr.Zero) { if (process.MainWindowTitle.IndexOf(FindTitle) == 0) { pid = process.Id; hWnd = windowHandle; break; } } } // クラス変数に記録 ProcessId = pid; WindowHandle = hWnd; } if (WindowHandle == IntPtr.Zero) { return; } // フレーム枠、タイトルバー、メニューバーを含まない LEFT:0 TOP:0 の矩形サイズが取得できる w32.RECT cliRect = new w32.RECT(); w32.GetClientRect(WindowHandle, ref cliRect); // スクリーン座標上のウィンドウ位置が取得できる w32.RECT w32Rect = new w32.RECT(); w32.GetWindowRect(WindowHandle, ref w32Rect); Rectangle rect = new Rectangle(w32Rect.Left, w32Rect.Top, w32Rect.Right - w32Rect.Left, w32Rect.Bottom - w32Rect.Top); if (PrimaryScreenBounds.Equals(rect)) { IsFullScreen = true; } else if (rect.Left < -9999) { IsFullScreen = true; rect = PrimaryScreenBounds; } else { IsFullScreen = false; } Bitmap bmp = new Bitmap(rect.Width, rect.Height); using (Graphics g = Graphics.FromImage(bmp)) { IntPtr hDC = g.GetHdc(); IntPtr disDC = IntPtr.Zero; try { sw2.Start(); switch (CaptureMethod) { case 1: // PrintWindow w32.PrintWindow(WindowHandle, hDC, 0); break; case 2: // BitBlt 全画面キャプチャ disDC = w32.GetDC(IntPtr.Zero); sw2.Start(); w32.BitBlt(hDC, 0, 0, rect.Width, rect.Height, disDC, rect.Left, rect.Top, w32.TernaryRasterOperations.SRCCOPY); sw2.Stop(); w32.ReleaseDC(IntPtr.Zero, disDC); break; case 3: // BitBlt ターゲットウィンドウキャプチャ disDC = w32.GetDC(WindowHandle); sw2.Start(); w32.BitBlt(hDC, 0, 0, rect.Width, rect.Height, disDC, 0, 0, w32.TernaryRasterOperations.SRCCOPY); sw2.Stop(); w32.ReleaseDC(WindowHandle, disDC); break; default: break; } sw2.Stop(); } finally { g.ReleaseHdc(hDC); } } // 全画面でない時はウィンドウ枠、タイトル、メニューバーをトリミング if (IsFullScreen == false) { // TODO: トリミング座標を ClientRect の情報を使うように修正 int CaptionHeight = System.Windows.Forms.SystemInformation.CaptionHeight; Size BorderSize = System.Windows.Forms.SystemInformation.FrameBorderSize; int MenuHeight = System.Windows.Forms.SystemInformation.MenuHeight; // 座標の修正 rect.X += BorderSize.Width; rect.Y += BorderSize.Height + CaptionHeight + MenuHeight; rect.Width -= BorderSize.Width * 2; rect.Height -= BorderSize.Height * 2 + CaptionHeight + MenuHeight; // トリミング座標 Rectangle clipRect = new Rectangle(); clipRect.X = BorderSize.Width; clipRect.Y = BorderSize.Height + CaptionHeight + MenuHeight; clipRect.Width = rect.Width; clipRect.Height = rect.Height; // トリミングした Bitmap に差し替え Bitmap tmp = bmp.Clone(clipRect, bmp.PixelFormat); bmp.Dispose(); bmp = tmp; } WindowPos = rect; sw2.Stop(); Bitmap oldBmp = null; lock (BitmapNull) { if (lastBitmap != BitmapNull) { oldBmp = lastBitmap; } lastBitmap = bmp; } if (oldBmp != null) { oldBmp.Dispose(); } } catch (Exception) { //System.Diagnostics.Debug.WriteLine(ex.ToString()); } finally { nowCapturingNum--; } sw1.Stop(); System.Diagnostics.Debug.WriteLine(string.Format("IntervalCapture: {0}ms {1}ms", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds)); }