예제 #1
0
        internal static void CaptureWindow(ref ScreenshotTask data)
        {
            IntPtr start   = WindowsApi.FindWindow("Button", "Start");
            IntPtr taskbar = WindowsApi.FindWindow("Shell_TrayWnd", null);

            if (data.ClipboardNotDisk || Directory.Exists(data.DiskSaveDirectory))
            {
                try
                {
                    // Hide the taskbar, just incase it gets in the way
                    if (data.WindowHandle != start &&
                        data.WindowHandle != taskbar)
                    {
                        WindowsApi.ShowWindow(start, 0);
                        WindowsApi.ShowWindow(taskbar, 0);
                        Application.DoEvents();
                    }
                    bool ClearTypeToggled = false;
                    if (data.DisableClearType && ClearTypeEnabled())
                    {
                        WindowsApi.SystemParametersInfo(SPI_SETFONTSMOOTHINGTYPE, 0, FE_FONTSMOOTHINGSTANDARD, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
                        WindowsApi.RedrawWindow(data.WindowHandle, IntPtr.Zero, IntPtr.Zero, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
                        ClearTypeToggled = true;
                    }
                    WindowsApi.SetForegroundWindow(data.WindowHandle);

                    bool AeroColorToggled = false;
                    WindowsApi.DWM_COLORIZATION_PARAMS originalParameters;
                    WindowsApi.DwmGetColorizationParameters(out originalParameters);
                    if (data.CustomGlass && AeroEnabled())
                    {
                        // Original colorization parameters
                        originalParameters.clrGlassReflectionIntensity = 50;

                        // Custom colorization parameters
                        WindowsApi.DWM_COLORIZATION_PARAMS parameters;
                        WindowsApi.DwmGetColorizationParameters(out parameters);
                        parameters.clrAfterGlowBalance = 2;
                        parameters.clrBlurBalance      = 29;
                        parameters.clrColor            = ColorToBgra(data.AeroColor);
                        parameters.nIntensity          = 69;

                        // Call the DwmSetColorizationParameters to make the change take effect.
                        WindowsApi.DwmSetColorizationParameters(ref parameters, false);
                        AeroColorToggled = true;
                    }

                    bool ShadowToggled = false;
                    if (data.DisableShadow && ShadowEnabled())
                    {
                        WindowsApi.SystemParametersInfo(SPI_SETDROPSHADOW, 0, false, 0);
                        ShadowToggled = true;
                    }

                    var r = new WindowsRect(0);
                    if (data.DoResize)
                    {
                        SmartResizeWindow(ref data, out r);
                        Thread.Sleep(100);
                    }

                    int length = WindowsApi.GetWindowTextLength(data.WindowHandle);
                    var sb     = new StringBuilder(length + 1);
                    WindowsApi.GetWindowText(data.WindowHandle, sb, sb.Capacity);

                    string name = sb.ToString();

                    foreach (char inv in Path.GetInvalidFileNameChars())
                    {
                        name = name.Replace(inv.ToString(), string.Empty);
                    }

                    Bitmap s = CaptureCompositeScreenshot(ref data);

                    if (AeroColorToggled)
                    {
                        WindowsApi.DwmSetColorizationParameters(ref originalParameters, false);
                    }

                    if (ClearTypeToggled)
                    {
                        WindowsApi.SystemParametersInfo(SPI_SETFONTSMOOTHINGTYPE, 0, FE_FONTSMOOTHINGCLEARTYPE, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
                        WindowsApi.RedrawWindow(data.WindowHandle, IntPtr.Zero, IntPtr.Zero, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
                    }

                    if (ShadowToggled)
                    {
                        WindowsApi.SystemParametersInfo(SPI_SETDROPSHADOW, 0, true, 0);
                    }

                    // Show the taskbar again
                    if (data.WindowHandle != start &&
                        data.WindowHandle != taskbar)
                    {
                        WindowsApi.ShowWindow(start, 1);
                        WindowsApi.ShowWindow(taskbar, 1);
                    }

                    if (s == null)
                    {
                        MessageBox.Show("The screenshot taken was blank, it will not be saved.",
                                        "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                        if (data.ClipboardNotDisk && data.Background !=
                            ScreenshotTask.BackgroundType.Transparent)
                        {
                            // Screenshot is already opaque, don't need to modify it
                            Clipboard.SetImage(s);
                        }
                        else if (data.ClipboardNotDisk)
                        {
                            var whiteS = new Bitmap(s.Width, s.Height, PixelFormat.Format24bppRgb);
                            using (Graphics graphics = Graphics.FromImage(whiteS))
                            {
                                graphics.Clear(Color.White);
                                graphics.DrawImage(s, 0, 0, s.Width, s.Height);
                            }
                            using (var stream = new MemoryStream())
                            {
                                // Save screenshot in clipboard as PNG which some applications support (eg. Microsoft Office)
                                s.Save(stream, ImageFormat.Png);
                                var pngClipboardData = new DataObject("PNG", stream);

                                // Add fallback for applications that don't support PNG from clipboard (eg. Photoshop or Paint)
                                pngClipboardData.SetData(DataFormats.Bitmap, whiteS);
                                Clipboard.Clear();
                                Clipboard.SetDataObject(pngClipboardData, true);
                            }
                            whiteS.Dispose();
                        }
                        else
                        {
                            name = name.Trim();
                            if (name == string.Empty)
                            {
                                name = "AeroShot";
                            }
                            string path = Path.Combine(data.DiskSaveDirectory, name + ".png");

                            if (File.Exists(path))
                            {
                                for (int i = 1; i < 9999; i++)
                                {
                                    path = Path.Combine(data.DiskSaveDirectory, name + " " + i + ".png");
                                    if (!File.Exists(path))
                                    {
                                        break;
                                    }
                                }
                            }
                            s.Save(path, ImageFormat.Png);
                        }
                        s.Dispose();
                    }

                    if (data.DoResize)
                    {
                        if ((WindowsApi.GetWindowLong(data.WindowHandle, GWL_STYLE) & WS_SIZEBOX) == WS_SIZEBOX)
                        {
                            WindowsApi.SetWindowPos(data.WindowHandle, (IntPtr)0, r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top, SWP_SHOWWINDOW);
                        }
                    }
                }
                catch (Exception)
                {
                    if (data.WindowHandle != start && data.WindowHandle != taskbar)
                    {
                        WindowsApi.ShowWindow(start, 1);
                        WindowsApi.ShowWindow(taskbar, 1);
                    }
                    MessageBox.Show("An error occurred while trying to take a screenshot.\r\n\r\nPlease make sure you have selected a valid window.",
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("Invalid directory chosen.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }