/// <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); }
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); }
/// <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); } }
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); }
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); } } }