diff --git a/GreenshotPlugin/UnmanagedHelpers/Enumerations.cs b/GreenshotPlugin/UnmanagedHelpers/Enumerations.cs index edd85a168..a449832fa 100644 --- a/GreenshotPlugin/UnmanagedHelpers/Enumerations.cs +++ b/GreenshotPlugin/UnmanagedHelpers/Enumerations.cs @@ -1221,4 +1221,21 @@ namespace GreenshotPlugin.UnmanagedHelpers { OBJID_VSCROLL = -5, OBJID_WINDOW = 0 } + + [Flags] + public enum DesktopAccessRight : uint { + DESKTOP_READOBJECTS = 0x00000001, + DESKTOP_CREATEWINDOW = 0x00000002, + DESKTOP_CREATEMENU = 0x00000004, + DESKTOP_HOOKCONTROL = 0x00000008, + DESKTOP_JOURNALRECORD = 0x00000010, + DESKTOP_JOURNALPLAYBACK = 0x00000020, + DESKTOP_ENUMERATE = 0x00000040, + DESKTOP_WRITEOBJECTS = 0x00000080, + DESKTOP_SWITCHDESKTOP = 0x00000100, + + GENERIC_ALL = (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | + DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | + DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP) + }; } diff --git a/GreenshotPlugin/UnmanagedHelpers/User32.cs b/GreenshotPlugin/UnmanagedHelpers/User32.cs index 74caffcc7..1a751ad1b 100644 --- a/GreenshotPlugin/UnmanagedHelpers/User32.cs +++ b/GreenshotPlugin/UnmanagedHelpers/User32.cs @@ -218,10 +218,19 @@ namespace GreenshotPlugin.UnmanagedHelpers { [DllImport("user32", SetLastError = true)] public static extern IntPtr CreateIconIndirect(ref IconInfo icon); + [DllImport("user32", SetLastError = true)] + public static extern IntPtr OpenInputDesktop(uint dwFlags, bool fInherit, DesktopAccessRight dwDesiredAccess); + [DllImport("user32", SetLastError = true)] + public static extern bool SetThreadDesktop(IntPtr hDesktop); + [DllImport("user32", SetLastError = true)] + public static extern bool CloseDesktop(IntPtr hDesktop); + + #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() { @@ -320,6 +329,34 @@ namespace GreenshotPlugin.UnmanagedHelpers { /// public delegate void WinEventDelegate(IntPtr hWinEventHook, WinEvent eventType, IntPtr hwnd, EventObjects idObject, int idChild, uint dwEventThread, uint dwmsEventTime); + /// + /// A SafeHandle class implementation for the current input desktop + /// + public class SafeCurrentInputDesktopHandle : SafeHandleZeroOrMinusOneIsInvalid { + private static readonly ILog LOG = LogManager.GetLogger(typeof(SafeCurrentInputDesktopHandle)); + + public SafeCurrentInputDesktopHandle() : base(true) { + IntPtr hDesktop = User32.OpenInputDesktop(0, true, DesktopAccessRight.GENERIC_ALL); + if (hDesktop != IntPtr.Zero) { + SetHandle(hDesktop); + if (User32.SetThreadDesktop(hDesktop)) { + LOG.DebugFormat("Switched to desktop {0}", hDesktop); + } else { + LOG.WarnFormat("Couldn't switch to desktop {0}", hDesktop); + LOG.Error(User32.CreateWin32Exception("SetThreadDesktop")); + } + } else { + LOG.Warn("Couldn't get current desktop."); + LOG.Error(User32.CreateWin32Exception("OpenInputDesktop")); + } + } + + [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] + protected override bool ReleaseHandle() { + return User32.CloseDesktop(handle); + } + } + /// /// A SafeHandle class implementation for the hIcon ///