diff --git a/src/ManagedShell.AppBar/AppBarWindow.cs b/src/ManagedShell.AppBar/AppBarWindow.cs index b3f9e78a..daaab462 100644 --- a/src/ManagedShell.AppBar/AppBarWindow.cs +++ b/src/ManagedShell.AppBar/AppBarWindow.cs @@ -465,7 +465,10 @@ protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lPa switch ((NativeMethods.AppBarNotifications)wParam.ToInt32()) { case NativeMethods.AppBarNotifications.PosChanged: - _appBarManager.ABSetPos(this); + if (!DeferWorkArea) + { + _appBarManager.ABSetPos(this); + } break; case NativeMethods.AppBarNotifications.WindowArrange: @@ -538,14 +541,14 @@ protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lPa changed = true; } - if (changed && AppBarMode == AppBarMode.Normal && !EnvironmentHelper.IsAppRunningAsShell && !AllowClose) + if (changed && AppBarMode == AppBarMode.Normal && !EnvironmentHelper.IsAppRunningAsShell && !AllowClose && !DeferWorkArea) { // Tell other AppBars we changed _appBarManager.AppBarWindowPosChanged(this); } // Determine if we are intentionally moving - if (changed && !IsMoving && (wndPos.flags & NativeMethods.SetWindowPosFlags.SWP_NOMOVE) == 0) + if (changed && !IsMoving && !DeferWorkArea && (wndPos.flags & NativeMethods.SetWindowPosFlags.SWP_NOMOVE) == 0) { // Someone else moved us! Let's restore state. ShellLogger.Debug($"AppBarWindow: Repositioning due to unexpected move to {wndPos.x},{wndPos.y}"); @@ -713,6 +716,8 @@ protected internal NativeMethods.Rect GetDesiredRect() return rect; } + public bool DeferWorkArea { get; set; } + protected internal bool SetWindowPosition(NativeMethods.Rect newRect) { var currentRect = WindowRect; @@ -735,7 +740,7 @@ protected internal bool SetWindowPosition(NativeMethods.Rect newRect) NativeMethods.SetWindowPos(Handle, IntPtr.Zero, newRect.Left, newRect.Top, newRect.Width, newRect.Height, swp); IsMoving = false; - if (EnvironmentHelper.IsAppRunningAsShell) + if (EnvironmentHelper.IsAppRunningAsShell && !DeferWorkArea) { _appBarManager.SetWorkArea(Screen); } @@ -768,7 +773,7 @@ protected virtual void SetScreenProperties(ScreenSetupReason reason) public virtual bool UpdatePosition() { // Let Explorer AppBar figure out our position if we are an AppBar, otherwise set our desired rect - if (AppBarMode == AppBarMode.Normal && !EnvironmentHelper.IsAppRunningAsShell) + if (AppBarMode == AppBarMode.Normal && !EnvironmentHelper.IsAppRunningAsShell && !DeferWorkArea) { return _appBarManager.ABSetPos(this); } diff --git a/src/ManagedShell.Common/Helpers/SoundHelper.cs b/src/ManagedShell.Common/Helpers/SoundHelper.cs index 382a7c34..cbe45c03 100644 --- a/src/ManagedShell.Common/Helpers/SoundHelper.cs +++ b/src/ManagedShell.Common/Helpers/SoundHelper.cs @@ -157,7 +157,7 @@ public static void PlayNotificationSound() if (EnvironmentHelper.IsWindows8OrBetter) { // Toast notification sound. - if (!PlaySystemSound("Notification.Default")) + if (!PlaySystemSound(".Default", "Notification.Default")) PlayXPNotificationSound(); } else diff --git a/src/ManagedShell.Interop/NativeMethods.Gdi32.cs b/src/ManagedShell.Interop/NativeMethods.Gdi32.cs index ff64fc2a..9cc1995f 100644 --- a/src/ManagedShell.Interop/NativeMethods.Gdi32.cs +++ b/src/ManagedShell.Interop/NativeMethods.Gdi32.cs @@ -9,5 +9,8 @@ public partial class NativeMethods [DllImport(Gdi32_DllName)] public static extern bool DeleteObject(IntPtr hObject); + + [DllImport(Gdi32_DllName)] + public static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); } } diff --git a/src/ManagedShell.Interop/NativeMethods.User32.cs b/src/ManagedShell.Interop/NativeMethods.User32.cs index 1d2d8bff..c88927da 100644 --- a/src/ManagedShell.Interop/NativeMethods.User32.cs +++ b/src/ManagedShell.Interop/NativeMethods.User32.cs @@ -36,6 +36,9 @@ public partial class NativeMethods [DllImport(User32_DllName)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); + [DllImport(User32_DllName)] + public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw); + public enum WindowZOrder { HWND_TOP = 0, @@ -232,11 +235,56 @@ public enum WindowLongFlags : int public const int HSHELL_HIGHBIT = 0x8000; public const int SC_MINIMIZE = 0xF020; + public const int SC_MAXIMIZE = 0xF030; public const int SC_MOVE = 0xF010; public const int SC_RESTORE = 0xF120; public const int SC_SIZE = 0xF000; public const int SC_CLOSE = 0xF060; + public const uint MF_BYCOMMAND = 0x00000000; + public const uint MF_GRAYED = 0x00000001; + public const uint MF_ENABLED = 0x00000000; + + // Specifies how TrackPopupMenuEx positions the shortcut menu horizontally + [Flags] + public enum TPM : uint + { + LEFTBUTTON = 0x0000, + RIGHTBUTTON = 0x0002, + LEFTALIGN = 0x0000, + CENTERALIGN = 0x0004, + RIGHTALIGN = 0x0008, + TOPALIGN = 0x0000, + VCENTERALIGN = 0x0010, + BOTTOMALIGN = 0x0020, + HORIZONTAL = 0x0000, + VERTICAL = 0x0040, + NONOTIFY = 0x0080, + RETURNCMD = 0x0100, + RECURSE = 0x0001, + HORPOSANIMATION = 0x0400, + HORNEGANIMATION = 0x0800, + VERPOSANIMATION = 0x1000, + VERNEGANIMATION = 0x2000, + NOANIMATION = 0x4000, + LAYOUTRTL = 0x8000, + WORKAREA = 0x10000 + } + + [DllImport(User32_DllName, SetLastError = true)] + public static extern bool GetCursorPos(out POINT lpPoint); + + [DllImport(User32_DllName, SetLastError = true)] + public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); + + [DllImport(User32_DllName, SetLastError = true)] + public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable); + + // Displays a shortcut menu at the specified location and + // tracks the selection of items on the shortcut menu + [DllImport(User32_DllName, ExactSpelling = true, SetLastError = true)] + public static extern uint TrackPopupMenuEx(IntPtr hMenu, TPM uFlags, int x, int y, IntPtr hWnd, IntPtr lpTPMParams); + [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { diff --git a/src/ManagedShell.Interop/NativeMethods.cs b/src/ManagedShell.Interop/NativeMethods.cs index 43d12352..bf750da5 100644 --- a/src/ManagedShell.Interop/NativeMethods.cs +++ b/src/ManagedShell.Interop/NativeMethods.cs @@ -53,16 +53,23 @@ public ShortRect(short left, short top, short right, short bottom) public int Height => Bottom - Top; } + [StructLayout(LayoutKind.Sequential)] public struct POINT { - public POINT(long x, long y) + public int x; + public int y; + + public POINT(int x, int y) { this.x = x; this.y = y; } - - public long x; - public long y; + + public POINT(long x, long y) + { + this.x = (int)x; + this.y = (int)y; + } } // lo = x; hi = y diff --git a/src/ManagedShell.ShellFolders/Enums/TPM.cs b/src/ManagedShell.ShellFolders/Enums/TPM.cs deleted file mode 100644 index 31295583..00000000 --- a/src/ManagedShell.ShellFolders/Enums/TPM.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace ManagedShell.ShellFolders.Enums -{ - // Specifies how TrackPopupMenuEx positions the shortcut menu horizontally - [Flags] - public enum TPM : uint - { - LEFTBUTTON = 0x0000, - RIGHTBUTTON = 0x0002, - LEFTALIGN = 0x0000, - CENTERALIGN = 0x0004, - RIGHTALIGN = 0x0008, - TOPALIGN = 0x0000, - VCENTERALIGN = 0x0010, - BOTTOMALIGN = 0x0020, - HORIZONTAL = 0x0000, - VERTICAL = 0x0040, - NONOTIFY = 0x0080, - RETURNCMD = 0x0100, - RECURSE = 0x0001, - HORPOSANIMATION = 0x0400, - HORNEGANIMATION = 0x0800, - VERPOSANIMATION = 0x1000, - VERNEGANIMATION = 0x2000, - NOANIMATION = 0x4000, - LAYOUTRTL = 0x8000 - } -} diff --git a/src/ManagedShell.ShellFolders/Interop.cs b/src/ManagedShell.ShellFolders/Interop.cs index 0d8a4242..0b2658c1 100644 --- a/src/ManagedShell.ShellFolders/Interop.cs +++ b/src/ManagedShell.ShellFolders/Interop.cs @@ -119,19 +119,6 @@ public static extern int CoCreateInstance( ref Guid riid, out IntPtr ppv); - // Displays a shortcut menu at the specified location and - // tracks the selection of items on the shortcut menu - [DllImport("user32.dll", - ExactSpelling = true, - CharSet = CharSet.Auto)] - public static extern uint TrackPopupMenuEx( - IntPtr hmenu, - TPM flags, - int x, - int y, - IntPtr hwnd, - IntPtr lptpm); - // Creates a popup-menu. The menu is initially empty, but it can be filled with // menu items by using the InsertMenuItem, AppendMenu, and InsertMenu functions [DllImport("user32", diff --git a/src/ManagedShell.ShellFolders/ShellFolderContextMenu.cs b/src/ManagedShell.ShellFolders/ShellFolderContextMenu.cs index c3551800..8df4d410 100644 --- a/src/ManagedShell.ShellFolders/ShellFolderContextMenu.cs +++ b/src/ManagedShell.ShellFolders/ShellFolderContextMenu.cs @@ -86,9 +86,9 @@ private void ShowMenu(ShellFolder folder, IntPtr contextMenu) NativeMethods.AllowDarkModeForWindow(Handle, true); } - uint selected = Interop.TrackPopupMenuEx( + uint selected = NativeMethods.TrackPopupMenuEx( contextMenu, - TPM.RETURNCMD, + NativeMethods.TPM.RETURNCMD, x, y, Handle, diff --git a/src/ManagedShell.ShellFolders/ShellItemContextMenu.cs b/src/ManagedShell.ShellFolders/ShellItemContextMenu.cs index e98c4045..7673461b 100644 --- a/src/ManagedShell.ShellFolders/ShellItemContextMenu.cs +++ b/src/ManagedShell.ShellFolders/ShellItemContextMenu.cs @@ -171,9 +171,9 @@ private void ShowMenu(ShellItem[] files, bool allFolders) NativeMethods.AllowDarkModeForWindow(Handle, true); } - uint selected = Interop.TrackPopupMenuEx( + uint selected = NativeMethods.TrackPopupMenuEx( nativeMenuPtr, - TPM.RETURNCMD, + NativeMethods.TPM.RETURNCMD, x, y, Handle,