#region License Information (GPL v3) /* ShareX - A program that allows you to take screenshots and share any file type Copyright (c) 2007-2023 ShareX Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Optionally you can also view the license at . */ #endregion License Information (GPL v3) using ShareX.HelpersLib; using System; using System.Drawing; using System.Drawing.Imaging; namespace ShareX.ScreenCaptureLib { public partial class Screenshot { public bool CaptureCursor { get; set; } = false; public bool CaptureClientArea { get; set; } = false; public bool RemoveOutsideScreenArea { get; set; } = true; public bool CaptureShadow { get; set; } = false; public int ShadowOffset { get; set; } = 20; public bool AutoHideTaskbar { get; set; } = false; public Bitmap CaptureRectangle(Rectangle rect) { if (RemoveOutsideScreenArea) { Rectangle bounds = CaptureHelpers.GetScreenBounds(); rect = Rectangle.Intersect(bounds, rect); } return CaptureRectangleNative(rect, CaptureCursor); } public Bitmap CaptureFullscreen() { Rectangle bounds = CaptureHelpers.GetScreenBounds(); return CaptureRectangle(bounds); } public Bitmap CaptureWindow(IntPtr handle) { if (handle.ToInt32() > 0) { Rectangle rect; if (CaptureClientArea) { rect = NativeMethods.GetClientRect(handle); } else { rect = CaptureHelpers.GetWindowRectangle(handle); } bool isTaskbarHide = false; try { if (AutoHideTaskbar) { isTaskbarHide = NativeMethods.SetTaskbarVisibilityIfIntersect(false, rect); } return CaptureRectangle(rect); } finally { if (isTaskbarHide) { NativeMethods.SetTaskbarVisibility(true); } } } return null; } public Bitmap CaptureActiveWindow() { IntPtr handle = NativeMethods.GetForegroundWindow(); return CaptureWindow(handle); } public Bitmap CaptureActiveMonitor() { Rectangle bounds = CaptureHelpers.GetActiveScreenBounds(); return CaptureRectangle(bounds); } private Bitmap CaptureRectangleNative(Rectangle rect, bool captureCursor = false) { IntPtr handle = NativeMethods.GetDesktopWindow(); return CaptureRectangleNative(handle, rect, captureCursor); } private Bitmap CaptureRectangleNative(IntPtr handle, Rectangle rect, bool captureCursor = false) { if (rect.Width == 0 || rect.Height == 0) { return null; } IntPtr hdcSrc = NativeMethods.GetWindowDC(handle); IntPtr hdcDest = NativeMethods.CreateCompatibleDC(hdcSrc); IntPtr hBitmap = NativeMethods.CreateCompatibleBitmap(hdcSrc, rect.Width, rect.Height); IntPtr hOld = NativeMethods.SelectObject(hdcDest, hBitmap); NativeMethods.BitBlt(hdcDest, 0, 0, rect.Width, rect.Height, hdcSrc, rect.X, rect.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); if (captureCursor) { try { CursorData cursorData = new CursorData(); cursorData.DrawCursor(hdcDest, rect.Location); } catch (Exception e) { DebugHelper.WriteException(e, "Cursor capture failed."); } } NativeMethods.SelectObject(hdcDest, hOld); NativeMethods.DeleteDC(hdcDest); NativeMethods.ReleaseDC(handle, hdcSrc); Bitmap bmp = Image.FromHbitmap(hBitmap); NativeMethods.DeleteObject(hBitmap); return bmp; } private Bitmap CaptureRectangleManaged(Rectangle rect) { if (rect.Width == 0 || rect.Height == 0) { return null; } Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format24bppRgb); using (Graphics g = Graphics.FromImage(bmp)) { // Managed can't use SourceCopy | CaptureBlt because of .NET bug g.CopyFromScreen(rect.Location, Point.Empty, rect.Size, CopyPixelOperation.SourceCopy); } return bmp; } } }