Пример #1
0
        /// <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("キャプチャ画像が保存できませんでした");
                }
            }
        }
Пример #2
0
        /// <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));
        }