mirror of
https://github.com/greenshot/greenshot
synced 2025-08-14 10:47:02 -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.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Printing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Greenshot.Configuration;
|
||||
using Greenshot.Drawing;
|
||||
using Greenshot.Helpers;
|
||||
|
@ -51,6 +51,7 @@ namespace Greenshot.Forms {
|
|||
|
||||
private int mX;
|
||||
private int mY;
|
||||
private Point mouseMovePos = Point.Empty;
|
||||
private Point cursorPos = Point.Empty;
|
||||
private Point cursorPosOnBitmap = Point.Empty;
|
||||
private CaptureMode captureMode = CaptureMode.None;
|
||||
|
@ -59,6 +60,8 @@ namespace Greenshot.Forms {
|
|||
private bool mouseDown = false;
|
||||
private Rectangle captureRect = Rectangle.Empty;
|
||||
private ICapture capture = null;
|
||||
private Image capturedImage = null;
|
||||
private Timer timer = null;
|
||||
|
||||
private Point previousMousePos = Point.Empty;
|
||||
private FixMode fixMode = FixMode.None;
|
||||
|
@ -101,6 +104,14 @@ namespace Greenshot.Forms {
|
|||
Application.DoEvents();
|
||||
}
|
||||
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
|
||||
this.FormClosed += delegate {
|
||||
|
@ -125,6 +136,13 @@ namespace Greenshot.Forms {
|
|||
WindowDetails.RegisterIgnoreHandle(this.Handle);
|
||||
// Unregister at close
|
||||
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");
|
||||
WindowDetails.UnregisterIgnoreHandle(this.Handle);
|
||||
};
|
||||
|
@ -143,13 +161,21 @@ namespace Greenshot.Forms {
|
|||
WindowDetails.ToForeground(this.Handle);
|
||||
this.TopMost = true;
|
||||
CreateZoom();
|
||||
if (timer != null) {
|
||||
timer.Interval = 40;
|
||||
timer.Tick += new EventHandler(timer_Tick);
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateZoom() {
|
||||
if (zoomForm == null) {
|
||||
zoomForm = new ZoomForm(capture);
|
||||
zoomForm = new ZoomForm(capturedImage);
|
||||
zoomForm.Show(this);
|
||||
|
||||
zoomForm.MouseLocation = cursorPos;
|
||||
zoomForm.ZoomLocation = cursorPosOnBitmap;
|
||||
|
||||
// Fix missing focus issue
|
||||
WindowDetails.ToForeground(this.Handle);
|
||||
}
|
||||
|
@ -271,13 +297,30 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
|
||||
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
|
||||
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.
|
||||
cursorPosOnBitmap = new Point(cursorPos.X, cursorPos.Y);
|
||||
cursorPosOnBitmap.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
|
||||
|
||||
Rectangle lastCaptureRect = new Rectangle(captureRect.Location, captureRect.Size);
|
||||
WindowDetails lastWindow = selectedCaptureWindow;
|
||||
bool horizontalMove = false;
|
||||
|
@ -390,6 +433,8 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Force update "now"
|
||||
Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -402,7 +447,8 @@ namespace Greenshot.Forms {
|
|||
void OnPaint(object sender, PaintEventArgs e) {
|
||||
Graphics graphics = e.Graphics;
|
||||
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
|
||||
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);
|
||||
|
|
|
@ -32,14 +32,14 @@ namespace Greenshot.Forms {
|
|||
/// </summary>
|
||||
public class ZoomForm : FormWithoutActivation {
|
||||
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 const int distanceX = 20;
|
||||
private const int distanceY = 20;
|
||||
|
||||
public ZoomForm(ICapture captureToZoom) {
|
||||
public ZoomForm(Image imageToZoom) {
|
||||
InitializeComponent();
|
||||
this.captureToZoom = captureToZoom;
|
||||
this.imageToZoom = imageToZoom;
|
||||
Zoom = 400;
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ namespace Greenshot.Forms {
|
|||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e) {
|
||||
if (captureToZoom == null || captureToZoom.Image == null) {
|
||||
if (imageToZoom == null) {
|
||||
return;
|
||||
}
|
||||
Graphics graphics = e.Graphics;
|
||||
|
@ -111,7 +111,7 @@ namespace Greenshot.Forms {
|
|||
graphics.SmoothingMode = SmoothingMode.None;
|
||||
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
graphics.CompositingQuality = CompositingQuality.HighSpeed;
|
||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
graphics.PixelOffsetMode = PixelOffsetMode.None;
|
||||
Rectangle clipRectangle = e.ClipRectangle;
|
||||
float zoom = (float)100 / (float)Zoom;
|
||||
|
||||
|
@ -119,7 +119,7 @@ namespace Greenshot.Forms {
|
|||
int sourceHeight = (int)(Height * zoom);
|
||||
Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2), ZoomLocation.Y - (sourceHeight / 2), sourceWidth, sourceHeight);
|
||||
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;
|
||||
using (Pen pen = new Pen(Color.Black, pixelThickness)) {
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
/// <summary>
|
||||
/// GDI32 Helpers
|
||||
/// </summary>
|
||||
public class GDI32 {
|
||||
public static class GDI32 {
|
||||
[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);
|
||||
[DllImport("gdi32", SetLastError=true)]
|
||||
|
@ -61,6 +61,29 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
|||
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
|
||||
[DllImport("gdi32")]
|
||||
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)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue