예제 #1
0
        /// <summary>
        /// Draws a bitmap to a Graphics context.
        /// </summary>
        /// <param name="dst">The Graphics context to draw the bitmap on to.</param>
        /// <param name="dstRect">The clipping rectangle in destination coordinates.</param>
        /// <param name="dstMatrix">The transformation matrix to apply. This is only used to transform the upper-left corner of dstRect.</param>
        /// <param name="srcBitmapHandle">The handle to the bitmap obtained from Memory.AllocateBitmap().</param>
        /// <param name="srcWidth">The full width of the bitmap.</param>
        /// <param name="srcHeight">The full height of the bitmap.</param>
        /// <param name="srcOffsetX">The left edge of the source bitmap to draw from.</param>
        /// <param name="srcOffsetY">The top edge of the source bitmap to draw from.</param>
        public unsafe static void DrawBitmap(
            Graphics dst,
            Rectangle dstRect,
            Matrix dstMatrix,
            IntPtr srcBitmapHandle,
            int srcOffsetX,
            int srcOffsetY)
        {
            if (srcBitmapHandle == IntPtr.Zero)
            {
                throw new ArgumentNullException("srcBitmapHandle");
            }

            Point[] points = new Point[] { dstRect.Location };
            dstMatrix.TransformPoints(points);
            dstRect.Location = points[0];

            IntPtr hdc  = IntPtr.Zero;
            IntPtr chdc = IntPtr.Zero;
            IntPtr old  = IntPtr.Zero;

            try
            {
                hdc  = dst.GetHdc();
                chdc = SafeNativeMethods.CreateCompatibleDC(hdc);
                old  = SafeNativeMethods.SelectObject(chdc, srcBitmapHandle);
                SafeNativeMethods.BitBlt(hdc, dstRect.Left, dstRect.Top, dstRect.Width,
                                         dstRect.Height, chdc, srcOffsetX, srcOffsetY, 13369376u);
            }

            finally
            {
                if (old != IntPtr.Zero)
                {
                    SafeNativeMethods.SelectObject(chdc, old);
                }

                if (chdc != IntPtr.Zero)
                {
                    SafeNativeMethods.DeleteDC(chdc);
                }

                if (hdc != IntPtr.Zero)
                {
                    dst.ReleaseHdc(hdc);
                }
            }

            GC.KeepAlive(dst);
        }
예제 #2
0
        public void PaintNative(IntPtr hdc)
        {
            var bmpHdc = SafeNativeMethods.CreateCompatibleDC(IntPtr.Zero);

            var bTrack = this.GetBufferTrack();
            var bA1    = this.GetBufferArrow1();
            var bA2    = this.GetBufferArrow2();
            var bThumb = this.GetBufferThumb();

            if (bTrack != null)
            {
                SafeNativeMethods.SelectObject(bmpHdc, bTrack.DangerousGetHandle());
                SafeNativeMethods.BitBlt(hdc, this.track.Left, this.track.Top, this.track.Width, this.track.Height, bmpHdc, 0, 0, NativeConstants.SRCCOPY);
            }

            if (bA1 != null)
            {
                SafeNativeMethods.SelectObject(bmpHdc, bA1.DangerousGetHandle());
                SafeNativeMethods.BitBlt(hdc, this.arrow1.Left, this.arrow1.Top, this.arrow1.Width, this.arrow1.Height, bmpHdc, 0, 0, NativeConstants.SRCCOPY);
            }

            if (bA2 != null)
            {
                SafeNativeMethods.SelectObject(bmpHdc, bA2.DangerousGetHandle());
                SafeNativeMethods.BitBlt(hdc, this.arrow2.Left, this.arrow2.Top, this.arrow2.Width, this.arrow2.Height, bmpHdc, 0, 0, NativeConstants.SRCCOPY);
            }

            if (bThumb != null)
            {
                SafeNativeMethods.SelectObject(bmpHdc, bThumb.DangerousGetHandle());
                SafeNativeMethods.BitBlt(hdc, this.thumb.Left, this.thumb.Top, this.thumb.Width, this.thumb.Height, bmpHdc, 0, 0, NativeConstants.SRCCOPY);
            }

            if (this.PaintBackgroundOverlay != null)
            {
                this.PaintBackgroundOverlay(this, new PaintScrollbarBackgroundArgs(hdc, this.thumb));
            }

            SafeNativeMethods.SelectObject(bmpHdc, IntPtr.Zero);
            SafeNativeMethods.DeleteDC(bmpHdc);
        }
예제 #3
0
        /// <summary>
        /// Uses BitBlt to geta snapshot of the control
        /// </summary>
        public static void GenerateSnapShotWithBitBlt(Control control, ref Image image)
        {
            // get the DC's and create our image
            HandleRef hWnd      = new HandleRef(control, control.Handle);
            IntPtr    controlDC = UnsafeNativeMethods.GetDC(hWnd);

            image = new Bitmap(Math.Max(control.Width, MINCONTROLBITMAPSIZE), Math.Max(control.Height, MINCONTROLBITMAPSIZE), System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

            using (Graphics gDest = Graphics.FromImage(image))
            {
                if (control.BackColor == Color.Transparent)
                {
                    gDest.Clear(SystemColors.Control);
                }

                IntPtr destDC = gDest.GetHdc();

                // perform our bitblit operation to push the image into the dest bitmap
                SafeNativeMethods.BitBlt(destDC, 0, 0, image.Width, image.Height, controlDC, 0, 0, 0xcc0020 /*RasterOp.SOURCE*/);
                //clean up all our handles and what not
                gDest.ReleaseHdc(destDC);
            }
        }
예제 #4
0
        protected override void OnPaint(PaintEventArgs e)
        {
            this.EnsureSelectionArrays(this.CurrentTextColumnIndex);

            #region buf

            if (this.bufHBitmap != null)
            {
                if (this.bufHBitmapSize.Width != Width || this.bufHBitmapSize.Height != Height)
                {
                    this.DisposeBuffer();
                }
            }

            var destHdc = e.Graphics.GetHdc();

            if (this.bufHdc == null || this.bufHdc.IsInvalid)
            {
                this.bufHdc = new SafeHandleDC(SafeNativeMethods.CreateCompatibleDC(destHdc));
            }

            if (this.bufHBitmap == null || this.bufHBitmap.IsInvalid)
            {
                var width  = Width;
                var height = Height;

                if (width <= 0 || height <= 0)
                {
                    e.Graphics.ReleaseHdc(destHdc);
                    return;
                }

                this.bufHBitmap     = new SafeHandleGDI(SafeNativeMethods.CreateCompatibleBitmap(destHdc, width, height));
                this.bufHBitmapSize = new Size(width, height);

                SafeNativeMethods.SelectObject(this.bufHdc.DangerousGetHandle(), this.bufHBitmap.DangerousGetHandle());
            }

            #endregion

            #region Initialize GDI resources

            if (this.backBrush == null)
            {
                var c = this.BackColor;
                this.backBrush = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(c)));

                c = Color.FromArgb((byte)(255 - SystemColors.Highlight.R), (byte)(255 - SystemColors.Highlight.G), (byte)(255 - SystemColors.Highlight.B));

                this.caretBrushSelection = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(c)));
            }

            #endregion

            var hdc = this.bufHdc;

            this.SetDefaultPaintState(hdc.DangerousGetHandle());

            var clientRect = new RECT
            {
                right  = ClientRectangle.Width,
                bottom = ClientRectangle.Height
            };

            if (BackgroundImage != null)
            {
                if (staticBackgroundHBitmap == null)
                {
                    staticBackgroundHBitmap = new SafeHandleGDI((BackgroundImage as Bitmap).GetHbitmap());
                }

                var bkgHdc     = SafeNativeMethods.CreateCompatibleDC(destHdc);
                var bkgHdcPrev = SafeNativeMethods.SelectObject(bkgHdc, staticBackgroundHBitmap.DangerousGetHandle());

                for (var imgX = 0; imgX < ClientSize.Width; imgX += BackgroundImage.Width)
                {
                    for (var imgY = 0; imgY < ClientSize.Height; imgY += BackgroundImage.Height)
                    {
                        SafeNativeMethods.BitBlt(hdc.DangerousGetHandle(), imgX, imgY, BackgroundImage.Width, BackgroundImage.Height, bkgHdc, 0, 0, NativeConstants.SRCCOPY);
                    }
                }

                SafeNativeMethods.SelectObject(bkgHdc, bkgHdcPrev);
                SafeNativeMethods.DeleteDC(bkgHdc);
            }
            else
            {
                SafeNativeMethods.FillRect(hdc.DangerousGetHandle(), ref clientRect, this.backBrush.DangerousGetHandle());
            }

            #region Paint overlay under text if the control is read-only

            if (this.IsReadOnly)
            {
                using (var g = Graphics.FromHdc(hdc.DangerousGetHandle()))
                {
                    using (var hatchBrush = new HatchBrush(HatchStyle.ForwardDiagonal, Color.FromArgb(50, Color.Gray), Color.Transparent))
                    {
                        g.FillRectangle(hatchBrush, 0, 0, Width, Height);
                    }
                }
            }

            #endregion

            this._renderer.Render(hdc.DangerousGetHandle(), this.ScrollHost.ScrollPosH + this.GetTextRectangle(false).Left, this.ScrollHost.ScrollPosVIntegral, ClientSize);

            #region Paint overlay if control is not enabled or virtual

            if (Enabled == false)
            {
                using (var g = Graphics.FromHdc(hdc.DangerousGetHandle()))
                {
                    using (var hatchBrush = new HatchBrush(HatchStyle.BackwardDiagonal, Color.Gray, Color.Transparent))
                    {
                        g.FillRectangle(hatchBrush, 0, 0, Width, Height);
                    }
                }
            }
            else if (this.IsVirtual)
            {
                this.SetDefaultPaintState(hdc.DangerousGetHandle());

                var brush = SafeNativeMethods.CreateHatchBrush(NativeConstants.HS_FDIAGONAL, ColorTranslator.ToWin32(Color.Gray));

                var previousBrush = SafeNativeMethods.SelectObject(hdc.DangerousGetHandle(), brush);

                var leftsideFillRect = new RECT
                {
                    bottom = Height,
                    right  = Padding.Left
                };

                SafeNativeMethods.FillRect(hdc.DangerousGetHandle(), ref leftsideFillRect, brush);

                SafeNativeMethods.SelectObject(hdc.DangerousGetHandle(), previousBrush);
                SafeNativeMethods.DeleteObject(brush);
            }

            #endregion

            #region Paint caret

            if (this._imeComposition != null && this._imeComposition.IsCompositioning)
            {
                this._imeComposition.Paint(hdc.DangerousGetHandle(), this.Caret.Location.X, this.Caret.Location.Y, this.Caret);
            }
            else
            {
                this.Caret.Render(hdc.DangerousGetHandle());
            }

            #endregion

            #region Paint text limitation guides (when scrolling outside)

            if (this.CanScrollOutside)
            {
                if (this.ScrollHost != null)
                {
                    var endY = this.ScrollHost.VerticalMax - this.ScrollHost.ScrollPosVIntegral - this.LineHeight;

                    if (endY + this.LineHeight < ClientRectangle.Height)
                    {
                        // TODO: Should not be gray. Should be ControlPaint.Light(255 - this.BackColor)
                        var penHandle = SafeNativeMethods.CreatePen(NativeConstants.PS_DOT, -1, ColorTranslator.ToWin32(Color.Gray));
                        var previous  = SafeNativeMethods.SelectObject(hdc.DangerousGetHandle(), penHandle);

                        SafeNativeMethods.MoveToEx(hdc.DangerousGetHandle(), 0, endY, IntPtr.Zero);
                        SafeNativeMethods.LineTo(hdc.DangerousGetHandle(), ClientRectangle.Width, endY);

                        SafeNativeMethods.SelectObject(hdc.DangerousGetHandle(), previous);
                        SafeNativeMethods.DeleteObject(penHandle);
                    }

                    var endX = this.ScrollHost.HorizontalMax - this.ScrollHost.ScrollPosH + Padding.Left + Padding.Right;

                    if (endX + this.LineHeight < ClientRectangle.Width)
                    {
                        var penHandle = SafeNativeMethods.CreatePen(NativeConstants.PS_DOT, -1,
                                                                    ColorTranslator.ToWin32(Color.Gray));
                        var previous = SafeNativeMethods.SelectObject(hdc.DangerousGetHandle(), penHandle);

                        SafeNativeMethods.MoveToEx(hdc.DangerousGetHandle(), endX, 0, IntPtr.Zero);
                        SafeNativeMethods.LineTo(hdc.DangerousGetHandle(), endX, endY == -1
                            ? ClientRectangle.Height
                            : endY);

                        SafeNativeMethods.SelectObject(hdc.DangerousGetHandle(), previous);
                        SafeNativeMethods.DeleteObject(penHandle);
                    }
                }
            }

            #endregion

            SafeNativeMethods.BitBlt(destHdc, 0, 0, this.bufHBitmapSize.Width, this.bufHBitmapSize.Height, hdc.DangerousGetHandle(), 0, 0, (int)NativeConstants.SRCCOPY);

            e.Graphics.ReleaseHdc(destHdc);
            destHdc = IntPtr.Zero;

            base.OnPaint(e);
        }
예제 #5
0
        public override unsafe void PaintLine(IntPtr hdc, RendererState rs)
        {
            if (this._hbmpInfo == null)
            {
                this._hbmpInfo = new SafeHandleGDI(((Bitmap)this.GetImage(rs.TextView)).GetHbitmap(Color.White));
            }

            if (this._handlePen == null)
            {
                this._handlePen       = new SafeHandleGDI(SafeNativeMethods.CreatePen(NativeConstants.PS_SOLID, -1, ColorTranslator.ToWin32(Color.Silver)));
                this._brushBackground = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(Color.White)));

                using (var faded = new Bitmap(16, 16))
                {
                    using (var g = Graphics.FromImage(faded))
                    {
                        g.DrawImage(this.GetImage(rs.TextView), 0, 0);

                        using (var b = new SolidBrush(Color.FromArgb(240, Color.White)))
                        {
                            g.FillRectangle(b, 0, 0, 16, 16);
                        }
                    }

                    this._hbmpInfoFaded = new SafeHandleGDI(faded.GetHbitmap(Color.White));
                }
            }

            var clientSize = rs.TextView.ClientSize;

            var previousPen = SafeNativeMethods.SelectObject(hdc, this._handlePen.DangerousGetHandle());

            SafeNativeMethods.MoveToEx(hdc, clientSize.Width - this.Width, rs.Y - rs.ViewportY, IntPtr.Zero);
            SafeNativeMethods.LineTo(hdc, clientSize.Width - this.Width, rs.Y - rs.ViewportY + rs.LineHeight);

            var hasNote = rs.Line.Metadata.ContainsKey("Note");

            if (hasNote)
            {
                SafeHandleGDI hbmp = this._hbmpInfo;

                // create a mirror device context associated with the target device context
                var hdcCreated = SafeNativeMethods.CreateCompatibleDC(hdc);

                // connect the bitmap with the mirror device context
                var hBmOld = SafeNativeMethods.SelectObject(hdcCreated, hbmp.DangerousGetHandle());

                // transfer the bitmap data from the mirror device context to the target DC
                SafeNativeMethods.BitBlt(hdc, clientSize.Width - 16, rs.Y - rs.ViewportY, 16, 16, hdcCreated, 0, 0, NativeConstants.SRCCOPY);

                SafeNativeMethods.SelectObject(hdc, previousPen);
                SafeNativeMethods.DeleteObject(hBmOld);
                SafeNativeMethods.DeleteDC(hdcCreated);
            }
            else
            {
                var r = new RECT
                {
                    top    = rs.Y - rs.ViewportY,
                    right  = rs.X + this.Width,
                    bottom = rs.Y + rs.LineHeight,
                    left   = rs.X + 1
                };

                SafeNativeMethods.FillRect(hdc, ref r, this._brushBackground.DangerousGetHandle());
            }

            if (rs.LineIndexVirtual == rs.LineIndexVirtualFocused && hasNote)
            {
                // We are currently on the same line
                var note = rs.Line.Metadata["Note"];
                var size = TextRenderer.MeasureText(note, rs.TextView.Font, rs.TextRectangle.Size);

                var r = new RECT
                {
                    top    = rs.Y - rs.ViewportY,
                    right  = rs.X - 5,
                    bottom = rs.Y + size.Height,
                    left   = rs.X - size.Width - 5
                };

                SafeNativeMethods.FillRect(hdc, ref r, this._brushBackground.DangerousGetHandle());

                fixed(char *c = note)
                {
                    SafeNativeMethods.TextOut(hdc, r.left, r.top, c, note.Length);
                }
            }
        }