Example #1
0
        void _WmNcpaint()
        {
            using var dc = new WindowDC_(Api.GetWindowDC(_w), _w);
            RECT r = new(0, 0, _size.window.width, _size.window.height);

            for (int i = 0; i < _size.border; i++)
            {
                Api.FrameRect(dc, r, Api.GetSysColorBrush(i == 0 ? Api.COLOR_BTNSHADOW : Api.COLOR_BTNFACE));
                r.Inflate(-1, -1);
            }
        }
Example #2
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; }
        }
Example #3
0
 static void _CaptureToDC(MemoryBitmap mb, RECT r, wnd w = default, bool printWindow = false)
 {
     if (printWindow)
     {
         if (!Api.PrintWindow(w, mb.Hdc, Api.PW_CLIENTONLY | (osVersion.minWin8_1 ? Api.PW_RENDERFULLCONTENT : 0)))
         {
             w.ThrowNoNative("Failed to get pixels");
         }
     }
     else
     {
         using var dc = new WindowDC_(w);
         if (dc.Is0)
         {
             w.ThrowNoNative("Failed to get pixels");
         }
         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
     }
 }
Example #4
0
            void _WmMousemove(POINT pc)
            {
                if (!_paintedOnce)
                {
                    return;
                }

                //format text to draw below magnifier
                string text;

                using (new StringBuilder_(out var s)) {
                    var ic = _flags & (ICFlags.Image | ICFlags.Color | ICFlags.Rectangle);
                    if (ic == 0)
                    {
                        ic = ICFlags.Image | ICFlags.Color;
                    }
                    bool canColor = ic.Has(ICFlags.Color);
                    if (canColor)
                    {
                        var color = _img.GetPixel(pc.x, pc.y).ToArgb() & 0xffffff;
                        s.Append("Color  #").Append(color.ToString("X6")).Append('\n');
                    }
                    if (ic == ICFlags.Color)
                    {
                        s.Append("Click to capture color.\n");
                    }
                    else if (ic == ICFlags.Rectangle)
                    {
                        s.Append("Mouse-drag to capture rectangle.\n");
                    }
                    else if (!canColor)
                    {
                        s.Append("Mouse-drag to capture image.\n");
                    }
                    else
                    {
                        s.Append("Mouse-drag to capture image,\nor Ctrl+click to capture color.\n");
                    }
                    s.Append("More:  right-click");                     //"  cancel:  key Esc\n  retry:  key F3 ... F3"
                    text = s.ToString();
                }

                var font   = NativeFont_.RegularCached(_dpi);
                int magnWH = Dpi.Scale(200, _dpi) / 10 * 10;                 //width and height of the magnified image without borders etc

                if (_textSize == default)
                {
                    using (var tr = new FontDC_(font)) _textSize = tr.MeasureDT(text, TFFlags.NOPREFIX);
                }
                int width = Math.Max(magnWH, _textSize.width) + 2, height = magnWH + 4 + _textSize.height;

                using var mb = new MemoryBitmap(width, height);
                var dc = mb.Hdc;

                using var wdc = new WindowDC_(_w);

                //draw frames and color background. Also erase magnifier, need when near screen edges.
                Api.FillRect(dc, (0, 0, width, height), Api.GetStockObject(4));                 //BLACK_BRUSH

                //copy from captured screen image to magnifier image. Magnify 5 times.
                int k = magnWH / 10;

                Api.StretchBlt(dc, 1, 1, magnWH, magnWH, wdc, pc.x - k, pc.y - k, k * 2, k * 2, Api.SRCCOPY);

                //draw red crosshair
                k = magnWH / 2;
                using (var pen = new Pen_(0xff)) {
                    pen.DrawLine(dc, (k, 1), (k, magnWH + 1));
                    pen.DrawLine(dc, (1, k), (magnWH + 1, k));
                }

                //draw text below magnifier
                var rc = new RECT(1, magnWH + 2, _textSize.width, _textSize.height);

                Api.SetTextColor(dc, 0x32CD9A);                 //Color.YellowGreen
                Api.SetBkMode(dc, 1);
                var oldFont = Api.SelectObject(dc, font);

                Api.DrawText(dc, text, ref rc, TFFlags.NOPREFIX);
                Api.SelectObject(dc, oldFont);

                //set magninifier position far from cursor
                var pm    = new POINT(4, 4); _w.MapScreenToClient(ref pm);
                int xMove = magnWH * 3;

                if (_magnMoved)
                {
                    pm.Offset(xMove, 0);
                }
                var rm = new RECT(pm.x, pm.y, width, height); rm.Inflate(magnWH / 2, magnWH / 2);

                if (rm.Contains(pc))
                {
                    Api.InvalidateRect(_w, (pm.x, pm.y, width, height));
                    _magnMoved ^= true;
                    pm.Offset(_magnMoved ? xMove : -xMove, 0);
                }

                Api.BitBlt(wdc, pm.x, pm.y, width, height, dc, 0, 0, Api.SRCCOPY);
            }