diff --git a/Greenshot/Forms/ZoomForm.cs b/Greenshot/Controls/ZoomControl.cs
similarity index 66%
rename from Greenshot/Forms/ZoomForm.cs
rename to Greenshot/Controls/ZoomControl.cs
index d144404f4..7837b8ff3 100644
--- a/Greenshot/Forms/ZoomForm.cs
+++ b/Greenshot/Controls/ZoomControl.cs
@@ -25,35 +25,75 @@ using System.Drawing;
using Greenshot.Plugin;
using System.Drawing.Drawing2D;
using GreenshotPlugin.Controls;
+using GreenshotPlugin.UnmanagedHelpers;
namespace Greenshot.Forms {
///
- /// This form will show the area around the mouse of the current capture
+ /// This control will show the area around the mouse of the current capture
///
- public class ZoomForm : FormWithoutActivation {
- private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ZoomForm));
+ public class ZoomControl : Control {
+ private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ZoomControl));
private Image imageToZoom = null;
private Point zoomLocation = Point.Empty;
private const int distanceX = 20;
private const int distanceY = 20;
- public ZoomForm(Image imageToZoom) {
+ ///
+ /// Create a zoom control for the image and with the size
+ ///
+ ///
+ ///
+ public ZoomControl(Image imageToZoom, Size zoomSize) {
InitializeComponent();
+ this.Width = zoomSize.Width;
+ this.Height = zoomSize.Height;
this.imageToZoom = imageToZoom;
Zoom = 400;
}
///
- /// Prevent the clipping of the child (this Form is a child of another)
+ /// Override some special form parameters
///
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
- parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
+ parms.Style &= ~((int)WindowStyleFlags.WS_CLIPCHILDREN); // Turn off WS_CLIPCHILDREN which prevents the screen to be cleared behind this form
+ parms.ExStyle |= (int)ExtendedWindowStyleFlags.WS_EX_NOACTIVATE | (int)ExtendedWindowStyleFlags.WS_EX_TOOLWINDOW | (int)ExtendedWindowStyleFlags.WS_EX_TOPMOST;
+ //parms.ExStyle |= (int)ExtendedWindowStyleFlags.WS_EX_TRANSPARENT;
+ parms.Parent = IntPtr.Zero; // Make parentless
return parms;
}
}
+ ///
+ /// Shows the control as a floating Window child
+ /// of the desktop. To hide the control again,
+ /// use the property.
+ ///
+ public void ShowFloating() {
+ if (this.Handle == IntPtr.Zero) {
+ base.CreateControl();
+ }
+ User32.SetParent(base.Handle, IntPtr.Zero);
+ User32.ShowWindow(base.Handle, ShowWindowCommand.Show);
+ }
+
+ ///
+ /// Make the mouse events pass through
+ ///
+ ///
+ protected override void WndProc(ref Message m) {
+ const int HTTRANSPARENT = (-1);
+ switch (m.Msg) {
+ case (int)WindowsMessages.WM_NCHITTEST:
+ m.Result = (IntPtr) HTTRANSPARENT;
+ break;
+ default:
+ base.WndProc(ref m);
+ break;
+ }
+ }
+
///
/// Sets the location of the mouse on the screen (using screen coordinates, which might differ from bitmap coordindates in a multi screen setup)
///
@@ -91,10 +131,14 @@ namespace Greenshot.Forms {
}
+ ///
+ /// The zoom property
+ ///
public int Zoom {
get;
set;
}
+
///
/// This makes sure there is no background painted, as we have complete "paint" control it doesn't make sense to do otherwise.
///
@@ -102,6 +146,10 @@ namespace Greenshot.Forms {
protected override void OnPaintBackground(PaintEventArgs pevent) {
}
+ ///
+ /// Paint the zoom area and the cross
+ ///
+ ///
protected override void OnPaint(PaintEventArgs e) {
if (imageToZoom == null) {
return;
@@ -111,14 +159,15 @@ namespace Greenshot.Forms {
graphics.SmoothingMode = SmoothingMode.None;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
- graphics.PixelOffsetMode = PixelOffsetMode.None;
+ graphics.PixelOffsetMode = PixelOffsetMode.Half;
Rectangle clipRectangle = e.ClipRectangle;
- float zoom = (float)100 / (float)Zoom;
+ float zoomFactor = (float)100 / (float)Zoom;
- int sourceWidth = (int)(Width * zoom);
- int sourceHeight = (int)(Height * zoom);
- Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2), ZoomLocation.Y - (sourceHeight / 2), sourceWidth, sourceHeight);
+ int sourceWidth = (int)(Width * zoomFactor);
+ int sourceHeight = (int)(Height * zoomFactor);
+ Rectangle sourceRectangle = new Rectangle(ZoomLocation.X - (sourceWidth / 2) + 1, ZoomLocation.Y - (sourceHeight / 2) + 1, sourceWidth, sourceHeight);
Rectangle destinationRectangle = new Rectangle(0, 0, Width, Height);
+ //graphics.StretchBlt((Bitmap)imageToZoom, sourceRectangle, destinationRectangle);
graphics.DrawImage(imageToZoom, destinationRectangle, sourceRectangle, GraphicsUnit.Pixel);
int pixelThickness = Zoom / 100;
@@ -136,25 +185,10 @@ namespace Greenshot.Forms {
private void InitializeComponent() {
this.SuspendLayout();
- //
- // ZoomForm
- //
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
- this.ClientSize = new System.Drawing.Size(100, 100);
- this.ControlBox = false;
// Only double-buffer when we are not in a TerminalServerSession
this.DoubleBuffered = !System.Windows.Forms.SystemInformation.TerminalServerSession;
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.MinimumSize = ClientSize;
this.Name = "Zoom";
- this.ShowIcon = false;
- this.ShowInTaskbar = false;
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
- this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
- this.TopMost = true;
this.ResumeLayout(false);
}
}
diff --git a/Greenshot/Forms/CaptureForm.cs b/Greenshot/Forms/CaptureForm.cs
index 54062be2b..7729c0057 100644
--- a/Greenshot/Forms/CaptureForm.cs
+++ b/Greenshot/Forms/CaptureForm.cs
@@ -37,7 +37,7 @@ using Greenshot.IniFile;
namespace Greenshot.Forms {
///
- /// Description of CaptureForm.
+ /// The capture form is used to select a part of the capture
///
public partial class CaptureForm : Form {
private enum FixMode {None, Initiated, Horizontal, Vertical};
@@ -65,20 +65,29 @@ namespace Greenshot.Forms {
private Point previousMousePos = Point.Empty;
private FixMode fixMode = FixMode.None;
- private ZoomForm zoomForm = null;
+ private ZoomControl zoomControl = null;
+ ///
+ /// Property to access the selected capture rectangle
+ ///
public Rectangle CaptureRectangle {
get {
return captureRect;
}
}
+ ///
+ /// Property to access the used capture mode
+ ///
public CaptureMode UsedCaptureMode {
get {
return captureMode;
}
}
+ ///
+ /// Get the selected window
+ ///
public WindowDetails SelectedCaptureWindow {
get {
return selectedCaptureWindow;
@@ -96,6 +105,11 @@ namespace Greenshot.Forms {
}
}
+ ///
+ /// This creates the capture form
+ ///
+ ///
+ ///
public CaptureForm(ICapture capture, List windows) {
if (currentForm != null) {
LOG.Debug("Found currentForm, Closing already opened CaptureForm");
@@ -109,9 +123,9 @@ namespace Greenshot.Forms {
timer = new Timer();
// Using 32bppPArgb speeds up the drawing.
- capturedImage = ImageHelper.Clone(capture.Image, PixelFormat.Format32bppPArgb);
+ //capturedImage = ImageHelper.Clone(capture.Image, PixelFormat.Format32bppPArgb);
// comment the clone, uncomment the assignment and the original bitmap is used.
- //capturedImage = capture.Image;
+ capturedImage = capture.Image;
// clean up
this.FormClosed += delegate {
@@ -160,36 +174,43 @@ namespace Greenshot.Forms {
// Fix missing focus
WindowDetails.ToForeground(this.Handle);
this.TopMost = true;
- CreateZoom();
if (timer != null) {
- timer.Interval = 40;
+ timer.Interval = 30;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
}
+ ///
+ /// Create the zoom control
+ ///
private void CreateZoom() {
- if (zoomForm == null) {
- zoomForm = new ZoomForm(capturedImage);
- zoomForm.Show(this);
-
- zoomForm.MouseLocation = cursorPos;
- zoomForm.ZoomLocation = cursorPosOnBitmap;
-
- // Fix missing focus issue
- WindowDetails.ToForeground(this.Handle);
+ if (zoomControl == null) {
+ zoomControl = new ZoomControl(capturedImage, new Size(200, 200));
+ zoomControl.MouseLocation = cursorPos;
+ zoomControl.ZoomLocation = cursorPosOnBitmap;
+ zoomControl.ShowFloating();
}
}
+ ///
+ /// Hide the zoom control
+ ///
private void RemoveZoom() {
- if (zoomForm != null) {
- zoomForm.Close();
- // Fix missing focus issue
- WindowDetails.ToForeground(this.Handle);
- zoomForm = null;
+ if (zoomControl != null) {
+ zoomControl.Hide();
}
}
+ ///
+ /// Create the zoom after the window is showing
+ ///
+ ///
+ protected override void OnShown(EventArgs e) {
+ base.OnShown(e);
+ CreateZoom();
+ }
+
#region key handling
void CaptureFormKeyUp(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.ShiftKey) {
@@ -220,7 +241,7 @@ namespace Greenshot.Forms {
Invalidate();
} else if (e.KeyCode == Keys.Z) {
// Toggle zoom
- if (zoomForm == null) {
+ if (zoomControl == null) {
CreateZoom();
} else {
RemoveZoom();
@@ -327,9 +348,9 @@ namespace Greenshot.Forms {
bool verticalMove = false;
// Change the zoom location
- if (zoomForm != null) {
- zoomForm.MouseLocation = cursorPos;
- zoomForm.ZoomLocation = cursorPosOnBitmap;
+ if (zoomControl != null) {
+ zoomControl.MouseLocation = cursorPos;
+ zoomControl.ZoomLocation = cursorPosOnBitmap;
}
if (lastPos.X != cursorPos.X) {
diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj
index e877121ad..3d1a94946 100644
--- a/Greenshot/Greenshot.csproj
+++ b/Greenshot/Greenshot.csproj
@@ -67,6 +67,9 @@
Component
+
+ Form
+
@@ -181,9 +184,6 @@
-
- Form
-
diff --git a/GreenshotPlugin/UnmanagedHelpers/GDI32.cs b/GreenshotPlugin/UnmanagedHelpers/GDI32.cs
index e0178cf74..f9c4f875a 100644
--- a/GreenshotPlugin/UnmanagedHelpers/GDI32.cs
+++ b/GreenshotPlugin/UnmanagedHelpers/GDI32.cs
@@ -44,6 +44,8 @@ namespace GreenshotPlugin.UnmanagedHelpers {
[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)]
+ public static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, CopyPixelOperation dwRop );
+ [DllImport("gdi32", SetLastError=true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32", SetLastError=true)]
public static extern bool DeleteDC(IntPtr hDC);
@@ -63,18 +65,43 @@ namespace GreenshotPlugin.UnmanagedHelpers {
public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);
///
- ///
+ /// Doesn't work?
///
///
///
- public static void BitBlt(this Graphics target, Bitmap source, Point location) {
+ public static void StretchBlt(this Graphics target, Bitmap sourceBitmap, Rectangle source, Rectangle destination) {
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);
+ IntPtr pOrig = SelectObject(hDCSrc, sourceBitmap.GetHbitmap());
+ StretchBlt(hDCDest, destination.X, destination.Y, destination.Width, destination.Height, hDCSrc, source.Left, source.Top, source.Width, source.Height, CopyPixelOperation.SourceCopy);
+ IntPtr pNew = SelectObject(hDCDest, pOrig);
+ } finally {
+ if (hDCSrc != IntPtr.Zero) {
+ DeleteDC(hDCSrc);
+ }
+ if (hDCDest != IntPtr.Zero) {
+ target.ReleaseHdc(hDCDest);
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void BitBlt(this Graphics target, Bitmap sourceBitmap, Rectangle source, Point destination) {
+ IntPtr hDCSrc = IntPtr.Zero;
+ IntPtr hDCDest = IntPtr.Zero;
+ try {
+ hDCDest = target.GetHdc();
+ hDCSrc = CreateCompatibleDC(hDCDest);
+ IntPtr pOrig = SelectObject(hDCSrc, sourceBitmap.GetHbitmap());
+ BitBlt(hDCDest, destination.X, destination.Y, source.Width, source.Height, hDCSrc, source.Left, source.Top, CopyPixelOperation.SourceCopy);
+ IntPtr pNew = SelectObject(hDCDest, pOrig);
} finally {
if (hDCSrc != IntPtr.Zero) {
DeleteDC(hDCSrc);
diff --git a/GreenshotPlugin/UnmanagedHelpers/User32.cs b/GreenshotPlugin/UnmanagedHelpers/User32.cs
index 10981d469..fb7252b29 100644
--- a/GreenshotPlugin/UnmanagedHelpers/User32.cs
+++ b/GreenshotPlugin/UnmanagedHelpers/User32.cs
@@ -309,10 +309,14 @@ namespace GreenshotPlugin.UnmanagedHelpers {
public extern static bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32", SetLastError = true)]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out IntPtr processId);
- [DllImport("user32", SetLastError = true, ExactSpelling=true, CharSet=CharSet.Auto)]
+ [DllImport("user32", SetLastError = true)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32", SetLastError = true)]
+ public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
+ [DllImport("user32", SetLastError = true)]
public static extern IntPtr GetWindow(IntPtr hWnd, GetWindowCommand uCmd);
+ [DllImport("user32", SetLastError = true)]
+ public static extern int ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow);
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
public extern static int GetWindowText(IntPtr hWnd, StringBuilder lpString, int cch);
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]