void _WmLbuttondown(POINT p0) { bool isColor = false; //bool isAnyShape = false; //rejected. Not useful. var ic = _flags & (ICFlags.Image | ICFlags.Color | ICFlags.Rectangle); if (ic == ICFlags.Color) { isColor = true; } else { var mod = keys.gui.getMod(); if (mod != 0 && ic == ICFlags.Rectangle) { return; } switch (mod) { case 0: break; //case KMod.Shift: isAnyShape = true; break; case KMod.Ctrl when ic == 0: isColor = true; break; default: return; } } Result = new ICResult(); var r = new RECT(p0.x, p0.y, 0, 0); if (isColor) { Result.color = (uint)_img.GetPixel(p0.x, p0.y).ToArgb(); r.right++; r.bottom++; } else { //var a = isAnyShape ? new List<POINT>() { p0 } : null; var pen = Pens.Red; bool notFirstMove = false; _capturing = true; try { if (!WndUtil.DragLoop(_w, MButtons.Left, m => { if (m.msg.message != Api.WM_MOUSEMOVE) { return; } POINT p = m.msg.pt; _w.MapScreenToClient(ref p); using var g = Graphics.FromHwnd(_w.Handle); //if (isAnyShape) { // a.Add(p); // g.DrawLine(pen, p0, p); // p0 = p; //} else { if (notFirstMove) //erase prev rect { r.right++; r.bottom++; g.DrawImage(_img, r, r, GraphicsUnit.Pixel); //FUTURE: prevent flickering. Also don't draw under magnifier. } else { notFirstMove = true; } r = RECT.FromLTRB(p0.x, p0.y, p.x, p.y); r.Normalize(true); g.DrawRectangle(pen, r); //} })) //Esc key etc { Api.InvalidateRect(_w); return; } } finally { _capturing = false; } //GraphicsPath path = null; //if (isAnyShape && a.Count > 1) { // path = _CreatePath(a); // r = RECT.From(path.GetBounds(), false); //} else { r.right++; r.bottom++; //} if (r.NoArea) { Api.DestroyWindow(_w); return; } if (ic != ICFlags.Rectangle) { var b = _img.Clone(r, PixelFormat.Format32bppArgb); var d = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat); try { unsafe { _SetAlpha((uint *)d.Scan0, r /*, path*/); } } finally { b.UnlockBits(d); /*path?.Dispose();*/ } Result.image = b; } } _w.MapClientToScreen(ref r); Result.rect = r; _res = 1; Api.DestroyWindow(_w); }