diff --git a/GreenshotPlugin/Core/WindowCapture.cs b/GreenshotPlugin/Core/WindowCapture.cs index 6106ea575..67b311d7f 100644 --- a/GreenshotPlugin/Core/WindowCapture.cs +++ b/GreenshotPlugin/Core/WindowCapture.cs @@ -458,30 +458,13 @@ namespace GreenshotPlugin.Core { return new Rectangle(left, top, (right + Math.Abs(left)), (bottom + Math.Abs(top))); } - /// - /// Retrieves the cursor location safely, accounting for DPI settings in Vista/Windows 7. - /// Point with cursor location, relative to the origin of the monitor setup (i.e. negative coordinates are - /// possible in multiscreen setups) - public static Point GetCursorLocation() { - if (Environment.OSVersion.Version.Major >= 6) { - POINT cursorLocation; - if (User32.GetPhysicalCursorPos(out cursorLocation)) { - return new Point(cursorLocation.X, cursorLocation.Y); - } else { - Win32Error error = Win32.GetLastErrorCode(); - LOG.ErrorFormat("Error retrieving PhysicalCursorPos : {0}", Win32.GetMessage(error)); - } - } - return new Point(Cursor.Position.X, Cursor.Position.Y); - } - /// /// Retrieves the cursor location safely, accounting for DPI settings in Vista/Windows 7. This implementation /// can conveniently be used when the cursor location is needed to deal with a fullscreen bitmap. /// Point with cursor location, relative to the top left corner of the monitor setup (which itself might /// actually not be on any screen) public static Point GetCursorLocationRelativeToScreenBounds() { - return GetLocationRelativeToScreenBounds(GetCursorLocation()); + return GetLocationRelativeToScreenBounds(User32.GetCursorLocation()); } /// @@ -515,7 +498,7 @@ namespace GreenshotPlugin.Core { if (cursorInfo.flags == User32.CURSOR_SHOWING) { using (SafeIconHandle safeIcon = User32.CopyIcon(cursorInfo.hCursor)) { if (User32.GetIconInfo(safeIcon, out iconInfo)) { - Point cursorLocation = GetCursorLocation(); + Point cursorLocation = User32.GetCursorLocation(); // Allign cursor location to Bitmap coordinates (instead of Screen coordinates) x = cursorLocation.X - iconInfo.xHotspot - capture.ScreenBounds.X; y = cursorLocation.Y - iconInfo.yHotspot - capture.ScreenBounds.Y; diff --git a/GreenshotPlugin/UnmanagedHelpers/User32.cs b/GreenshotPlugin/UnmanagedHelpers/User32.cs index e378ff1ec..74caffcc7 100644 --- a/GreenshotPlugin/UnmanagedHelpers/User32.cs +++ b/GreenshotPlugin/UnmanagedHelpers/User32.cs @@ -18,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + using System; using System.ComponentModel; using System.Diagnostics; @@ -28,6 +29,7 @@ using System.Windows.Forms; using Microsoft.Win32.SafeHandles; using System.Security; using System.Security.Permissions; +using log4net; namespace GreenshotPlugin.UnmanagedHelpers { /// @@ -42,6 +44,8 @@ namespace GreenshotPlugin.UnmanagedHelpers { /// User32 Wrappers /// public static class User32 { + private static readonly ILog LOG = LogManager.GetLogger(typeof(User32)); + private static bool _CanCallGetPhysicalCursorPos = true; public const int SC_RESTORE = 0xF120; public const int SC_CLOSE = 0xF060; public const int SC_MAXIMIZE = 0xF030; @@ -55,7 +59,8 @@ namespace GreenshotPlugin.UnmanagedHelpers { public const int MONITOR_DEFAULTTOPRIMARY = 1; public const int MONITOR_DEFAULTTONEAREST = 2; public const Int32 CURSOR_SHOWING = 0x00000001; - + + #region DllImports [DllImport("user32", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public extern static bool IsWindowVisible(IntPtr hWnd); @@ -186,7 +191,7 @@ namespace GreenshotPlugin.UnmanagedHelpers { [DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult); [DllImport("user32", SetLastError = true)] - public static extern bool GetPhysicalCursorPos(out POINT cursorLocation); + private static extern bool GetPhysicalCursorPos(out POINT cursorLocation); [DllImport("user32", SetLastError=true)] public static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref POINT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints); [DllImport("user32", SetLastError = true)] @@ -213,6 +218,30 @@ namespace GreenshotPlugin.UnmanagedHelpers { [DllImport("user32", SetLastError = true)] public static extern IntPtr CreateIconIndirect(ref IconInfo icon); + #endregion + + /// + /// Retrieves the cursor location safely, accounting for DPI settings in Vista/Windows 7. + /// Point with cursor location, relative to the origin of the monitor setup + /// (i.e. negative coordinates arepossible in multiscreen setups) + public static Point GetCursorLocation() { + if (Environment.OSVersion.Version.Major >= 6 && _CanCallGetPhysicalCursorPos) { + POINT cursorLocation; + try { + if (GetPhysicalCursorPos(out cursorLocation)) { + return new Point(cursorLocation.X, cursorLocation.Y); + } else { + Win32Error error = Win32.GetLastErrorCode(); + LOG.ErrorFormat("Error retrieving PhysicalCursorPos : {0}", Win32.GetMessage(error)); + } + } catch (Exception ex) { + LOG.Error("Exception retrieving PhysicalCursorPos, no longer calling this. Cause :", ex); + _CanCallGetPhysicalCursorPos = false; + } + } + return new Point(Cursor.Position.X, Cursor.Position.Y); + } + /// /// Wrapper for the GetClassLong which decides if the system is 64-bit or not and calls the right one. ///