public static Image VisualStyleRendererToImage(VisualStyleElement element, Rectangle bounds)
    {
        if (ToolStripManager.VisualStylesEnabled && VisualStyleRenderer.IsElementDefined(element))
        {
            VisualStyleRenderer renderer = new VisualStyleRenderer(element);

            using (Bitmap bit = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb))
            {
                NativeMethods.BITMAPINFO bmi = new NativeMethods.BITMAPINFO();

                bmi.biWidth         = bit.Width;
                bmi.biHeight        = bit.Height;
                bmi.biPlanes        = 1;
                bmi.biBitCount      = 32;
                bmi.biXPelsPerMeter = (int)bit.HorizontalResolution;
                bmi.biYPelsPerMeter = (int)bit.VerticalResolution;
                bmi.biSize          = Marshal.SizeOf(typeof(NativeMethods.BITMAPINFO));

                IntPtr bits;
                IntPtr bmp = NativeMethods.CreateDIBSection(IntPtr.Zero, ref bmi,
                                                            NativeMethods.DIB_RGB_COLORS, out bits, IntPtr.Zero, 0);

                IntPtr dc  = NativeMethods.GetDC(IntPtr.Zero);
                IntPtr hdc = NativeMethods.CreateCompatibleDC(dc);
                NativeMethods.SelectObject(hdc, bmp);

                using (Graphics g = Graphics.FromHdc(hdc))
                {
                    renderer.DrawBackground(g, bounds);
                }

                Bitmap image = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppPArgb);

                using (Bitmap tempImage = new Bitmap(bounds.Width, bounds.Height, bounds.Width * 4,
                                                     PixelFormat.Format32bppPArgb, bits))
                {
                    BitmapData tempBitmapData = tempImage.LockBits(bounds, ImageLockMode.ReadOnly,
                                                                   PixelFormat.Format32bppPArgb);
                    BitmapData bitmapData = image.LockBits(bounds, ImageLockMode.WriteOnly,
                                                           PixelFormat.Format32bppPArgb);

                    NativeMethods.CopyMemory(bitmapData.Scan0, tempBitmapData.Scan0,
                                             (uint)tempBitmapData.Stride * (uint)tempBitmapData.Height);

                    tempImage.UnlockBits(tempBitmapData);
                    image.UnlockBits(bitmapData);
                }

                NativeMethods.DeleteObject(bmp);
                NativeMethods.DeleteDC(hdc);
                NativeMethods.ReleaseDC(IntPtr.Zero, dc);

                return(image);
            }
        }
        else
        {
            return(new Bitmap(bounds.Width, bounds.Height));
        }
    }
Пример #2
0
        /// <summary>
        ///     Copies a bitmap into a 1bpp/8bpp bitmap of the same dimensions, fast
        /// </summary>
        /// <param name="b">original bitmap</param>
        /// <param name="bpp">1 or 8, target bpp</param>
        /// <returns>a 1bpp copy of the bitmap</returns>
        public static Image CopyToBpp(Bitmap b, int bpp)
        {
            if (bpp != 1 && bpp != 8)
            {
                throw new ArgumentException("1 or 8", nameof(bpp));
            }
            var w   = b.Width;
            var h   = b.Height;
            var hbm = b.GetHbitmap();
            var bmi = new NativeMethods.BITMAPINFO
            {
                biSize          = 40,
                biWidth         = w,
                biHeight        = h,
                biPlanes        = 1,
                biBitCount      = (short)bpp,
                biCompression   = NativeMethods.BI_RGB,
                biSizeBitmap    = (uint)(((w + 7) & 0xFFFFFFF8) * h / 8),
                biXPelsPerMeter = 1000000,
                biYPelsPerMeter = 1000000
            };
            var ncols = (uint)1 << bpp;

            bmi.biClrUsed      = ncols;
            bmi.biClrImportant = ncols;
            bmi.cols           = new uint[256];
            if (bpp == 1)
            {
                bmi.cols[0] = MAKERGB(0, 0, 0);
                bmi.cols[1] = MAKERGB(255, 255, 255);
            }
            else
            {
                for (var i = 0; i < ncols; i++)
                {
                    bmi.cols[i] = MAKERGB(i, i, i);
                }
            }
            var hbm0 = NativeMethods.CreateDIBSection(IntPtr.Zero, ref bmi, NativeMethods.DIB_RGB_COLORS, out var bits0,
                                                      IntPtr.Zero, 0);
            var sdc = NativeMethods.GetDC(IntPtr.Zero);
            var hdc = NativeMethods.CreateCompatibleDC(sdc);

            NativeMethods.SelectObject(hdc, hbm);
            var hdc0 = NativeMethods.CreateCompatibleDC(sdc);

            NativeMethods.SelectObject(hdc0, hbm0);
            NativeMethods.BitBlt(hdc0, 0, 0, w, h, hdc, 0, 0, NativeMethods.SRCCOPY);
            var b0 = Image.FromHbitmap(hbm0);

            NativeMethods.DeleteDC(hdc);
            NativeMethods.DeleteDC(hdc0);
            NativeMethods.ReleaseDC(IntPtr.Zero, sdc);
            NativeMethods.DeleteObject(hbm);
            NativeMethods.DeleteObject(hbm0);
            return(b0);
        }
Пример #3
0
 internal static NativeMethods.IconHandle CreateIconCursor(byte[] colorArray, int width, int height, int xHotspot, int yHotspot, bool isIcon)
 {
     NativeMethods.BitmapHandle bitmapHandle  = null;
     NativeMethods.BitmapHandle bitmapHandle2 = null;
     NativeMethods.IconHandle   result;
     try
     {
         NativeMethods.BITMAPINFO bitmapinfo = new NativeMethods.BITMAPINFO(width, -height, 32);
         bitmapinfo.bmiHeader_biCompression = 0;
         IntPtr zero = IntPtr.Zero;
         bitmapHandle = UnsafeNativeMethods.CreateDIBSection(new HandleRef(null, IntPtr.Zero), ref bitmapinfo, 0, ref zero, null, 0);
         if (bitmapHandle.IsInvalid || zero == IntPtr.Zero)
         {
             result = NativeMethods.IconHandle.GetInvalidIcon();
         }
         else
         {
             Marshal.Copy(colorArray, 0, zero, colorArray.Length);
             byte[] array = IconHelper.GenerateMaskArray(width, height, colorArray);
             Invariant.Assert(array != null);
             bitmapHandle2 = UnsafeNativeMethods.CreateBitmap(width, height, 1, 1, array);
             if (bitmapHandle2.IsInvalid)
             {
                 result = NativeMethods.IconHandle.GetInvalidIcon();
             }
             else
             {
                 result = UnsafeNativeMethods.CreateIconIndirect(new NativeMethods.ICONINFO
                 {
                     fIcon    = isIcon,
                     xHotspot = xHotspot,
                     yHotspot = yHotspot,
                     hbmMask  = bitmapHandle2,
                     hbmColor = bitmapHandle
                 });
             }
         }
     }
     finally
     {
         if (bitmapHandle != null)
         {
             bitmapHandle.Dispose();
             bitmapHandle = null;
         }
         if (bitmapHandle2 != null)
         {
             bitmapHandle2.Dispose();
             bitmapHandle2 = null;
         }
     }
     return(result);
 }
Пример #4
0
        public static Graphics CreateGdiGraphics(this IpcImage ipcImage, Bitmap bitmap)
        {
            var bitmapInfo = new NativeMethods.BITMAPINFO {
                biWidth       = ipcImage.Width,
                biHeight      = ipcImage.Height,
                biBitCount    = (short)ipcImage.BitsPerPixel,
                biPlanes      = 1,
                biCompression = ipcImage.IpcPixelFormat.ToGdiBiFormat()
            };

            bitmapInfo.biSize = Marshal.SizeOf(bitmapInfo);
            return(Graphics.FromImage(bitmap));
        }
Пример #5
0
        public static void DrawTextOnGlass(Graphics graphics, string text, Font font, Rectangle bounds, Color color, TextFormatFlags flags, int rflags)
        {
            IntPtr primaryHdc = graphics.GetHdc();

            IntPtr memoryHdc = NativeMethods.CreateCompatibleDC(new HandleRef(null, primaryHdc));

            NativeMethods.BITMAPINFO info = new NativeMethods.BITMAPINFO();
            info.bmiHeader_biSize        = Marshal.SizeOf(info);
            info.bmiHeader_biWidth       = bounds.Width;
            info.bmiHeader_biHeight      = -bounds.Height;
            info.bmiHeader_biPlanes      = 1;
            info.bmiHeader_biBitCount    = 32;
            info.bmiHeader_biCompression = 0;

            IntPtr ppbBits = IntPtr.Zero;

            IntPtr dib = NativeMethods.CreateDIBSection(primaryHdc, info, (uint)0, out ppbBits, IntPtr.Zero, (uint)0);

            NativeMethods.SelectObject(new HandleRef(null, memoryHdc), new HandleRef(null, dib));


            IntPtr fontHandle = font.ToHfont();

            NativeMethods.SelectObject(new HandleRef(null, memoryHdc), new HandleRef(null, fontHandle));


            System.Windows.Forms.VisualStyles.VisualStyleRenderer renderer = new System.Windows.Forms.VisualStyles.VisualStyleRenderer(System.Windows.Forms.VisualStyles.VisualStyleElement.Window.Caption.Active);
            DWMAPI.DTTOPTS dttOpts = new DWMAPI.DTTOPTS();
            dttOpts.dwSize    = Marshal.SizeOf(typeof(DWMAPI.DTTOPTS));
            dttOpts.dwFlags   = DWMAPI.DTT_COMPOSITED | rflags | DWMAPI.DTT_TEXTCOLOR;
            dttOpts.crText    = ColorTranslator.ToWin32(color);
            dttOpts.iGlowSize = 10;
            NativeMethods.RECT textBounds = new NativeMethods.RECT(0, 0, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
            UXTheme.DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, -1, (int)flags, ref textBounds, ref dttOpts);

            const int SRCCOPY = 0x00CC0020;

            NativeMethods.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);


            NativeMethods.DeleteObject(new HandleRef(null, fontHandle));
            NativeMethods.DeleteObject(new HandleRef(null, dib));
            NativeMethods.DeleteDC(new HandleRef(null, memoryHdc));

            graphics.ReleaseHdc(primaryHdc);
        }
Пример #6
0
        public DiBitmap(Size size, PixelFormat pixelFormat = PixelFormat.Format32bppArgb)
        {
            Size        = size;
            PixelFormat = pixelFormat;

            var binfo = new NativeMethods.BITMAPINFO
            {
                bmiHeader =
                {
                    biSize        = Marshal.SizeOf(typeof(NativeMethods.BITMAPINFOHEADER)),
                    biWidth       = Size.Width,
                    biHeight      = Size.Height,
                    biBitCount    = (short)Image.GetPixelFormatSize(PixelFormat),
                    biPlanes      =                                                      1,
                    biCompression = 0
                }
            };

            //var screenDc = Native.GetDC(IntPtr.Zero);
            //var memDc = Native.CreateCompatibleDC(IntPtr.Zero);
            //if (memDc == IntPtr.Zero) throw new ApplicationException("初始化失败:创建MemDc失败(" + Native.GetLastError() + ")");

            _memDc = NativeMethods.CreateCompatibleDC(IntPtr.Zero);
            if (_memDc == IntPtr.Zero)
            {
                throw new ApplicationException("CreateCompatibleDC(IntPtr.Zero)fail(" + Marshal.GetLastWin32Error() + ")");
            }

            IntPtr ptrBits;

            HBitmap = NativeMethods.CreateDIBSection(_memDc, ref binfo, 0, out ptrBits, IntPtr.Zero, 0);

            //HBitmap = Native.CreateCompatibleBitmap(MemDc, size.Width, size.Height);
            if (HBitmap == IntPtr.Zero)
            {
                throw new ApplicationException("Initialization failure:CreateDIBSection(...)fail(" + Marshal.GetLastWin32Error() + ")");
            }

            _oldObject = NativeMethods.SelectObject(_memDc, HBitmap);
            _graphics  = Graphics.FromHdc(_memDc);
            _graphics.CompositingQuality = CompositingQuality.HighSpeed;
            _graphics.SmoothingMode      = SmoothingMode.AntiAlias;
            NativeMethods.SelectObject(_memDc, _oldObject);
        }
Пример #7
0
        public static void DrawTextOnGlass(
            Graphics graphics,
            string text,
            Font font,
            Rectangle bounds,
            Color color,
            TextFormatFlags flags,
            int rflags)
        {
            IntPtr hdc          = graphics.GetHdc();
            IntPtr compatibleDc = NativeMethods.CreateCompatibleDC(new HandleRef((object)null, hdc));

            NativeMethods.BITMAPINFO pbmi = new NativeMethods.BITMAPINFO();
            pbmi.bmiHeader_biSize        = Marshal.SizeOf((object)pbmi);
            pbmi.bmiHeader_biWidth       = bounds.Width;
            pbmi.bmiHeader_biHeight      = -bounds.Height;
            pbmi.bmiHeader_biPlanes      = (short)1;
            pbmi.bmiHeader_biBitCount    = (short)32;
            pbmi.bmiHeader_biCompression = 0;
            IntPtr ppvBits    = IntPtr.Zero;
            IntPtr dibSection = NativeMethods.CreateDIBSection(hdc, pbmi, 0U, out ppvBits, IntPtr.Zero, 0U);

            NativeMethods.SelectObject(new HandleRef((object)null, compatibleDc), new HandleRef((object)null, dibSection));
            IntPtr hfont = font.ToHfont();

            NativeMethods.SelectObject(new HandleRef((object)null, compatibleDc), new HandleRef((object)null, hfont));
            VisualStyleRenderer visualStyleRenderer = new VisualStyleRenderer(VisualStyleElement.Window.Caption.Active);

            DWMAPI.DTTOPTS pOptions = new DWMAPI.DTTOPTS();
            pOptions.dwSize    = Marshal.SizeOf(typeof(DWMAPI.DTTOPTS));
            pOptions.dwFlags   = 8192 | rflags | 1;
            pOptions.crText    = ColorTranslator.ToWin32(color);
            pOptions.iGlowSize = 10;
            NativeMethods.RECT pRect = new NativeMethods.RECT(0, 0, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
            UXTheme.DrawThemeTextEx(visualStyleRenderer.Handle, compatibleDc, 0, 0, text, -1, (int)flags, ref pRect, ref pOptions);
            NativeMethods.BitBlt(hdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, compatibleDc, 0, 0, 13369376);
            NativeMethods.DeleteObject(new HandleRef((object)null, hfont));
            NativeMethods.DeleteObject(new HandleRef((object)null, dibSection));
            NativeMethods.DeleteDC(new HandleRef((object)null, compatibleDc));
            graphics.ReleaseHdc(hdc);
        }
        /*public static void DrawGlowingText(this VisualStyleRenderer rnd, IDeviceContext dc, Rectangle bounds, string text, Font font, Color color, System.Windows.Forms.TextFormatFlags flags)
         * {
         *      using (SafeGDIHandle primaryHdc = new SafeGDIHandle(dc))
         *      {
         *              // Create a memory DC so we can work offscreen
         *              using (SafeCompatibleDCHandle memoryHdc = new SafeCompatibleDCHandle(primaryHdc))
         *              {
         *                      // Create a device-independent bitmap and select it into our DC
         *                      BITMAPINFO info = new BITMAPINFO(bounds.Width, -bounds.Height);
         *                      using (SafeDCObjectHandle dib = new SafeDCObjectHandle(memoryHdc, GDI.CreateDIBSection(primaryHdc, ref info, 0, 0, IntPtr.Zero, 0)))
         *                      {
         *                              // Create and select font
         *                              using (SafeDCObjectHandle fontHandle = new SafeDCObjectHandle(memoryHdc, font.ToHfont()))
         *                              {
         *                                      // Draw glowing text
         *                                      DrawThemeTextOptions dttOpts = new DrawThemeTextOptions(true);
         *                                      dttOpts.TextColor = color;
         *                                      dttOpts.GlowSize = 10;
         *                                      dttOpts.AntiAliasedAlpha = true;
         *                                      NativeMethods.RECT textBounds = new NativeMethods.RECT(4, 0, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
         *                                      DrawThemeTextEx(rnd.Handle, memoryHdc, rnd.Part, rnd.State, text, text.Length, (int)flags, ref textBounds, ref dttOpts);
         *
         *                                      // Copy to foreground
         *                                      const int SRCCOPY = 0x00CC0020;
         *                                      GDI.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);
         *                              }
         *                      }
         *              }
         *      }
         * }*/

        private static void DrawWrapper(VisualStyleRenderer rnd, IDeviceContext dc, Rectangle bounds, DrawWrapperMethod func)
        {
            using (SafeGDIHandle primaryHdc = new SafeGDIHandle(dc))
            {
                // Create a memory DC so we can work offscreen
                using (NativeMethods.SafeCompatibleDCHandle memoryHdc = new NativeMethods.SafeCompatibleDCHandle(primaryHdc))
                {
                    // Create a device-independent bitmap and select it into our DC
                    NativeMethods.BITMAPINFO info = new NativeMethods.BITMAPINFO(bounds.Width, -bounds.Height);
                    using (NativeMethods.SafeDCObjectHandle dib = new NativeMethods.SafeDCObjectHandle(memoryHdc, NativeMethods.CreateDIBSection(primaryHdc, ref info, 0, IntPtr.Zero, IntPtr.Zero, 0)))
                    {
                        // Call method
                        func(memoryHdc);

                        // Copy to foreground
                        const int SRCCOPY = 0x00CC0020;
                        NativeMethods.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);
                    }
                }
            }
        }
Пример #9
0
        // Also used by PenCursorManager
        // Creates a 32 bit per pixel Icon or cursor.  This code is moved from framework\ms\internal\ink\pencursormanager.cs
        internal static NativeMethods.IconHandle CreateIconCursor(
            byte[] colorArray,
            int width,
            int height,
            int xHotspot,
            int yHotspot,
            bool isIcon)
        {
            //   1. We are going to generate a WIN32 color bitmap which represents the color cursor.
            //   2. Then we need to create a monochrome bitmap which is used as the cursor mask.
            //   3. At last we create a WIN32 HICON from the above two bitmaps
            NativeMethods.BitmapHandle colorBitmap = null;
            NativeMethods.BitmapHandle maskBitmap  = null;

            try
            {
                // 1) Create the color bitmap using colorArray
                // Fill in the header information
                NativeMethods.BITMAPINFO bi = new NativeMethods.BITMAPINFO(
                    width,                                      // width
                    -height,                                    // A negative value indicates the bitmap is top-down DIB
                    32                                          // biBitCount
                    );
                bi.bmiHeader_biCompression = NativeMethods.BI_RGB;

                IntPtr bits = IntPtr.Zero;
                colorBitmap = MS.Win32.UnsafeNativeMethods.CreateDIBSection(
                    new HandleRef(null, IntPtr.Zero),                // A device context. Pass null in if no DIB_PAL_COLORS is used.
                    ref bi,                                          // A BITMAPINFO structure which specifies the dimensions and colors.
                    NativeMethods.DIB_RGB_COLORS,                    // Specifies the type of data contained in the bmiColors array member of the BITMAPINFO structure
                    ref bits,                                        // An out Pointer to a variable that receives a pointer to the location of the DIB bit values
                    null,                                            // Handle to a file-mapping object that the function will use to create the DIB. This parameter can be null.
                    0                                                // dwOffset. This value is ignored if hSection is NULL
                    );

                if (colorBitmap.IsInvalid || bits == IntPtr.Zero)
                {
                    // Note we will release the GDI resources in the finally block.
                    return(NativeMethods.IconHandle.GetInvalidIcon());
                }

                // Copy the color bits to the win32 bitmap
                Marshal.Copy(colorArray, 0, bits, colorArray.Length);


                // 2) Now create the mask bitmap which is monochrome
                byte[] maskArray = GenerateMaskArray(width, height, colorArray);
                Invariant.Assert(maskArray != null);

                maskBitmap = UnsafeNativeMethods.CreateBitmap(width, height, 1, 1, maskArray);
                if (maskBitmap.IsInvalid)
                {
                    // Note we will release the GDI resources in the finally block.
                    return(NativeMethods.IconHandle.GetInvalidIcon());
                }

                // Now create HICON from two bitmaps.
                NativeMethods.ICONINFO iconInfo = new NativeMethods.ICONINFO();
                iconInfo.fIcon    = isIcon;         // fIcon == ture means creating an Icon, otherwise Cursor
                iconInfo.xHotspot = xHotspot;
                iconInfo.yHotspot = yHotspot;
                iconInfo.hbmMask  = maskBitmap;
                iconInfo.hbmColor = colorBitmap;

                return(UnsafeNativeMethods.CreateIconIndirect(iconInfo));
            }
            finally
            {
                if (colorBitmap != null)
                {
                    colorBitmap.Dispose();
                    colorBitmap = null;
                }

                if (maskBitmap != null)
                {
                    maskBitmap.Dispose();
                    maskBitmap = null;
                }
            }
        }
        /*public static void DrawGlowingText(this VisualStyleRenderer rnd, IDeviceContext dc, Rectangle bounds, string text, Font font, Color color, System.Windows.Forms.TextFormatFlags flags)
        {
            using (SafeGDIHandle primaryHdc = new SafeGDIHandle(dc))
            {
                // Create a memory DC so we can work offscreen
                using (SafeCompatibleDCHandle memoryHdc = new SafeCompatibleDCHandle(primaryHdc))
                {
                    // Create a device-independent bitmap and select it into our DC
                    BITMAPINFO info = new BITMAPINFO(bounds.Width, -bounds.Height);
                    using (SafeDCObjectHandle dib = new SafeDCObjectHandle(memoryHdc, GDI.CreateDIBSection(primaryHdc, ref info, 0, 0, IntPtr.Zero, 0)))
                    {
                        // Create and select font
                        using (SafeDCObjectHandle fontHandle = new SafeDCObjectHandle(memoryHdc, font.ToHfont()))
                        {
                            // Draw glowing text
                            DrawThemeTextOptions dttOpts = new DrawThemeTextOptions(true);
                            dttOpts.TextColor = color;
                            dttOpts.GlowSize = 10;
                            dttOpts.AntiAliasedAlpha = true;
                            NativeMethods.RECT textBounds = new NativeMethods.RECT(4, 0, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
                            DrawThemeTextEx(rnd.Handle, memoryHdc, rnd.Part, rnd.State, text, text.Length, (int)flags, ref textBounds, ref dttOpts);

                            // Copy to foreground
                            const int SRCCOPY = 0x00CC0020;
                            GDI.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);
                        }
                    }
                }
            }
        }*/
        private static void DrawWrapper(VisualStyleRenderer rnd, IDeviceContext dc, Rectangle bounds, DrawWrapperMethod func)
        {
            using (SafeGDIHandle primaryHdc = new SafeGDIHandle(dc))
            {
                // Create a memory DC so we can work offscreen
                using (NativeMethods.SafeCompatibleDCHandle memoryHdc = new NativeMethods.SafeCompatibleDCHandle(primaryHdc))
                {
                    // Create a device-independent bitmap and select it into our DC
                    NativeMethods.BITMAPINFO info = new NativeMethods.BITMAPINFO(bounds.Width, -bounds.Height);
                    using (NativeMethods.SafeDCObjectHandle dib = new NativeMethods.SafeDCObjectHandle(memoryHdc, NativeMethods.CreateDIBSection(primaryHdc, ref info, 0, IntPtr.Zero, IntPtr.Zero, 0)))
                    {
                        // Call method
                        func(memoryHdc);

                        // Copy to foreground
                        const int SRCCOPY = 0x00CC0020;
                        NativeMethods.BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY);
                    }
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Attempts to capture a screenshot of the current desktop.
        /// </summary>
        /// <returns></returns>
        private Screenshot CaptureScreenshot(int x, int y, int width, int height)
        {
            BasicEventTimer bet = new BasicEventTimer("0.000");

            bet.Start("Setup");
            if (!CreateCaptureHandleIfNecessary())
            {
                return(null);
            }

            NativeMethods.BITMAPINFO bmpInfo = new NativeMethods.BITMAPINFO();
            using (AutoDisposeHandle bmp = AutoDisposeHandle.Create(NativeMethods.CreateCompatibleBitmap(deviceContext, 1, 1), h => NativeMethods.DeleteObject(h)))
            {
                bmpInfo.bmiHeader.biSize = Marshal.SizeOf(typeof(NativeMethods.BITMAPINFOHEADER));
                if (0 == NativeMethods.GetDIBits(deviceContext, bmp, 0, 1, null, ref bmpInfo, NativeMethods.DIB_Color_Mode.DIB_RGB_COLORS))
                {
                    Win32Helper.ThrowLastWin32Error();
                }
                bmpInfo.bmiHeader.biSize = Marshal.SizeOf(typeof(NativeMethods.BITMAPINFO));
                if (0 == NativeMethods.GetDIBits(deviceContext, bmp, 0, 1, null, ref bmpInfo, NativeMethods.DIB_Color_Mode.DIB_RGB_COLORS))
                {
                    Win32Helper.ThrowLastWin32Error();
                }
            }
            bmpInfo.bmiHeader.biWidth     = width;
            bmpInfo.bmiHeader.biHeight    = -height;
            bmpInfo.bmiHeader.biSizeImage = 0;

            // Create memory device context.  When done, delete it.
            using (AutoDisposeHandle dc = AutoDisposeHandle.Create(NativeMethods.CreateCompatibleDC(IntPtr.Zero), h => NativeMethods.DeleteDC(h)))
            {
                if (dc == null)
                {
                    Win32Helper.ThrowLastWin32Error("Failed to create memory device context");
                }

                // Create "DIB Section" (a Bitmap, more or less).  When done, delete it.
                IntPtr ppvBits = new IntPtr();
                using (AutoDisposeHandle newDib = AutoDisposeHandle.Create(NativeMethods.CreateDIBSection(dc, ref bmpInfo, 0U, out ppvBits, IntPtr.Zero, 0U), h => NativeMethods.DeleteObject(h)))
                //using (AutoDisposeHandle newDib = AutoDisposeHandle.Create(NativeMethods.CreateCompatibleBitmap(deviceContext, width, height), h => NativeMethods.DeleteObject(h)))
                {
                    if (newDib == null)
                    {
                        Win32Helper.ThrowLastWin32Error("Failed to create DIB Section");
                    }

                    // Assign new DIB Section to our memory device context.  When done, put back the old DIB Section.
                    using (AutoDisposeHandle oldDib = AutoDisposeHandle.Create(NativeMethods.SelectObject(dc, newDib), h => NativeMethods.SelectObject(dc, h)))
                    {
                        if (oldDib == null)
                        {
                            Win32Helper.ThrowLastWin32Error("Failed to assign new DIB Section to memory device context");
                        }
                        bet.Start("BitBlt");

                        // Copy data from the screen to our memory device context
                        if (!NativeMethods.BitBlt(dc, 0, 0, width, height, deviceContext, x, y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
                        {
                            Logger.Debug("BitBlt failed with error code: " + Win32Helper.GetLastWin32Error());
                            ClearCaptureHandle();
                            DesktopManager.ShouldReassociate = true;
                        }
                        else
                        {
                            bet.Start("new Screenshot/Copy bits");
                            Screenshot screenshot = new Screenshot(width, height, bmpInfo.bmiHeader.biBitCount);
                            Marshal.Copy(ppvBits, screenshot.Buffer, 0, screenshot.Buffer.Length);
                            bet.Stop();
                            //Logger.Info(bet.ToString(Environment.NewLine));
                            return(screenshot);
                        }
                    }
                }
            }
            return(null);
        }