mirror of
https://github.com/greenshot/greenshot
synced 2025-08-20 05:23:24 -07:00
Fixed the zoom, it was drawn incorrectly. Also changed the drawing to work with a timer, so the updates are made even if the mouse moves to quick. Added a bitblt method in the GDI32 class.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2294 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
16ad103450
commit
5a1c5fd0eb
3 changed files with 82 additions and 13 deletions
|
@ -23,10 +23,10 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.Drawing.Printing;
|
using System.Drawing.Printing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Greenshot.Configuration;
|
using Greenshot.Configuration;
|
||||||
using Greenshot.Drawing;
|
using Greenshot.Drawing;
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
|
@ -51,6 +51,7 @@ namespace Greenshot.Forms {
|
||||||
|
|
||||||
private int mX;
|
private int mX;
|
||||||
private int mY;
|
private int mY;
|
||||||
|
private Point mouseMovePos = Point.Empty;
|
||||||
private Point cursorPos = Point.Empty;
|
private Point cursorPos = Point.Empty;
|
||||||
private Point cursorPosOnBitmap = Point.Empty;
|
private Point cursorPosOnBitmap = Point.Empty;
|
||||||
private CaptureMode captureMode = CaptureMode.None;
|
private CaptureMode captureMode = CaptureMode.None;
|
||||||
|
@ -59,6 +60,8 @@ namespace Greenshot.Forms {
|
||||||
private bool mouseDown = false;
|
private bool mouseDown = false;
|
||||||
private Rectangle captureRect = Rectangle.Empty;
|
private Rectangle captureRect = Rectangle.Empty;
|
||||||
private ICapture capture = null;
|
private ICapture capture = null;
|
||||||
|
private Image capturedImage = null;
|
||||||
|
private Timer timer = null;
|
||||||
|
|
||||||
private Point previousMousePos = Point.Empty;
|
private Point previousMousePos = Point.Empty;
|
||||||
private FixMode fixMode = FixMode.None;
|
private FixMode fixMode = FixMode.None;
|
||||||
|
@ -101,6 +104,14 @@ namespace Greenshot.Forms {
|
||||||
Application.DoEvents();
|
Application.DoEvents();
|
||||||
}
|
}
|
||||||
currentForm = this;
|
currentForm = this;
|
||||||
|
|
||||||
|
// comment this out if the timer should not be used
|
||||||
|
timer = new Timer();
|
||||||
|
|
||||||
|
// Using 32bppPArgb speeds up the drawing.
|
||||||
|
capturedImage = ImageHelper.Clone(capture.Image, PixelFormat.Format32bppPArgb);
|
||||||
|
// comment the clone, uncomment the assignment and the original bitmap is used.
|
||||||
|
//capturedImage = capture.Image;
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
this.FormClosed += delegate {
|
this.FormClosed += delegate {
|
||||||
|
@ -125,6 +136,13 @@ namespace Greenshot.Forms {
|
||||||
WindowDetails.RegisterIgnoreHandle(this.Handle);
|
WindowDetails.RegisterIgnoreHandle(this.Handle);
|
||||||
// Unregister at close
|
// Unregister at close
|
||||||
this.FormClosing += delegate {
|
this.FormClosing += delegate {
|
||||||
|
if (timer != null) {
|
||||||
|
timer.Stop();
|
||||||
|
}
|
||||||
|
// remove the buffer if it was created inside this form
|
||||||
|
if (capturedImage != capture.Image) {
|
||||||
|
capturedImage.Dispose();
|
||||||
|
}
|
||||||
LOG.Debug("Closing captureform");
|
LOG.Debug("Closing captureform");
|
||||||
WindowDetails.UnregisterIgnoreHandle(this.Handle);
|
WindowDetails.UnregisterIgnoreHandle(this.Handle);
|
||||||
};
|
};
|
||||||
|
@ -143,13 +161,21 @@ namespace Greenshot.Forms {
|
||||||
WindowDetails.ToForeground(this.Handle);
|
WindowDetails.ToForeground(this.Handle);
|
||||||
this.TopMost = true;
|
this.TopMost = true;
|
||||||
CreateZoom();
|
CreateZoom();
|
||||||
|
if (timer != null) {
|
||||||
|
timer.Interval = 40;
|
||||||
|
timer.Tick += new EventHandler(timer_Tick);
|
||||||
|
timer.Start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateZoom() {
|
private void CreateZoom() {
|
||||||
if (zoomForm == null) {
|
if (zoomForm == null) {
|
||||||
zoomForm = new ZoomForm(capture);
|
zoomForm = new ZoomForm(capturedImage);
|
||||||
zoomForm.Show(this);
|
zoomForm.Show(this);
|
||||||
|
|
||||||
|
zoomForm.MouseLocation = cursorPos;
|
||||||
|
zoomForm.ZoomLocation = cursorPosOnBitmap;
|
||||||
|
|
||||||
// Fix missing focus issue
|
// Fix missing focus issue
|
||||||
WindowDetails.ToForeground(this.Handle);
|
WindowDetails.ToForeground(this.Handle);
|
||||||
}
|
}
|
||||||
|
@ -271,13 +297,30 @@ namespace Greenshot.Forms {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnMouseMove(object sender, MouseEventArgs e) {
|
void OnMouseMove(object sender, MouseEventArgs e) {
|
||||||
Point lastPos = new Point(cursorPos.X, cursorPos.Y);
|
|
||||||
cursorPos = WindowCapture.GetCursorLocation();
|
|
||||||
// Make sure the mouse coordinates are fixed, when pressing shift
|
// Make sure the mouse coordinates are fixed, when pressing shift
|
||||||
cursorPos = FixMouseCoordinates(cursorPos);
|
mouseMovePos = FixMouseCoordinates(WindowCapture.GetCursorLocation());
|
||||||
|
// If the timer is used, the timer_Tick does the following.
|
||||||
|
// If the timer is not used, we need to call the update ourselves
|
||||||
|
if (timer == null) {
|
||||||
|
updateFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_Tick(object sender, EventArgs e) {
|
||||||
|
updateFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFrame() {
|
||||||
|
Point lastPos = cursorPos.Clone();
|
||||||
|
cursorPos = mouseMovePos.Clone();
|
||||||
|
if (lastPos.Equals(cursorPos)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// As the cursorPos is not in Bitmap coordinates, we need to correct.
|
// As the cursorPos is not in Bitmap coordinates, we need to correct.
|
||||||
cursorPosOnBitmap = new Point(cursorPos.X, cursorPos.Y);
|
cursorPosOnBitmap = new Point(cursorPos.X, cursorPos.Y);
|
||||||
cursorPosOnBitmap.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
|
cursorPosOnBitmap.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
|
||||||
|
|
||||||
Rectangle lastCaptureRect = new Rectangle(captureRect.Location, captureRect.Size);
|
Rectangle lastCaptureRect = new Rectangle(captureRect.Location, captureRect.Size);
|
||||||
WindowDetails lastWindow = selectedCaptureWindow;
|
WindowDetails lastWindow = selectedCaptureWindow;
|
||||||
bool horizontalMove = false;
|
bool horizontalMove = false;
|
||||||
|
@ -390,6 +433,8 @@ namespace Greenshot.Forms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Force update "now"
|
||||||
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -402,7 +447,8 @@ namespace Greenshot.Forms {
|
||||||
void OnPaint(object sender, PaintEventArgs e) {
|
void OnPaint(object sender, PaintEventArgs e) {
|
||||||
Graphics graphics = e.Graphics;
|
Graphics graphics = e.Graphics;
|
||||||
Rectangle clipRectangle = e.ClipRectangle;
|
Rectangle clipRectangle = e.ClipRectangle;
|
||||||
graphics.DrawImageUnscaled(capture.Image, Point.Empty);
|
//graphics.BitBlt((Bitmap)buffer, Point.Empty);
|
||||||
|
graphics.DrawImageUnscaled(capturedImage, Point.Empty);
|
||||||
// Only draw Cursor if it's (partly) visible
|
// Only draw Cursor if it's (partly) visible
|
||||||
if (capture.Cursor != null && capture.CursorVisible && clipRectangle.IntersectsWith(new Rectangle(capture.CursorLocation, capture.Cursor.Size))) {
|
if (capture.Cursor != null && capture.CursorVisible && clipRectangle.IntersectsWith(new Rectangle(capture.CursorLocation, capture.Cursor.Size))) {
|
||||||
graphics.DrawIcon(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y);
|
graphics.DrawIcon(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y);
|
||||||
|
|
|
@ -32,14 +32,14 @@ namespace Greenshot.Forms {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ZoomForm : FormWithoutActivation {
|
public class ZoomForm : FormWithoutActivation {
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ZoomForm));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ZoomForm));
|
||||||
private ICapture captureToZoom = null;
|
private Image imageToZoom = null;
|
||||||
private Point zoomLocation = Point.Empty;
|
private Point zoomLocation = Point.Empty;
|
||||||
private const int distanceX = 20;
|
private const int distanceX = 20;
|
||||||
private const int distanceY = 20;
|
private const int distanceY = 20;
|
||||||
|
|
||||||
public ZoomForm(ICapture captureToZoom) {
|
public ZoomForm(Image imageToZoom) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
this.captureToZoom = captureToZoom;
|
this.imageToZoom = imageToZoom;
|
||||||
Zoom = 400;
|
Zoom = 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ namespace Greenshot.Forms {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPaint(PaintEventArgs e) {
|
protected override void OnPaint(PaintEventArgs e) {
|
||||||
if (captureToZoom == null || captureToZoom.Image == null) {
|
if (imageToZoom == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Graphics graphics = e.Graphics;
|
Graphics graphics = e.Graphics;
|
||||||
|
@ -111,7 +111,7 @@ namespace Greenshot.Forms {
|
||||||
graphics.SmoothingMode = SmoothingMode.None;
|
graphics.SmoothingMode = SmoothingMode.None;
|
||||||
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||||
graphics.CompositingQuality = CompositingQuality.HighSpeed;
|
graphics.CompositingQuality = CompositingQuality.HighSpeed;
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
graphics.PixelOffsetMode = PixelOffsetMode.None;
|
||||||
Rectangle clipRectangle = e.ClipRectangle;
|
Rectangle clipRectangle = e.ClipRectangle;
|
||||||
float zoom = (float)100 / (float)Zoom;
|
float zoom = (float)100 / (float)Zoom;
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ namespace Greenshot.Forms {
|
||||||
int sourceHeight = (int)(Height * zoom);
|
int sourceHeight = (int)(Height * zoom);
|
||||||
Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2), ZoomLocation.Y - (sourceHeight / 2), sourceWidth, sourceHeight);
|
Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2), ZoomLocation.Y - (sourceHeight / 2), sourceWidth, sourceHeight);
|
||||||
Rectangle destinationRectangle = new Rectangle(0, 0, Width, Height);
|
Rectangle destinationRectangle = new Rectangle(0, 0, Width, Height);
|
||||||
graphics.DrawImage(captureToZoom.Image, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel);
|
graphics.DrawImage(imageToZoom, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel);
|
||||||
|
|
||||||
int pixelThickness = Zoom / 100;
|
int pixelThickness = Zoom / 100;
|
||||||
using (Pen pen = new Pen(Color.Black, pixelThickness)) {
|
using (Pen pen = new Pen(Color.Black, pixelThickness)) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GDI32 Helpers
|
/// GDI32 Helpers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GDI32 {
|
public static class GDI32 {
|
||||||
[DllImport("gdi32", SetLastError=true)]
|
[DllImport("gdi32", SetLastError=true)]
|
||||||
public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest, int nWidth,int nHeight,IntPtr hObjectSource, int nXSrc,int nYSrc, CopyPixelOperation dwRop);
|
public static extern bool BitBlt(IntPtr hObject,int nXDest,int nYDest, int nWidth,int nHeight,IntPtr hObjectSource, int nXSrc,int nYSrc, CopyPixelOperation dwRop);
|
||||||
[DllImport("gdi32", SetLastError=true)]
|
[DllImport("gdi32", SetLastError=true)]
|
||||||
|
@ -61,6 +61,29 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
|
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
|
||||||
[DllImport("gdi32")]
|
[DllImport("gdi32")]
|
||||||
public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);
|
public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target"></param>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
public static void BitBlt(this Graphics target, Bitmap source, Point location) {
|
||||||
|
IntPtr hDCSrc = IntPtr.Zero;
|
||||||
|
IntPtr hDCDest = IntPtr.Zero;
|
||||||
|
try {
|
||||||
|
hDCDest = target.GetHdc();
|
||||||
|
hDCSrc = CreateCompatibleDC(hDCDest);
|
||||||
|
SelectObject(hDCSrc, source.GetHbitmap());
|
||||||
|
GDI32.BitBlt(hDCDest, location.X, location.Y, source.Width, source.Height, hDCSrc, 0, 0, CopyPixelOperation.SourceCopy);
|
||||||
|
} finally {
|
||||||
|
if (hDCSrc != IntPtr.Zero) {
|
||||||
|
DeleteDC(hDCSrc);
|
||||||
|
}
|
||||||
|
if (hDCDest != IntPtr.Zero) {
|
||||||
|
target.ReleaseHdc(hDCDest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue