From ce314678b5140075744361c8110e3377209bbd0a Mon Sep 17 00:00:00 2001 From: Daniel Clark Date: Sat, 13 Feb 2021 17:08:00 +0000 Subject: [PATCH] Moved all PInvokes to a lower class without any relianceon WPF, NotificationIconHelper, TaskbarHelper, SystemPersonalisationHelper are WPF window no more --- .../NotificationFlyoutSample.Host.csproj | 3 - samples/NotificationFlyoutSample.sln | 168 +++++++-------- .../NotificationFlyoutSample.csproj | 8 +- .../Extensions/ExecutionMode.cs | 2 +- .../Extensions/ImageSourceExtensions.cs | 3 +- .../Extensions/OperatingSystemExtensions.cs | 9 + .../Extensions/OperatingSystemVersion.cs | 2 +- .../Extensions/RECTExtensions.cs | 5 +- .../Extensions/RegistryKeyExtensions.cs | 2 +- .../Helpers/CursorHelper.cs | 2 +- .../NotificationIconHelper.PInvokes.cs | 81 +++++++ .../Helpers/NotificationIconHelper.cs | 110 ++++++++++ .../NotificationIconInvokedEventArgs.cs | 11 + .../Helpers/PointerButton.cs | 11 + .../Helpers}/Screen.cs | 5 +- .../Helpers/SystemInformationHelper.cs | 15 +- .../SystemPersonalisationChangedEventArgs.cs} | 2 +- .../Helpers/SystemPersonalisationHelper.cs | 28 +-- .../Helpers/SystemTheme.cs | 2 +- .../Helpers/TaskbarHelper.PInvokes.cs | 55 +++++ .../Helpers/TaskbarHelper.cs | 51 +++++ .../Helpers/TaskbarPosition.cs | 2 +- .../Helpers/TaskbarState.cs | 4 +- .../Helpers/WindowHelper.cs | 12 ++ .../Helpers/WndProcHelper.PInvokes.cs | 35 +++ .../Helpers/WndProcHelper.cs | 50 +++++ .../Helpers/WndProcHelperMessageEventArgs.cs | 18 ++ .../Helpers/WndProcMessages.cs | 2 +- .../INotificationFlyoutApplication.cs | 0 .../NativeMethods.json | 4 + .../NativeMethods.txt | 11 +- .../NotificationFlyout.Shared.UI.csproj} | 32 +-- .../Properties/AssemblyInfo.cs | 5 + .../WndProc/IWndProcHandler.cs | 9 + .../WndProc/IWndProcHandlerCollection.cs | 8 + .../WndProc/IWndProcHandlerSubscriber.cs | 7 + .../WndProc/WndProcHandlerCollection.cs | 11 + .../WndProc/WndProcHandlerReference.cs | 26 +++ .../WndProc/WndProcHandlerSubscriber.cs | 21 ++ .../WndProc/WndProcListener.cs | 49 +++++ .../NotificationFlyout.Uwp.UI.Controls.csproj | 13 +- .../NotificationFlyoutHost.cs | 9 + .../NotificationFlyoutHost.xaml | 2 +- .../NativeMethods.txt | 2 - .../NotificationFlyout.Wpf.UI.Controls.csproj | 2 +- .../NotificationFlyoutApplication.cs | 5 +- .../NotificationFlyoutContextMenuXamlHost.cs | 2 +- .../NotificationFlyoutXamlHost.cs | 32 ++- .../Extensions/ImageSourceExtensions.cs | 19 +- .../Extensions/OperatingSystemExtensions.cs | 13 -- .../Helpers/NotificationIconHelper.cs | 201 ------------------ .../NotificationIconInvokedEventArgs.cs | 10 - .../Helpers/TaskbarHelper.cs | 118 ---------- .../Helpers/WindowHelper.cs | 18 -- .../NativeMethods.json | 4 + .../NotificationFlyout.Wpf.UI.csproj | 15 +- src/NotificationFlyout.sln | 42 ++-- 57 files changed, 800 insertions(+), 588 deletions(-) rename src/{NotificationFlyout.Uwp.UI => NotificationFlyout.Shared.UI}/Extensions/ExecutionMode.cs (86%) rename src/{NotificationFlyout.Uwp.UI => NotificationFlyout.Shared.UI}/Extensions/ImageSourceExtensions.cs (93%) create mode 100644 src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemExtensions.cs rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Extensions/OperatingSystemVersion.cs (85%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Extensions/RECTExtensions.cs (83%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Extensions/RegistryKeyExtensions.cs (87%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/CursorHelper.cs (83%) create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.PInvokes.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/NotificationIconInvokedEventArgs.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/PointerButton.cs rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI/Helpers}/Screen.cs (97%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/SystemInformationHelper.cs (71%) rename src/{NotificationFlyout.Wpf.UI/Helpers/ThemeChangedEventArgs.cs => NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationChangedEventArgs.cs} (89%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/SystemPersonalisationHelper.cs (64%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/SystemTheme.cs (59%) create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.PInvokes.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.cs rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/TaskbarPosition.cs (70%) rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/TaskbarState.cs (65%) create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/WindowHelper.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.PInvokes.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.cs create mode 100644 src/NotificationFlyout.Shared.UI/Helpers/WndProcHelperMessageEventArgs.cs rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/Helpers/WndProcMessages.cs (80%) rename src/{NotificationFlyout.Uwp.UI => NotificationFlyout.Shared.UI}/INotificationFlyoutApplication.cs (100%) create mode 100644 src/NotificationFlyout.Shared.UI/NativeMethods.json rename src/{NotificationFlyout.Wpf.UI => NotificationFlyout.Shared.UI}/NativeMethods.txt (75%) rename src/{NotificationFlyout.Uwp.UI/NotificationFlyout.Uwp.UI.csproj => NotificationFlyout.Shared.UI/NotificationFlyout.Shared.UI.csproj} (50%) create mode 100644 src/NotificationFlyout.Shared.UI/Properties/AssemblyInfo.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandler.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerCollection.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerSubscriber.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerCollection.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerReference.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerSubscriber.cs create mode 100644 src/NotificationFlyout.Shared.UI/WndProc/WndProcListener.cs delete mode 100644 src/NotificationFlyout.Uwp.UI/NativeMethods.txt delete mode 100644 src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs delete mode 100644 src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs delete mode 100644 src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs delete mode 100644 src/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs delete mode 100644 src/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs create mode 100644 src/NotificationFlyout.Wpf.UI/NativeMethods.json diff --git a/samples/NotificationFlyoutSample.Host/NotificationFlyoutSample.Host.csproj b/samples/NotificationFlyoutSample.Host/NotificationFlyoutSample.Host.csproj index 60019fc..92bb23f 100644 --- a/samples/NotificationFlyoutSample.Host/NotificationFlyoutSample.Host.csproj +++ b/samples/NotificationFlyoutSample.Host/NotificationFlyoutSample.Host.csproj @@ -17,10 +17,7 @@ - - - diff --git a/samples/NotificationFlyoutSample.sln b/samples/NotificationFlyoutSample.sln index 909956b..2667c1c 100644 --- a/samples/NotificationFlyoutSample.sln +++ b/samples/NotificationFlyoutSample.sln @@ -12,13 +12,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI.Controls", "..\src\NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj", "{95F851E4-87A5-4BB7-953E-C0FE3B306F0E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Shared.UI", "..\src\NotificationFlyout.Shared.UI\NotificationFlyout.Shared.UI.csproj", "{5A47C726-FA50-4A16-B639-DEC79B9D365B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI", "..\src\NotificationFlyout.Wpf.UI\NotificationFlyout.Wpf.UI.csproj", "{49BCC188-22D2-468B-89EA-99C810BE790E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI.Controls", "..\src\NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj", "{197A7AC8-6F6B-48D4-A95B-9AE9E2008817}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI.Controls", "..\src\NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj", "{094A2030-C430-490B-AB26-205385A0D4BF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI", "..\src\NotificationFlyout.Wpf.UI\NotificationFlyout.Wpf.UI.csproj", "{3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI", "..\src\NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj", "{AFCE4980-A641-4BBB-A745-F0D4E54A0D86}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI.Controls", "..\src\NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj", "{DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -81,86 +81,86 @@ Global {2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}.Release|x86.ActiveCfg = Release|x86 {2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}.Release|x86.Build.0 = Release|x86 {2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}.Release|x86.Deploy.0 = Release|x86 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|Any CPU.ActiveCfg = Debug|x64 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|Any CPU.Build.0 = Debug|x64 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|ARM.Build.0 = Debug|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|ARM64.Build.0 = Debug|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|x64.ActiveCfg = Debug|x64 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|x64.Build.0 = Debug|x64 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|x86.ActiveCfg = Debug|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Debug|x86.Build.0 = Debug|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|Any CPU.Build.0 = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|ARM.ActiveCfg = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|ARM.Build.0 = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|ARM64.ActiveCfg = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|ARM64.Build.0 = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|x64.ActiveCfg = Release|x64 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|x64.Build.0 = Release|x64 - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|x86.ActiveCfg = Release|Any CPU - {95F851E4-87A5-4BB7-953E-C0FE3B306F0E}.Release|x86.Build.0 = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|Any CPU.ActiveCfg = Debug|x64 - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|Any CPU.Build.0 = Debug|x64 - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|ARM.Build.0 = Debug|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|ARM64.Build.0 = Debug|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|x64.ActiveCfg = Debug|x64 - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|x64.Build.0 = Debug|x64 - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|x86.ActiveCfg = Debug|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Debug|x86.Build.0 = Debug|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|Any CPU.Build.0 = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|ARM.ActiveCfg = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|ARM.Build.0 = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|ARM64.ActiveCfg = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|ARM64.Build.0 = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|x64.ActiveCfg = Release|x64 - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|x64.Build.0 = Release|x64 - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|x86.ActiveCfg = Release|Any CPU - {49BCC188-22D2-468B-89EA-99C810BE790E}.Release|x86.Build.0 = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|Any CPU.ActiveCfg = Debug|x64 - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|Any CPU.Build.0 = Debug|x64 - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|ARM.ActiveCfg = Debug|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|ARM.Build.0 = Debug|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|ARM64.Build.0 = Debug|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|x64.ActiveCfg = Debug|x64 - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|x64.Build.0 = Debug|x64 - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|x86.ActiveCfg = Debug|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Debug|x86.Build.0 = Debug|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|Any CPU.Build.0 = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|ARM.ActiveCfg = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|ARM.Build.0 = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|ARM64.ActiveCfg = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|ARM64.Build.0 = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|x64.ActiveCfg = Release|x64 - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|x64.Build.0 = Release|x64 - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|x86.ActiveCfg = Release|Any CPU - {094A2030-C430-490B-AB26-205385A0D4BF}.Release|x86.Build.0 = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|ARM.ActiveCfg = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|ARM.Build.0 = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|ARM64.Build.0 = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|x64.ActiveCfg = Debug|x64 - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|x64.Build.0 = Debug|x64 - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|x86.ActiveCfg = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Debug|x86.Build.0 = Debug|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|Any CPU.Build.0 = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|ARM.ActiveCfg = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|ARM.Build.0 = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|ARM64.ActiveCfg = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|ARM64.Build.0 = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x64.ActiveCfg = Release|x64 - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x64.Build.0 = Release|x64 - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x86.ActiveCfg = Release|Any CPU - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x86.Build.0 = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|ARM.ActiveCfg = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|ARM.Build.0 = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|ARM64.Build.0 = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|x64.ActiveCfg = Debug|x64 + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|x64.Build.0 = Debug|x64 + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|x86.ActiveCfg = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Debug|x86.Build.0 = Debug|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|Any CPU.Build.0 = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|ARM.ActiveCfg = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|ARM.Build.0 = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|ARM64.ActiveCfg = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|ARM64.Build.0 = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|x64.ActiveCfg = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|x64.Build.0 = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|x86.ActiveCfg = Release|Any CPU + {5A47C726-FA50-4A16-B639-DEC79B9D365B}.Release|x86.Build.0 = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|Any CPU.Build.0 = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|ARM.ActiveCfg = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|ARM.Build.0 = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|ARM64.Build.0 = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|x64.ActiveCfg = Debug|x64 + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|x64.Build.0 = Debug|x64 + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|x86.ActiveCfg = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Debug|x86.Build.0 = Debug|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|Any CPU.ActiveCfg = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|Any CPU.Build.0 = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|ARM.ActiveCfg = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|ARM.Build.0 = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|ARM64.ActiveCfg = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|ARM64.Build.0 = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|x64.ActiveCfg = Release|x64 + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|x64.Build.0 = Release|x64 + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|x86.ActiveCfg = Release|Any CPU + {197A7AC8-6F6B-48D4-A95B-9AE9E2008817}.Release|x86.Build.0 = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|ARM.ActiveCfg = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|ARM.Build.0 = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|ARM64.Build.0 = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|x64.ActiveCfg = Debug|x64 + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|x64.Build.0 = Debug|x64 + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Debug|x86.Build.0 = Debug|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|Any CPU.Build.0 = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|ARM.ActiveCfg = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|ARM.Build.0 = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|ARM64.ActiveCfg = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|ARM64.Build.0 = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|x64.ActiveCfg = Release|x64 + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|x64.Build.0 = Release|x64 + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|x86.ActiveCfg = Release|Any CPU + {3222D603-00E9-4C00-BDA3-B2F33AFDE4BB}.Release|x86.Build.0 = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|ARM.ActiveCfg = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|ARM.Build.0 = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|ARM64.Build.0 = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|x64.ActiveCfg = Debug|x64 + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|x64.Build.0 = Debug|x64 + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|x86.ActiveCfg = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Debug|x86.Build.0 = Debug|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|Any CPU.Build.0 = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|ARM.ActiveCfg = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|ARM.Build.0 = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|ARM64.ActiveCfg = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|ARM64.Build.0 = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|x64.ActiveCfg = Release|x64 + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|x64.Build.0 = Release|x64 + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|x86.ActiveCfg = Release|Any CPU + {DEEF73AF-26B6-46BE-B824-0FDF0EE671F3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/samples/NotificationFlyoutSample/NotificationFlyoutSample.csproj b/samples/NotificationFlyoutSample/NotificationFlyoutSample.csproj index 4ce7fa6..1d8e753 100644 --- a/samples/NotificationFlyoutSample/NotificationFlyoutSample.csproj +++ b/samples/NotificationFlyoutSample/NotificationFlyoutSample.csproj @@ -173,12 +173,12 @@ - {95f851e4-87a5-4bb7-953e-c0fe3b306f0e} + {197a7ac8-6f6b-48d4-a95b-9ae9e2008817} NotificationFlyout.Uwp.UI.Controls - - {AFCE4980-A641-4BBB-A745-F0D4E54A0D86} - NotificationFlyout.Uwp.UI + + {197a7ac8-6f6b-48d4-a95b-9ae9e2008817} + NotificationFlyout.Shared.UI diff --git a/src/NotificationFlyout.Uwp.UI/Extensions/ExecutionMode.cs b/src/NotificationFlyout.Shared.UI/Extensions/ExecutionMode.cs similarity index 86% rename from src/NotificationFlyout.Uwp.UI/Extensions/ExecutionMode.cs rename to src/NotificationFlyout.Shared.UI/Extensions/ExecutionMode.cs index f19d8fc..04bac75 100644 --- a/src/NotificationFlyout.Uwp.UI/Extensions/ExecutionMode.cs +++ b/src/NotificationFlyout.Shared.UI/Extensions/ExecutionMode.cs @@ -1,6 +1,6 @@ using Microsoft.Windows.Sdk; -namespace NotificationFlyout.Uwp.UI.Extensions +namespace NotificationFlyout.Shared.UI.Extensions { internal class ExecutionMode { diff --git a/src/NotificationFlyout.Uwp.UI/Extensions/ImageSourceExtensions.cs b/src/NotificationFlyout.Shared.UI/Extensions/ImageSourceExtensions.cs similarity index 93% rename from src/NotificationFlyout.Uwp.UI/Extensions/ImageSourceExtensions.cs rename to src/NotificationFlyout.Shared.UI/Extensions/ImageSourceExtensions.cs index 6ff6806..a3851ec 100644 --- a/src/NotificationFlyout.Uwp.UI/Extensions/ImageSourceExtensions.cs +++ b/src/NotificationFlyout.Shared.UI/Extensions/ImageSourceExtensions.cs @@ -1,4 +1,5 @@ using Microsoft.Windows.Sdk; +using NotificationFlyout.Shared.UI.Extensions; using System; using System.Drawing; using System.IO; @@ -6,7 +7,7 @@ using System.Threading.Tasks; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; -namespace NotificationFlyout.Uwp.UI.Extensions +namespace NotificationFlyout.Shared.UI.Extensions { public static class ImageSourceExtensions { diff --git a/src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemExtensions.cs b/src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemExtensions.cs new file mode 100644 index 0000000..f832700 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemExtensions.cs @@ -0,0 +1,9 @@ +using System; + +namespace NotificationFlyout.Shared.UI.Extensions +{ + public static class OperatingSystemExtensions + { + public static bool IsGreaterThan(this OperatingSystem operatingSystem, OperatingSystemVersion version) => operatingSystem.Version.Build > (int)version; + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemVersion.cs b/src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemVersion.cs similarity index 85% rename from src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemVersion.cs rename to src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemVersion.cs index 35de1b3..9ac6b3e 100644 --- a/src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemVersion.cs +++ b/src/NotificationFlyout.Shared.UI/Extensions/OperatingSystemVersion.cs @@ -1,4 +1,4 @@ -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Extensions { public enum OperatingSystemVersion : int { diff --git a/src/NotificationFlyout.Wpf.UI/Extensions/RECTExtensions.cs b/src/NotificationFlyout.Shared.UI/Extensions/RECTExtensions.cs similarity index 83% rename from src/NotificationFlyout.Wpf.UI/Extensions/RECTExtensions.cs rename to src/NotificationFlyout.Shared.UI/Extensions/RECTExtensions.cs index 6b8c2f7..b05240e 100644 --- a/src/NotificationFlyout.Wpf.UI/Extensions/RECTExtensions.cs +++ b/src/NotificationFlyout.Shared.UI/Extensions/RECTExtensions.cs @@ -1,14 +1,13 @@ using Microsoft.Windows.Sdk; -using System.Windows; +using Windows.Foundation; -namespace NotificationFlyout.Wpf.UI.Extensions +namespace NotificationFlyout.Shared.UI.Extensions { internal static class RECTExtensions { internal static Rect ToRect(this RECT rect) { if (rect.right - rect.left < 0 || rect.bottom - rect.top < 0) return new Rect(rect.left, rect.top, 0, 0); - return new Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); } } diff --git a/src/NotificationFlyout.Wpf.UI/Extensions/RegistryKeyExtensions.cs b/src/NotificationFlyout.Shared.UI/Extensions/RegistryKeyExtensions.cs similarity index 87% rename from src/NotificationFlyout.Wpf.UI/Extensions/RegistryKeyExtensions.cs rename to src/NotificationFlyout.Shared.UI/Extensions/RegistryKeyExtensions.cs index cfdd6e9..d3fc097 100644 --- a/src/NotificationFlyout.Wpf.UI/Extensions/RegistryKeyExtensions.cs +++ b/src/NotificationFlyout.Shared.UI/Extensions/RegistryKeyExtensions.cs @@ -1,6 +1,6 @@ using Microsoft.Win32; -namespace NotificationFlyout.Wpf.UI.Extensions +namespace NotificationFlyout.Shared.UI.Extensions { public static class RegistryKeyExtensions { diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/CursorHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/CursorHelper.cs similarity index 83% rename from src/NotificationFlyout.Wpf.UI/Helpers/CursorHelper.cs rename to src/NotificationFlyout.Shared.UI/Helpers/CursorHelper.cs index dd6e39d..d06b187 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/CursorHelper.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/CursorHelper.cs @@ -1,6 +1,6 @@ using Microsoft.Windows.Sdk; -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Helpers { internal class CursorHelper { diff --git a/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.PInvokes.cs b/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.PInvokes.cs new file mode 100644 index 0000000..169e419 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.PInvokes.cs @@ -0,0 +1,81 @@ +using System; +using System.Runtime.InteropServices; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public partial class NotificationIconHelper + { + private enum NotifyIconBalloonType + { + None = 0x00, + Info = 0x01, + Warning = 0x02, + Error = 0x03, + User = 0x04, + NoSound = 0x10, + LargeIcon = 0x20, + RespectQuietTime = 0x80 + } + + private enum NotifyIconCommand : uint + { + Add = 0x0, + Delete = 0x2, + Modify = 0x1, + SetVersion = 0x4 + } + + [Flags] + private enum NotifyIconDataMember : uint + { + Message = 0x01, + Icon = 0x02, + Tip = 0x04, + State = 0x08, + Info = 0x10, + Realtime = 0x40, + UseLegacyToolTips = 0x80 + } + + private enum NotifyIconState : uint + { + Visible = 0x00, + Hidden = 0x01 + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); + + [DllImport("shell32.dll", SetLastError = true)] + private static extern int Shell_NotifyIcon(NotifyIconCommand notifyCommand, ref NotifyIconData notifyIconData); + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + private struct NotifyIconData + { + public uint cbSize; + public IntPtr WindowHandle; + public uint TaskbarIconId; + public NotifyIconDataMember ValidMembers; + public uint CallbackMessageId; + public IntPtr IconHandle; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string ToolTipText; + + public NotifyIconState IconState; + public NotifyIconState StateMask; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string BalloonText; + + public uint VersionOrTimeout; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string BalloonTitle; + + public NotifyIconBalloonType BalloonFlags; + public Guid TaskbarIconGuid; + public IntPtr CustomBalloonIconHandle; + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.cs new file mode 100644 index 0000000..23c2a46 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconHelper.cs @@ -0,0 +1,110 @@ +using System; +using System.Runtime.InteropServices; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public partial class NotificationIconHelper : IDisposable, IWndProcHandler + { + private const int CallbackMessage = 0x400; + private const uint IconVersion = 0x4; + + private readonly object _lock = new(); + private bool _isDisposed; + private NotifyIconData _notifyIconData; + + private NotificationIconHelper() + { + WndProcHandlerSubscriber.Current.Subscribe(this); + CreateNotificationIcon(); + } + + ~NotificationIconHelper() + { + Dispose(false); + } + + public event EventHandler IconInvoked; + + public static NotificationIconHelper Create() => new(); + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Handle(uint message, IntPtr wParam, IntPtr lParam) + { + if (message == CallbackMessage) + { + switch ((uint)lParam) + { + case (uint)WndProcMessages.WM_LBUTTONUP: + InvokeIconInvoked(PointerButton.Left); + break; + + case (uint)WndProcMessages.WM_MBUTTONUP: + InvokeIconInvoked(PointerButton.Middle); + break; + + case (uint)WndProcMessages.WM_RBUTTONUP: + InvokeIconInvoked(PointerButton.Right); + break; + } + } + } + + public void SetIcon(IntPtr iconHandle) + { + lock (_lock) + { + _notifyIconData.IconHandle = iconHandle; + WriteNotifyIconData(NotifyIconCommand.Modify, NotifyIconDataMember.Icon); + } + } + + private void CreateNotificationIcon() + { + lock (_lock) + { + _notifyIconData = new NotifyIconData(); + + _notifyIconData.cbSize = (uint)Marshal.SizeOf(_notifyIconData); + _notifyIconData.WindowHandle = WndProcListener.Current.Handle; + _notifyIconData.TaskbarIconId = 0x0; + _notifyIconData.CallbackMessageId = CallbackMessage; + _notifyIconData.VersionOrTimeout = IconVersion; + + _notifyIconData.IconHandle = IntPtr.Zero; + + _notifyIconData.IconState = NotifyIconState.Hidden; + _notifyIconData.StateMask = NotifyIconState.Hidden; + + WriteNotifyIconData(NotifyIconCommand.Add, NotifyIconDataMember.Message | NotifyIconDataMember.Icon | NotifyIconDataMember.Tip); + } + } + + private void Dispose(bool disposing) + { + if (_isDisposed || !disposing) return; + lock (_lock) + { + _isDisposed = true; + RemoveNotificationIcon(); + } + } + + private void InvokeIconInvoked(PointerButton pointerButton) => IconInvoked?.Invoke(this, new NotificationIconInvokedEventArgs(pointerButton)); + + private void RemoveNotificationIcon() => WriteNotifyIconData(NotifyIconCommand.Delete, NotifyIconDataMember.Message); + + private void WriteNotifyIconData(NotifyIconCommand command, NotifyIconDataMember flags) + { + _notifyIconData.ValidMembers = flags; + lock (_lock) + { + Shell_NotifyIcon(command, ref _notifyIconData); + } + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconInvokedEventArgs.cs b/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconInvokedEventArgs.cs new file mode 100644 index 0000000..e101c6c --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/NotificationIconInvokedEventArgs.cs @@ -0,0 +1,11 @@ +using System; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public class NotificationIconInvokedEventArgs : EventArgs + { + internal NotificationIconInvokedEventArgs(PointerButton pointerButton) => PointerButton = pointerButton; + + public PointerButton PointerButton { get; private set; } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/PointerButton.cs b/src/NotificationFlyout.Shared.UI/Helpers/PointerButton.cs new file mode 100644 index 0000000..590fcd9 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/PointerButton.cs @@ -0,0 +1,11 @@ +namespace NotificationFlyout.Shared.UI.Helpers +{ + public enum PointerButton + { + Left = 0, + Middle = 1, + Right = 2, + XButton1 = 3, + XButton2 = 4 + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Screen.cs b/src/NotificationFlyout.Shared.UI/Helpers/Screen.cs similarity index 97% rename from src/NotificationFlyout.Wpf.UI/Screen.cs rename to src/NotificationFlyout.Shared.UI/Helpers/Screen.cs index 345ab03..92d006f 100644 --- a/src/NotificationFlyout.Wpf.UI/Screen.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/Screen.cs @@ -1,10 +1,9 @@ using Microsoft.Windows.Sdk; -using NotificationFlyout.Wpf.UI.Helpers; using System; using System.Runtime.InteropServices; -using System.Windows; +using Windows.Foundation; -namespace NotificationFlyout.Wpf.UI +namespace NotificationFlyout.Shared.UI.Helpers { public class Screen { diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/SystemInformationHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/SystemInformationHelper.cs similarity index 71% rename from src/NotificationFlyout.Wpf.UI/Helpers/SystemInformationHelper.cs rename to src/NotificationFlyout.Shared.UI/Helpers/SystemInformationHelper.cs index 26ddde2..26f2c35 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/SystemInformationHelper.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/SystemInformationHelper.cs @@ -1,9 +1,8 @@ using Microsoft.Windows.Sdk; -using System.Reflection; using System.Runtime.InteropServices; -using System.Windows; +using Windows.Foundation; -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Helpers { public static class SystemInformationHelper { @@ -14,16 +13,6 @@ namespace NotificationFlyout.Wpf.UI.Helpers public static Rect VirtualScreen => GetVirtualScreen(); public static Rect WorkingArea => GetWorkingArea(); - public static int GetCurrentDpi() - { - return (int)typeof(SystemParameters).GetProperty("Dpi", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null); - } - - public static double GetCurrentDpiScaleFactor() - { - return (double)GetCurrentDpi() / 96; - } - private static Rect GetVirtualScreen() { var size = new Size(PInvoke.GetSystemMetrics(SM_CXSCREEN), PInvoke.GetSystemMetrics(SM_CYSCREEN)); diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/ThemeChangedEventArgs.cs b/src/NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationChangedEventArgs.cs similarity index 89% rename from src/NotificationFlyout.Wpf.UI/Helpers/ThemeChangedEventArgs.cs rename to src/NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationChangedEventArgs.cs index 94455c5..240d893 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/ThemeChangedEventArgs.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationChangedEventArgs.cs @@ -1,6 +1,6 @@ using System; -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Helpers { public class SystemPersonalisationChangedEventArgs : EventArgs { diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/SystemPersonalisationHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationHelper.cs similarity index 64% rename from src/NotificationFlyout.Wpf.UI/Helpers/SystemPersonalisationHelper.cs rename to src/NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationHelper.cs index e96784f..6cef582 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/SystemPersonalisationHelper.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/SystemPersonalisationHelper.cs @@ -1,24 +1,20 @@ using Microsoft.Win32; -using NotificationFlyout.Wpf.UI.Extensions; +using NotificationFlyout.Shared.UI.Extensions; using System; -using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Interop; using Windows.UI.ViewManagement; -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Helpers { - public class SystemPersonalisationHelper + public class SystemPersonalisationHelper : IWndProcHandler { private readonly UISettings _settings = new(); private readonly string PersonalizeKey = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; private SystemTheme _currentTheme; private bool _isColorPrevalence; - private SystemPersonalisationHelper(Window window) + private SystemPersonalisationHelper() { - var source = HwndSource.FromHwnd(window.GetHandle()); - source.AddHook(new HwndSourceHook(WndProc)); + WndProcHandlerSubscriber.Current.Subscribe(this); _currentTheme = GetTheme(); _isColorPrevalence = GetIsColorPrevalence(); @@ -29,13 +25,7 @@ namespace NotificationFlyout.Wpf.UI.Helpers public bool IsColorPrevalence => GetIsColorPrevalence(); public SystemTheme Theme => GetTheme(); - public static SystemPersonalisationHelper Create(Window window) - { - return new SystemPersonalisationHelper(window); - } - - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); + public static SystemPersonalisationHelper Create() => new(); private bool GetIsColorPrevalence() { @@ -64,14 +54,12 @@ namespace NotificationFlyout.Wpf.UI.Helpers } } - private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + public void Handle(uint message, IntPtr wParam, IntPtr lParam) { - if (msg == (int)WndProcMessages.WM_SETTINGCHANGE) + if (message == (int)WndProcMessages.WM_SETTINGCHANGE) { RaiseThemeChangedEvent(); } - - return DefWindowProcW(hwnd, (uint)msg, wParam, (lParam)); } } } \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/SystemTheme.cs b/src/NotificationFlyout.Shared.UI/Helpers/SystemTheme.cs similarity index 59% rename from src/NotificationFlyout.Wpf.UI/Helpers/SystemTheme.cs rename to src/NotificationFlyout.Shared.UI/Helpers/SystemTheme.cs index f11aaa7..1b24272 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/SystemTheme.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/SystemTheme.cs @@ -1,4 +1,4 @@ -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Helpers { public enum SystemTheme { diff --git a/src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.PInvokes.cs b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.PInvokes.cs new file mode 100644 index 0000000..7d048a5 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.PInvokes.cs @@ -0,0 +1,55 @@ +using Microsoft.Windows.Sdk; +using System; +using System.Runtime.InteropServices; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public partial class TaskbarHelper + { + private const string ShellTrayHandleName = "Shell_TrayWnd"; + private const int SPI_SETWORKAREA = 0x002F; + private readonly uint WM_TASKBARCREATED = PInvoke.RegisterWindowMessage("TaskbarCreated"); + + private enum AppBarEdge : uint + { + Left = 0, + Top = 1, + Right = 2, + Bottom = 3 + } + + private enum AppBarMessage : uint + { + New = 0x00000000, + Remove = 0x00000001, + QueryPos = 0x00000002, + SetPos = 0x00000003, + GetState = 0x00000004, + GetTaskbarPos = 0x00000005, + Activate = 0x00000006, + GetAutoHideBar = 0x00000007, + SetAutoHideBar = 0x00000008, + WindowPosChanged = 0x00000009, + SetState = 0x0000000A, + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); + + private static IntPtr GetSystemTrayHandle() => WindowHelper.GetHandle(ShellTrayHandleName); + + [DllImport("shell32.dll", SetLastError = true)] + private static extern IntPtr SHAppBarMessage(AppBarMessage dwMessage, ref AppBarData pData); + + [StructLayout(LayoutKind.Sequential)] + private struct AppBarData + { + public uint cbSize; + public IntPtr hWnd; + public uint uCallbackMessage; + public AppBarEdge uEdge; + public RECT rect; + public int lParam; + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.cs new file mode 100644 index 0000000..b4fa57d --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarHelper.cs @@ -0,0 +1,51 @@ +using NotificationFlyout.Shared.UI.Extensions; +using System; +using System.Runtime.InteropServices; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public partial class TaskbarHelper : IWndProcHandler + { + private TaskbarHelper() => WndProcHandlerSubscriber.Current.Subscribe(this); + + public event EventHandler TaskbarChanged; + + public static TaskbarHelper Create() => new(); + + public TaskbarState GetCurrentState() + { + var handle = GetSystemTrayHandle(); + var state = new TaskbarState + { + Screen = Screen.FromHandle(handle) + }; + + var appBarData = GetAppBarData(handle); + GetAppBarPosition(ref appBarData); + + state.Rect = appBarData.rect.ToRect(); + state.Position = (TaskbarPosition)appBarData.uEdge; + + return state; + } + + public void Handle(uint message, IntPtr wParam, IntPtr lParam) + { + if (message == WM_TASKBARCREATED || message == (int)WndProcMessages.WM_SETTINGCHANGE && (int)wParam == SPI_SETWORKAREA) + { + TaskbarChanged?.Invoke(this, EventArgs.Empty); + } + } + + private AppBarData GetAppBarData(IntPtr handle) + { + return new AppBarData + { + cbSize = (uint)Marshal.SizeOf(typeof(AppBarData)), + hWnd = handle + }; + } + + private void GetAppBarPosition(ref AppBarData appBarData) => SHAppBarMessage(AppBarMessage.GetTaskbarPos, ref appBarData); + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarPosition.cs b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarPosition.cs similarity index 70% rename from src/NotificationFlyout.Wpf.UI/Helpers/TaskbarPosition.cs rename to src/NotificationFlyout.Shared.UI/Helpers/TaskbarPosition.cs index 9353f4e..47ae1d6 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarPosition.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarPosition.cs @@ -1,4 +1,4 @@ -namespace NotificationFlyout.Wpf.UI +namespace NotificationFlyout.Shared.UI.Helpers { public enum TaskbarPosition { diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarState.cs b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarState.cs similarity index 65% rename from src/NotificationFlyout.Wpf.UI/Helpers/TaskbarState.cs rename to src/NotificationFlyout.Shared.UI/Helpers/TaskbarState.cs index 7e3e020..5957190 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarState.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/TaskbarState.cs @@ -1,6 +1,6 @@ -using System.Windows; +using Windows.Foundation; -namespace NotificationFlyout.Wpf.UI +namespace NotificationFlyout.Shared.UI.Helpers { public struct TaskbarState { diff --git a/src/NotificationFlyout.Shared.UI/Helpers/WindowHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/WindowHelper.cs new file mode 100644 index 0000000..e83d13d --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/WindowHelper.cs @@ -0,0 +1,12 @@ +using Microsoft.Windows.Sdk; +using System; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public class WindowHelper + { + public static IntPtr GetHandle(string windowName) => PInvoke.FindWindow(windowName, null); + + public static uint GetDpi(IntPtr handle) => PInvoke.GetDpiForWindow((HWND)handle); + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.PInvokes.cs b/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.PInvokes.cs new file mode 100644 index 0000000..3943831 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.PInvokes.cs @@ -0,0 +1,35 @@ +using System; +using System.Runtime.InteropServices; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + internal partial class WndProcHelper + { + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr CreateWindowExW(uint dwExStyle, [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam); + + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", SetLastError = true)] + private static extern bool DestroyWindow(IntPtr handle); + + [DllImport("user32.dll", SetLastError = true)] + private static extern ushort RegisterClassW([In] ref WNDCLASSW lpWndClass); + + [StructLayout(LayoutKind.Sequential)] + private struct WNDCLASSW + { + public uint style; + public WndProcHandler lpfnWndProc; + public int cbClsExtra; + public int cbWndExtra; + public IntPtr hInstance; + public IntPtr hIcon; + public IntPtr hCursor; + public IntPtr hbrBackground; + [MarshalAs(UnmanagedType.LPWStr)] public string lpszMenuName; + [MarshalAs(UnmanagedType.LPWStr)] public string lpszClassName; + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.cs b/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.cs new file mode 100644 index 0000000..06be779 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelper.cs @@ -0,0 +1,50 @@ +using System; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + internal partial class WndProcHelper : IDisposable + { + private WndProcHandler _handler; + + private WndProcHelper() => CreateWndProcWindow(); + + private delegate IntPtr WndProcHandler(IntPtr hwnd, uint uMsg, IntPtr wparam, IntPtr lparam); + + public event EventHandler WndProcMessage; + + public IntPtr Handle { get; private set; } + + public static WndProcHelper Create() => new(); + + public void Dispose() => DestroyWindow(Handle); + + private void CreateWndProcWindow() + { + var windowName = Guid.NewGuid().ToString(); + _handler = WndProc; + + WNDCLASSW wndProcWindow; + + wndProcWindow.style = 0; + wndProcWindow.lpfnWndProc = _handler; + wndProcWindow.cbClsExtra = 0; + wndProcWindow.cbWndExtra = 0; + wndProcWindow.hInstance = IntPtr.Zero; + wndProcWindow.hIcon = IntPtr.Zero; + wndProcWindow.hCursor = IntPtr.Zero; + wndProcWindow.hbrBackground = IntPtr.Zero; + wndProcWindow.lpszMenuName = ""; + wndProcWindow.lpszClassName = windowName; + + RegisterClassW(ref wndProcWindow); + + Handle = CreateWindowExW(0, windowName, "", 0, 0, 0, 1, 1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } + + private IntPtr WndProc(IntPtr handle, uint message, IntPtr wParam, IntPtr lParam) + { + WndProcMessage?.Invoke(this, new WndProcHelperMessageEventArgs(message, wParam, lParam)); + return DefWindowProcW(handle, message, wParam, lParam); + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelperMessageEventArgs.cs b/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelperMessageEventArgs.cs new file mode 100644 index 0000000..fad0a74 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Helpers/WndProcHelperMessageEventArgs.cs @@ -0,0 +1,18 @@ +using System; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + internal class WndProcHelperMessageEventArgs : EventArgs + { + public WndProcHelperMessageEventArgs(uint message, IntPtr wParam, IntPtr lParam) + { + Message = message; + WParam = wParam; + LParam = lParam; + } + + public IntPtr LParam { get; private set; } + public uint Message { get; private set; } + public IntPtr WParam { get; private set; } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/WndProcMessages.cs b/src/NotificationFlyout.Shared.UI/Helpers/WndProcMessages.cs similarity index 80% rename from src/NotificationFlyout.Wpf.UI/Helpers/WndProcMessages.cs rename to src/NotificationFlyout.Shared.UI/Helpers/WndProcMessages.cs index e6a2cb2..ee754b3 100644 --- a/src/NotificationFlyout.Wpf.UI/Helpers/WndProcMessages.cs +++ b/src/NotificationFlyout.Shared.UI/Helpers/WndProcMessages.cs @@ -1,4 +1,4 @@ -namespace NotificationFlyout.Wpf.UI.Helpers +namespace NotificationFlyout.Shared.UI.Helpers { internal enum WndProcMessages { diff --git a/src/NotificationFlyout.Uwp.UI/INotificationFlyoutApplication.cs b/src/NotificationFlyout.Shared.UI/INotificationFlyoutApplication.cs similarity index 100% rename from src/NotificationFlyout.Uwp.UI/INotificationFlyoutApplication.cs rename to src/NotificationFlyout.Shared.UI/INotificationFlyoutApplication.cs diff --git a/src/NotificationFlyout.Shared.UI/NativeMethods.json b/src/NotificationFlyout.Shared.UI/NativeMethods.json new file mode 100644 index 0000000..29dbe6e --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/NativeMethods.json @@ -0,0 +1,4 @@ +{ + "$schema": "D:\\git\\CsWin32\\src\\Microsoft.Windows.CsWin32\\settings.schema.json", + "emitSingleFile": true +} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/NativeMethods.txt b/src/NotificationFlyout.Shared.UI/NativeMethods.txt similarity index 75% rename from src/NotificationFlyout.Wpf.UI/NativeMethods.txt rename to src/NotificationFlyout.Shared.UI/NativeMethods.txt index f4fe388..c29cf4e 100644 --- a/src/NotificationFlyout.Wpf.UI/NativeMethods.txt +++ b/src/NotificationFlyout.Shared.UI/NativeMethods.txt @@ -1,13 +1,14 @@ Shell_NotifyIcon -GetSystemMetricsForDpi DefWindowProcW -GetSystemMetrics MonitorFromWindow RegisterWindowMessage SHAppBarMessage -SetWindowPos GetWindowLong -SetWindowLong GetDpiForWindow FindWindow -GetPhysicalCursorPos \ No newline at end of file +GetPhysicalCursorPos +GetSystemMetricsForDpi +GetCurrentPackageFullName +GetSystemMetrics +SetWindowLong +SetWindowPos \ No newline at end of file diff --git a/src/NotificationFlyout.Uwp.UI/NotificationFlyout.Uwp.UI.csproj b/src/NotificationFlyout.Shared.UI/NotificationFlyout.Shared.UI.csproj similarity index 50% rename from src/NotificationFlyout.Uwp.UI/NotificationFlyout.Uwp.UI.csproj rename to src/NotificationFlyout.Shared.UI/NotificationFlyout.Shared.UI.csproj index 4996447..79a48cf 100644 --- a/src/NotificationFlyout.Uwp.UI/NotificationFlyout.Uwp.UI.csproj +++ b/src/NotificationFlyout.Shared.UI/NotificationFlyout.Shared.UI.csproj @@ -1,38 +1,24 @@  - + - uap10.0.19041 - AnyCPU;x64 - false - false + netcoreapp3.1;uap10.0.19041 9.0 false TheXamlGuy TheXamlGuy NotificationFlyout 1.0.0 + AnyCPU;x64 - - - - - - - - - - - - - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + - - \ No newline at end of file + diff --git a/src/NotificationFlyout.Shared.UI/Properties/AssemblyInfo.cs b/src/NotificationFlyout.Shared.UI/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2841bf6 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/Properties/AssemblyInfo.cs @@ -0,0 +1,5 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("NotificationFlyout.Wpf.UI")] +[assembly: InternalsVisibleTo("NotificationFlyout.Wpf.UI.Extensions")] +[assembly: InternalsVisibleTo("NotificationFlyout.Wpf.UI.Controls")] \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandler.cs b/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandler.cs new file mode 100644 index 0000000..11f569e --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandler.cs @@ -0,0 +1,9 @@ +using System; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public interface IWndProcHandler + { + void Handle(uint message, IntPtr wParam, IntPtr lParam); + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerCollection.cs b/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerCollection.cs new file mode 100644 index 0000000..958ac40 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerCollection.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + internal interface IWndProcHandlerCollection : IList + { + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerSubscriber.cs b/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerSubscriber.cs new file mode 100644 index 0000000..a4621c4 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/IWndProcHandlerSubscriber.cs @@ -0,0 +1,7 @@ +namespace NotificationFlyout.Shared.UI.Helpers +{ + public interface IWndProcHandlerSubscriber + { + void Subscribe(TWndProcHandler handler) where TWndProcHandler : IWndProcHandler; + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerCollection.cs b/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerCollection.cs new file mode 100644 index 0000000..57db27e --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerCollection.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + internal class WndProcHandlerCollection : List, IWndProcHandlerCollection + { + private static readonly Lazy _current = new(() => new WndProcHandlerCollection()); + public static WndProcHandlerCollection Current => _current.Value; + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerReference.cs b/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerReference.cs new file mode 100644 index 0000000..ebb84a0 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerReference.cs @@ -0,0 +1,26 @@ +using System; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + internal class WndProcHandlerReference + { + private readonly WeakReference _reference; + + public WndProcHandlerReference(object handler) => _reference = new WeakReference(handler); + + public bool IsDead => _reference.Target == null; + + public void Handle(uint message, IntPtr wParam, IntPtr lParam) + { + if (_reference.Target == null) return; + + var target = _reference.Target; + if (target is IWndProcHandler handler) + { + handler.Handle(message, wParam, lParam); + } + } + + public bool Matches(object instance) => _reference.Target == instance; + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerSubscriber.cs b/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerSubscriber.cs new file mode 100644 index 0000000..8fa1fa7 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/WndProcHandlerSubscriber.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public class WndProcHandlerSubscriber : IWndProcHandlerSubscriber + { + private static readonly Lazy _current = new(() => new WndProcHandlerSubscriber()); + public static WndProcHandlerSubscriber Current => _current.Value; + + public void Subscribe(TWndProcHandler handler) where TWndProcHandler : IWndProcHandler + { + var handlers = WndProcHandlerCollection.Current; + lock (handlers) + { + if (handlers.Any(x => x.Matches(handler))) return; + handlers.Add(new WndProcHandlerReference(handler)); + } + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Shared.UI/WndProc/WndProcListener.cs b/src/NotificationFlyout.Shared.UI/WndProc/WndProcListener.cs new file mode 100644 index 0000000..c843a64 --- /dev/null +++ b/src/NotificationFlyout.Shared.UI/WndProc/WndProcListener.cs @@ -0,0 +1,49 @@ +using System; +using System.Linq; + +namespace NotificationFlyout.Shared.UI.Helpers +{ + public class WndProcListener + { + private static readonly Lazy _current = new(() => new WndProcListener()); + + private readonly WndProcHelper _wndProcHelper; + + private WndProcListener() => _wndProcHelper = WndProcHelper.Create(); + + public static WndProcListener Current => _current.Value; + + public IntPtr Handle => _wndProcHelper.Handle; + + public void Start() + { + _wndProcHelper.WndProcMessage -= OnWndProcMessage; + _wndProcHelper.WndProcMessage += OnWndProcMessage; + } + + private void OnWndProcMessage(object sender, WndProcHelperMessageEventArgs args) + { + WndProcHandlerReference[] handlers; + var subscribers = WndProcHandlerCollection.Current; + + lock (subscribers) + { + handlers = subscribers.ToArray(); + } + + foreach (var handler in handlers) + { + handler.Handle(args.Message, args.WParam, args.LParam); + } + + var deadHandlers = handlers.Where(x => x.IsDead).ToList(); + if (deadHandlers.Count > 0) + { + lock (subscribers) + { + foreach (var deadHandler in deadHandlers) subscribers.Remove(deadHandler); + } + } + } + } +} \ No newline at end of file diff --git a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj index 442fa07..22631bc 100644 --- a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj +++ b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj @@ -10,7 +10,8 @@ TheXamlGuy TheXamlGuy NotificationFlyout - 1.0.0 + 1.0.0 + @@ -29,10 +30,10 @@ Designer MSBuild:Compile - - - - - + + + + + \ No newline at end of file diff --git a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs index c25a04b..47d6b96 100644 --- a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs +++ b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs @@ -46,6 +46,11 @@ namespace NotificationFlyout.Uwp.UI.Controls flyout.Hide(); } + internal void UpdateThemeVisualState() + { + + } + public void SetFlyoutPlacement(string placement) { if (!_isLoaded) @@ -98,8 +103,12 @@ namespace NotificationFlyout.Uwp.UI.Controls }); } + private NotificationFlyoutPresenter _flyoutPresenter; + protected override void OnApplyTemplate() { + _flyoutPresenter = GetTemplateChild("FlyoutPresenter") as NotificationFlyoutPresenter; + _flyout = GetTemplateChild("Flyout") as Flyout; if (_flyout != null) { diff --git a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.xaml b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.xaml index d87c833..e792122 100644 --- a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.xaml +++ b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.xaml @@ -63,7 +63,7 @@ FromVerticalOffset="0" /> - + diff --git a/src/NotificationFlyout.Uwp.UI/NativeMethods.txt b/src/NotificationFlyout.Uwp.UI/NativeMethods.txt deleted file mode 100644 index 14fd210..0000000 --- a/src/NotificationFlyout.Uwp.UI/NativeMethods.txt +++ /dev/null @@ -1,2 +0,0 @@ -GetSystemMetricsForDpi -GetCurrentPackageFullName \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj index 510778f..f95f90c 100644 --- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj +++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj @@ -18,8 +18,8 @@ - + diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs index 94d4625..c6e0b49 100644 --- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs +++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs @@ -1,4 +1,5 @@ -using NotificationFlyout.Uwp.UI; +using NotificationFlyout.Shared.UI.Helpers; +using NotificationFlyout.Uwp.UI; using System.Windows; using System.Windows.Markup; @@ -20,6 +21,8 @@ namespace NotificationFlyout.Wpf.UI.Controls _application = this; Uwp.UI.Controls.NotificationFlyout.SetApplication(this); + WndProcListener.Current.Start(); + PrepareFlyoutHost(); } diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs index a1c6c3e..0ee3e99 100644 --- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs +++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs @@ -1,6 +1,6 @@ using NotificationFlyout.Uwp.UI.Controls; +using NotificationFlyout.Shared.UI.Helpers; using NotificationFlyout.Wpf.UI.Extensions; -using NotificationFlyout.Wpf.UI.Helpers; using System; namespace NotificationFlyout.Wpf.UI.Controls diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs index b69e9a3..0914309 100644 --- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs +++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs @@ -1,9 +1,8 @@ -using NotificationFlyout.Uwp.UI.Controls; -using NotificationFlyout.Uwp.UI.Extensions; +using NotificationFlyout.Shared.UI.Extensions; +using NotificationFlyout.Shared.UI.Helpers; +using NotificationFlyout.Uwp.UI.Controls; using NotificationFlyout.Wpf.UI.Extensions; -using NotificationFlyout.Wpf.UI.Helpers; using System; -using System.ComponentModel; using System.Windows; using System.Windows.Input; using Windows.UI.Xaml.Controls.Primitives; @@ -92,12 +91,12 @@ namespace NotificationFlyout.Wpf.UI.Controls private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args) { - if (args.MouseButton == MouseButton.Left) + if (args.PointerButton == PointerButton.Left) { ShowFlyout(); } - if (args.MouseButton == MouseButton.Right) + if (args.PointerButton == PointerButton.Right) { ShowContextMenuFlyout(); } @@ -107,7 +106,20 @@ namespace NotificationFlyout.Wpf.UI.Controls private void OnTaskbarChanged(object sender, EventArgs args) => UpdateWindow(); - private void OnThemeChanged(object sender, SystemPersonalisationChangedEventArgs args) => UpdateIcons(); + private void OnThemeChanged(object sender, SystemPersonalisationChangedEventArgs args) + { + UpdateFlyoutTheme(args.IsColorPrevalence); + UpdateIcons(); + } + + private void UpdateFlyoutTheme(bool isColorPrevalence) + { + var content = GetHostContent(); + if (content != null) + { + // content.UpdateFlyoutTheme(isColorPrevalence); + } + } private void PrepareContextMenu() { @@ -131,10 +143,10 @@ namespace NotificationFlyout.Wpf.UI.Controls private void PrepareNotificationIcon() { - _notificationIconHelper = NotificationIconHelper.Create(this); + _notificationIconHelper = NotificationIconHelper.Create(); _notificationIconHelper.IconInvoked += OnIconInvoked; - _systemPersonalisationHelper = SystemPersonalisationHelper.Create(this); + _systemPersonalisationHelper = SystemPersonalisationHelper.Create(); _systemPersonalisationHelper.ThemeChanged += OnThemeChanged; UpdateIcons(); @@ -142,7 +154,7 @@ namespace NotificationFlyout.Wpf.UI.Controls private void PrepareTaskbar() { - _taskbarHelper = TaskbarHelper.Create(this); + _taskbarHelper = TaskbarHelper.Create(); _taskbarHelper.TaskbarChanged += OnTaskbarChanged; } diff --git a/src/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs b/src/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs index f6feae7..d068b04 100644 --- a/src/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs +++ b/src/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs @@ -1,5 +1,4 @@ -using Microsoft.Windows.Sdk; -using System; +using System; using System.Drawing; using System.Windows; using System.Windows.Media; @@ -8,17 +7,17 @@ namespace NotificationFlyout.Wpf.UI.Extensions { public static class ImageSourceExtensions { - public static Icon ConvertToIcon(this ImageSource imageSource, uint dpi) - { - if (imageSource == null) return null; + //public static Icon ConvertToIcon(this ImageSource imageSource, uint dpi) + //{ + // if (imageSource == null) return null; - var uri = new Uri(imageSource.ToString(), UriKind.RelativeOrAbsolute); + // var uri = new Uri(imageSource.ToString(), UriKind.RelativeOrAbsolute); - var streamResource = Application.GetResourceStream(uri); - if (streamResource == null) throw new ArgumentException(nameof(streamResource)); + // var streamResource = Application.GetResourceStream(uri); + // if (streamResource == null) throw new ArgumentException(nameof(streamResource)); - return new Icon(streamResource.Stream, new System.Drawing.Size(PInvoke.GetSystemMetricsForDpi((int)SystemMetricFlag.SM_CXICON, dpi), PInvoke.GetSystemMetricsForDpi((int)SystemMetricFlag.SM_CYICON, dpi))); - } + // return new Icon(streamResource.Stream, new System.Drawing.Size(PInvoke.GetSystemMetricsForDpi((int)SystemMetricFlag.SM_CXICON, dpi), PInvoke.GetSystemMetricsForDpi((int)SystemMetricFlag.SM_CYICON, dpi))); + //} private enum SystemMetricFlag : int { diff --git a/src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs b/src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs deleted file mode 100644 index 18afe5b..0000000 --- a/src/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using NotificationFlyout.Wpf.UI.Helpers; -using System; - -namespace NotificationFlyout.Wpf.UI.Extensions -{ - public static class OperatingSystemExtensions - { - public static bool IsGreaterThan(this OperatingSystem operatingSystem, OperatingSystemVersion version) - { - return operatingSystem.Version.Build > (int)version; - } - } -} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs b/src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs deleted file mode 100644 index 7e188f1..0000000 --- a/src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs +++ /dev/null @@ -1,201 +0,0 @@ -using NotificationFlyout.Wpf.UI.Extensions; -using System; -using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Input; -using System.Windows.Interop; - -namespace NotificationFlyout.Wpf.UI.Helpers -{ - public class NotificationIconHelper : IDisposable - { - private const int CallbackMessage = 0x400; - private const uint IconVersion = 0x4; - - private readonly object _lock = new(); - private readonly IntPtr _windowHandle; - private bool _isDisposed; - private NotifyIconData _notifyIconData; - - private NotificationIconHelper(Window window) - { - _windowHandle = window.GetHandle(); - - HwndSource source = HwndSource.FromHwnd(_windowHandle); - source.AddHook(new HwndSourceHook(WndProc)); - - CreateNotificationIcon(); - } - - ~NotificationIconHelper() - { - Dispose(false); - } - - public event EventHandler IconInvoked; - - private enum NotifyIconBalloonType - { - None = 0x00, - Info = 0x01, - Warning = 0x02, - Error = 0x03, - User = 0x04, - NoSound = 0x10, - LargeIcon = 0x20, - RespectQuietTime = 0x80 - } - - private enum NotifyIconCommand : uint - { - Add = 0x0, - Delete = 0x2, - Modify = 0x1, - SetVersion = 0x4 - } - - [Flags] - private enum NotifyIconDataMember : uint - { - Message = 0x01, - Icon = 0x02, - Tip = 0x04, - State = 0x08, - Info = 0x10, - Realtime = 0x40, - UseLegacyToolTips = 0x80 - } - - private enum NotifyIconState : uint - { - Visible = 0x00, - Hidden = 0x01 - } - - public static NotificationIconHelper Create(Window window) - { - return new NotificationIconHelper(window); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public void SetIcon(IntPtr iconHandle) - { - lock (_lock) - { - _notifyIconData.IconHandle = iconHandle; - WriteNotifyIconData(NotifyIconCommand.Modify, NotifyIconDataMember.Icon); - } - } - - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); - - [DllImport("shell32.dll", SetLastError = true)] - private static extern int Shell_NotifyIcon(NotifyIconCommand notifyCommand, ref NotifyIconData notifyIconData); - - private void CreateNotificationIcon() - { - lock (_lock) - { - _notifyIconData = new NotifyIconData(); - - _notifyIconData.cbSize = (uint)Marshal.SizeOf(_notifyIconData); - _notifyIconData.WindowHandle = _windowHandle; - _notifyIconData.TaskbarIconId = 0x0; - _notifyIconData.CallbackMessageId = CallbackMessage; - _notifyIconData.VersionOrTimeout = IconVersion; - - _notifyIconData.IconHandle = IntPtr.Zero; - - _notifyIconData.IconState = NotifyIconState.Hidden; - _notifyIconData.StateMask = NotifyIconState.Hidden; - - WriteNotifyIconData(NotifyIconCommand.Add, NotifyIconDataMember.Message | NotifyIconDataMember.Icon | NotifyIconDataMember.Tip); - } - } - - private void Dispose(bool disposing) - { - if (_isDisposed || !disposing) return; - - lock (_lock) - { - _isDisposed = true; - RemoveNotificationIcon(); - } - } - - private void InvokeIconInvoked(MouseButton mouseButton) - { - IconInvoked?.Invoke(this, new NotificationIconInvokedEventArgs { MouseButton = mouseButton }); - } - - private void RemoveNotificationIcon() => WriteNotifyIconData(NotifyIconCommand.Delete, NotifyIconDataMember.Message); - - private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) - { - if (msg == CallbackMessage) - { - switch ((uint)lParam) - { - case (uint)WndProcMessages.WM_LBUTTONUP: - InvokeIconInvoked(MouseButton.Left); - break; - - case (uint)WndProcMessages.WM_MBUTTONUP: - InvokeIconInvoked(MouseButton.Middle); - break; - - case (uint)WndProcMessages.WM_RBUTTONUP: - InvokeIconInvoked(MouseButton.Right); - break; - } - } - - return DefWindowProcW(hwnd, (uint)msg, wParam, (lParam)); - } - - private void WriteNotifyIconData(NotifyIconCommand command, NotifyIconDataMember flags) - { - _notifyIconData.ValidMembers = flags; - lock (_lock) - { - Shell_NotifyIcon(command, ref _notifyIconData); - } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private struct NotifyIconData - { - public uint cbSize; - public IntPtr WindowHandle; - public uint TaskbarIconId; - public NotifyIconDataMember ValidMembers; - public uint CallbackMessageId; - public IntPtr IconHandle; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - public string ToolTipText; - - public NotifyIconState IconState; - public NotifyIconState StateMask; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] - public string BalloonText; - - public uint VersionOrTimeout; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] - public string BalloonTitle; - - public NotifyIconBalloonType BalloonFlags; - public Guid TaskbarIconGuid; - public IntPtr CustomBalloonIconHandle; - } - } -} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs b/src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs deleted file mode 100644 index 80737dc..0000000 --- a/src/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Windows.Input; - -namespace NotificationFlyout.Wpf.UI.Helpers -{ - public class NotificationIconInvokedEventArgs : EventArgs - { - public MouseButton MouseButton { get; internal set; } - } -} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs b/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs deleted file mode 100644 index 2cb4f7c..0000000 --- a/src/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs +++ /dev/null @@ -1,118 +0,0 @@ -using Microsoft.Windows.Sdk; -using NotificationFlyout.Wpf.UI.Extensions; -using System; -using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Interop; - -namespace NotificationFlyout.Wpf.UI.Helpers -{ - public class TaskbarHelper - { - private const string ShellTrayHandleName = "Shell_TrayWnd"; - private const int SPI_SETWORKAREA = 0x002F; - - private readonly uint WM_TASKBARCREATED = PInvoke.RegisterWindowMessage("TaskbarCreated"); - - private TaskbarHelper(Window window) - { - var handle = window.GetHandle(); - - var source = HwndSource.FromHwnd(handle); - source.AddHook(new HwndSourceHook(WndProc)); - } - - public event EventHandler TaskbarChanged; - - private enum AppBarEdge : uint - { - Left = 0, - Top = 1, - Right = 2, - Bottom = 3 - } - - private enum AppBarMessage : uint - { - New = 0x00000000, - Remove = 0x00000001, - QueryPos = 0x00000002, - SetPos = 0x00000003, - GetState = 0x00000004, - GetTaskbarPos = 0x00000005, - Activate = 0x00000006, - GetAutoHideBar = 0x00000007, - SetAutoHideBar = 0x00000008, - WindowPosChanged = 0x00000009, - SetState = 0x0000000A, - } - - public static TaskbarHelper Create(Window window) - { - return new TaskbarHelper(window); - } - - public TaskbarState GetCurrentState() - { - var handle = GetSystemTrayHandle(); - var state = new TaskbarState - { - Screen = Screen.FromHandle(handle) - }; - - var appBarData = GetAppBarData(handle); - GetAppBarPosition(ref appBarData); - - state.Rect = appBarData.rect.ToRect(); - state.Position = (TaskbarPosition)appBarData.uEdge; - - return state; - } - - [DllImport("user32.dll", SetLastError = true)] - private static extern IntPtr DefWindowProcW(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); - - private static IntPtr GetSystemTrayHandle() - { - return WindowHelper.GetHandle(ShellTrayHandleName); - } - - [DllImport("shell32.dll", SetLastError = true)] - private static extern IntPtr SHAppBarMessage(AppBarMessage dwMessage, ref AppBarData pData); - - private AppBarData GetAppBarData(IntPtr handle) - { - return new AppBarData - { - cbSize = (uint)Marshal.SizeOf(typeof(AppBarData)), - hWnd = handle - }; - } - - private void GetAppBarPosition(ref AppBarData appBarData) - { - SHAppBarMessage(AppBarMessage.GetTaskbarPos, ref appBarData); - } - - private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) - { - if (msg == WM_TASKBARCREATED || msg == (int)WndProcMessages.WM_SETTINGCHANGE && (int)wParam == SPI_SETWORKAREA) - { - TaskbarChanged?.Invoke(this, EventArgs.Empty); - } - - return DefWindowProcW(hwnd, (uint)msg, wParam, (lParam)); - } - - [StructLayout(LayoutKind.Sequential)] - private struct AppBarData - { - public uint cbSize; - public IntPtr hWnd; - public uint uCallbackMessage; - public AppBarEdge uEdge; - public RECT rect; - public int lParam; - } - } -} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs b/src/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs deleted file mode 100644 index b0113ef..0000000 --- a/src/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.Windows.Sdk; -using System; - -namespace NotificationFlyout.Wpf.UI.Helpers -{ - public class WindowHelper - { - public static IntPtr GetHandle(string windowName) - { - return PInvoke.FindWindow(windowName, null); - } - - public static uint GetDpi(IntPtr handle) - { - return PInvoke.GetDpiForWindow((HWND)handle); - } - } -} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/NativeMethods.json b/src/NotificationFlyout.Wpf.UI/NativeMethods.json new file mode 100644 index 0000000..29dbe6e --- /dev/null +++ b/src/NotificationFlyout.Wpf.UI/NativeMethods.json @@ -0,0 +1,4 @@ +{ + "$schema": "D:\\git\\CsWin32\\src\\Microsoft.Windows.CsWin32\\settings.schema.json", + "emitSingleFile": true +} \ No newline at end of file diff --git a/src/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj b/src/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj index 6fa42d6..dcfa2a5 100644 --- a/src/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj +++ b/src/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj @@ -12,12 +12,15 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + + + + + + + diff --git a/src/NotificationFlyout.sln b/src/NotificationFlyout.sln index 19d529b..206722d 100644 --- a/src/NotificationFlyout.sln +++ b/src/NotificationFlyout.sln @@ -14,7 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI", "NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj", "{3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Shared.UI", "NotificationFlyout.Shared.UI\NotificationFlyout.Shared.UI.csproj", "{B88D3299-5C7D-4ED1-A508-F72637DEFE1E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -90,26 +90,26 @@ Global {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x64.Build.0 = Release|x64 {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x86.ActiveCfg = Release|Any CPU {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x86.Build.0 = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|Any CPU.ActiveCfg = Debug|x64 - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|Any CPU.Build.0 = Debug|x64 - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|ARM.ActiveCfg = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|ARM.Build.0 = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|ARM64.Build.0 = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|x64.ActiveCfg = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|x64.Build.0 = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|x86.ActiveCfg = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Debug|x86.Build.0 = Debug|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|Any CPU.Build.0 = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|ARM.ActiveCfg = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|ARM.Build.0 = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|ARM64.ActiveCfg = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|ARM64.Build.0 = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|x64.ActiveCfg = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|x64.Build.0 = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|x86.ActiveCfg = Release|Any CPU - {3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}.Release|x86.Build.0 = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|ARM.Build.0 = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|ARM64.Build.0 = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|x64.ActiveCfg = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|x64.Build.0 = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|x86.ActiveCfg = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Debug|x86.Build.0 = Debug|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|Any CPU.Build.0 = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|ARM.ActiveCfg = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|ARM.Build.0 = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|ARM64.ActiveCfg = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|ARM64.Build.0 = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|x64.ActiveCfg = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|x64.Build.0 = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|x86.ActiveCfg = Release|Any CPU + {B88D3299-5C7D-4ED1-A508-F72637DEFE1E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE