コード例 #1
0
        static unsafe Bitmap _Capture(RECT r, AWnd w = default, bool usePrintWindow = false, GraphicsPath path = null)
        {
            //Transfer from screen/window DC to memory DC (does not work without this) and get pixels.

            //rejected: parameter includeNonClient (GetWindowDC).
            //	Nothing good. If in background, captures incorrect caption etc.
            //	If need nonclient part, better activate window and capture window rectangle from screen.

            //FUTURE: if w is DWM-scaled...

            using var mb = new AMemoryBitmap(r.Width, r.Height);
            if (usePrintWindow && Api.PrintWindow(w, mb.Hdc, Api.PW_CLIENTONLY | (AVersion.MinWin8_1 ? Api.PW_RENDERFULLCONTENT : 0)))
            {
                //AOutput.Write("PrintWindow OK");
            }
            else
            {
                using (var dc = new WindowDC_(w)) {
                    if (dc.Is0)
                    {
                        w.ThrowNoNative("Failed");
                    }
                    uint rop = !w.Is0 ? Api.SRCCOPY : Api.SRCCOPY | Api.CAPTUREBLT;
                    bool ok  = Api.BitBlt(mb.Hdc, 0, 0, r.Width, r.Height, dc, r.left, r.top, rop);
                    Debug.Assert(ok);                     //the API fails only if a HDC is invalid
                }
            }

            var R = new Bitmap(r.Width, r.Height, PixelFormat.Format32bppRgb);

            try {
                var bh = new Api.BITMAPINFOHEADER()
                {
                    biSize   = sizeof(Api.BITMAPINFOHEADER),
                    biWidth  = r.Width, biHeight = -r.Height,                    //use -height for top-down
                    biPlanes = 1, biBitCount = 32,
                    //biCompression = 0, //BI_RGB
                };
                var d = R.LockBits(new Rectangle(0, 0, r.Width, r.Height), ImageLockMode.ReadWrite, R.PixelFormat);             //tested: fast, no copy
                try {
                    var apiResult = Api.GetDIBits(mb.Hdc, mb.Hbitmap, 0, r.Height, (void *)d.Scan0, &bh, 0);                    //DIB_RGB_COLORS
                    if (apiResult != r.Height)
                    {
                        throw new AuException("GetDIBits");
                    }
                    _SetAlpha(d, r, path);
                }
                finally { R.UnlockBits(d); }                 //tested: fast, no copy
                return(R);
            }
            catch { R.Dispose(); throw; }
        }
コード例 #2
0
        /// <summary>
        /// Creates Bitmap from a GDI bitmap.
        /// </summary>
        /// <param name="hbitmap">GDI bitmap handle. This function makes its copy.</param>
        /// <remarks>
        /// How this function is different from <see cref="Image.FromHbitmap"/>:
        /// 1. Image.FromHbitmap usually creates bottom-up bitmap, which is incompatible with <see cref="Find"/>. This function creates normal top-down bitmap, like <c>new Bitmap(...)</c>, <c>Bitmap.FromFile(...)</c> etc do.
        /// 2. This function always creates bitmap of PixelFormat Format32bppRgb.
        /// </remarks>
        /// <exception cref="AuException">Failed. For example hbitmap is default(IntPtr).</exception>
        /// <exception cref="Exception">Exceptions of Bitmap(int, int, PixelFormat) constructor.</exception>
        public static unsafe Bitmap BitmapFromHbitmap(IntPtr hbitmap)
        {
            var bh = new Api.BITMAPINFOHEADER()
            {
                biSize = sizeof(Api.BITMAPINFOHEADER)
            };

            using (var dcs = new ScreenDC_(0)) {
                if (0 == Api.GetDIBits(dcs, hbitmap, 0, 0, null, &bh, 0))
                {
                    goto ge;
                }
                int wid = bh.biWidth, hei = bh.biHeight;
                if (hei > 0)
                {
                    bh.biHeight = -bh.biHeight;
                }
                else
                {
                    hei = -hei;
                }
                bh.biBitCount = 32;

                var  R  = new Bitmap(wid, hei, PixelFormat.Format32bppRgb);
                var  d  = R.LockBits(new Rectangle(0, 0, wid, hei), ImageLockMode.ReadWrite, R.PixelFormat);
                bool ok = hei == Api.GetDIBits(dcs, hbitmap, 0, hei, (void *)d.Scan0, &bh, 0);
                R.UnlockBits(d);
                if (!ok)
                {
                    R.Dispose(); goto ge;
                }
                return(R);
            }
ge:
            throw new AuException();
        }