From a3fb81d8807ed86e709596099874e6b7754aebca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E6=80=A1=E9=A3=9E?= <363301617@qq.com> Date: Wed, 2 Oct 2024 20:23:49 +0800 Subject: [PATCH] Add SystemBackdrop API for GetStoreAppInstaller Add SystemBackdrop API for GetStoreAppInstaller --- Description/README_EN-US.md | 3 +- Description/README_ZH-CN.md | 3 +- GetStoreApp/GetStoreApp.csproj | 2 +- GetStoreApp/GetStoreApp.res | Bin 438024 -> 438036 bytes GetStoreApp/Properties/AssemblyInfo.cs | 6 +- GetStoreApp/Views/Pages/AboutPage.xaml.cs | 1 + .../PInvoke/Kernel32/Kernel32Library.cs | 2 +- .../PInvoke/User32/User32Library.cs | 2 +- GetStoreAppInstaller/GetStoreAppInstaller.res | Bin 438060 -> 438072 bytes .../Helpers/Backdrop/BackdropHelper.cs | 34 + .../Properties/AssemblyInfo.cs | 6 +- .../UI/Backdrop/BlendEffect.cs | 96 + .../UI/Backdrop/BlendEffectMode.cs | 32 + .../UI/Backdrop/BorderEffect.cs | 108 + .../UI/Backdrop/CanvasComposite.cs | 19 + .../UI/Backdrop/CanvasEdgeBehavior.cs | 9 + .../UI/Backdrop/ColorConversion.cs | 364 +++ .../UI/Backdrop/ColorSourceEffect.cs | 80 + .../UI/Backdrop/CompositeEffect.cs | 91 + .../UI/Backdrop/CrossFadeEffect.cs | 96 + .../UI/Backdrop/DesktopAcrylicBackdrop.cs | 794 +++++ .../UI/Backdrop/DesktopAcrylicKind.cs | 23 + .../UI/Backdrop/EffectBorderMode.cs | 8 + .../UI/Backdrop/EffectOptimization.cs | 9 + .../UI/Backdrop/GaussianBlurEffect.cs | 126 + .../UI/Backdrop/MicaBackdrop.cs | 670 ++++ GetStoreAppInstaller/UI/Backdrop/MicaKind.cs | 18 + .../UI/Backdrop/OpacityEffect.cs | 81 + .../UI/Backdrop/SystemBackdrop.cs | 41 + .../GRAPHICS_EFFECT_PROPERTY_MAPPING.cs | 63 + .../ComTypes/ICompositorDesktopInterop.cs | 15 + .../ComTypes/IGraphicsEffectD2D1Interop.cs | 243 ++ .../IGraphicsEffectD2D1InteropMethods.cs | 15 + .../ComTypes/IPropertyValueStatics.cs | 409 +++ .../PInvoke/Comctl32/Comctl32Library.cs | 50 + .../PInvoke/Comctl32/SUBCLASSPROC.cs | 17 + .../PInvoke/User32/WindowMessage.cs | 2728 +++++++++++++++++ GetStoreAppPackage/Package.appxmanifest | 2 +- .../Properties/AssemblyInfo.cs | 6 +- .../ComTypes/IEnumExplorerCommand.cs | 2 +- GetStoreAppWebView/GetStoreAppWebView.res | Bin 438092 -> 438104 bytes GetStoreAppWebView/UI/Backdrop/MicaBrush.cs | 1 - GetStoreAppWidget/GetStoreAppWidget.csproj | 2 +- GetStoreAppWidget/GetStoreAppWidget.res | Bin 157672 -> 157684 bytes GetStoreAppWidget/Properties/AssemblyInfo.cs | 6 +- .../Properties/AssemblyInfo.cs | 6 +- README.md | 1 + 47 files changed, 6266 insertions(+), 24 deletions(-) create mode 100644 GetStoreAppInstaller/Helpers/Backdrop/BackdropHelper.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/BlendEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/BlendEffectMode.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/BorderEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/CanvasComposite.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/CanvasEdgeBehavior.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/ColorConversion.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/ColorSourceEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/CompositeEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/CrossFadeEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicBackdrop.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicKind.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/EffectBorderMode.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/EffectOptimization.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/GaussianBlurEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/MicaBackdrop.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/MicaKind.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/OpacityEffect.cs create mode 100644 GetStoreAppInstaller/UI/Backdrop/SystemBackdrop.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/ComTypes/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/ComTypes/ICompositorDesktopInterop.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1Interop.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1InteropMethods.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/ComTypes/IPropertyValueStatics.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/Comctl32Library.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/SUBCLASSPROC.cs create mode 100644 GetStoreAppInstaller/WindowsAPI/PInvoke/User32/WindowMessage.cs diff --git a/Description/README_EN-US.md b/Description/README_EN-US.md index d1eba8145..e2300e3bc 100644 --- a/Description/README_EN-US.md +++ b/Description/README_EN-US.md @@ -120,7 +120,8 @@ All the content of the program has been developed > * [Microsoft.Windows.SDK.BuildTools](https://aka.ms/WinSDKProjectURL)  > * [Microsoft.WindowsAppSDK](https://github.com/microsoft/windowsappsdk)  > * [Microsoft.WindowsPackageManager.ComInterop](https://github.com/microsoft/winget-cli)  - +> * [Mile.Xaml](https://github.com/ProjectMile/Mile.Xaml)  + [Code referenced or used during the learning process](https://github.com/Gaoyifei1011/GetStoreApp/blob/main/Description/StudyReferenceCode.md)  [Auxiliary Tools](https://github.com/Gaoyifei1011/GetStoreApp/blob/main/Description/AuxiliaryTools.md)  diff --git a/Description/README_ZH-CN.md b/Description/README_ZH-CN.md index a7a0f8cde..51d316aad 100644 --- a/Description/README_ZH-CN.md +++ b/Description/README_ZH-CN.md @@ -119,7 +119,8 @@ > * [Microsoft.Windows.SDK.BuildTools](https://aka.ms/WinSDKProjectURL)  > * [Microsoft.WindowsAppSDK](https://github.com/microsoft/windowsappsdk)  > * [Microsoft.WindowsPackageManager.ComInterop](https://github.com/microsoft/winget-cli)  - +> * [Mile.Xaml](https://github.com/ProjectMile/Mile.Xaml)  + [学习过程中参考或使用的代码](https://github.com/Gaoyifei1011/GetStoreApp/blob/main/Description/StudyReferenceCode.md)  [辅助工具](https://github.com/Gaoyifei1011/GetStoreApp/blob/main/Description/AuxiliaryTools.md)  diff --git a/GetStoreApp/GetStoreApp.csproj b/GetStoreApp/GetStoreApp.csproj index 1f1c0cd6d..667869db8 100644 --- a/GetStoreApp/GetStoreApp.csproj +++ b/GetStoreApp/GetStoreApp.csproj @@ -166,7 +166,7 @@ - + diff --git a/GetStoreApp/GetStoreApp.res b/GetStoreApp/GetStoreApp.res index 1f2bbf846b01f50ea3925de5aac2a664e11945be..86354e66c8512ac9e321a2ee94c428a3883a7b78 100644 GIT binary patch delta 150 zcmeCUCpG1sR6`463sVbo3rh>@7Pd1p8AGO@oyjH-q~6YCGv$2A%)r3Pz`*cwy7nwK zS;j5XJ!i2gGftSEJBv-6*^YsGdiyLkU0y>510XbH&;ybT)A!C|>t;3s%6ZRbQ$>~A ZUOAi1o{`xKD7kwMn@7Pd1p89k<-oyjH-q~6YCGv!>!%)r3Pz`(F@y7nwK zS;iI9J!i2gGqz06oy8{3Y{S4cy?qv&E~h1f5rZXz9)rR3gR|JWnN5J={3fB*mh diff --git a/GetStoreApp/Properties/AssemblyInfo.cs b/GetStoreApp/Properties/AssemblyInfo.cs index cb79d7fc7..7309f20b4 100644 --- a/GetStoreApp/Properties/AssemblyInfo.cs +++ b/GetStoreApp/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ [assembly: AssemblyCompany("高怡飞")] [assembly: AssemblyCopyright("Copyright ©2022-2024 高怡飞, All Rights Reserved.")] [assembly: AssemblyDescription("获取商店应用")] -[assembly: AssemblyFileVersion("5.0.929.0")] -[assembly: AssemblyInformationalVersion("5.0.929.0")] +[assembly: AssemblyFileVersion("5.0.1001.0")] +[assembly: AssemblyInformationalVersion("5.0.1001.0")] [assembly: AssemblyProduct("获取商店应用")] [assembly: AssemblyTitle("获取商店应用")] -[assembly: AssemblyVersion("5.0.929.0")] +[assembly: AssemblyVersion("5.0.1001.0")] // 应用程序默认区域性的资源控制器设置 [assembly: NeutralResourcesLanguage("en-us")] diff --git a/GetStoreApp/Views/Pages/AboutPage.xaml.cs b/GetStoreApp/Views/Pages/AboutPage.xaml.cs index bb0c6a56e..49f1f610f 100644 --- a/GetStoreApp/Views/Pages/AboutPage.xaml.cs +++ b/GetStoreApp/Views/Pages/AboutPage.xaml.cs @@ -63,6 +63,7 @@ public bool IsChecking new DictionaryEntry("Microsoft.Windows.SDK.BuildTools","https://aka.ms/WinSDKProjectURL"), new DictionaryEntry("Microsoft.WindowsAppSDK","https://github.com/microsoft/windowsappsdk"), new DictionaryEntry("Microsoft.WindowsPackageManager.ComInterop", "https://github.com/microsoft/winget-cli"), + new DictionaryEntry("Mile.Xaml", "https://github.com/ProjectMile/Mile.Xaml"), ]; //项目感谢者信息 diff --git a/GetStoreApp/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs b/GetStoreApp/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs index db127ce4c..f04a8da58 100644 --- a/GetStoreApp/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs +++ b/GetStoreApp/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs @@ -68,7 +68,7 @@ public static partial class Kernel32Library /// 如果该函数成功,则返回值为非零值。如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。 [LibraryImport(Kernel32, EntryPoint = "ReadConsoleW", SetLastError = false), PreserveSig] [return: MarshalAs(UnmanagedType.Bool)] - public static partial bool ReadConsole(IntPtr hConsoleInput, [Out] byte[] lpBuffer, int nNumberOfCharsToRead, out int lpNumberOfCharsRead, IntPtr pInputControl); + public static partial bool ReadConsole(IntPtr hConsoleInput, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer, int nNumberOfCharsToRead, out int lpNumberOfCharsRead, IntPtr pInputControl); /// /// 设置由 WriteFile 或 WriteConsole 函数写入控制台屏幕缓冲区或由 ReadFile 或 ReadConsole 函数回显的字符的属性。 此函数会影响函数调用后写入的文本。 diff --git a/GetStoreApp/WindowsAPI/PInvoke/User32/User32Library.cs b/GetStoreApp/WindowsAPI/PInvoke/User32/User32Library.cs index f8881ed11..3b70ffb34 100644 --- a/GetStoreApp/WindowsAPI/PInvoke/User32/User32Library.cs +++ b/GetStoreApp/WindowsAPI/PInvoke/User32/User32Library.cs @@ -30,7 +30,7 @@ public static partial class User32Library /// 如果 参数为 NULL 且此函数成功,则返回值为文件中的图标数。 如果函数失败,则返回值为 0。 如果 参数不是 NULL 且函数成功,则返回值是提取的图标数。 否则,如果未找到文件,则返回值0xFFFFFFFF。 /// [LibraryImport(User32, EntryPoint = "PrivateExtractIconsW", SetLastError = false, StringMarshalling = StringMarshalling.Utf16), PreserveSig] - public static partial int PrivateExtractIcons([MarshalAs(UnmanagedType.LPWStr)] string lpszFile, int nIconIndex, int cxIcon, int cyIcon, [Out] IntPtr[] phicon, [Out] int[] piconid, int nIcons, int flags); + public static partial int PrivateExtractIcons([MarshalAs(UnmanagedType.LPWStr)] string lpszFile, int nIconIndex, int cxIcon, int cyIcon, [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] phicon, [Out, MarshalAs(UnmanagedType.LPArray)] int[] piconid, int nIcons, int flags); /// /// 将指定的消息发送到窗口或窗口。 SendMessage 函数调用指定窗口的窗口过程,在窗口过程处理消息之前不会返回。 diff --git a/GetStoreAppInstaller/GetStoreAppInstaller.res b/GetStoreAppInstaller/GetStoreAppInstaller.res index 0510f125e2db597d62f7cc19daac294d235e6668..8f972c19d8090c3f5804b3dc1ea42afb094ef37f 100644 GIT binary patch delta 150 zcmZ2;Pin_KsfHHD7N!>F7M2#)Eo^6IGFD7KJCjWwNWGoOX3F`JnSp_ofq~)WbnRJe zvWz#Td(L80X52D8cNUvCvmFEX^!8b7y1a%A20&=Ypa&!wrth7_wwT!rD3?5&O%+vc a`^4F7-i*vvK*{@a*fh~31?RF!3jqLdsV4vc delta 138 zcmdmSPioCQsfHHD7N!>F7M2#)Eo^6IGUiM_JCjWwNWGoOX3DvcnSp_ofq`M+bnRJe zvW#b@d(L80W?V5ncNUvCvke2+^!8b7x}25_Mhun=dJG2B56)s+%xnS_PoK@EiV)vE Yb2ghdBeMli;`tmlO(Y4~xopxx0Hebt^#A|> diff --git a/GetStoreAppInstaller/Helpers/Backdrop/BackdropHelper.cs b/GetStoreAppInstaller/Helpers/Backdrop/BackdropHelper.cs new file mode 100644 index 000000000..ef2ff2908 --- /dev/null +++ b/GetStoreAppInstaller/Helpers/Backdrop/BackdropHelper.cs @@ -0,0 +1,34 @@ +using System; +using Windows.System; +using Windows.UI.Composition.Desktop; +using Windows.UI.Xaml; +using WindowsTools.WindowsAPI.ComTypes; + +namespace GetStoreAppInstaller.Helpers.Backdrop +{ + /// + /// 背景色辅助类 + /// + public static class BackdropHelper + { + /// + /// 初始化 DesktopWindowTarget(表示作为合成目标的窗口) + /// + public static DesktopWindowTarget InitializeDesktopWindowTarget(IntPtr handle, bool isTopMost) + { + if (handle == nint.Zero) + { + throw new NullReferenceException("窗口句柄无效"); + } + + IntPtr desktopWindowTargetPtr = IntPtr.Zero; + if (DispatcherQueue.GetForCurrentThread() is not null) + { + ICompositorDesktopInterop interop = Window.Current.Compositor as object as ICompositorDesktopInterop; + interop.CreateDesktopWindowTarget(handle, isTopMost, out desktopWindowTargetPtr); + } + + return desktopWindowTargetPtr != IntPtr.Zero ? DesktopWindowTarget.FromAbi(desktopWindowTargetPtr) : null; + } + } +} diff --git a/GetStoreAppInstaller/Properties/AssemblyInfo.cs b/GetStoreAppInstaller/Properties/AssemblyInfo.cs index 87c7f76a5..027e14731 100644 --- a/GetStoreAppInstaller/Properties/AssemblyInfo.cs +++ b/GetStoreAppInstaller/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ [assembly: AssemblyCompany("高怡飞")] [assembly: AssemblyCopyright("Copyright ©2022-2024 高怡飞, All Rights Reserved.")] [assembly: AssemblyDescription("获取商店应用 应用安装器")] -[assembly: AssemblyFileVersion("5.0.929.0")] -[assembly: AssemblyInformationalVersion("5.0.929.0")] +[assembly: AssemblyFileVersion("5.0.1001.0")] +[assembly: AssemblyInformationalVersion("5.0.1001.0")] [assembly: AssemblyProduct("获取商店应用 应用安装器")] [assembly: AssemblyTitle("获取商店应用 应用安装器")] -[assembly: AssemblyVersion("5.0.929.0")] +[assembly: AssemblyVersion("5.0.1001.0")] // 应用程序默认区域性的资源控制器设置 [assembly: NeutralResourcesLanguage("en-us")] diff --git a/GetStoreAppInstaller/UI/Backdrop/BlendEffect.cs b/GetStoreAppInstaller/UI/Backdrop/BlendEffect.cs new file mode 100644 index 000000000..cf4ebc3fb --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/BlendEffect.cs @@ -0,0 +1,96 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("81C5B77B-13F8-4CDD-AD20-C890547AC65D")] + public sealed partial class BlendEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public BlendEffectMode Mode { get; set; } = BlendEffectMode.Multiply; + + public string Name { get; set; } = string.Empty; + + public IGraphicsEffectSource Background { get; set; } + + public IGraphicsEffectSource Foreground { get; set; } + + public int GetEffectId(out Guid id) + { + id = typeof(BlendEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(Mode): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateUInt32((uint)Mode, out IntPtr ptr); + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 1; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + if (index is 0) + { + source = Background; + return 0; + } + else if (index is 1) + { + source = Foreground; + return 0; + } + else + { + source = null; + return 2147483637; + } + } + + public int GetSourceCount(out uint count) + { + count = 2; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/BlendEffectMode.cs b/GetStoreAppInstaller/UI/Backdrop/BlendEffectMode.cs new file mode 100644 index 000000000..568741e31 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/BlendEffectMode.cs @@ -0,0 +1,32 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + public enum BlendEffectMode + { + Multiply = 0, + Screen = 1, + Darken = 2, + Lighten = 3, + Dissolve = 4, + ColorBurn = 5, + LinearBurn = 6, + DarkerColor = 7, + LighterColor = 8, + ColorDodge = 9, + LinearDodge = 10, + Overlay = 11, + SoftLight = 12, + HardLight = 13, + VividLight = 14, + LinearLight = 15, + PinLight = 16, + HardMix = 17, + Difference = 18, + Exclusion = 19, + Hue = 20, + Saturation = 21, + Color = 22, + Luminosity = 23, + Subtract = 24, + Division = 25 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/BorderEffect.cs b/GetStoreAppInstaller/UI/Backdrop/BorderEffect.cs new file mode 100644 index 000000000..e8ef02df4 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/BorderEffect.cs @@ -0,0 +1,108 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("2A2D49C0-4ACF-43C7-8C6A-7C4A27874D27")] + public sealed partial class BorderEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public string Name { get; set; } = string.Empty; + + public CanvasEdgeBehavior ExtendX { get; set; } = CanvasEdgeBehavior.Clamp; + + public CanvasEdgeBehavior ExtendY { get; set; } = CanvasEdgeBehavior.Clamp; + + public IGraphicsEffectSource Source { get; set; } + + public int GetEffectId(out Guid id) + { + id = typeof(BorderEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(ExtendX): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + case nameof(ExtendY): + { + index = 1; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateUInt32((uint)ExtendX, out IntPtr ptr); + + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + else if (index is 1) + { + propertyValue.CreateUInt32((uint)ExtendY, out IntPtr ptr); + + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 2; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + if (index is 0) + { + source = Source; + return 0; + } + else + { + source = null; + return 2147483637; + } + } + + public int GetSourceCount(out uint count) + { + count = 1; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/CanvasComposite.cs b/GetStoreAppInstaller/UI/Backdrop/CanvasComposite.cs new file mode 100644 index 000000000..5a644abda --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/CanvasComposite.cs @@ -0,0 +1,19 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + public enum CanvasComposite + { + SourceOver = 0, + DestinationOver = 1, + SourceIn = 2, + DestinationIn = 3, + SourceOut = 4, + DestinationOut = 5, + SourceAtop = 6, + DestinationAtop = 7, + Xor = 8, + Add = 9, + Copy = 10, + BoundedCopy = 11, + MaskInvert = 12 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/CanvasEdgeBehavior.cs b/GetStoreAppInstaller/UI/Backdrop/CanvasEdgeBehavior.cs new file mode 100644 index 000000000..c0389aa5e --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/CanvasEdgeBehavior.cs @@ -0,0 +1,9 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + public enum CanvasEdgeBehavior + { + Clamp = 0, + Wrap = 1, + Mirror = 2 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/ColorConversion.cs b/GetStoreAppInstaller/UI/Backdrop/ColorConversion.cs new file mode 100644 index 000000000..5cede99d3 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/ColorConversion.cs @@ -0,0 +1,364 @@ +using System; +using Windows.UI; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + public static class ColorConversion + { + public static Color GetEffectiveTintColor(Color tintColor, double tintOpacity, double? luminosityOpacity) + { + // Update tintColor's alpha with the combined opacity value + // If LuminosityOpacity was specified, we don't intervene into users parameters + if (luminosityOpacity.HasValue) + { + tintColor.A = (byte)Math.Round(tintColor.A * tintOpacity); + } + else + { + double tintOpacityModifier = GetTintOpacityModifier(tintColor); + tintColor.A = (byte)Math.Round(tintColor.A * tintOpacity * tintOpacityModifier); + } + + return tintColor; + } + + public static double GetTintOpacityModifier(Color tintColor) + { + // TintOpacityModifier affects the 19H1+ Luminosity-based recipe only + //if (!SharedHelpers::Is19H1OrHigher()) + //{ + // return 1.0; + //} + + // This method supresses the maximum allowable tint opacity depending on the luminosity and saturation of a color by + // compressing the range of allowable values - for example, a user-defined value of 100% will be mapped to 45% for pure + // white (100% luminosity), 85% for pure black (0% luminosity), and 90% for pure gray (50% luminosity). The intensity of + // the effect increases linearly as luminosity deviates from 50%. After this effect is calculated, we cancel it out + // linearly as saturation increases from zero. + + const double midPoint = 0.50; // Mid point of HsvV range that these calculations are based on. This is here for easy tuning. + + const double whiteMaxOpacity = 0.45; // 100% luminosity + const double midPointMaxOpacity = 0.90; // 50% luminosity + const double blackMaxOpacity = 0.85; // 0% luminosity + + (double, double, double) rgb = (tintColor.R / 255.0, tintColor.G / 255.0, tintColor.B / 255.0); + (double _, double s, double v) = RgbToHsv(rgb); + + double opacityModifier = midPointMaxOpacity; + + if (v != midPoint) + { + // Determine maximum suppression amount + double lowestMaxOpacity = midPointMaxOpacity; + double maxDeviation = midPoint; + + if (v > midPoint) + { + lowestMaxOpacity = whiteMaxOpacity; // At white (100% hsvV) + maxDeviation = 1 - maxDeviation; + } + else if (v < midPoint) + { + lowestMaxOpacity = blackMaxOpacity; // At black (0% hsvV) + } + + double maxOpacitySuppression = midPointMaxOpacity - lowestMaxOpacity; + + // Determine normalized deviation from the midpoint + double deviation = Math.Abs(v - midPoint); + double normalizedDeviation = deviation / maxDeviation; + + // If we have saturation, reduce opacity suppression to allow that color to come through more + if (s > 0) + { + // Dampen opacity suppression based on how much saturation there is + maxOpacitySuppression *= Math.Max(1 - (s * 2), 0.0); + } + + double opacitySuppression = maxOpacitySuppression * normalizedDeviation; + + opacityModifier = midPointMaxOpacity - opacitySuppression; + } + + return opacityModifier; + } + + public static Color GetEffectiveLuminosityColor(Color tintColor, double tintOpacity, double? luminosityOpacity) + { + // Purposely leaving out tint opacity modifier here because GetLuminosityColor needs the *original* tint opacity set by the user. + tintColor.A = (byte)Math.Round(tintColor.A * tintOpacity); + + return GetLuminosityColor(tintColor, luminosityOpacity); + } + + public static Color GetLuminosityColor(Color tintColor, double? luminosityOpacity) + { + (double r, double g, double b) rgbTintColor = (tintColor.R / 255.0, tintColor.G / 255.0, tintColor.B / 255.0); + + // If luminosity opacity is specified, just use the values as is + if (luminosityOpacity.HasValue) + { + return Color.FromArgb((byte)(Math.Min(luminosityOpacity.Value, 1.0) * 255), + (byte)(rgbTintColor.r * 255), + (byte)(rgbTintColor.g * 255), + (byte)(rgbTintColor.b * 255)); + } + else + { + // To create the Luminosity blend input color without luminosity opacity, + // we're taking the TintColor input, converting to HSV, and clamping the V between these values + const double minHsvV = 0.125; + const double maxHsvV = 0.965; + + (double h, double s, double v) = RgbToHsv(rgbTintColor); + + double clampedHsvV = Clamp(v, minHsvV, maxHsvV); + + (double h, double s, double clampedHsvV) hsvLuminosityColor = (h, s, clampedHsvV); + (double r, double g, double b) = HsvToRgb(hsvLuminosityColor); + + // Now figure out luminosity opacity + // Map original *tint* opacity to this range + double minLuminosityOpacity = 0.15; + double maxLuminosityOpacity = 1.03; + + double luminosityOpacityRangeMax = maxLuminosityOpacity - minLuminosityOpacity; + double mappedTintOpacity = ((tintColor.A / 255.0) * luminosityOpacityRangeMax) + minLuminosityOpacity; + + // Finally, combine the luminosity opacity and the HsvV-clamped tint color + return Color.FromArgb((byte)(Math.Min(mappedTintOpacity, 1.0) * 255), + (byte)(r * 255), + (byte)(g * 255), + (byte)(b * 255)); + } + } + + public static (double h, double s, double v) RgbToHsv((double r, double g, double b) rgb) + { + double max = rgb.r >= rgb.g ? (rgb.r >= rgb.b ? rgb.r : rgb.b) : (rgb.g >= rgb.b ? rgb.g : rgb.b); + double min = rgb.r <= rgb.g ? (rgb.r <= rgb.b ? rgb.r : rgb.b) : (rgb.g <= rgb.b ? rgb.g : rgb.b); + + // The value, a number between 0 and 1, is the largest of R, G, and B (divided by 255). + // Conceptually speaking, it represents how much color is present. + // If at least one of R, G, B is 255, then there exists as much color as there can be. + // If RGB = (0, 0, 0), then there exists no color at all - a value of zero corresponds + // to black (i.e., the absence of any color). + double value = max; + + // The "chroma" of the color is a value directly proportional to the extent to which + // the color diverges from greyscale. If, for example, we have RGB = (255, 255, 0), + // then the chroma is maximized - this is a pure yellow, no grey of any kind. + // On the other hand, if we have RGB = (128, 128, 128), then the chroma being zero + // implies that this color is pure greyscale, with no actual hue to be found. + double chroma = max - min; + + double hue; + double saturation; + // If the chrome is zero, then hue is technically undefined - a greyscale color + // has no hue. For the sake of convenience, we'll just set hue to zero, since + // it will be unused in this circumstance. Since the color is purely grey, + // saturation is also equal to zero - you can think of saturation as basically + // a measure of hue intensity, such that no hue at all corresponds to a + // nonexistent intensity. + if (chroma is 0) + { + hue = 0.0; + saturation = 0.0; + } + else + { + // In this block, hue is properly defined, so we'll extract both hue + // and saturation information from the RGB color. + + // Hue can be thought of as a cyclical thing, between 0 degrees and 360 degrees. + // A hue of 0 degrees is red; 120 degrees is green; 240 degrees is blue; and 360 is back to red. + // Every other hue is somewhere between either red and green, green and blue, and blue and red, + // so every other hue can be thought of as an angle on this color wheel. + // These if/else statements determines where on this color wheel our color lies. + if (rgb.r == max) + { + // If the red channel is the most pronounced channel, then we exist + // somewhere between (-60, 60) on the color wheel - i.e., the section around 0 degrees + // where red dominates. We figure out where in that section we are exactly + // by considering whether the green or the blue channel is greater - by subtracting green from blue, + // then if green is greater, we'll nudge ourselves closer to 60, whereas if blue is greater, then + // we'll nudge ourselves closer to -60. We then divide by chroma (which will actually make the result larger, + // since chroma is a value between 0 and 1) to normalize the value to ensure that we get the right hue + // even if we're very close to greyscale. + hue = 60 * (rgb.g - rgb.b) / chroma; + } + else if (rgb.g == max) + { + // We do the exact same for the case where the green channel is the most pronounced channel, + // only this time we want to see if we should tilt towards the blue direction or the red direction. + // We add 120 to center our value in the green third of the color wheel. + hue = 120 + 60 * (rgb.b - rgb.r) / chroma; + } + else // rgb.b == max + { + // And we also do the exact same for the case where the blue channel is the most pronounced channel, + // only this time we want to see if we should tilt towards the red direction or the green direction. + // We add 240 to center our value in the blue third of the color wheel. + hue = 240 + 60 * (rgb.r - rgb.g) / chroma; + } + + // Since we want to work within the range [0, 360), we'll add 360 to any value less than zero - + // this will bump red values from within -60 to -1 to 300 to 359. The hue is the same at both values. + if (hue < 0.0) + { + hue += 360.0; + } + + // The saturation, our final HSV axis, can be thought of as a value between 0 and 1 indicating how intense our color is. + // To find it, we divide the chroma - the distance between the minimum and the maximum RGB channels - by the maximum channel (i.e., the value). + // This effectively normalizes the chroma - if the maximum is 0.5 and the minimum is 0, the saturation will be (0.5 - 0) / 0.5 = 1, + // meaning that although this color is not as bright as it can be, the dark color is as intense as it possibly could be. + // If, on the other hand, the maximum is 0.5 and the minimum is 0.25, then the saturation will be (0.5 - 0.25) / 0.5 = 0.5, + // meaning that this color is partially washed out. + // A saturation value of 0 corresponds to a greyscale color, one in which the color is *completely* washed out and there is no actual hue. + saturation = chroma / value; + } + + return (hue, saturation, value); + } + + public static (double r, double g, double b) HsvToRgb((double h, double s, double v) hsv) + { + double hue = hsv.h; + double saturation = hsv.s; + double value = hsv.v; + + // We want the hue to be between 0 and 359, + // so we first ensure that that's the case. + while (hue >= 360.0) + { + hue -= 360.0; + } + + while (hue < 0.0) + { + hue += 360.0; + } + + // We similarly clamp saturation and value between 0 and 1. + saturation = saturation < 0.0 ? 0.0 : saturation; + saturation = saturation > 1.0 ? 1.0 : saturation; + + value = value < 0.0 ? 0.0 : value; + value = value > 1.0 ? 1.0 : value; + + // The first thing that we need to do is to determine the chroma (see above for its definition). + // Remember from above that: + // + // 1. The chroma is the difference between the maximum and the minimum of the RGB channels, + // 2. The value is the maximum of the RGB channels, and + // 3. The saturation comes from dividing the chroma by the maximum of the RGB channels (i.e., the value). + // + // From these facts, you can see that we can retrieve the chroma by simply multiplying the saturation and the value, + // and we can retrieve the minimum of the RGB channels by subtracting the chroma from the value. + double chroma = saturation * value; + double min = value - chroma; + + // If the chroma is zero, then we have a greyscale color. In that case, the maximum and the minimum RGB channels + // have the same value (and, indeed, all of the RGB channels are the same), so we can just immediately return + // the minimum value as the value of all the channels. + if (chroma is 0) + { + return (min, min, min); + } + + // If the chroma is not zero, then we need to continue. The first step is to figure out + // what section of the color wheel we're located in. In order to do that, we'll divide the hue by 60. + // The resulting value means we're in one of the following locations: + // + // 0 - Between red and yellow. + // 1 - Between yellow and green. + // 2 - Between green and cyan. + // 3 - Between cyan and blue. + // 4 - Between blue and purple. + // 5 - Between purple and red. + // + // In each of these sextants, one of the RGB channels is completely present, one is partially present, and one is not present. + // For example, as we transition between red and yellow, red is completely present, green is becoming increasingly present, and blue is not present. + // Then, as we transition from yellow and green, green is now completely present, red is becoming decreasingly present, and blue is still not present. + // As we transition from green to cyan, green is still completely present, blue is becoming increasingly present, and red is no longer present. And so on. + // + // To convert from hue to RGB value, we first need to figure out which of the three channels is in which configuration + // in the sextant that we're located in. Next, we figure out what value the completely-present color should have. + // We know that chroma = (max - min), and we know that this color is the max color, so to find its value we simply add + // min to chroma to retrieve max. Finally, we consider how far we've transitioned from the pure form of that color + // to the next color (e.g., how far we are from pure red towards yellow), and give a value to the partially present channel + // equal to the minimum plus the chroma (i.e., the max minus the min), multiplied by the percentage towards the new color. + // This gets us a value between the maximum and the minimum representing the partially present channel. + // Finally, the not-present color must be equal to the minimum value, since it is the one least participating in the overall color. + int sextant = (int)(hue / 60); + double intermediateColorPercentage = hue / 60 - sextant; + double max = chroma + min; + + double r = 0; + double g = 0; + double b = 0; + + switch (sextant) + { + case 0: + r = max; + g = min + chroma * intermediateColorPercentage; + b = min; + break; + + case 1: + r = min + chroma * (1 - intermediateColorPercentage); + g = max; + b = min; + break; + + case 2: + r = min; + g = max; + b = min + chroma * intermediateColorPercentage; + break; + + case 3: + r = min; + g = min + chroma * (1 - intermediateColorPercentage); + b = max; + break; + + case 4: + r = min + chroma * intermediateColorPercentage; + g = min; + b = max; + break; + + case 5: + r = max; + g = min; + b = min + chroma * (1 - intermediateColorPercentage); + break; + } + + return (r, g, b); + } + + public static double Clamp(double value, double min, double max) + { + if (min > max) + { + throw new ArgumentException(string.Format("最小值不能超过最大值,最小值 {0},最大值 {1}", min, max)); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/ColorSourceEffect.cs b/GetStoreAppInstaller/UI/Backdrop/ColorSourceEffect.cs new file mode 100644 index 000000000..efc230f44 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/ColorSourceEffect.cs @@ -0,0 +1,80 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; +using Windows.UI; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("61C23C20-AE69-4D8E-94CF-50078DF638F2")] + public sealed partial class ColorSourceEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public string Name { get; set; } = string.Empty; + + public Color Color { get; set; } = Color.FromArgb(255, 255, 255, 255); + + public int GetEffectId(out Guid id) + { + id = typeof(ColorSourceEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(Color): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR4; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateSingleArray(4, [Color.R / 255.0f, Color.G / 255.0f, Color.B / 255.0f, Color.A / 255.0f], out IntPtr ptr); + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 1; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + source = null; + return 0; + } + + public int GetSourceCount(out uint count) + { + count = 0; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/CompositeEffect.cs b/GetStoreAppInstaller/UI/Backdrop/CompositeEffect.cs new file mode 100644 index 000000000..9038c3a0e --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/CompositeEffect.cs @@ -0,0 +1,91 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("48FC9F51-F6AC-48F1-8B58-3B28AC46F76D")] + public sealed partial class CompositeEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public string Name { get; set; } = string.Empty; + + public CanvasComposite Mode { get; set; } = CanvasComposite.SourceOver; + + public List Sources { get; set; } = []; + + public int GetEffectId(out Guid id) + { + id = typeof(CompositeEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(Mode): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateUInt32((uint)Mode, out IntPtr ptr); + + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 1; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + if (index < Sources.Count) + { + source = Sources[(int)index]; + return 0; + } + else + { + source = null; + return 2147483637; + } + } + + public int GetSourceCount(out uint count) + { + count = (uint)Sources.Count; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/CrossFadeEffect.cs b/GetStoreAppInstaller/UI/Backdrop/CrossFadeEffect.cs new file mode 100644 index 000000000..5ea7ecaba --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/CrossFadeEffect.cs @@ -0,0 +1,96 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("12F575E8-4DB1-485F-9A84-03A07DD3829F")] + public sealed partial class CrossFadeEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public string Name { get; set; } = string.Empty; + + public float CrossFade { get; set; } = 0.5f; + + public IGraphicsEffectSource Source1 { get; set; } + + public IGraphicsEffectSource Source2 { get; set; } + + public int GetEffectId(out Guid id) + { + id = typeof(CrossFadeEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(CrossFade): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateSingle((float)CrossFade, out IntPtr ptr); + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 1; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + if (index is 0) + { + source = Source1; + return 0; + } + else if (index is 1) + { + source = Source2; + return 0; + } + else + { + source = null; + return 2147483637; + } + } + + public int GetSourceCount(out uint count) + { + count = 2; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicBackdrop.cs b/GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicBackdrop.cs new file mode 100644 index 000000000..2417b7bc3 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicBackdrop.cs @@ -0,0 +1,794 @@ +using GetStoreAppInstaller.WindowsAPI.PInvoke.Comctl32; +using GetStoreAppInstaller.WindowsAPI.PInvoke.User32; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation.Metadata; +using Windows.Graphics.Display; +using Windows.System; +using Windows.System.Power; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Composition.Desktop; +using Windows.UI.ViewManagement; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; + +// 抑制 CA1822 警告 +#pragma warning disable CA1822 + +namespace GetStoreAppInstaller.UI.Backdrop +{ + /// + /// Desktop Acrylic 背景色 + /// + public sealed partial class DesktopAcrylicBackdrop : SystemBackdrop + { + private bool isInitialized; + private bool isWindowClosed; + private bool isActivated = true; + private bool useMicaBrush; + private bool useDesktopAcrylicBackdrop; + + private readonly IntPtr windowHandle; + private readonly FrameworkElement rootElement; + private readonly UISettings uiSettings = new(); + private readonly AccessibilitySettings accessibilitySettings = new(); + private readonly CompositionCapabilities compositionCapabilities = CompositionCapabilities.GetForCurrentView(); + private readonly DisplayInformation displayInformation = DisplayInformation.GetForCurrentView(); + private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + + private readonly float defaultDesktopAcrylicDefaultLightTintOpacity = 0; + private readonly float defaultDesktopAcrylicDefaultLightLuminosityOpacity = 0.85f; + private readonly float defaultDesktopAcrylicDefaultDarkTintOpacity = 0.15f; + private readonly float defaultDesktopAcrylicDefaultDarkLuminosityOpacity = 96; + private readonly Color defaultDesktopAcrylicDefaultLightTintColor = Color.FromArgb(255, 252, 252, 252); + private readonly Color defaultDesktopAcrylicDefaultLightFallbackColor = Color.FromArgb(255, 249, 249, 249); + private readonly Color defaultDesktopAcrylicDefaultDarkTintColor = Color.FromArgb(255, 44, 44, 44); + private readonly Color defaultDesktopAcrylicDefaultDarkFallbackColor = Color.FromArgb(255, 44, 44, 44); + + private readonly float defaultDesktopAcrylicBaseLightTintOpacity = 0; + private readonly float defaultDesktopAcrylicBaseLightLuminosityOpacity = 0.9f; + private readonly float defaultDesktopAcrylicBaseDarkTintOpacity = 0.5f; + private readonly float defaultDesktopAcrylicBaseDarkLuminosityOpacity = 0.96f; + private readonly Color defaultDesktopAcrylicBaseLightTintColor = Color.FromArgb(255, 243, 243, 243); + private readonly Color defaultDesktopAcrylicBaseLightFallbackColor = Color.FromArgb(255, 238, 238, 238); + private readonly Color defaultDesktopAcrylicBaseDarkTintColor = Color.FromArgb(255, 32, 32, 32); + private readonly Color defaultDesktopAcrylicBaseDarkFallbackColor = Color.FromArgb(255, 28, 28, 28); + + private readonly float defaultDesktopAcrylicThinLightTintOpacity = 0; + private readonly float defaultDesktopAcrylicThinLightLuminosityOpacity = 0.44f; + private readonly float defaultDesktopAcrylicThinDarkTintOpacity = 0.15f; + private readonly float defaultDesktopAcrylicThinDarkLuminosityOpacity = 0.64f; + private readonly Color defaultDesktopAcrylicThinLightTintColor = Color.FromArgb(255, 211, 211, 211); + private readonly Color defaultDesktopAcrylicThinLightFallbackColor = Color.FromArgb(255, 211, 211, 211); + private readonly Color defaultDesktopAcrylicThinDarkTintColor = Color.FromArgb(255, 84, 84, 84); + private readonly Color defaultDesktopAcrylicThinDarkFallbackColor = Color.FromArgb(255, 84, 84, 84); + + private SUBCLASSPROC windowSubClassProc; + + public DesktopAcrylicKind Kind { get; set; } = DesktopAcrylicKind.Default; + + private float _lightTintOpacity = 0; + + public override float LightTintOpacity + { + get { return _lightTintOpacity; } + + set + { + if (!Equals(_lightTintOpacity, value)) + { + _lightTintOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private float _lightLuminosityOpacity = 0; + + public override float LightLuminosityOpacity + { + get { return _lightLuminosityOpacity; } + + set + { + if (!Equals(_lightLuminosityOpacity, value)) + { + _lightLuminosityOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private float _darkTintOpacity = 0; + + public override float DarkTintOpacity + { + get { return _darkTintOpacity; } + + set + { + if (!Equals(_darkTintOpacity, value)) + { + _darkTintOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private float _darkLuminosityOpacity = 0; + + public override float DarkLuminosityOpacity + { + get { return _darkLuminosityOpacity; } + + set + { + if (!Equals(_darkLuminosityOpacity, value)) + { + _darkLuminosityOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private Color _lightTintColor = Color.FromArgb(0, 0, 0, 0); + + public override Color LightTintColor + { + get { return _lightTintColor; } + + set + { + if (!Equals(_lightTintColor, value)) + { + _lightTintColor = value; + UpdateBrush(); + } + } + } + + private Color _lightFallbackColor = Color.FromArgb(0, 0, 0, 0); + + public override Color LightFallbackColor + { + get { return _lightFallbackColor; } + + set + { + if (!Equals(_lightFallbackColor, value)) + { + _lightFallbackColor = value; + UpdateBrush(); + } + } + } + + private Color _darkTintColor = Color.FromArgb(0, 0, 0, 0); + + public override Color DarkTintColor + { + get { return _darkTintColor; } + + set + { + if (!Equals(_darkTintColor, value)) + { + _darkTintColor = value; + UpdateBrush(); + } + } + } + + private Color _darkFallbackColor = Color.FromArgb(0, 0, 0, 0); + + public override Color DarkFallbackColor + { + get { return _darkFallbackColor; } + + set + { + if (!Equals(_darkFallbackColor, value)) + { + _darkFallbackColor = value; + UpdateBrush(); + } + } + } + + private ElementTheme _requestedTheme = ElementTheme.Default; + + public override ElementTheme RequestedTheme + { + get { return _requestedTheme; } + + set + { + if (!Equals(_requestedTheme, value)) + { + _requestedTheme = value; + UpdateBrush(); + } + } + } + + private bool _isInputActive = false; + + public override bool IsInputActive + { + get { return _isInputActive; } + + set + { + if (!Equals(_isInputActive, value)) + { + _isInputActive = value; + } + } + } + + private bool _useHostBackdropBrush = false; + + public bool UseHostBackdropBrush + { + get { return _useHostBackdropBrush; } + + set + { + if (!Equals(_useHostBackdropBrush, value)) + { + _useHostBackdropBrush = value; + UpdateBrush(); + } + } + } + + private float _blurAmount = 30f; + + public float BlurAmount + { + get { return _blurAmount; } + + set + { + if (!Equals(_blurAmount, value)) + { + _blurAmount = value; + UpdateBrush(); + } + } + } + + public static bool IsSupported + { + get + { + return ApiInformation.IsMethodPresent(typeof(Compositor).FullName, nameof(Compositor.TryCreateBlurredWallpaperBackdropBrush)); + } + } + + public static bool IsHostBackdropSupported + { + get { return Environment.OSVersion.Version >= new Version(10, 0, 22000, 0); } + } + + public DesktopAcrylicBackdrop(DesktopWindowTarget target, FrameworkElement element, IntPtr handle) : base(target) + { + if (target is null) + { + throw new ArgumentNullException(string.Format("参数 {0} 不可以为空值", nameof(target))); + } + + if (handle == IntPtr.Zero) + { + throw new NullReferenceException("窗口句柄无效"); + } + + windowHandle = handle; + rootElement = element; + } + + ~DesktopAcrylicBackdrop() + { + Dispose(false); + } + + /// + /// 初始化系统背景色 + /// + public override void InitializeBackdrop() + { + if (!isInitialized) + { + float defaultOpacityValue = 0; + Color defaultColorValue = Color.FromArgb(0, 0, 0, 0); + + if (Kind is DesktopAcrylicKind.Default) + { + _lightTintOpacity = _lightTintOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicDefaultLightTintOpacity : _lightTintOpacity; + _lightLuminosityOpacity = _lightLuminosityOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicDefaultLightLuminosityOpacity : _lightLuminosityOpacity; + _darkTintOpacity = _darkTintOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicDefaultDarkTintOpacity : _darkTintOpacity; + _darkLuminosityOpacity = _darkLuminosityOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicDefaultDarkLuminosityOpacity : _darkLuminosityOpacity; + _lightTintColor = _lightTintColor.Equals(defaultColorValue) ? defaultDesktopAcrylicDefaultLightTintColor : _lightTintColor; + _lightFallbackColor = _lightFallbackColor.Equals(defaultColorValue) ? defaultDesktopAcrylicDefaultLightFallbackColor : _lightFallbackColor; + _darkTintColor = _darkTintColor.Equals(defaultColorValue) ? defaultDesktopAcrylicDefaultDarkTintColor : _darkTintColor; + _darkFallbackColor = _darkFallbackColor.Equals(defaultColorValue) ? defaultDesktopAcrylicDefaultDarkFallbackColor : _darkFallbackColor; + } + else if (Kind is DesktopAcrylicKind.Base) + { + _lightTintOpacity = _lightTintOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicBaseLightTintOpacity : _lightTintOpacity; + _lightLuminosityOpacity = _lightLuminosityOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicBaseLightLuminosityOpacity : _lightLuminosityOpacity; + _darkTintOpacity = _darkTintOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicBaseDarkTintOpacity : _darkTintOpacity; + _darkLuminosityOpacity = _darkLuminosityOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicBaseDarkLuminosityOpacity : _darkLuminosityOpacity; + _lightTintColor = _lightTintColor.Equals(defaultColorValue) ? defaultDesktopAcrylicBaseLightTintColor : _lightTintColor; + _lightFallbackColor = _lightFallbackColor.Equals(defaultColorValue) ? defaultDesktopAcrylicBaseLightFallbackColor : _lightFallbackColor; + _darkTintColor = _darkTintColor.Equals(defaultColorValue) ? defaultDesktopAcrylicBaseDarkTintColor : _darkTintColor; + _darkFallbackColor = _darkFallbackColor.Equals(defaultColorValue) ? defaultDesktopAcrylicBaseDarkFallbackColor : _darkFallbackColor; + } + else + { + _lightTintOpacity = _lightTintOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicThinLightTintOpacity : _lightTintOpacity; + _lightLuminosityOpacity = _lightLuminosityOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicThinLightLuminosityOpacity : _lightLuminosityOpacity; + _darkTintOpacity = _darkTintOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicThinDarkTintOpacity : _darkTintOpacity; + _darkLuminosityOpacity = _darkLuminosityOpacity.Equals(defaultOpacityValue) ? defaultDesktopAcrylicThinDarkLuminosityOpacity : _darkLuminosityOpacity; + _lightTintColor = _lightTintColor.Equals(defaultColorValue) ? defaultDesktopAcrylicThinLightTintColor : _lightTintColor; + _lightFallbackColor = _lightFallbackColor.Equals(defaultColorValue) ? defaultDesktopAcrylicThinLightFallbackColor : _lightFallbackColor; + _darkTintColor = _darkTintColor.Equals(defaultColorValue) ? defaultDesktopAcrylicThinDarkTintColor : _darkTintColor; + _darkFallbackColor = _darkFallbackColor.Equals(defaultColorValue) ? defaultDesktopAcrylicThinDarkFallbackColor : _darkFallbackColor; + } + + if (DesktopWindowTarget.Root is null) + { + DesktopWindowTarget.Root = DesktopWindowTarget.Compositor.CreateSpriteVisual(); + } + + uiSettings.ColorValuesChanged += OnColorValuesChanged; + accessibilitySettings.HighContrastChanged += OnHighContrastChanged; + compositionCapabilities.Changed += OnCompositionCapabilitiesChanged; + displayInformation.DpiChanged += OnDpiChanged; + PowerManager.EnergySaverStatusChanged += OnEnergySaverStatusChanged; + + if (rootElement is not null) + { + rootElement.ActualThemeChanged += OnActualThemeChanged; + } + + windowSubClassProc = new SUBCLASSPROC(OnWindowSubClassProc); + Comctl32Library.SetWindowSubclass(windowHandle, Marshal.GetFunctionPointerForDelegate(windowSubClassProc), 0, IntPtr.Zero); + + isInitialized = true; + UpdateBrush(); + } + } + + /// + /// 恢复默认值 + /// + public override void ResetProperties() + { + if (Kind is DesktopAcrylicKind.Default) + { + _lightTintOpacity = defaultDesktopAcrylicDefaultLightTintOpacity; + _lightLuminosityOpacity = defaultDesktopAcrylicDefaultLightLuminosityOpacity; + _darkTintOpacity = defaultDesktopAcrylicDefaultDarkTintOpacity; + _darkLuminosityOpacity = defaultDesktopAcrylicDefaultDarkLuminosityOpacity; + _lightTintColor = defaultDesktopAcrylicDefaultLightTintColor; + _lightFallbackColor = defaultDesktopAcrylicDefaultLightFallbackColor; + _darkTintColor = defaultDesktopAcrylicDefaultDarkTintColor; + _darkFallbackColor = defaultDesktopAcrylicDefaultDarkFallbackColor; + } + else if (Kind is DesktopAcrylicKind.Base) + { + _lightTintOpacity = defaultDesktopAcrylicBaseLightTintOpacity; + _lightLuminosityOpacity = defaultDesktopAcrylicBaseLightLuminosityOpacity; + _darkTintOpacity = defaultDesktopAcrylicBaseDarkTintOpacity; + _darkLuminosityOpacity = defaultDesktopAcrylicBaseDarkLuminosityOpacity; + _lightTintColor = defaultDesktopAcrylicBaseLightTintColor; + _lightFallbackColor = defaultDesktopAcrylicBaseLightFallbackColor; + _darkTintColor = defaultDesktopAcrylicBaseDarkTintColor; + _darkFallbackColor = defaultDesktopAcrylicBaseDarkFallbackColor; + } + else + { + _lightTintOpacity = defaultDesktopAcrylicThinLightTintOpacity; + _lightLuminosityOpacity = defaultDesktopAcrylicThinLightLuminosityOpacity; + _darkTintOpacity = defaultDesktopAcrylicThinDarkTintOpacity; + _darkLuminosityOpacity = defaultDesktopAcrylicThinDarkLuminosityOpacity; + _lightTintColor = defaultDesktopAcrylicThinLightTintColor; + _lightFallbackColor = defaultDesktopAcrylicThinLightFallbackColor; + _darkTintColor = defaultDesktopAcrylicThinDarkTintColor; + _darkFallbackColor = defaultDesktopAcrylicThinDarkFallbackColor; + } + + _requestedTheme = ElementTheme.Default; + _isInputActive = false; + _useHostBackdropBrush = false; + + if (isInitialized) + { + UpdateBrush(); + } + } + + /// + /// 关闭背景色 + /// + public override void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 关闭背景色 + /// + private void Dispose(bool disposing) + { + if (!disposing) + { + return; + } + + lock (this) + { + if (isInitialized) + { + isInitialized = false; + + uiSettings.ColorValuesChanged -= OnColorValuesChanged; + accessibilitySettings.HighContrastChanged -= OnHighContrastChanged; + compositionCapabilities.Changed -= OnCompositionCapabilitiesChanged; + displayInformation.DpiChanged -= OnDpiChanged; + PowerManager.EnergySaverStatusChanged -= OnEnergySaverStatusChanged; + + if (rootElement is not null) + { + rootElement.ActualThemeChanged -= OnActualThemeChanged; + } + + Comctl32Library.RemoveWindowSubclass(windowHandle, Marshal.GetFunctionPointerForDelegate(windowSubClassProc), 0); + + if (DesktopWindowTarget.Root is SpriteVisual spriteVisual && spriteVisual.Brush is not null) + { + spriteVisual.Brush.Dispose(); + spriteVisual.Brush = null; + } + } + } + } + + /// + /// 颜色值更改时发生的事件 + /// + private void OnColorValuesChanged(UISettings sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 当系统高对比度功能打开或关闭时发生的事件 + /// + private void OnHighContrastChanged(AccessibilitySettings sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 当支持的合成功能发生更改时触发的事件 + /// + private void OnCompositionCapabilitiesChanged(CompositionCapabilities sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 显示窗口的屏幕的 DPI 发生更改后触发的事件 + /// + private void OnDpiChanged(DisplayInformation sender, object args) + { + dispatcherQueue.TryEnqueue(() => + { + if (DesktopWindowTarget.Root is SpriteVisual spriteVisual) + { + //spriteVisual.Size = new Vector2(formRoot.Width, formRoot.Height); + } + }); + } + + /// + /// 在设备的节电模式状态更改时触发的事件 + /// + private void OnEnergySaverStatusChanged(object sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 在 ActualTheme 属性值更改时触发的事件 + /// + private void OnActualThemeChanged(FrameworkElement sender, object args) + { + UpdateBrush(); + } + + /// + /// 更新应用的背景色 + /// + private void UpdateBrush() + { + if (isInitialized) + { + ElementTheme actualTheme = ElementTheme.Default; + + // 如果传入的 FrameworkElement 为空值,则由系统默认主题色值决定窗口的背景色 + if (rootElement is not null) + { + // 主题值为默认时,窗口背景色主题值则由 FrameworkElement 决定 + actualTheme = RequestedTheme is ElementTheme.Default ? rootElement.ActualTheme : RequestedTheme; + } + else + { + actualTheme = Windows.UI.Xaml.Application.Current.RequestedTheme is ApplicationTheme.Light ? ElementTheme.Light : ElementTheme.Dark; + } + + float tintOpacity; + float luminosityOpacity; + Color tintColor; + Color fallbackColor; + + if (actualTheme is ElementTheme.Light) + { + tintOpacity = LightTintOpacity; + luminosityOpacity = LightLuminosityOpacity; + tintColor = LightTintColor; + fallbackColor = LightFallbackColor; + } + else + { + tintOpacity = DarkTintOpacity; + luminosityOpacity = DarkLuminosityOpacity; + tintColor = DarkTintColor; + fallbackColor = DarkFallbackColor; + } + + useDesktopAcrylicBackdrop = IsSupported && uiSettings.AdvancedEffectsEnabled && PowerManager.EnergySaverStatus is not EnergySaverStatus.On && compositionCapabilities.AreEffectsSupported() && (IsInputActive || isActivated); + + if (accessibilitySettings.HighContrast) + { + tintColor = uiSettings.GetColorValue(UIColorType.Background); + useDesktopAcrylicBackdrop = false; + } + + Compositor compositor = DesktopWindowTarget.Compositor; + CompositionBrush newBrush = useDesktopAcrylicBackdrop ? BuildDesktopAcrylicEffectBrush(compositor, tintColor, tintOpacity, luminosityOpacity) : compositor.CreateColorBrush(fallbackColor); + CompositionBrush oldBrush = (DesktopWindowTarget.Root as SpriteVisual).Brush; + + if (oldBrush is null || oldBrush.Comment is "Crossfade") + { + // 直接设置新笔刷 + oldBrush?.Dispose(); + (DesktopWindowTarget.Root as SpriteVisual).Brush = newBrush; + //(DesktopWindowTarget.Root as SpriteVisual).Size = new Vector2(formRoot.Width, formRoot.Height); + } + else + { + // 回退色切换时的动画颜色 + CompositionBrush crossFadeBrush = CreateCrossFadeEffectBrush(compositor, oldBrush, newBrush); + ScalarKeyFrameAnimation animation = CreateCrossFadeAnimation(compositor); + (DesktopWindowTarget.Root as SpriteVisual).Brush = crossFadeBrush; + //(DesktopWindowTarget.Root as SpriteVisual).Size = new Vector2(formRoot.Width, formRoot.Height); + + CompositionScopedBatch crossFadeAnimationBatch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + crossFadeBrush.StartAnimation("CrossFade.CrossFade", animation); + crossFadeAnimationBatch.End(); + + crossFadeAnimationBatch.Completed += (o, a) => + { + crossFadeBrush.Dispose(); + oldBrush.Dispose(); + (DesktopWindowTarget.Root as SpriteVisual).Brush = newBrush; + //(DesktopWindowTarget.Root as SpriteVisual).Size = new Vector2(formRoot.Width, formRoot.Height); + }; + } + } + } + + /// + /// 创建 DesktopAcrylic 背景色 + /// + private CompositionEffectBrush BuildDesktopAcrylicEffectBrush(Compositor compositor, Color tintColor, float tintOpacity, float luminosityOpacity) + { + Color convertedLuminosityColor = ColorConversion.GetEffectiveLuminosityColor(tintColor, tintOpacity, luminosityOpacity); + Color convertedTintColor = ColorConversion.GetEffectiveTintColor(tintColor, tintOpacity, luminosityOpacity); + + // Source 1 : Host backdrop layer effect + ColorSourceEffect hostBackdropEffect = new() + { + Color = Color.FromArgb(255, 0, 0, 0) + }; + + OpacityEffect hostBackdropLayerEffect = new() + { + Name = "FixHostBackdropLayer", + Opacity = IsHostBackdropSupported && UseHostBackdropBrush ? 1 : 0, + Source = hostBackdropEffect, + }; + + // Source 2 : Tint color effect + GaussianBlurEffect gaussianBlurEffect = new() + { + Name = "GaussianBlurEffect", + BlurAmount = IsHostBackdropSupported && UseHostBackdropBrush ? Math.Max(BlurAmount - 30, 0) : BlurAmount, + Source = new CompositionEffectSourceParameter("source"), + BorderMode = EffectBorderMode.Hard + }; + + BlendEffect luminosityColorEffect = new() + { + Mode = BlendEffectMode.Color, + Foreground = new ColorSourceEffect + { + Name = "LuminosityColorEffect", + Color = convertedLuminosityColor, + }, + Background = gaussianBlurEffect + }; + + ColorSourceEffect tintColorEffect = new() + { + Name = "TintColorEffect", + Color = convertedTintColor, + }; + + BlendEffect tintAndLuminosityColorEffect = new() + { + Mode = BlendEffectMode.Luminosity, + Foreground = tintColorEffect, + Background = luminosityColorEffect + }; + + OpacityEffect tintColorOpacityEffect = new() + { + Name = "TintColorOpacityEffect", + Opacity = convertedTintColor.A is 255 ? 0f : 1f, + Source = tintAndLuminosityColorEffect + }; + + // Source 3: Tint color effect without alpha + ColorSourceEffect tintColorEffectWithoutAlphaEffect = new() + { + Name = "TintColorEffectWithoutAlpha", + Color = convertedTintColor + }; + + OpacityEffect TintColorWithoutAlphaOpacityEffect = new() + { + Name = "TintColorWithoutAlphaOpacityEffect", + Opacity = convertedTintColor.A is 255 ? 1f : 0f, + Source = tintColorEffectWithoutAlphaEffect, + }; + + // Source 4 : Noise border effect + BorderEffect noiseBorderEffect = new() + { + Source = new CompositionEffectSourceParameter("noise"), + ExtendX = CanvasEdgeBehavior.Wrap, + ExtendY = CanvasEdgeBehavior.Wrap, + }; + + OpacityEffect noiseEffect = new() + { + Opacity = 0.02f, + Source = noiseBorderEffect, + }; + + CompositeEffect compositeEffect = new() + { + Mode = CanvasComposite.SourceOver, + Sources = + { + hostBackdropLayerEffect, + tintColorOpacityEffect, + TintColorWithoutAlphaOpacityEffect, + noiseEffect + } + }; + + CompositionSurfaceBrush noiseBrush = compositor.CreateSurfaceBrush(); + noiseBrush.Stretch = CompositionStretch.None; + noiseBrush.Surface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/Images/NoiseAsset_256x256_PNG.png")); + + CompositionEffectBrush desktopAcrylicBrush = compositor.CreateEffectFactory(compositeEffect).CreateBrush(); + + CompositionBrush backdropBrush = IsHostBackdropSupported && UseHostBackdropBrush ? compositor.CreateHostBackdropBrush() : compositor.CreateBackdropBrush(); + + desktopAcrylicBrush.SetSourceParameter("source", backdropBrush); + desktopAcrylicBrush.SetSourceParameter("noise", noiseBrush); + + return desktopAcrylicBrush; + } + + /// + /// 创建回退色切换时的动画颜色 + /// + private CompositionEffectBrush CreateCrossFadeEffectBrush(Compositor compositor, CompositionBrush from, CompositionBrush to) + { + CrossFadeEffect crossFadeEffect = new() + { + Name = "Crossfade", // Name to reference when starting the animation. + Source1 = new CompositionEffectSourceParameter("source1"), + Source2 = new CompositionEffectSourceParameter("source2"), + CrossFade = 0 + }; + + CompositionEffectBrush crossFadeEffectBrush = compositor.CreateEffectFactory(crossFadeEffect, ["Crossfade.CrossFade"]).CreateBrush(); + crossFadeEffectBrush.Comment = "Crossfade"; + + crossFadeEffectBrush.SetSourceParameter("source1", from); + crossFadeEffectBrush.SetSourceParameter("source2", to); + return crossFadeEffectBrush; + } + + /// + /// 为回退色创建动画效果 + /// + private ScalarKeyFrameAnimation CreateCrossFadeAnimation(Compositor compositor) + { + ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation(); + LinearEasingFunction linearEasing = compositor.CreateLinearEasingFunction(); + animation.InsertKeyFrame(0.0f, 0.0f, linearEasing); + animation.InsertKeyFrame(1.0f, 1.0f, linearEasing); + animation.Duration = TimeSpan.FromMilliseconds(250); + return animation; + } + + /// + /// 应用主窗口消息处理 + /// + private IntPtr OnWindowSubClassProc(IntPtr hWnd, WindowMessage Msg, UIntPtr wParam, IntPtr lParam, uint uIdSubclass, IntPtr dwRefData) + { + // 窗口大小发生变化时的消息 + if (Msg is WindowMessage.WM_SIZE) + { + if (DesktopWindowTarget.Root is SpriteVisual spriteVisual) + { + //spriteVisual.Size = new Vector2(formRoot.Width, formRoot.Height); + } + } + // 窗口关闭时的消息 + else if (Msg is WindowMessage.WM_CLOSE) + { + isWindowClosed = true; + Dispose(); + } + // 窗口激活状态发生变化时的消息 + else if (Msg is WindowMessage.WM_ACTIVATE) + { + isActivated = true; + UpdateBrush(); + } + + return Comctl32Library.DefSubclassProc(hWnd, Msg, wParam, lParam); + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicKind.cs b/GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicKind.cs new file mode 100644 index 000000000..2a081338e --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/DesktopAcrylicKind.cs @@ -0,0 +1,23 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + /// + /// 定义指定使用亚克力材料的变体的常量 + /// + public enum DesktopAcrylicKind + { + /// + /// 系统确定使用哪个 Acrylic 变体 + /// + Default = 0, + + /// + /// 使用基亚克力变体 + /// + Base = 1, + + /// + /// 使用细亚克力变体 + /// + Thin = 2 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/EffectBorderMode.cs b/GetStoreAppInstaller/UI/Backdrop/EffectBorderMode.cs new file mode 100644 index 000000000..692fbda36 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/EffectBorderMode.cs @@ -0,0 +1,8 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + public enum EffectBorderMode + { + Soft = 0, + Hard = 1 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/EffectOptimization.cs b/GetStoreAppInstaller/UI/Backdrop/EffectOptimization.cs new file mode 100644 index 000000000..604997c6d --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/EffectOptimization.cs @@ -0,0 +1,9 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + public enum EffectOptimization + { + Speed = 0, + Balanced = 1, + Quality = 2 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/GaussianBlurEffect.cs b/GetStoreAppInstaller/UI/Backdrop/GaussianBlurEffect.cs new file mode 100644 index 000000000..97513f9f2 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/GaussianBlurEffect.cs @@ -0,0 +1,126 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("1FEB6D69-2FE6-4AC9-8C58-1D7F93E7A6A5")] + public sealed partial class GaussianBlurEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public string Name { get; set; } = string.Empty; + + public float BlurAmount { get; set; } = 3.0f; + + public EffectOptimization Optimization { get; set; } = EffectOptimization.Balanced; + + public EffectBorderMode BorderMode { get; set; } = EffectBorderMode.Soft; + + public IGraphicsEffectSource Source { get; set; } + + public int GetEffectId(out Guid id) + { + id = typeof(GaussianBlurEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(BlurAmount): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + case nameof(Optimization): + { + index = 1; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + case nameof(BorderMode): + { + index = 2; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateSingle(BlurAmount, out IntPtr ptr); + + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + else if (index is 1) + { + propertyValue.CreateUInt32((uint)Optimization, out IntPtr ptr); + + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + else if (index is 2) + { + propertyValue.CreateUInt32((uint)BorderMode, out IntPtr ptr); + + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 3; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + if (index is 0) + { + source = Source; + return 0; + } + else + { + source = null; + return 2147483637; + } + } + + public int GetSourceCount(out uint count) + { + count = 1; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/MicaBackdrop.cs b/GetStoreAppInstaller/UI/Backdrop/MicaBackdrop.cs new file mode 100644 index 000000000..56bc3d231 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/MicaBackdrop.cs @@ -0,0 +1,670 @@ +using GetStoreAppInstaller.WindowsAPI.PInvoke.Comctl32; +using GetStoreAppInstaller.WindowsAPI.PInvoke.User32; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation.Metadata; +using Windows.Graphics.Display; +using Windows.System; +using Windows.System.Power; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Composition.Desktop; +using Windows.UI.ViewManagement; +using Windows.UI.Xaml; + +// 抑制 CA1822 警告 +#pragma warning disable CA1822 + +namespace GetStoreAppInstaller.UI.Backdrop +{ + /// + /// Mica 背景色 + /// + public sealed partial class MicaBackdrop : SystemBackdrop + { + private bool isInitialized; + private bool isWindowClosed; + private bool isActivated = true; + private bool useMicaBackdrop; + + private readonly IntPtr windowHandle; + private readonly FrameworkElement rootElement; + private readonly UISettings uiSettings = new(); + private readonly AccessibilitySettings accessibilitySettings = new(); + private readonly CompositionCapabilities compositionCapabilities = CompositionCapabilities.GetForCurrentView(); + private readonly DisplayInformation displayInformation = DisplayInformation.GetForCurrentView(); + private readonly DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread(); + + private readonly float defaultMicaBaseLightTintOpacity = 0.5f; + private readonly float defaultMicaBaseLightLuminosityOpacity = 1; + private readonly float defaultMicaBaseDarkTintOpacity = 0.8f; + private readonly float defaultMicaBaseDarkLuminosityOpacity = 1; + private readonly Color defaultMicaBaseLightTintColor = Color.FromArgb(255, 243, 243, 243); + private readonly Color defaultMicaBaseLightFallbackColor = Color.FromArgb(255, 243, 243, 243); + private readonly Color defaultMicaBaseDarkTintColor = Color.FromArgb(255, 32, 32, 32); + private readonly Color defaultMicaBaseDarkFallbackColor = Color.FromArgb(255, 32, 32, 32); + + private readonly float defaultMicaAltLightTintOpacity = 0.5f; + private readonly float defaultMicaAltLightLuminosityOpacity = 1; + private readonly float defaultMicaAltDarkTintOpacity = 0; + private readonly float defaultMicaAltDarkLuminosityOpacity = 1; + private readonly Color defaultMicaAltLightTintColor = Color.FromArgb(255, 218, 218, 218); + private readonly Color defaultMicaAltLightFallbackColor = Color.FromArgb(255, 218, 218, 218); + private readonly Color defaultMicaAltDarkTintColor = Color.FromArgb(255, 10, 10, 10); + private readonly Color defaultMicaAltDarkFallbackColor = Color.FromArgb(255, 10, 10, 10); + + private SUBCLASSPROC windowSubClassProc; + + public MicaKind Kind { get; set; } = MicaKind.Base; + + private float _lightTintOpacity = 0; + + public override float LightTintOpacity + { + get { return _lightTintOpacity; } + + set + { + if (!Equals(_lightTintOpacity, value)) + { + _lightTintOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private float _lightLuminosityOpacity = 0; + + public override float LightLuminosityOpacity + { + get { return _lightLuminosityOpacity; } + + set + { + if (!Equals(_lightLuminosityOpacity, value)) + { + _lightLuminosityOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private float _darkTintOpacity = 0; + + public override float DarkTintOpacity + { + get { return _darkTintOpacity; } + + set + { + if (!Equals(_darkTintOpacity, value)) + { + _darkTintOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private float _darkLuminosityOpacity = 0; + + public override float DarkLuminosityOpacity + { + get { return _darkLuminosityOpacity; } + + set + { + if (!Equals(_darkLuminosityOpacity, value)) + { + _darkLuminosityOpacity = value; + if (value < 0 || value > 1) + { + throw new ArgumentException("值必须在 0 到 1 之间"); + } + + UpdateBrush(); + } + } + } + + private Color _lightTintColor = Color.FromArgb(0, 0, 0, 0); + + public override Color LightTintColor + { + get { return _lightTintColor; } + + set + { + if (!Equals(_lightTintColor, value)) + { + _lightTintColor = value; + UpdateBrush(); + } + } + } + + private Color _lightFallbackColor = Color.FromArgb(0, 0, 0, 0); + + public override Color LightFallbackColor + { + get { return _lightFallbackColor; } + + set + { + if (!Equals(_lightFallbackColor, value)) + { + _lightFallbackColor = value; + UpdateBrush(); + } + } + } + + private Color _darkTintColor = Color.FromArgb(0, 0, 0, 0); + + public override Color DarkTintColor + { + get { return _darkTintColor; } + + set + { + if (!Equals(_darkTintColor, value)) + { + _darkTintColor = value; + UpdateBrush(); + } + } + } + + private Color _darkFallbackColor = Color.FromArgb(0, 0, 0, 0); + + public override Color DarkFallbackColor + { + get { return _darkFallbackColor; } + + set + { + if (!Equals(_darkFallbackColor, value)) + { + _darkFallbackColor = value; + UpdateBrush(); + } + } + } + + private ElementTheme _requestedTheme = ElementTheme.Default; + + public override ElementTheme RequestedTheme + { + get { return _requestedTheme; } + + set + { + if (!Equals(_requestedTheme, value)) + { + _requestedTheme = value; + UpdateBrush(); + } + } + } + + private bool _isInputActive = false; + + public override bool IsInputActive + { + get { return _isInputActive; } + + set + { + if (!Equals(_isInputActive, value)) + { + _isInputActive = value; + } + } + } + + public static bool IsSupported + { + get + { + return ApiInformation.IsMethodPresent(typeof(Compositor).FullName, nameof(Compositor.TryCreateBlurredWallpaperBackdropBrush)); + } + } + + public MicaBackdrop(DesktopWindowTarget target, FrameworkElement element, IntPtr handle) : base(target) + { + if (target is null) + { + throw new ArgumentNullException(string.Format("参数 {0} 不可以为空值", nameof(target))); + } + + if (handle == IntPtr.Zero) + { + throw new NullReferenceException("窗口句柄无效"); + } + + windowHandle = handle; + rootElement = element; + } + + ~MicaBackdrop() + { + Dispose(false); + } + + /// + /// 初始化系统背景色 + /// + public override void InitializeBackdrop() + { + if (!isInitialized) + { + float defaultOpacityValue = 0; + Color defaultColorValue = Color.FromArgb(0, 0, 0, 0); + + if (Kind is MicaKind.Base) + { + _lightTintOpacity = _lightTintOpacity.Equals(defaultOpacityValue) ? defaultMicaBaseLightTintOpacity : _lightTintOpacity; + _lightLuminosityOpacity = _lightLuminosityOpacity.Equals(defaultOpacityValue) ? defaultMicaBaseLightLuminosityOpacity : _lightLuminosityOpacity; + _darkTintOpacity = _darkTintOpacity.Equals(defaultOpacityValue) ? defaultMicaBaseDarkTintOpacity : _darkTintOpacity; + _darkLuminosityOpacity = _darkLuminosityOpacity.Equals(defaultOpacityValue) ? defaultMicaBaseDarkLuminosityOpacity : _darkLuminosityOpacity; + _lightTintColor = _lightTintColor.Equals(defaultColorValue) ? defaultMicaBaseLightTintColor : _lightTintColor; + _lightFallbackColor = _lightFallbackColor.Equals(defaultColorValue) ? defaultMicaBaseLightFallbackColor : _lightFallbackColor; + _darkTintColor = _darkTintColor.Equals(defaultColorValue) ? defaultMicaBaseDarkTintColor : _darkTintColor; + _darkFallbackColor = _darkFallbackColor.Equals(defaultColorValue) ? defaultMicaBaseDarkFallbackColor : _darkFallbackColor; + } + else + { + _lightTintOpacity = _lightTintOpacity.Equals(defaultOpacityValue) ? defaultMicaAltLightTintOpacity : _lightTintOpacity; + _lightLuminosityOpacity = _lightLuminosityOpacity.Equals(defaultOpacityValue) ? defaultMicaAltLightLuminosityOpacity : _lightLuminosityOpacity; + _darkTintOpacity = _darkTintOpacity.Equals(defaultOpacityValue) ? defaultMicaAltDarkTintOpacity : _darkTintOpacity; + _darkLuminosityOpacity = _darkLuminosityOpacity.Equals(defaultOpacityValue) ? defaultMicaAltDarkLuminosityOpacity : _darkLuminosityOpacity; + _lightTintColor = _lightTintColor.Equals(defaultColorValue) ? defaultMicaAltLightTintColor : _lightTintColor; + _lightFallbackColor = _lightFallbackColor.Equals(defaultColorValue) ? defaultMicaAltLightFallbackColor : _lightFallbackColor; + _darkTintColor = _darkTintColor.Equals(defaultColorValue) ? defaultMicaAltDarkTintColor : _darkTintColor; + _darkFallbackColor = _darkFallbackColor.Equals(defaultColorValue) ? defaultMicaAltDarkFallbackColor : _darkFallbackColor; + } + + if (DesktopWindowTarget.Root is null) + { + DesktopWindowTarget.Root = DesktopWindowTarget.Compositor.CreateSpriteVisual(); + } + + uiSettings.ColorValuesChanged += OnColorValuesChanged; + accessibilitySettings.HighContrastChanged += OnHighContrastChanged; + compositionCapabilities.Changed += OnCompositionCapabilitiesChanged; + displayInformation.DpiChanged += OnDpiChanged; + PowerManager.EnergySaverStatusChanged += OnEnergySaverStatusChanged; + + if (rootElement is not null) + { + rootElement.ActualThemeChanged += OnActualThemeChanged; + } + + windowSubClassProc = new SUBCLASSPROC(OnWindowSubClassProc); + Comctl32Library.SetWindowSubclass(windowHandle, Marshal.GetFunctionPointerForDelegate(windowSubClassProc), 0, IntPtr.Zero); + + isInitialized = true; + UpdateBrush(); + } + } + + /// + /// 恢复默认值 + /// + public override void ResetProperties() + { + if (Kind is MicaKind.Base) + { + _lightTintOpacity = defaultMicaBaseLightTintOpacity; + _lightLuminosityOpacity = defaultMicaBaseLightLuminosityOpacity; + _darkTintOpacity = defaultMicaBaseDarkTintOpacity; + _darkLuminosityOpacity = defaultMicaBaseDarkLuminosityOpacity; + _lightTintColor = defaultMicaBaseLightTintColor; + _lightFallbackColor = defaultMicaBaseLightFallbackColor; + _darkTintColor = defaultMicaBaseDarkTintColor; + _darkFallbackColor = defaultMicaBaseDarkFallbackColor; + } + else + { + _lightTintOpacity = defaultMicaAltLightTintOpacity; + _lightLuminosityOpacity = defaultMicaAltLightLuminosityOpacity; + _darkTintOpacity = defaultMicaAltDarkTintOpacity; + _darkLuminosityOpacity = defaultMicaAltDarkLuminosityOpacity; + _lightTintColor = defaultMicaAltLightTintColor; + _lightFallbackColor = defaultMicaAltLightFallbackColor; + _darkTintColor = defaultMicaAltDarkTintColor; + _darkFallbackColor = defaultMicaAltDarkFallbackColor; + } + + _requestedTheme = ElementTheme.Default; + _isInputActive = false; + + if (isInitialized) + { + UpdateBrush(); + } + } + + /// + /// 关闭背景色 + /// + public override void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 关闭背景色 + /// + private void Dispose(bool disposing) + { + if (!disposing) + { + return; + } + + lock (this) + { + if (isInitialized) + { + isInitialized = false; + + uiSettings.ColorValuesChanged -= OnColorValuesChanged; + accessibilitySettings.HighContrastChanged -= OnHighContrastChanged; + compositionCapabilities.Changed -= OnCompositionCapabilitiesChanged; + displayInformation.DpiChanged -= OnDpiChanged; + PowerManager.EnergySaverStatusChanged -= OnEnergySaverStatusChanged; + + if (rootElement is not null) + { + rootElement.ActualThemeChanged -= OnActualThemeChanged; + } + + Comctl32Library.RemoveWindowSubclass(windowHandle, Marshal.GetFunctionPointerForDelegate(windowSubClassProc), 0); + + if (DesktopWindowTarget.Root is SpriteVisual spriteVisual && spriteVisual.Brush is not null) + { + spriteVisual.Brush.Dispose(); + spriteVisual.Brush = null; + } + } + } + } + + /// + /// 颜色值更改时发生的事件 + /// + private void OnColorValuesChanged(UISettings sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 当系统高对比度功能打开或关闭时发生的事件 + /// + private void OnHighContrastChanged(AccessibilitySettings sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 当支持的合成功能发生更改时触发的事件 + /// + private void OnCompositionCapabilitiesChanged(CompositionCapabilities sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 显示窗口的屏幕的 DPI 发生更改后触发的事件 + /// + private void OnDpiChanged(DisplayInformation sender, object args) + { + dispatcherQueue.TryEnqueue(() => + { + if (DesktopWindowTarget.Root is SpriteVisual spriteVisual) + { + //spriteVisual.Size = new Vector2(formRoot.Width, formRoot.Height); + } + }); + } + + /// + /// 在设备的节电模式状态更改时触发的事件 + /// + private void OnEnergySaverStatusChanged(object sender, object args) + { + dispatcherQueue.TryEnqueue(UpdateBrush); + } + + /// + /// 在 ActualTheme 属性值更改时触发的事件 + /// + private void OnActualThemeChanged(FrameworkElement sender, object args) + { + UpdateBrush(); + } + + /// + /// 更新应用的背景色 + /// + private void UpdateBrush() + { + if (isInitialized) + { + ElementTheme actualTheme = ElementTheme.Default; + + // 如果传入的 FrameworkElement 为空值,则由系统默认主题色值决定窗口的背景色 + if (rootElement is not null) + { + // 主题值为默认时,窗口背景色主题值则由 FrameworkElement 决定 + actualTheme = RequestedTheme is ElementTheme.Default ? rootElement.ActualTheme : RequestedTheme; + } + else + { + actualTheme = Application.Current.RequestedTheme is ApplicationTheme.Light ? ElementTheme.Light : ElementTheme.Dark; + } + + float tintOpacity; + float luminosityOpacity; + Color tintColor; + Color fallbackColor; + + if (actualTheme is ElementTheme.Light) + { + tintOpacity = LightTintOpacity; + luminosityOpacity = LightLuminosityOpacity; + tintColor = LightTintColor; + fallbackColor = LightFallbackColor; + } + else + { + tintOpacity = DarkTintOpacity; + luminosityOpacity = DarkLuminosityOpacity; + tintColor = DarkTintColor; + fallbackColor = DarkFallbackColor; + } + + useMicaBackdrop = IsSupported && uiSettings.AdvancedEffectsEnabled && PowerManager.EnergySaverStatus is not EnergySaverStatus.On && compositionCapabilities.AreEffectsSupported() && (IsInputActive || isActivated); + + if (accessibilitySettings.HighContrast) + { + tintColor = uiSettings.GetColorValue(UIColorType.Background); + useMicaBackdrop = false; + } + + Compositor compositor = DesktopWindowTarget.Compositor; + CompositionBrush newBrush = useMicaBackdrop ? BuildMicaEffectBrush(compositor, tintColor, tintOpacity, luminosityOpacity) : compositor.CreateColorBrush(fallbackColor); + CompositionBrush oldBrush = (DesktopWindowTarget.Root as SpriteVisual).Brush; + + if (oldBrush is null || oldBrush.Comment is "Crossfade") + { + // 直接设置新笔刷 + oldBrush?.Dispose(); + (DesktopWindowTarget.Root as SpriteVisual).Brush = newBrush; + //(DesktopWindowTarget.Root as SpriteVisual).Size = new(formRoot.Width, formRoot.Height); + } + else + { + // 回退色切换时的动画颜色 + CompositionBrush crossFadeBrush = CreateCrossFadeEffectBrush(compositor, oldBrush, newBrush); + ScalarKeyFrameAnimation animation = CreateCrossFadeAnimation(compositor); + (DesktopWindowTarget.Root as SpriteVisual).Brush = crossFadeBrush; + //(DesktopWindowTarget.Root as SpriteVisual).Size = new(formRoot.Width, formRoot.Height); + + CompositionScopedBatch crossFadeAnimationBatch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation); + crossFadeBrush.StartAnimation("CrossFade.CrossFade", animation); + crossFadeAnimationBatch.End(); + + crossFadeAnimationBatch.Completed += (o, a) => + { + crossFadeBrush.Dispose(); + oldBrush.Dispose(); + (DesktopWindowTarget.Root as SpriteVisual).Brush = newBrush; + //(DesktopWindowTarget.Root as SpriteVisual).Size = new(formRoot.Width, formRoot.Height); + }; + } + } + } + + /// + /// 创建 Mica 背景色 + /// + private CompositionEffectBrush BuildMicaEffectBrush(Compositor compositor, Color tintColor, float tintOpacity, float luminosityOpacity) + { + // Tint Color. + ColorSourceEffect tintColorEffect = new() + { + Name = "TintColor", + Color = tintColor + }; + + // OpacityEffect applied to Tint. + OpacityEffect tintOpacityEffect = new() + { + Name = "TintOpacity", + Opacity = tintOpacity, + Source = tintColorEffect + }; + + // Apply Luminosity: + + // Luminosity Color. + ColorSourceEffect luminosityColorEffect = new() + { + Color = tintColor + }; + + // OpacityEffect applied to Luminosity. + OpacityEffect luminosityOpacityEffect = new() + { + Name = "LuminosityOpacity", + Opacity = luminosityOpacity, + Source = luminosityColorEffect + }; + + // Luminosity Blend. + // NOTE: There is currently a bug where the names of BlendEffectMode::Luminosity and BlendEffectMode::Color are flipped. + BlendEffect luminosityBlendEffect = new() + { + Mode = BlendEffectMode.Color, + Background = new CompositionEffectSourceParameter("BlurredWallpaperBackdrop"), + Foreground = luminosityOpacityEffect + }; + + // Apply Tint: + + // Color Blend. + // NOTE: There is currently a bug where the names of BlendEffectMode::Luminosity and BlendEffectMode::Color are flipped. + BlendEffect colorBlendEffect = new() + { + Mode = BlendEffectMode.Luminosity, + Background = luminosityBlendEffect, + Foreground = tintOpacityEffect + }; + + CompositionEffectBrush micaEffectBrush = compositor.CreateEffectFactory(colorBlendEffect).CreateBrush(); + micaEffectBrush.SetSourceParameter("BlurredWallpaperBackdrop", compositor.TryCreateBlurredWallpaperBackdropBrush()); + + return micaEffectBrush; + } + + /// + /// 创建回退色切换时的动画颜色 + /// + private CompositionEffectBrush CreateCrossFadeEffectBrush(Compositor compositor, CompositionBrush from, CompositionBrush to) + { + CrossFadeEffect crossFadeEffect = new() + { + Name = "Crossfade", // Name to reference when starting the animation. + Source1 = new CompositionEffectSourceParameter("source1"), + Source2 = new CompositionEffectSourceParameter("source2"), + CrossFade = 0, + }; + + CompositionEffectBrush crossFadeEffectBrush = compositor.CreateEffectFactory(crossFadeEffect, ["Crossfade.CrossFade"]).CreateBrush(); + crossFadeEffectBrush.Comment = "Crossfade"; + + crossFadeEffectBrush.SetSourceParameter("source1", from); + crossFadeEffectBrush.SetSourceParameter("source2", to); + return crossFadeEffectBrush; + } + + /// + /// 为回退色创建动画效果 + /// + private ScalarKeyFrameAnimation CreateCrossFadeAnimation(Compositor compositor) + { + ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation(); + LinearEasingFunction linearEasing = compositor.CreateLinearEasingFunction(); + animation.InsertKeyFrame(0.0f, 0.0f, linearEasing); + animation.InsertKeyFrame(1.0f, 1.0f, linearEasing); + animation.Duration = TimeSpan.FromMilliseconds(250); + return animation; + } + + /// + /// 应用主窗口消息处理 + /// + private IntPtr OnWindowSubClassProc(IntPtr hWnd, WindowMessage Msg, UIntPtr wParam, IntPtr lParam, uint uIdSubclass, IntPtr dwRefData) + { + // 窗口大小发生变化时的消息 + if (Msg is WindowMessage.WM_SIZE) + { + if (DesktopWindowTarget.Root is SpriteVisual spriteVisual) + { + //spriteVisual.Size = new Vector2(formRoot.Width, formRoot.Height); + } + } + // 窗口关闭时的消息 + else if (Msg is WindowMessage.WM_CLOSE) + { + isWindowClosed = true; + Dispose(); + } + // 窗口激活状态发生变化时的消息 + else if (Msg is WindowMessage.WM_ACTIVATE) + { + isActivated = true; + UpdateBrush(); + } + + return Comctl32Library.DefSubclassProc(hWnd, Msg, wParam, lParam); + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/MicaKind.cs b/GetStoreAppInstaller/UI/Backdrop/MicaKind.cs new file mode 100644 index 000000000..0c84929e7 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/MicaKind.cs @@ -0,0 +1,18 @@ +namespace GetStoreAppInstaller.UI.Backdrop +{ + /// + /// 定义指定使用 Mica 材料的变体的常量 + /// + public enum MicaKind + { + /// + /// 使用基 Mica 材料 + /// + Base = 0, + + /// + /// 使用 MicaAlt 材料 + /// + BaseAlt = 1 + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/OpacityEffect.cs b/GetStoreAppInstaller/UI/Backdrop/OpacityEffect.cs new file mode 100644 index 000000000..5d849c6e6 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/OpacityEffect.cs @@ -0,0 +1,81 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using Windows.Graphics.Effects; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + [Guid("811D79A4-DE28-4454-8094-C64685F8BD4C")] + public sealed partial class OpacityEffect : IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + { + private readonly IPropertyValueStatics propertyValue = PropertyValue.As(); + + public string Name { get; set; } = string.Empty; + + public float Opacity { get; set; } = 1.0f; + + public IGraphicsEffectSource Source { get; set; } + + public int GetEffectId(out Guid id) + { + id = typeof(OpacityEffect).GUID; + return 0; + } + + public int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping) + { + switch (Marshal.PtrToStringUni(name)) + { + case nameof(Opacity): + { + index = 0; + mapping = GRAPHICS_EFFECT_PROPERTY_MAPPING.GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; + break; + } + default: + { + index = 0xFF; + mapping = (GRAPHICS_EFFECT_PROPERTY_MAPPING)0xFF; + break; + } + } + + return 0; + } + + public int GetProperty(uint index, out IntPtr source) + { + if (index is 0) + { + propertyValue.CreateSingle(Opacity, out IntPtr ptr); + if (ptr != IntPtr.Zero) + { + source = ptr; + return 0; + } + } + + source = IntPtr.Zero; + return -2147483637; + } + + public int GetPropertyCount(out uint count) + { + count = 1; + return 0; + } + + public int GetSource(uint index, out IGraphicsEffectSource source) + { + source = Source; + return 0; + } + + public int GetSourceCount(out uint count) + { + count = 1; + return 0; + } + } +} diff --git a/GetStoreAppInstaller/UI/Backdrop/SystemBackdrop.cs b/GetStoreAppInstaller/UI/Backdrop/SystemBackdrop.cs new file mode 100644 index 000000000..1236c4c03 --- /dev/null +++ b/GetStoreAppInstaller/UI/Backdrop/SystemBackdrop.cs @@ -0,0 +1,41 @@ +using System; +using Windows.UI; +using Windows.UI.Composition.Desktop; +using Windows.UI.Xaml; + +namespace GetStoreAppInstaller.UI.Backdrop +{ + /// + /// 抽象类:系统背景色 + /// + public abstract class SystemBackdrop(DesktopWindowTarget target) : IDisposable + { + public abstract float LightTintOpacity { get; set; } + + public abstract float LightLuminosityOpacity { get; set; } + + public abstract float DarkTintOpacity { get; set; } + + public abstract float DarkLuminosityOpacity { get; set; } + + public abstract Color LightTintColor { get; set; } + + public abstract Color LightFallbackColor { get; set; } + + public abstract Color DarkTintColor { get; set; } + + public abstract Color DarkFallbackColor { get; set; } + + public abstract ElementTheme RequestedTheme { get; set; } + + public abstract bool IsInputActive { get; set; } + + public DesktopWindowTarget DesktopWindowTarget { get; } = target; + + public abstract void InitializeBackdrop(); + + public abstract void ResetProperties(); + + public abstract void Dispose(); + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/ComTypes/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs b/GetStoreAppInstaller/WindowsAPI/ComTypes/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs new file mode 100644 index 000000000..cb9e891d7 --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/ComTypes/GRAPHICS_EFFECT_PROPERTY_MAPPING.cs @@ -0,0 +1,63 @@ +namespace GetStoreAppInstaller.WindowsAPI.ComTypes +{ + /// + /// 指示强类型效果属性如何映射到基础 Direct2D 效果属性。 此枚举支持 Windows.UI.Composition API,不应直接在代码中使用。 + /// + public enum GRAPHICS_EFFECT_PROPERTY_MAPPING + { + /// + /// 指定值不能映射到 Direct2D 效果属性。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_UNKNOWN = 0, + + /// + /// 指定可以在 Direct2D 效果属性上按原样设置值。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT = 1, + + /// + /// 指定该值映射到矢量类型 Direct2D 效果属性的 X 分量。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORX = 2, + + /// + /// 指定该值映射到矢量类型 Direct2D 效果属性的 Y 分量。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORY = 3, + + /// + /// 指定该值映射到矢量类型 Direct2D 效果属性的 Z 分量。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORZ = 4, + + /// + /// 指定值映射到矢量类型 Direct2D 效果属性的 W 分量。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORW = 5, + + /// + /// 指定 rect 值映射到 Vector4 Direct2D 效果属性。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_RECT_TO_VECTOR4 = 6, + + /// + /// 指定在对 Direct2D 效果属性进行设置之前,需要将值从弧度转换为度。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_RADIANS_TO_DEGREES = 7, + + /// + /// 指定在对效果属性进行设置之前,需要将颜色矩阵 alpha 模式枚举值转换为等效的 Direct2D 枚举值。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_COLORMATRIX_ALPHA_MODE = 8, + + /// + /// 指定在 Direct2D 效果属性上设置之前,需要将 Windows.UI.Color 值转换为 RGB Vector3。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR3 = 9, + + /// + /// 指定在 Direct2D 效果属性上设置之前,需要将 Windows.UI.Color 值转换为 RGBA Vector4。 + /// + GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR4 = 10 + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/ComTypes/ICompositorDesktopInterop.cs b/GetStoreAppInstaller/WindowsAPI/ComTypes/ICompositorDesktopInterop.cs new file mode 100644 index 000000000..f95166222 --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/ComTypes/ICompositorDesktopInterop.cs @@ -0,0 +1,15 @@ +using System; +using System.Runtime.InteropServices; + +namespace WindowsTools.WindowsAPI.ComTypes +{ + [ComImport, Guid("29E691FA-4567-4DCA-B319-D0F207EB6807"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface ICompositorDesktopInterop + { + [PreserveSig] + int CreateDesktopWindowTarget(IntPtr hwndTarget, [MarshalAs(UnmanagedType.Bool)] bool isTopmost, out IntPtr result); + + [PreserveSig] + int EnsureOnThread(int threadId); + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1Interop.cs b/GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1Interop.cs new file mode 100644 index 000000000..805b666de --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1Interop.cs @@ -0,0 +1,243 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Windows.Graphics.Effects; +using WinRT; +using WinRT.Interop; + +namespace GetStoreAppInstaller.WindowsAPI.ComTypes +{ + /// + /// 本机互操作接口,提供 与 IGraphicsEffect 对应的接口,并允许元数据查询。 + /// 暂不支持 COM 源生成 + /// + [WindowsRuntimeType, Guid("2FC57384-A068-44D7-A331-30982FCF7177")] + public interface IGraphicsEffectD2D1Interop + { + /// + /// 检索效果的 ID。 + /// + /// 此方法返回时,此参数将包含效果的 ID。 + /// 此方法返回 HRESULT 成功或错误代码。 + int GetEffectId(out Guid id); + + /// + /// 检索效果属性的映射。 + /// + /// 属性的名称。 + /// 此方法返回时,此参数将包含 属性的索引。 + /// 指示强类型效果属性如何映射到基础 Direct2D 效果属性。 + /// 此方法返回 HRESULT 成功或错误代码。 + int GetNamedPropertyMapping(IntPtr name, out uint index, out GRAPHICS_EFFECT_PROPERTY_MAPPING mapping); + + /// + /// 检索效果的属性计数。 + /// + /// 当方法返回时,此参数将包含属性计数。 + /// 此方法返回 HRESULT 成功或错误代码。 + int GetPropertyCount(out uint count); + + /// + /// 检索指定索引处的效果属性。 + /// + /// 要检索的属性的索引。 + /// 此方法返回时,此参数将包含检索到的属性。 + /// 此方法返回 HRESULT 成功或错误代码。 + int GetProperty(uint index, out IntPtr value); + + /// + /// 检索指定索引处的效果源。 + /// + /// 检索的源的索引。 + /// 当方法返回时,此参数将包含指定索引处的源。 + /// 此方法返回 HRESULT 成功或错误代码。 + int GetSource(uint index, out IGraphicsEffectSource source); + + /// + /// 检索效果的源计数。 + /// + /// 方法返回时,此参数将包含效果的源计数。 + /// 此方法返回 HRESULT 成功或错误代码。 + int GetSourceCount(out uint count); + + internal unsafe struct Vftbl + { + public static IntPtr InitVtbl() + { + Vftbl* lpVtbl = (Vftbl*)ComWrappersSupport.AllocateVtableMemory(typeof(Vftbl), sizeof(Vftbl)); + + lpVtbl->IUnknownVftbl = IUnknownVftbl.AbiToProjectionVftbl; + lpVtbl->GetEffectId = &GetEffectIdFromAbi; + lpVtbl->GetNamedPropertyMapping = &GetNamedPropertyMappingFromAbi; + lpVtbl->GetPropertyCount = &GetPropertyCountFromAbi; + lpVtbl->GetProperty = &GetPropertyFromAbi; + lpVtbl->GetSource = &GetSourceFromAbi; + lpVtbl->GetSourceCount = &GetSourceCountFromAbi; + return (IntPtr)lpVtbl; + } + + private IUnknownVftbl IUnknownVftbl; + + // 接口委托 + + private delegate* unmanaged[MemberFunction] GetEffectId; + private delegate* unmanaged[MemberFunction] GetNamedPropertyMapping; + private delegate* unmanaged[MemberFunction] GetPropertyCount; + private delegate* unmanaged[MemberFunction] GetProperty; + private delegate* unmanaged[MemberFunction] GetSource; + private delegate* unmanaged[MemberFunction] GetSourceCount; + + // 接口实现 + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])] + private static int GetEffectIdFromAbi(IntPtr thisPtr, Guid* id) + { + try + { + if (id is not null) + { + *id = Guid.Empty; + } + + int hr = ComWrappersSupport.FindObject(thisPtr).GetEffectId(out Guid idObject); + if (hr >= 0) + { + *id = idObject; + } + return hr; + } + catch (Exception e) + { + ExceptionHelpers.SetErrorInfo(e); + return Marshal.GetHRForException(e); + } + } + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])] + private static int GetNamedPropertyMappingFromAbi(IntPtr thisPtr, IntPtr name, uint* index, GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) + { + try + { + if (index is not null) + { + *index = 0; + } + + if (mapping is not null) + { + *mapping = 0; + } + + int hr = ComWrappersSupport.FindObject(thisPtr).GetNamedPropertyMapping(name, out uint indexObject, out GRAPHICS_EFFECT_PROPERTY_MAPPING mappingObject); + if (hr >= 0) + { + *index = indexObject; + *mapping = mappingObject; + } + return hr; + } + catch (Exception e) + { + ExceptionHelpers.SetErrorInfo(e); + return Marshal.GetHRForException(e); + } + } + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])] + private static int GetPropertyCountFromAbi(IntPtr thisPtr, uint* count) + { + try + { + if (count is not null) + { + *count = 0; + } + + int hr = ComWrappersSupport.FindObject(thisPtr).GetPropertyCount(out uint countObject); + if (hr >= 0) + { + *count = countObject; + } + return hr; + } + catch (Exception e) + { + ExceptionHelpers.SetErrorInfo(e); + return Marshal.GetHRForException(e); + } + } + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])] + private static int GetPropertyFromAbi(IntPtr thisPtr, uint index, IntPtr* value) + { + try + { + if (value is not null) + { + *value = 0; + } + + int hr = ComWrappersSupport.FindObject(thisPtr).GetProperty(index, out IntPtr valueObject); + if (hr >= 0) + { + *value = valueObject; + } + return hr; + } + catch (Exception e) + { + ExceptionHelpers.SetErrorInfo(e); + return Marshal.GetHRForException(e); + } + } + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])] + private static int GetSourceFromAbi(IntPtr thisPtr, uint index, IntPtr* source) + { + try + { + if (source is not null) + { + *source = 0; + } + + int hr = ComWrappersSupport.FindObject(thisPtr).GetSource(index, out IGraphicsEffectSource sourceObject); + if (hr >= 0) + { + *source = MarshalInspectable.FromManaged(sourceObject!); + } + return hr; + } + catch (Exception e) + { + ExceptionHelpers.SetErrorInfo(e); + return Marshal.GetHRForException(e); + } + } + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])] + private static int GetSourceCountFromAbi(IntPtr thisPtr, uint* count) + { + try + { + if (count is not null) + { + *count = 0; + } + + int hr = ComWrappersSupport.FindObject(thisPtr).GetSourceCount(out uint countObject); + if (hr >= 0) + { + *count = countObject; + } + return hr; + } + catch (Exception e) + { + ExceptionHelpers.SetErrorInfo(e); + return Marshal.GetHRForException(e); + } + } + } + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1InteropMethods.cs b/GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1InteropMethods.cs new file mode 100644 index 000000000..5c15b4e1c --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/ComTypes/IGraphicsEffectD2D1InteropMethods.cs @@ -0,0 +1,15 @@ +using GetStoreAppInstaller.WindowsAPI.ComTypes; +using System; + +// 抑制 IDE0130 警告 +#pragma warning disable IDE0130 + +namespace ABI.GetStoreAppInstaller.WindowsAPI.ComTypes +{ + public static class IGraphicsEffectD2D1InteropMethods + { + public static Guid IID { get; } = typeof(IGraphicsEffectD2D1Interop).GUID; + + public static IntPtr AbiToProjectionVftablePtr { get; } = IGraphicsEffectD2D1Interop.Vftbl.InitVtbl(); + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/ComTypes/IPropertyValueStatics.cs b/GetStoreAppInstaller/WindowsAPI/ComTypes/IPropertyValueStatics.cs new file mode 100644 index 000000000..d518abd71 --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/ComTypes/IPropertyValueStatics.cs @@ -0,0 +1,409 @@ +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using Windows.Foundation; +using WinRT; + +namespace GetStoreAppInstaller.WindowsAPI.ComTypes +{ + /// + /// 创建可在属性存储中存储的 IPropertyValue 对象。 + /// + [GeneratedComInterface, Guid("629BDBC8-D932-4FF4-96B9-8D96C5C1E858")] + public partial interface IPropertyValueStatics + { + /// + /// 获取由当前Windows 运行时类实现的接口。 + /// + /// 当前 Windows 运行时 对象实现的接口数,不包括 IUnknown 和 IInspectable 实现。 + /// 指向数组的指针,该数组包含当前 Windows 运行时 对象实现的每个接口的 IID。 排除 IUnknown 和 IInspectable 接口。 + /// 此函数可以返回以下值。S_OK 和 E_OUTOFMEMORY + [PreserveSig] + int GetIids(out ulong iidCount, out IntPtr iids); + + /// + /// 获取当前Windows 运行时 对象的完全限定名称。 + /// + /// 当前Windows 运行时对象的完全限定名称。 + /// 此函数可以返回以下值。S_OK、E_OUTOFMEMORY 和 E_ILLEGAL_METHOD_CALL + [PreserveSig] + int GetRuntimeClassName(out IntPtr className); + + /// + /// 获取当前Windows 运行时对象的信任级别。 + /// + /// 当前Windows 运行时对象的信任级别。 默认值为 BaseLevel。 + /// 此方法始终返回 S_OK。 + [PreserveSig] + int GetTrustLevel(out TrustLevel trustLevel); + + /// + /// 创建表示空值的新 IPropertyValue 对象。 + /// + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateEmpty(out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 8 位布尔值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt8(byte value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的有符号 16 位整数值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInt16(short value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 16 位整数值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt16(ushort value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的有符号 32 位整数值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInt32(int value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 32 位整数值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt32(uint value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的有符号 64 位整数值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInt64(long value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 64 位整数值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt64(ulong value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 32 位浮点值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateSingle(float value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 64 位浮点值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateDouble(double value, out IntPtr propertyValue); + + /// + /// 创建包含指定 Unicode 字符的新 IPropertyValue 对象。 + /// + /// 要存储的 Unicode 字符。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateChar16(char value, out IntPtr propertyValue); + + /// + /// + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateBoolean([MarshalAs(UnmanagedType.Bool)] bool value, out IntPtr propertyValue); + + /// + /// 创建包含指定字符串值的新 IPropertyValue 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateString(IntPtr value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 IInspectable 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInspectable(IntPtr value, out IntPtr propertyValue); + + /// + /// 创建包含指定 GUID 值的新 IPropertyValue 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateGuid(Guid value, out IntPtr propertyValue); + + /// + /// 创建包含指定 DateTime 值的新 IPropertyValue 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateDateTime(DateTimeOffset value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 TimeSpan 值。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateTimeSpan(TimeSpan value, out IntPtr propertyValue); + + /// + /// 创建包含指定 Point 值的新 IPropertyValue 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreatePoint(Point value, out IntPtr propertyValue); + + /// + /// 创建包含指定 Size 值的新 IPropertyValue 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateSize(Size value, out IntPtr propertyValue); + + /// + /// 创建包含指定 Rect 值的新 IPropertyValue 对象。 + /// + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateRect(Rect value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 8 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt8Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的有符号 16 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInt16Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] short[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 16 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt16Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ushort[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的有符号 32 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInt32Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 32 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt32Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的有符号 64 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInt64Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] long[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的无符号 64 位整数值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateUInt64Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ulong[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 32 位浮点值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateSingleArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] float[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 64 位浮点值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateDoubleArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] double[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 Unicode 字符数组。 + /// + /// 数组长度 + /// 要存储的 Unicode 字符数组。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateChar16Array(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 8 位布尔值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateBooleanArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.Bool)] bool[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的字符串值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateStringArray(int valueLength, IntPtr value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 IInspectable 对象数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateInspectableArray(int valueLength, IntPtr value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 Guid 值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateGuidArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Guid[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 DateTime 值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateDateTimeArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] DateTimeOffset[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 TimeSpan 值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateTimeSpanArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] TimeSpan[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 Point 值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreatePointArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Point[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 Size 值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateSizeArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Size[] value, out IntPtr propertyValue); + + /// + /// 创建一个新的 IPropertyValue 对象,该对象包含指定的 Rect 值数组。 + /// + /// 数组长度 + /// 要存储的值。 + /// 指向新对象的指针,该对象将其 Type 属性设置为 PropertyType_Empty。 新对象中不存储任何值。 使用 IUnknown::QueryInterface 方法获取对象的 IPropertyValue 接口。 + /// 此方法可以返回其中一个值。S_OK 为已成功创建属性值,E_POINTER 为 NULL,E_OUTOFMEMORY 为无法创建 IPropertyValue 对象。 + [PreserveSig] + int CreateRectArray(int valueLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Rect[] value, out IntPtr propertyValue); + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/Comctl32Library.cs b/GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/Comctl32Library.cs new file mode 100644 index 000000000..72380532a --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/Comctl32Library.cs @@ -0,0 +1,50 @@ +using GetStoreAppInstaller.WindowsAPI.PInvoke.User32; +using System.Runtime.InteropServices; + +// 抑制 CA1401 警告 +#pragma warning disable CA1401 + +namespace GetStoreAppInstaller.WindowsAPI.PInvoke.Comctl32 +{ + /// + /// Comctl32.dll 函数库 + /// + public static partial class Comctl32Library + { + private const string Comctl32 = "comctl32.dll"; + + /// + /// 安装或更新窗口子类回调。 + /// + /// 正在子类化的窗口的句柄。 + /// 指向窗口过程的指针。 此指针和子类 ID 唯一标识此子类回调。 有关回调函数原型,请参阅 SUBCLASSPROC。 + /// 子类 ID。 此 ID 与子类过程一起唯一标识子类。 若要删除子类,请将子类过程和此值传递给 RemoveWindowSubclass 函数。 此值将传递给 uIdSubclass 参数中的子类过程。 + /// 用于 引用数据的DWORD_PTR。 此值的含义由调用应用程序确定。 此值将传递给 dwRefData 参数中的子类过程。 不同的 dwRefData 与窗口句柄、子类过程和 uIdSubclass 的每个组合相关联。 + /// 如果成功安装子类回调,则为 TRUE;否则为 FALSE。 + [LibraryImport(Comctl32, EntryPoint = "SetWindowSubclass", SetLastError = false), PreserveSig] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool SetWindowSubclass(nint hWnd, nint pfnSubclass, uint uIdSubclass, nint dwRefData); + + /// + /// 在窗口的子类链中调用下一个处理程序。 子类链中的最后一个处理程序调用窗口的原始窗口过程。 + /// + /// 正在子类化的窗口的句柄。 + /// 一个 unsigned int 类型的值,该值指定窗口消息。 + /// 指定附加消息信息。 此参数的内容取决于窗口消息的值。 + /// 指定附加消息信息。 此参数的内容取决于窗口消息的值。 注意:在 64 位版本的 Windows LPARAM 上是一个 64 位值。 + /// 返回的值特定于发送的消息。 应忽略此值。 + [LibraryImport(Comctl32, EntryPoint = "DefSubclassProc", SetLastError = false), PreserveSig] + public static partial nint DefSubclassProc(nint hWnd, WindowMessage uMsg, nuint wParam, nint lParam); + + /// + /// 从窗口中删除子类回调。 + /// + /// 正在子类化的窗口的句柄。 + /// 指向窗口过程的指针。 此指针和子类 ID 唯一标识此子类回调。 有关回调函数原型,请参阅 SUBCLASSPROC。 + /// UINT_PTR子类 ID。 此 ID 和回调指针唯一标识此子类回调。 注意:在 64 位版本的 Windows 上,这是一个 64 位值。 + /// 如果成功删除子类回调,则为 TRUE;否则为 FALSE。 + [LibraryImport(Comctl32, EntryPoint = "RemoveWindowSubclass", SetLastError = false), PreserveSig] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool RemoveWindowSubclass(nint hWnd, nint pfnSubclass, uint uIdSubclass); + } +} diff --git a/GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/SUBCLASSPROC.cs b/GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/SUBCLASSPROC.cs new file mode 100644 index 000000000..7fe7113dc --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/PInvoke/Comctl32/SUBCLASSPROC.cs @@ -0,0 +1,17 @@ +using GetStoreAppInstaller.WindowsAPI.PInvoke.User32; +using System; + +namespace GetStoreAppInstaller.WindowsAPI.PInvoke.Comctl32 +{ + /// + /// 定义 RemoveWindowSubclass 和 SetWindowSubclass 使用的回调函数的原型。 + /// + /// 子类化窗口的句柄。 + /// 正在传递的消息。 + /// 其他消息信息。 此参数的内容取决于 uMsg 的值。 + /// 其他消息信息。 此参数的内容取决于 uMsg 的值。 + /// 子类 ID。 + /// 提供给 SetWindowSubclass 函数的引用数据。 这可用于将子类实例与“this”指针相关联。 + /// 返回值是消息处理的结果,取决于发送的消息。 + public delegate IntPtr SUBCLASSPROC(IntPtr hWnd, WindowMessage uMsg, UIntPtr wParam, IntPtr lParam, uint uIdSubclass, IntPtr dwRefData); +} diff --git a/GetStoreAppInstaller/WindowsAPI/PInvoke/User32/WindowMessage.cs b/GetStoreAppInstaller/WindowsAPI/PInvoke/User32/WindowMessage.cs new file mode 100644 index 000000000..4d362854c --- /dev/null +++ b/GetStoreAppInstaller/WindowsAPI/PInvoke/User32/WindowMessage.cs @@ -0,0 +1,2728 @@ +namespace GetStoreAppInstaller.WindowsAPI.PInvoke.User32 +{ + /// + /// 窗口消息 + /// 系统预留使用的消息 0x0000 - 0x03FF + /// 被私有窗口类使用的消息 0x0400 - 0x07FF + /// 被应用程序使用的消息 0x0800 - 0xBFFF + /// 被应用程序使用的字符串消息 0xC000 - 0xFFFF + /// 系统预留 大于0xFFFF + /// + public enum WindowMessage : int + { + /// + /// 不执行任何操作。 如果应用程序想要帖子收件人窗口将忽略的邮件,则应用程序会发送WM_NULL邮件。 + /// + WM_NULL = 0x0000, + + /// + /// 当应用程序请求通过调用 CreateWindow 或 CreateWindowEx 函数创建窗口时发送。 (函数返回之前发送消息。) 新窗口的窗口过程在创建窗口后接收此消息,但在窗口变为可见之前。 + /// + WM_CREATE = 0x0001, + + /// + /// 当窗口被销毁时发送。 它将发送到从屏幕中删除窗口后正在销毁的窗口过程。 + /// + WM_DESTROY = 0x0002, + + /// + /// 在移动窗口后发送。 + /// + WM_MOVE = 0x0003, + + /// + /// 更改窗口大小后发送到窗口。 + /// + WM_SIZE = 0x0005, + + /// + /// 发送到正在激活的窗口和正在停用的窗口。 如果窗口使用相同的输入队列,则会同步发送消息,首先发送到正在停用的顶级窗口的窗口过程, + /// 然后发送到正在激活的顶级窗口的窗口过程。 如果窗口使用不同的输入队列,则会异步发送消息,以便立即激活该窗口。 + /// + WM_ACTIVATE = 0x0006, + + /// + /// 在窗口获得键盘焦点后发送到窗口。 + /// + WM_SETFOCUS = 0x0007, + + /// + /// 在失去键盘焦点之前立即发送到窗口。 + /// + WM_KILLFOCUS = 0x0008, + + WM_SETVISIBLE = 0x0009, + + /// + /// 当应用程序更改窗口的启用状态时发送。 它会发送到启用状态正在更改的窗口。 此消息在 EnableWindow 函数返回之前发送, + /// 但在启用状态 (WS_DISABLED 样式位) 窗口已更改之后。 + /// + WM_ENABLE = 0x000A, + + /// + /// 将 WM_SETREDRAW 消息发送到窗口,以允许重新绘制该窗口中的更改,或阻止重新绘制该窗口中的更改。 + /// + WM_SETREDRAW = 0x000B, + + /// + /// 设置窗口的文本。 + /// + WM_SETTEXT = 0x000C, + + /// + /// 将对应于窗口的文本复制到调用方提供的缓冲区中。 + /// + WM_GETTEXT = 0x000D, + + /// + /// 确定与窗口关联的文本的长度(以字符为单位)。 + /// + WM_GETTEXTLENGTH = 0x000E, + + /// + /// 当系统或其他应用程序发出绘制应用程序窗口部分的请求时,将发送 WM_PAINT 消息。 当调用 UpdateWindow 或 RedrawWindow 函数或 + /// DispatchMessage 函数时,应用程序通过使用 GetMessage 或 PeekMessage 函数获取 WM_PAINT 消息时发送该消息。 + /// + WM_PAINT = 0x000F, + + /// + /// 发送为窗口或应用程序应终止的信号。 + /// + WM_CLOSE = 0x0010, + + /// + /// WM_ENDSESSION 消息在系统处理 WM_QUERYENDSESSION 消息的结果后发送到应用程序。 WM_ENDSESSION 消息通知应用程序会话是否结束。 + /// + WM_QUERYENDSESSION = 0x0011, + + /// + /// 指示终止应用程序的请求,并在应用程序调用 PostQuitMessage 函数时生成。 此消息导致 GetMessage 函数返回零。 + /// + WM_QUIT = 0x0012, + + /// + /// 当用户请求将窗口还原到其以前的大小和位置时,发送到图标。 + /// + WM_QUERYOPEN = 0x0013, + + /// + /// 当窗口背景必须在 (擦除时发送,例如,当窗口大小调整为) 时。 将发送消息以准备窗口的无效部分进行绘制。 + /// + WM_ERASEBKGND = 0x0014, + + /// + /// 对系统颜色设置进行更改时 ,会将WM_SYSCOLORCHANGE 消息发送到所有顶级窗口。 + /// + WM_SYSCOLORCHANGE = 0x0015, + + /// + /// WM_ENDSESSION 消息在系统处理 WM_QUERYENDSESSION 消息的结果后发送到应用程序。 WM_ENDSESSION 消息通知应用程序会话是否结束。 + /// + WM_ENDSESSION = 0x0016, + + WM_SYSTEMERROR = 0x0017, + + /// + /// 当窗口即将隐藏或显示时发送到窗口。 + /// + WM_SHOWWINDOW = 0x0018, + + /// + /// 在每个控件开始绘制之前,都会向其父窗口发送 WM_CTLCOLOR 通告消息,在该消息的处理函数中,可以设置控件显示文本的前景色、背景色以及字体。该消息处理函数还要求返回一个画刷的句柄,用于在控件具体的绘制之前擦除其客户区。 + /// + WM_CTLCOLOR = 0x0019, + + /// + /// 应用程序在更改WIN.INI文件后,将 WM_WININICHANGE 消息发送到所有顶级窗口。 SystemParametersInfo 函数在应用程序使用该函数更改WIN.INI中的设置后发送此消息。 + /// + WM_WININICHANGE = 0x001A, + + /// + /// 当 SystemParametersInfo 函数更改系统范围设置或策略设置发生更改时,将发送到所有顶级窗口的消息。 + /// + WM_SETTINGCHANGE = WM_WININICHANGE, + + /// + /// 每当用户更改设备模式设置时, WM_DEVMODECHANGE 消息都会发送到所有顶级窗口。 + /// + WM_DEVMODECHANGE = 0x001B, + + /// + /// 当属于与活动窗口不同的应用程序的窗口即将激活时发送。 该消息将发送到正在激活其窗口的应用程序以及正在停用其窗口的应用程序。 + /// + WM_ACTIVATEAPP = 0x001C, + + /// + /// 应用程序更改字体资源池后,将 WM_FONTCHANGE 消息发送到系统中的所有顶级窗口。 + /// + WM_FONTCHANGE = 0x001D, + + /// + /// 每当系统时间发生更改时发送的消息。 + /// + WM_TIMECHANGE = 0x001E, + + /// + /// 发送到取消某些模式,例如鼠标捕获。 例如,当显示对话框或消息框时,系统会将此消息发送到活动窗口。 + /// 某些函数还会显式将此消息发送到指定窗口,而不考虑它是活动窗口。 + /// + WM_CANCELMODE = 0x001F, + + /// + /// 如果鼠标导致光标在窗口中移动,并且未捕获鼠标输入,则发送到窗口。 + /// + WM_SETCURSOR = 0x0020, + + /// + /// 当光标处于非活动窗口中且用户按下鼠标按钮时发送。 仅当子窗口将其传递给 DefWindowProc 函数时,父窗口才会接收此消息。 + /// + WM_MOUSEACTIVATE = 0x0021, + + /// + /// 当用户单击窗口的标题栏或窗口被激活、移动或调整大小时,发送到子窗口。 + /// + WM_CHILDACTIVATE = 0x0022, + + /// + /// 由基于计算机的训练 (CBT) 应用程序发送,以将用户输入消息与通过 WH_JOURNALPLAYBACK 过程发送的其他消息分开。 + /// + WM_QUEUESYNC = 0x0023, + + /// + /// 当窗口的大小或位置即将更改时,发送到窗口。 应用程序可以使用此消息替代窗口的默认最大化大小和位置,或者默认的最小或最大跟踪大小。 + /// + WM_GETMINMAXINFO = 0x0024, + + WM_LOGOFF = 0x0025, + + /// + /// 发送给最小化窗口,当它图标将要被重画时 + /// + WM_PAINTICON = 0x0026, + + /// + /// 发送给某个最小化窗口,仅当它在画图标前它的背景必须被重画 + /// + WM_ICONERASEBKGND = 0x0027, + + /// + /// 发送到对话框过程,将键盘焦点设置为对话框中的其他控件。 + /// + WM_NEXTDLGCTL = 0x0028, + + WM_ALTTABACTIVE = 0x0029, + + /// + /// 每当向打印管理器队列中添加或删除作业时,都会从打印管理器发送 WM_SPOOLERSTATUS 消息。 + /// + WM_SPOOLERSTATUS = 0x002A, + + /// + /// 当按钮、组合框、列表框或菜单的可视方面发生更改时,发送到所有者绘制按钮、组合框、列表框或菜单的父窗口。 + /// + WM_DRAWITEM = 0x002B, + + /// + /// 创建控件或菜单时,发送到组合框、列表框、列表视图控件或菜单项的所有者窗口。 + /// + WM_MEASUREITEM = 0x002C, + + /// + /// 当列表框或组合框被销毁或项目被 LB_DELETESTRING、 LB_RESETCONTENT、 CB_DELETESTRING或 CB_RESETCONTENT 消息删除时,发送到列表框或组合框的所有者。 系统为每个已删除的项发送 一条 WM_DELETEITEM 消息。 系统为包含非零项数据的任何已删除列表框或组合框项发送 WM_DELETEITEM 消息。 + /// + WM_DELETEITEM = 0x002D, + + /// + /// 由具有 LBS_WANTKEYBOARDINPUT 样式的列表框发送到其所有者以响应 WM_KEYDOWN 消息。 + /// + WM_VKEYTOITEM = 0x002E, + + /// + /// 由具有 LBS_WANTKEYBOARDINPUT 样式的列表框发送到其所有者,以响应 WM_CHAR 消息。 + /// + WM_CHARTOITEM = 0x002F, + + /// + /// 设置控件在绘制文本时要使用的字体。 + /// + WM_SETFONT = 0x0030, + + /// + /// 检索控件当前正在绘制其文本的字体。 + /// + WM_GETFONT = 0x0031, + + /// + /// 发送到窗口以将热键与窗口相关联。 当用户按下热键时,系统会激活窗口。 + /// + WM_SETHOTKEY = 0x0032, + + /// + /// 已发送以确定与窗口关联的热键。 + /// + WM_GETHOTKEY = 0x0033, + + WM_SHELLNOTIFY = 0x0034, + + WM_ISACTIVEICON = 0x0035, + + WM_QUERYPARKICON = 0x0036, + + /// + /// 发送到最小化的 (标志性的) 窗口。 窗口将由用户拖动,但没有为其类定义的图标。 应用程序可以将句柄返回到图标或游标。 当用户拖动图标时,系统会显示此光标或图标。 + /// + WM_QUERYDRAGICON = 0x0037, + + WM_WINHELP = 0x0038, + + /// + /// 已发送到确定新项在所有者绘制组合框或列表框的排序列表中相对位置。 每当应用程序添加新项时,系统会将此消息发送到使用 CBS_SORT 或 LBS_SORT 样式创建的组合框或列表框的所有者。 + /// + WM_COMPAREITEM = 0x0039, + + WM_FULLSCREEN = 0x003A, + + WM_CLIENTSHUTDOWN = 0x003B, + + WM_DDEMLEVENT = 0x003C, + + /// + /// Microsoft Active Accessibility 和 Microsoft UI 自动化发送,以获取有关服务器应用程序中包含的可访问对象的信息。 应用程序永远不会直接发送此消息。 + /// + WM_GETOBJECT = 0x003D, + + // 0x003E - 0x003F 消息未定义 + + WM_TESTING = 0x0040, + + /// + /// 当系统检测到超过 30 秒到 60 秒间隔的系统时间超过 12.5% 时,发送到所有顶级窗口。 这表示系统内存较低。 + /// + WM_COMPACTING = 0x0041, + + WM_OTHERWINDOWCREATED = 0x0042, + + WM_OTHERWINDOWDESTROYED = 0x0043, + + /// + /// 每当发生 COM 端口事件时,通信设备驱动程序都会发布 WM_COMMNOTIFY 消息。该消息指示窗口的输入或输出队列的状态。 + /// + WM_COMMNOTIFY = 0x0044, + + // 0x0045 消息未定义 + + /// + /// 发送到一个窗口,其大小、位置或位置在 Z 顺序中将随着 对 SetWindowPos 函数或其他窗口管理函数的调用而更改。 + /// + WM_WINDOWPOSCHANGING = 0x0046, + + /// + /// 由于对 SetWindowPos 函数或其他窗口管理函数的调用,其大小、位置或位置在 Z 顺序中的窗口已更改。 + /// + WM_WINDOWPOSCHANGED = 0x0047, + + /// + /// 通知应用程序,系统(通常是电池供电的个人电脑)即将进入暂停模式。 + /// + WM_POWER = 0x0048, + + /// + /// 从 Win3.1 开始可能与 WM_COPYDATA 有关,现在很可能从 MSDN 中删除。每个于此相关的功能还是带着这个消息。 + /// + WM_COPYGLOBALDATA = 0x0049, + + /// + /// 应用程序将 WM_COPYDATA 消息发送到另一个应用程序。 + /// + WM_COPYDATA = 0x004A, + + /// + /// 当用户取消应用程序的日记活动时发布到应用程序。 消息使用 NULL 窗口句柄发布。 + /// + WM_CANCELJOURNAL = 0x004B, + + // 0x004C 消息未定义 + + WM_KEYF1 = 0x004D, + + /// + /// 当发生事件或控件需要一些信息时,由公共控件发送到其父窗口。 + /// + WM_NOTIFY = 0x004E, + + WM_ACCESS_WINDOW = 0x004F, + + /// + /// 当用户选择新的输入语言(在键盘控制面板应用程序) 或系统任务栏上的指示器中指定的热键时,发布到具有焦点的窗口。 应用程序可以通过将消息传递给 DefWindowProc 函数来接受更改,或者拒绝更改,并阻止它立即返回) 。 + /// + WM_INPUTLANGCHANGEREQUEST = 0x0050, + + /// + /// 更改应用程序输入语言后,发送到最受影响的窗口。 应进行任何特定于应用程序的设置并将消息传递给 DefWindowProc 函数,该函数会将消息传递给所有第一级子窗口。 这些子窗口可以将消息传递给 DefWindowProc ,使其将消息传递给其子窗口等。 + /// + WM_INPUTLANGCHANGE = 0x0051, + + /// + /// 发送到已启动具有Windows帮助的训练卡的应用程序。 当用户单击可创作按钮时,该消息会通知应用程序。 应用程序通过在对 WinHelp 函数的调用中指定HELP_TCARD命令来启动训练卡。 + /// + WM_TCARD = 0x0052, + + /// + /// 指示用户按下了 F1 键。 如果按下 F1 时菜单处于活动状态, WM_HELP 发送到与菜单关联的窗口;否则, WM_HELP 将发送到具有键盘焦点的窗口。 如果没有窗口具有键盘焦点, WM_HELP 将发送到当前活动窗口。 + /// + WM_HELP = 0x0053, + + /// + /// 用户登录或关闭后发送到所有窗口。 当用户登录或关闭时,系统会更新用户特定的设置。 系统更新设置后立即发送此消息。 + /// + WM_USERCHANGED = 0x0054, + + /// + /// 确定窗口是否接受 WM_NOTIFY 通知消息中的 ANSI 或 Unicode 结构。 WM_NOTIFYFORMAT 消息从公共控件发送到其父窗口,从父窗口发送到公共控件。 + /// + WM_NOTIFYFORMAT = 0x0055, + + // 0x0056 - 0x006F 消息未定义 + + WM_FINALDESTROY = 0x0070, + + WM_MEASUREITEM_CLIENTDATA = 0x0071, + + // 0x0072 - 0x007A 消息未定义 + + /// + /// 通知用户希望显示上下文菜单的窗口。 用户可能已在窗口中单击鼠标右键 (右键单击) 、按 Shift+F10 或按应用程序键 (上下文菜单键) 某些键盘上可用。 + /// + WM_CONTEXTMENU = 0x007B, + + /// + /// 当 SetWindowLong 函数即将更改窗口的一个或多个样式时,发送到窗口。 + /// + WM_STYLECHANGING = 0x007C, + + /// + /// SetWindowLong 函数更改窗口的一个或多个样式后发送到窗口。 + /// + WM_STYLECHANGED = 0x007D, + + /// + /// 显示分辨率发生更改时 ,会将 WM_DISPLAYCHANGE 消息发送到所有窗口。 + /// + WM_DISPLAYCHANGE = 0x007E, + + /// + /// 发送到窗口以检索与窗口关联的大图标或小图标的句柄。 系统在 Alt+TAB 对话框中显示大图标,并在窗口标题中显示小图标。 + /// + WM_GETICON = 0x007F, + + /// + /// 将新的大或小图标与窗口相关联。 系统在 Alt+TAB 对话框中显示大图标,以及窗口标题中的小图标。 + /// + WM_SETICON = 0x0080, + + /// + /// 首次创建窗口时 ,在 WM_CREATE 消息之前发送。 + /// + WM_NCCREATE = 0x0081, + + /// + /// 通知窗口其非客户区域正在被销毁。 DestroyWindow 函数将 WM_NCDESTROY 消息发送到 WM_DESTROY 消息后面的窗口。WM_DESTROY 用于释放与窗口关联的已分配内存对象。 + /// 子窗口被销毁后,将发送 WM_NCDESTROY 消息。 相比之下, WM_DESTROY 在销毁子窗口之前发送。 + /// + WM_NCDESTROY = 0x0082, + + /// + /// 在必须计算窗口工作区的大小和位置时发送。 通过处理此消息,当窗口的大小或位置发生更改时,应用程序可以控制窗口工作区的内容。 + /// + WM_NCCALCSIZE = 0x0083, + + /// + /// 发送到窗口以确定窗口的哪个部分对应于特定的屏幕坐标。 例如,当光标移动、按下或释放鼠标按钮或响应对 WindowFromPoint 等函数的调用时,可能会发生这种情况。 如果未捕获鼠标,则会将消息发送到光标下方的窗口。 否则,消息将发送到已捕获鼠标的窗口。 + /// + WM_NCHITTEST = 0x0084, + + /// + /// WM_NCPAINT 消息在必须绘制其框架时发送到窗口。 + /// + WM_NCPAINT = 0x0085, + + /// + /// 当需要更改其非client 区域以指示活动或非活动状态时,发送到窗口。 + /// + WM_NCACTIVATE = 0x0086, + + /// + /// 发送到与控件关联的窗口过程。 默认情况下,系统将处理控件的所有键盘输入;系统将某些类型的键盘输入解释为对话框导航键。 若要替代此默认行为,控件可以响应 WM_GETDLGCODE 消息,以指示要处理其本身的输入类型。 + /// + WM_GETDLGCODE = 0x0087, + + /// + /// WM_SYNCPAINT 消息用于同步绘制,同时避免链接独立的 GUI 线程。 + /// + WM_SYNCPAINT = 0x0088, + + WM_SYNCTASK = 0x0089, + + // 0x008A 消息未定义 + + WM_KLUDGEMINRECT = 0x008B, + + WM_LPKDRAWSWITCHWND = 0x008C, + + // 0x008D - 0x008F 消息未定义 + + WM_UAHDESTROYWINDOW = 0x0090, + + WM_UAHDRAWMENU = 0x0091, + + WM_UAHDRAWMENUITEM = 0x0092, + + WM_UAHINITMENU = 0x0093, + + WM_UAHMEASUREMENUITEM = 0x0094, + + WM_UAHNCPAINTMENUPOPUP = 0x0095, + + WM_UAHUPDATE = 0x0096, + + // 0x0097 - 0x009F 消息未定义 + + /// + /// 当光标在窗口的非工作区内移动时发布到窗口。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCMOUSEMOVE = 0x00A0, + + /// + /// 当用户在光标位于窗口的非工作区内时按下鼠标左键时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCLBUTTONDOWN = 0x00A1, + + /// + /// 当用户释放鼠标左键时,光标位于窗口的非工作区内时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCLBUTTONUP = 0x00A2, + + /// + /// 当用户在光标位于窗口的非工作区内时双击鼠标左键时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCLBUTTONDBLCLK = 0x00A3, + + /// + /// 当用户按下鼠标右键时,光标位于窗口的非工作区内时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCRBUTTONDOWN = 0x00A4, + + /// + /// 当用户松开鼠标右键时,光标位于窗口的非工作区内时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCRBUTTONUP = 0x00A5, + + /// + /// 当用户在光标位于窗口的非工作区内时双击鼠标右键时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCRBUTTONDBLCLK = 0x00A6, + + /// + /// 当用户按下鼠标中键时光标位于窗口的非工作区内时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCMBUTTONDOWN = 0x00A7, + + /// + /// 当用户松开鼠标中键时,光标位于窗口的非工作区内时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCMBUTTONUP = 0x00A8, + + /// + /// 当用户在光标位于窗口的非工作区内时双击鼠标中键时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCMBUTTONDBLCLK = 0x00A9, + + // 0x00AA 消息未定义 + + /// + /// 当用户按下第一个或第二个 X 按钮时,光标位于窗口的非工作区时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则 不会 发布此消息。 + /// + WM_NCXBUTTONDOWN = 0x00AB, + + /// + /// 当用户释放第一个或第二个 X 按钮时,光标位于窗口的非工作区时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则 不会 发布此消息。 + /// + WM_NCXBUTTONUP = 0x00AC, + + /// + /// 当用户在光标位于窗口的非工作区时双击第一个或第二个 X 按钮时发布。 此消息将发布到包含光标的窗口。 如果窗口捕获了鼠标,则不会发布此消息。 + /// + WM_NCXBUTTONDBLCLK = 0x00AD, + + WM_NCUAHDRAWCAPTION = 0x00AE, + + WM_NCUAHDRAWFRAME = 0x00AF, + + /// + /// 获取编辑控件中当前所选内容) TCHARs 中 (开始和结束字符位置。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETSEL = 0x00B0, + + /// + /// 在编辑控件中选择一系列字符。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETSEL = 0x00B1, + + /// + /// 获取编辑控件 的格式设置矩形 。 格式设置矩形是控件在其中绘制文本的限制矩形。 限制矩形与编辑控件窗口的大小无关。 可以将此消息发送到编辑控件或富编辑控件。 + /// + EM_GETRECT = 0x00B2, + + /// + /// 设置多行编辑控件 的格式矩形 。 格式设置矩形是控件在其中绘制文本的限制矩形。 限制矩形与编辑控件窗口的大小无关。 + /// 此消息仅由多行编辑控件处理。 可以将此消息发送到编辑控件或富编辑控件。 + /// + EM_SETRECT = 0x00B3, + + /// + /// 设置多行编辑控件 的格式矩形 。 EM_SETRECTNP消息与EM_SETRECT消息相同,只是EM_SETRECTNP不会重绘编辑控件窗口。 + /// 格式设置矩形是控件在其中绘制文本的限制矩形。 限制矩形与编辑控件窗口的大小无关。 + /// 此消息仅由多行编辑控件处理。 可以将此消息发送到编辑控件或富编辑控件。 + /// + EM_SETRECTNP = 0x00B4, + + /// + /// 在多行编辑控件中垂直滚动文本。 此消息等效于将 WM_VSCROLL 消息发送到编辑控件。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SCROLL = 0x00B5, + + /// + /// 滚动多行编辑控件中的文本。 + /// + EM_LINESCROLL = 0x00B6, + + /// + /// 将插入点滚动到编辑控件的视图中。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SCROLLCARET = 0x00B7, + + /// + /// 获取编辑控件的修改标志的状态。 标志指示是否已修改编辑控件的内容。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETMODIFY = 0x00B8, + + /// + /// 设置或清除编辑控件的修改标志。 修改标志指示编辑控件中的文本是否已修改。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETMODIFY = 0x00B9, + + /// + /// 获取多行编辑控件中的行数。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETLINECOUNT = 0x00BA, + + /// + /// 获取多行编辑控件中指定行的第一个字符的字符索引。 字符索引是从编辑控件的开头开始的字符的从零开始的索引。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_LINEINDEX = 0x00BB, + + /// + /// 设置多行编辑控件将使用的内存的句柄。 + /// + EM_SETHANDLE = 0x00BC, + + /// + /// 获取当前为多行编辑控件的文本分配的内存的句柄。 + /// + EM_GETHANDLE = 0x00BD, + + /// + /// 获取多行编辑控件垂直滚动条中滚动框 (拇指) 的位置。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETTHUMB = 0x00BE, + + // 0x00BF - 0x00C0 消息未定义 + + /// + /// 检索编辑控件中行的长度(以字符为单位)。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_LINELENGTH = 0x00C1, + + /// + /// 将编辑控件中的选定文本或丰富的编辑控件替换为指定的文本。 + /// + EM_REPLACESEL = 0x00C2, + + /// + /// 设置富编辑控件中所选文本的字体。 + /// + EM_SETFONT = 0x00C3, + + /// + /// 从编辑控件复制文本行,并将其置于指定的缓冲区中。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETLINE = 0x00C4, + + /// + /// 设置编辑控件的文本限制。 文本限制是用户可以在编辑控件中键入的最大文本量(以 TCHAR 为单位)。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// 对于编辑控件和 Microsoft Rich Edit 1.0,将使用字节。 对于 Microsoft Rich Edit 2.0 及更高版本,将使用字符。 + /// + EM_LIMITTEXT = 0x00C5, + + /// + /// 设置编辑控件的文本限制。 文本限制是用户可在编辑控件中键入的最大文本量( 在 TCHARs 中)。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// 对于编辑控件和 Microsoft Rich Edit 1.0,将使用字节。 对于 Microsoft Rich Edit 2.0 及更高版本,将使用字符。 + /// EM_SETLIMITTEXT 消息与 EM_LIMITTEXT 消息相同。 + /// + EM_SETLIMITTEXT = EM_LIMITTEXT, + + /// + /// 确定编辑控件的撤消队列中是否有任何操作。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_CANUNDO = 0x00C6, + + /// + /// 此消息撤消控件队列中最后一次编辑控件操作。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_UNDO = 0x00C7, + + /// + /// 设置一个标志,用于确定多行编辑控件是否包含软换行符。 软换行符由两个回车符和一个换行符组成,插入到由于单词包装而断开的行的末尾。 + /// + EM_FMTLINES = 0x00C8, + + /// + /// 获取包含多行编辑控件中指定字符索引的行的索引。 字符索引是从编辑控件的开头开始的字符的从零开始的索引。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_LINEFROMCHAR = 0x00C9, + + /// + /// 本操作现已不支持,请使用 EM_SETWORDBREAKPROC + /// + EM_SETWORDBREAK = 0x00CA, + + /// + /// EM_SETTABSTOPS消息设置多行编辑控件中的制表位。 当文本复制到控件时,文本中的任何制表符都会导致空间生成到下一个制表位。 + /// 此消息仅由多行编辑控件处理。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETTABSTOPS = 0x00CB, + + /// + /// 设置或删除编辑控件的密码字符。 设置密码字符时,将显示该字符代替用户键入的字符。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETPASSWORDCHAR = 0x00CC, + + /// + /// 重置编辑控件的撤消标志。 每当可以撤消编辑控件中的操作时,都会设置撤消标志。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_EMPTYUNDOBUFFER = 0x00CD, + + /// + /// 获取多行编辑控件中最上端可见行的从零开始的索引。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETFIRSTVISIBLELINE = 0x00CE, + + /// + /// 设置或删除编辑控件的只读样式 (ES_READONLY) 。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETREADONLY = 0x00CF, + + /// + /// 将编辑控件的默认 Wordwrap 函数替换为应用程序定义的 Wordwrap 函数。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETWORDBREAKPROC = 0x00D0, + + /// + /// 获取当前 Wordwrap 函数的地址。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETWORDBREAKPROC = 0x00D1, + + /// + /// 获取编辑控件在用户输入文本时显示的密码字符。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETPASSWORDCHAR = 0x00D2, + + /// + /// 设置编辑控件的左右边距的宽度。 消息重新绘制控件以反映新边距。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_SETMARGINS = 0x00D3, + + /// + /// 获取编辑控件的左右边距的宽度。 + /// + EM_GETMARGINS = 0x00D4, + + /// + /// 获取编辑控件的当前文本限制。 可以将此消息发送到编辑控件或丰富的编辑控件。 + /// + EM_GETLIMITTEXT = 0x00D5, + + /// + /// 检索编辑控件中指定字符的工作区坐标。 可以将此消息发送到编辑控件或富编辑控件。 + /// + EM_POSFROMCHAR = 0x00D6, + + /// + /// 获取有关编辑控件工作区中最靠近指定点的字符的信息。 可以将此消息发送到编辑控件或富编辑控件。 + /// + EM_CHARFROMPOS = 0x00D7, + + /// + /// 设置状态标志,确定编辑控件如何与输入法编辑器交互 (IME) 。 + /// + EM_SETIMESTATUS = 0x00D8, + + /// + /// 获取一组状态标志,指示编辑控件如何与输入法编辑器交互 (IME) 。 + /// + EM_GETIMESTATUS = 0x00D9, + + EM_MSGMAX = 0x00DA, + + // 0x00DB - 0x00DF 消息未定义 + + /// + /// 发送 SBM_SETPOS 消息以设置滚动框的位置 (拇指) ,如果请求,请重新绘制滚动条以反映滚动框的新位置。 + /// 应用程序不应直接发送此消息。 相反,它们应使用 SetScrollPos 函数。 窗口通过其 WndProc 函数接收此消息。 实现自定义滚动条控件的应用程序必须响应这些消息, 以便 SetScrollPos 函数正常工作。 + /// + SBM_SETPOS = 0x00E0, + + /// + /// 发送 SBM_GETPOS 消息以检索滚动条控件滚动框的当前位置。 当前位置是一个相对值,该值取决于当前滚动范围。 例如,如果滚动范围为 0 到 100,并且滚动框位于条形图中间,则当前位置为 50。 + /// 应用程序不应直接发送此消息。 相反,它们应使用 GetScrollPos 函数。 窗口通过其 WndProc 函数接收此消息。 实现自定义滚动条控件的应用程序必须响应这些消息, 以便 GetScrollPos 函数正常运行。 + /// + SBM_GETPOS = 0x00E1, + + /// + /// 发送 SBM_SETRANGE 消息以设置滚动条控件的最小和最大位置值。 + /// 应用程序不应直接发送此消息。 相反,它们应使用 SetScrollRange 函数。 窗口通过其 WndProc 函数接收此消息。 实现自定义滚动条控件的应用程序必须响应这些消息, 才能使 SetScrollRange 函数正常工作。 + /// + SBM_SETRANGE = 0x00E2, + + /// + /// 发送 SBM_GETRANGE 消息以检索滚动条控件的最小和最大位置值。 + /// 应用程序不应直接发送此消息。 相反,它们应使用 GetScrollRange 函数。 窗口通过其 WndProc 函数接收此消息。 实现自定义滚动条控件的应用程序必须响应这些消息, 以便 GetScrollRange 函数正常工作。 + /// + SBM_GETRANGE = 0x00E3, + + /// + /// 应用程序发送 SBM_ENABLE_ARROWS 消息,以启用或禁用滚动条控件的一个或多个箭头。 + /// + SBM_ENABLE_ARROWS = 0x00E4, + + // 0x00E5 消息未定义 + + /// + /// 应用程序将 SBM_SETRANGEREDRAW 消息发送到滚动条控件,以设置最小和最大位置值并重新绘制控件。 + /// + SBM_SETRANGEREDRAW = 0x00E6, + + // 0x00E7 - 0x00E8 消息未定义 + + /// + /// 发送 SBM_SETSCROLLINFO 消息以设置滚动条的参数。 + /// 应用程序不应直接发送此消息。 相反,它们应使用 SetScrollInfo 函数。 窗口通过其 WndProc 函数接收此消息。 实现自定义滚动条控件的应用程序必须响应这些消息, SetScrollInfo 函数才能正常运行。 + /// + SBM_SETSCROLLINFO = 0x00E9, + + /// + /// 发送 SBM_GETSCROLLINFO 消息以检索滚动条的参数。 + /// 应用程序不应直接发送此消息。 相反,它们应使用 GetScrollInfo 函数。 窗口通过其 WndProc 函数接收此消息。 实现自定义滚动条控件的应用程序必须响应这些消息,以便 GetScrollInfo 函数正常工作。 + /// + SBM_GETSCROLLINFO = 0x00EA, + + /// + /// 应用程序发送以检索有关指定滚动条的信息。 + /// + SBM_GETSCROLLBARINFO = 0x00EB, + + // 0x00EC - 0x00EF 消息未定义 + + /// + /// 获取单选按钮或复选框的选中状态。 可以显式发送此消息或使用 Button_GetCheck 宏。 + /// + BM_GETCHECK = 0x00F0, + + /// + /// 设置单选按钮或复选框的选中状态。 可以显式发送此消息,也可以使用 Button_SetCheck 宏。 + /// + BM_SETCHECK = 0x00F1, + + /// + /// 检索按钮或复选框的状态。 可以显式发送此消息或使用 Button_GetState 宏。 + /// + BM_GETSTATE = 0x00F2, + + /// + /// 设置按钮的突出显示状态。 突出显示状态指示按钮是否突出显示,就像用户已推送按钮一样。 可以显式发送此消息或使用 Button_SetState 宏。 + /// + BM_SETSTATE = 0x00F3, + + /// + /// 设置按钮的样式。 可以显式发送此消息或使用 Button_SetStyle 宏。 + /// + BM_SETSTYLE = 0x00F4, + + /// + /// 模拟用户单击按钮。 此消息会导致该按钮接收 WM_LBUTTONDOWN 和 WM_LBUTTONUP 消息,以及按钮的父窗口接收 BN_CLICKED 通知代码。 + /// + BM_CLICK = 0x00F5, + + /// + /// 检索与按钮关联的图像 (图标或位图) 的句柄。 + /// + BM_GETIMAGE = 0x00F6, + + /// + /// 将新图像 (图标或位图) 与按钮相关联。 + /// + BM_SETIMAGE = 0x00F7, + + /// + /// 在单选按钮上设置一个标志,用于控制按钮接收焦点时生成 BN_CLICKED 消息。 + /// + BM_SETDONTCLICK = 0x00F8, + + // 0x00F9 - 0x00FD 消息未定义 + + /// + /// 发送到注册以接收原始输入的窗口。 + /// 仅当应用程序调用 RegisterRawInputDevices 和 RIDEV_DEVNOTIFY 标志后,原始输入通知才可用。 + /// 窗口通过其 WndProc 函数接收此消息。 + /// + WM_INPUT_DEVICE_CHANGE = 0x00FE, + + /// + /// 发送到正在获取原始输入的窗口。 + /// + WM_INPUT = 0x00FF, + + /// + /// This message filters for keyboard messages. + /// + WM_KEYFIRST = 0x0100, + + /// + /// 按下非系统键时,使用键盘焦点发布到窗口。 非系统键是未按下 ALT 键时按下的键。 + /// + WM_KEYDOWN = WM_KEYFIRST, + + /// + /// 当释放非系统键时,发布到具有键盘焦点的窗口。 非系统键是当 Alt 键未按下时按下的键,或者当窗口具有键盘焦点时按下的键盘键。 + /// + WM_KEYUP = 0x0101, + + /// + /// 当 TranslateMessage 函数翻译 WM_KEYDOWN 消息时,发布到具有键盘焦点的窗口。 WM_CHAR 消息包含按下的键的字符代码。 + /// + WM_CHAR = 0x0102, + + /// + /// 当 TranslateMessage 函数翻译 WM_KEYUP 消息时,发布到具有键盘焦点的窗口。 WM_DEADCHAR 指定死键生成的字符代码。 死键是生成字符(如 umlaut (双点) )的键,该键与另一个字符结合使用以形成复合字符。 例如,通过键入 umlaut 字符的死键,然后键入 O 键,生成 umlaut-O 字符 ( ) 。 + /// + WM_DEADCHAR = 0x0103, + + /// + /// 当用户按下 F10 键 (激活菜单栏) 或按住 Alt 键,然后按另一个键时,发布到具有键盘焦点的窗口。 当当前没有窗口具有键盘焦点时,也会发生这种情况;在这种情况下, WM_SYSKEYDOWN 消息发送到活动窗口。 接收消息的窗口可以通过检查 lParam 参数中的上下文代码来区分这两个上下文。 + /// + WM_SYSKEYDOWN = 0x0104, + + /// + /// 当用户释放按下 Alt 键时按下的键时,发布到具有键盘焦点的窗口。 当没有窗口当前具有键盘焦点时,也会发生这种情况;在这种情况下, WM_SYSKEYUP 消息将发送到活动窗口。 接收消息的窗口可以通过检查 lParam 参数中的上下文代码来区分这两个上下文。 + /// + WM_SYSKEYUP = 0x0105, + + /// + /// 当 TranslateMessage 函数翻译 WM_SYSKEYDOWN 消息时,使用键盘焦点发布到窗口。 它指定系统字符键的字符代码,即在 ALT 键关闭时按下的字符键。 + /// + WM_SYSCHAR = 0x0106, + + /// + /// 当 TranslateMessage 函数翻译 WM_SYSKEYDOWN 消息时,使用键盘焦点发送到窗口。 WM_SYSDEADCHAR 指定系统死键的字符代码,即按住 Alt 键时按下的死键。 + /// + WM_SYSDEADCHAR = 0x0107, + + WM_YOMICHAR = 0x0108, + + /// + /// 应用程序可以使用 WM_UNICHAR 消息将输入发布到其他窗口。 此消息包含按下的键的字符代码。 (测试目标应用是否可以通过将 wParam 设置为 UNICODE_NOCHAR.) 的消息来处理 WM_UNICHAR 消息 + /// + WM_UNICHAR = 0x0109, + + /// + /// 此消息筛选键盘消息。 + /// + WM_KEYLAST = WM_UNICHAR, + + WM_CONVERTREQUEST = 0x010A, + + WM_CONVERTRESULT = 0x010B, + + WM_INTERIM = 0x010C, + + /// + /// 在 IME 生成合成字符串之前立即发送,因为击键。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_STARTCOMPOSITION = 0x010D, + + /// + /// 当 IME 结束组合时发送到应用程序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_ENDCOMPOSITION = 0x010E, + + /// + /// 当 IME 因击键而更改组合状态时发送到应用程序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_COMPOSITION = 0x010F, + + WM_IME_KEYLAST = WM_IME_COMPOSITION, + + /// + /// 在显示对话框之前立即发送到对话框过程。 对话框过程通常使用此消息来初始化控件并执行影响对话框外观的任何其他初始化任务。 + /// + WM_INITDIALOG = 0x0110, + + /// + /// 当用户从菜单中选择命令项、控件将通知消息发送到其父窗口或翻译快捷键击时发送。 + /// + WM_COMMAND = 0x0111, + + /// + /// 当用户从 “窗口 ”菜单中选择命令时,窗口会收到此消息, (以前称为系统或控件菜单) ,或者当用户选择最大化按钮、最小化按钮、还原按钮或关闭按钮时。 + /// + WM_SYSCOMMAND = 0x0112, + + /// + /// 在计时器过期时发布到安装线程的消息队列。 消息由 GetMessage 或 PeekMessage 函数发布。 + /// + WM_TIMER = 0x0113, + + /// + /// 当窗口的标准水平滚动条中发生滚动事件时, 会将 WM_HSCROLL 消息发送到窗口。 当控件中发生滚动事件时,此消息也会发送到水平滚动条控件的所有者。 + /// + WM_HSCROLL = 0x0114, + + /// + /// 当窗口的标准垂直滚动条中发生滚动事件时, 会将 WM_VSCROLL 消息发送到窗口。 当控件中发生滚动事件时,此消息也会发送到垂直滚动条控件的所有者。 + /// + WM_VSCROLL = 0x0115, + + /// + /// 当菜单即将处于活动状态时发送。 当用户单击菜单栏上的项或按菜单键时发生。 这样,应用程序就可以在显示菜单之前对其进行修改。 + /// + WM_INITMENU = 0x0116, + + /// + /// 下拉菜单或子菜单即将处于活动状态时发送。 这样,应用程序就可以在显示菜单之前修改菜单,而无需更改整个菜单。 + /// + WM_INITMENUPOPUP = 0x0117, + + /// + /// WM_SYSTIMER 是一个众所周知但仍未记录的消息。Windows 使用 WM_SYSTIMER 进行滚动等内部操作。 + /// + WM_SYSTIMER = 0x0118, + + /// + /// 传递有关手势的信息。 + /// + WM_GESTURE = 0x0119, + + /// + /// 提供设置手势配置的机会。 + /// + WM_GESTURENOTIFY = 0x011A, + + WM_GESTUREINPUT = 0x011B, + + WM_GESTURENOTIFIED = 0x011C, + + // 0x011D - 0x011E 消息未定义 + + /// + /// 当用户选择菜单项时发送到菜单的所有者窗口。 + /// + WM_MENUSELECT = 0x011F, + + /// + /// 当菜单处于活动状态并且用户按下与任何助记键或快捷键不对应的键时发送。 此消息将发送到拥有菜单的窗口。 + /// + WM_MENUCHAR = 0x0120, + + /// + /// 发送到进入空闲状态的模式对话框或菜单的所有者窗口。 模式对话框或菜单在处理一个或多个以前的消息后没有消息在队列中等待时进入空闲状态。 + /// + WM_ENTERIDLE = 0x0121, + + /// + /// 当用户在光标位于菜单项上时释放鼠标右键时发送。 + /// + WM_MENURBUTTONUP = 0x0122, + + /// + /// 当用户拖动菜单项时发送到拖放菜单的所有者。 + /// + WM_MENUDRAG = 0x0123, + + /// + /// 当鼠标光标进入菜单项或从项目中心移动到项的顶部或底部时,发送到拖放菜单的所有者。 + /// + WM_MENUGETOBJECT = 0x0124, + + /// + /// 下拉菜单或子菜单被销毁时发送。 + /// + WM_UNINITMENUPOPUP = 0x0125, + + /// + /// 当用户从菜单中做出选择时发送。 + /// + WM_MENUCOMMAND = 0x0126, + + /// + /// 应用程序发送 WM_CHANGEUISTATE 消息以指示应更改 UI 状态。 + /// + WM_CHANGEUISTATE = 0x0127, + + /// + /// 应用程序发送 WM_UPDATEUISTATE 消息以更改指定窗口及其所有子窗口的 UI 状态。 + /// + WM_UPDATEUISTATE = 0x0128, + + /// + /// 应用程序发送 WM_QUERYUISTATE 消息以检索窗口的 UI 状态。 + /// + WM_QUERYUISTATE = 0x0129, + + // 0x012A - 0x0130 消息未定义 + + WM_LBTRACKPOINT = 0x0131, + + /// + /// 在系统绘制列表框之前发送到列表框的父窗口。 通过响应此消息,父窗口可以使用指定的显示设备上下文句柄设置列表框的文本和背景色。 + /// + WM_CTLCOLORMSGBOX = 0x0132, + + /// + /// 非只读或禁用的编辑控件将在控件即将绘制时将 WM_CTLCOLOREDIT 消息发送到其父窗口。 通过响应此消息,父窗口可以使用指定的设备上下文句柄来设置编辑控件的文本和背景色。 + /// + WM_CTLCOLOREDIT = 0x0133, + + /// + /// 在系统绘制列表框之前发送到列表框的父窗口。 通过响应此消息,父窗口可以使用指定的显示设备上下文句柄设置列表框的文本和背景色。 + /// + WM_CTLCOLORLISTBOX = 0x0134, + + /// + /// 在绘制按钮之前, WM_CTLCOLORBTN 消息发送到按钮的父窗口。 父窗口可以更改按钮的文本和背景色。 但是,只有所有者绘制的按钮响应处理此消息的父窗口。 + /// + WM_CTLCOLORBTN = 0x0135, + + /// + /// 在系统绘制对话框之前发送到对话框。 通过响应此消息,对话框可以使用指定的显示设备上下文句柄设置其文本和背景颜色。 + /// + WM_CTLCOLORDLG = 0x0136, + + /// + /// 当控件即将绘制时, WM_CTLCOLORSCROLLBAR 消息将发送到滚动条控件的父窗口。 通过响应此消息,父窗口可以使用显示上下文句柄设置滚动条控件的背景色。 + /// + WM_CTLCOLORSCROLLBAR = 0x0137, + + /// + /// 静态控件或只读或禁用的编辑控件在即将绘制控件时将 WM_CTLCOLORSTATIC 消息发送到其父窗口。 通过响应此消息,父窗口可以使用指定的设备上下文句柄来设置静态控件的文本前景和背景色。 + /// + WM_CTLCOLORSTATIC = 0x0138, + + // 0x0139 - 0x013F 消息未定义 + + /// + /// 获取组合框的编辑控件中当前所选内容的起始和结束字符位置。 + /// + CB_GETEDITSEL = 0x0140, + + /// + /// 限制用户可在组合框的编辑控件中键入的文本长度。 + /// + CB_LIMITTEXT = 0x0141, + + /// + /// 应用程序发送 CB_SETEDITSEL 消息以在组合框的编辑控件中选择字符。 + /// + CB_SETEDITSEL = 0x0142, + + /// + /// 将字符串添加到组合框的列表框中。 如果组合框没有 CBS_SORT 样式,则字符串将添加到列表的末尾。 否则,字符串将插入到列表中,并对列表进行排序。 + /// + CB_ADDSTRING = 0x0143, + + /// + /// 删除组合框列表框中的字符串。 + /// + CB_DELETESTRING = 0x0144, + + /// + /// 将名称添加到组合框显示的列表。 该消息将添加与指定字符串和文件属性集匹配的目录和文件的名称。 CB_DIR 还可以将映射的驱动器号添加到列表中。 + /// + CB_DIR = 0x0145, + + /// + /// 获取组合框列表框中的项数。 + /// + CB_GETCOUNT = 0x0146, + + /// + /// 应用程序在组合框的列表框中发送 CB_GETCURSEL 消息以检索当前所选项(如果有)的索引。 + /// + CB_GETCURSEL = 0x0147, + + /// + /// 从组合框列表中获取字符串。 + /// + CB_GETLBTEXT = 0x0148, + + /// + /// 获取组合框中字符串的长度(以字符为单位)。 + /// + CB_GETLBTEXTLEN = 0x0149, + + /// + /// 将字符串或项数据插入组合框列表中。 与 CB_ADDSTRING 消息不同, CB_INSERTSTRING 消息不会导致对具有 CBS_SORT 样式的列表进行排序。 + /// + CB_INSERTSTRING = 0x014A, + + /// + /// 从列表框中删除所有项,并编辑组合框的控件。 + /// + CB_RESETCONTENT = 0x014B, + + /// + /// 在组合框的列表框中搜索以指定字符串中的字符开头的项目。 + /// + CB_FINDSTRING = 0x014C, + + /// + /// 在组合框列表中搜索以指定字符串中的字符开头的项。 如果找到匹配项,则会将其选中并复制到编辑控件。 + /// + CB_SELECTSTRING = 0x014D, + + /// + /// 应用程序发送 CB_SETCURSEL 消息,以在组合框中选择字符串。 如有必要,列表会将字符串滚动到视图中。 组合框的编辑控件中的文本将更改以反映新选定内容,并删除列表中任何以前的选定内容。 + /// + CB_SETCURSEL = 0x014E, + + /// + /// 应用程序发送 CB_SHOWDROPDOWN 消息以显示或隐藏具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框的列表框。 + /// + CB_SHOWDROPDOWN = 0x014F, + + /// + /// 应用程序将 CB_GETITEMDATA 消息发送到组合框,以检索与组合框中指定项关联的应用程序提供的值。 + /// + CB_GETITEMDATA = 0x0150, + + /// + /// 应用程序发送 CB_SETITEMDATA 消息以设置与组合框中指定项关联的值。 + /// + CB_SETITEMDATA = 0x0151, + + /// + /// 应用程序发送 CB_GETDROPPEDCONTROLRECT 消息以检索处于下拉状态的组合框的屏幕坐标。 + /// + CB_GETDROPPEDCONTROLRECT = 0x0152, + + /// + /// 应用程序发送 CB_SETITEMHEIGHT 消息以设置组合框中的列表项或选择字段的高度。 + /// + CB_SETITEMHEIGHT = 0x0153, + + /// + /// 确定组合框中列表项或选择字段的高度。 + /// + CB_GETITEMHEIGHT = 0x0154, + + /// + /// 应用程序发送 CB_SETEXTENDEDUI 消息,以选择具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框的默认 UI 或扩展 UI。 + /// + CB_SETEXTENDEDUI = 0x0155, + + /// + /// 确定组合框是具有默认用户界面还是扩展用户界面。 + /// + CB_GETEXTENDEDUI = 0x0156, + + /// + /// 确定组合框的列表框是否下拉。 + /// + CB_GETDROPPEDSTATE = 0x0157, + + /// + /// 查找与 lParam 参数中指定的字符串匹配的组合框中的第一个列表框字符串。 + /// + CB_FINDSTRINGEXACT = 0x0158, + + /// + /// 应用程序发送 CB_SETLOCALE 消息以设置组合框的当前区域设置。 如果组合框具有使用 CB_ADDSTRING 添加 CBS_SORT 样式和字符串,则组合框的区域设置会影响列表项的排序方式。 + /// + CB_SETLOCALE = 0x0159, + + /// + /// 获取组合框的当前区域设置。 区域设置用于确定使用 CB_ADDSTRING 消息添加 CBS_SORT 样式和文本的组合框显示文本的正确排序顺序。 + /// + CB_GETLOCALE = 0x015A, + + /// + /// 应用程序发送 CB_GETTOPINDEX 消息以检索组合框列表框部分第一个可见项的从零开始的索引。 最初,索引为 0 的项位于列表框顶部,但如果列表框内容已滚动,则其他项可能位于顶部。 + /// + CB_GETTOPINDEX = 0x015B, + + /// + /// 应用程序发送 CB_SETTOPINDEX 消息,以确保特定项在组合框的列表框中可见。 系统滚动列表框内容,以便指定的项显示在列表框顶部或已达到最大滚动范围。 + /// + CB_SETTOPINDEX = 0x015C, + + /// + /// 获取列表框可以水平滚动的宽度(以像素为单位), (可滚动宽度) 。 仅当列表框具有水平滚动条时,此选项才适用。 + /// + CB_GETHORIZONTALEXTENT = 0x015D, + + /// + /// 应用程序发送 CB_SETHORIZONTALEXTENT 消息以设置宽度(以像素为单位),列表框可以水平滚动 (可滚动宽度) 。 如果列表框的宽度小于此值,则水平滚动条水平滚动列表框中的项目。 如果列表框的宽度等于或大于此值,则隐藏水平滚动条,或者,如果组合框具有 CBS_DISABLENOSCROLL 样式,则禁用。 + /// + CB_SETHORIZONTALEXTENT = 0x015E, + + /// + /// 获取具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框列表框的最小允许宽度(以像素为单位)。 + /// + CB_GETDROPPEDWIDTH = 0x015F, + + /// + /// 应用程序发送 CB_SETDROPPEDWIDTH 消息,以设置具有 CBS_DROPDOWN 或 CBS_DROPDOWNLIST 样式的组合框列表框的最小允许宽度(以像素为单位)。 + /// + CB_SETDROPPEDWIDTH = 0x0160, + + /// + /// 应用程序在将大量项目添加到组合框的列表框部分之前发送 CB_INITSTORAGE 消息。 此消息分配用于存储列表框项的内存。 + /// + CB_INITSTORAGE = 0x0161, + + CB_MSGMAX_OLD = 0x0162, + + CB_MULTIPLEADDSTRING = 0x0163, + + /// + /// 获取有关指定组合框的信息。 + /// + CB_GETCOMBOBOXINFO = 0x0164, + + CB_MSGMAX = 0x0165, + + // 0x0166 - 0x017F 消息未定义 + + /// + /// 将字符串添加到列表框。 如果列表框没有 LBS_SORT 样式,则字符串将添加到列表末尾。 否则,字符串将插入到列表中,并对列表进行排序。 + /// + LB_ADDSTRING = 0x0180, + + /// + /// 将字符串或项数据插入列表框中。 与 LB_ADDSTRING 消息不同, LB_INSERTSTRING 消息不会导致对具有 LBS_SORT 样式的列表进行排序。 + /// + LB_INSERTSTRING = 0x0181, + + /// + /// 删除列表框中的字符串。 + /// + LB_DELETESTRING = 0x0182, + + /// + /// 在多选列表框中选择一个或多个连续项。 + /// + LB_SELITEMRANGEEX = 0x0183, + + /// + /// 从列表框中删除所有项。 + /// + LB_RESETCONTENT = 0x0184, + + /// + /// 在多选列表框中选择一个项目,如有必要,将项目滚动到视图中。 + /// + LB_SETSEL = 0x0185, + + /// + /// 根据需要选择字符串并将其滚动到视图中。 选中新字符串后,列表框将从之前选择的字符串中删除突出显示。 + /// + LB_SETCURSEL = 0x0186, + + /// + /// 获取项的选择状态。 + /// + LB_GETSEL = 0x0187, + + /// + /// 获取单选列表框中当前选定项(如果有)的索引。 + /// + LB_GETCURSEL = 0x0188, + + /// + /// 从列表框中获取字符串。 + /// + LB_GETTEXT = 0x0189, + + /// + /// 获取列表框中字符串的长度。 + /// + LB_GETTEXTLEN = 0x018A, + + /// + /// 获取列表框中的项数。 + /// + LB_GETCOUNT = 0x018B, + + /// + /// 在列表框中搜索以指定字符串中的字符开头的项。 如果找到匹配项,则选择该项。 + /// + LB_SELECTSTRING = 0x018C, + + /// + /// 向列表框显示的列表添加名称。 该消息将添加与指定字符串和文件属性集匹配的目录和文件的名称。 LB_DIR 还可以将映射的驱动器号添加到列表框。 + /// + LB_DIR = 0x018D, + + /// + /// 获取列表框中第一个可见项的索引。 最初,索引为 0 的项位于列表框的顶部,但如果列表框内容已滚动,则另一个项目可能位于顶部。 多列列表框中的第一个可见项是左上角的项。 + /// + LB_GETTOPINDEX = 0x018E, + + /// + /// 查找以指定字符串开头的列表框中的第一个字符串。 + /// + LB_FINDSTRING = 0x018F, + + /// + /// 获取多选列表框中所选项的总数。 + /// + LB_GETSELCOUNT = 0x0190, + + /// + /// 用整数数组填充缓冲区,该数组指定多选列表框中选定项的项数。 + /// + LB_GETSELITEMS = 0x0191, + + /// + /// 设置列表框中的制表位位置。 + /// + LB_SETTABSTOPS = 0x0192, + + /// + /// 获取列表框的水平滚动宽度(以像素为单位),如果列表框具有水平滚动条,则列表框可以水平滚动 (可滚动宽度) 。 + /// + LB_GETHORIZONTALEXTENT = 0x0193, + + /// + /// 设置列表框可以水平滚动的宽度(以像素为单位), (可滚动宽度) 。 如果列表框的宽度小于此值,水平滚动条水平滚动列表框中的项目。 如果列表框的宽度等于或大于此值,则水平滚动条处于隐藏状态。 + /// + LB_SETHORIZONTALEXTENT = 0x0194, + + /// + /// 设置多列列表框中所有列的宽度(以像素为单位)。 + /// + LB_SETCOLUMNWIDTH = 0x0195, + + /// + /// 将指定的文件名添加到包含目录列表的列表框中。 + /// + LB_ADDFILE = 0x0196, + + /// + /// 确保列表框中的指定项可见。 + /// + LB_SETTOPINDEX = 0x0197, + + /// + /// 获取当前显示在列表框中的列表框项的矩形的尺寸。 + /// + LB_GETITEMRECT = 0x0198, + + /// + /// 获取与指定列表框项关联的应用程序定义值。 + /// + LB_GETITEMDATA = 0x0199, + + /// + /// 设置与列表框中指定项关联的值。 + /// + LB_SETITEMDATA = 0x019A, + + /// + /// 在多选列表框中选择或取消选择一个或多个连续项。 + /// + LB_SELITEMRANGE = 0x019B, + + /// + /// 设置定位项,即从中启动多个选择的项。 多个选择跨越定位点项到插入点项的所有项。 + /// + LB_SETANCHORINDEX = 0x019C, + + /// + /// 获取定位点项的索引,即从中启动多个选择的项。 多个选择跨越定位点项到插入点项的所有项。 + /// + LB_GETANCHORINDEX = 0x019D, + + /// + /// 将焦点矩形设置为多选列表框中指定索引处的项。 如果该项不可见,则会滚动到视图中。 + /// + LB_SETCARETINDEX = 0x019E, + + /// + /// 检索具有多选列表框中焦点的项的索引。 该项目可能或可能未选中。 + /// + LB_GETCARETINDEX = 0x019F, + + /// + /// 设置列表框中项的高度(以像素为单位)。 如果列表框具有 LBS_OWNERDRAWVARIABLE 样式,此消息将设置 wParam 参数指定的项的高度。 否则,此消息将设置列表框中所有项的高度。 + /// + LB_SETITEMHEIGHT = 0x01A0, + + /// + /// 获取列表框中项的高度。 + /// + LB_GETITEMHEIGHT = 0x01A1, + + /// + /// 查找与指定字符串完全匹配的第一个列表框字符串,但搜索不区分大小写。 + /// + LB_FINDSTRINGEXACT = 0x01A2, + + LBCB_CARETON = 0x01A3, + + LBCB_CARETOFF = 0x01A4, + + /// + /// 设置列表框的当前区域设置。 可以使用区域设置来确定列表框显示的文本 (的正确排序顺序,其中包含 LBS_SORT 样式) 以及 由 LB_ADDSTRING 邮件添加的文本。 + /// + LB_SETLOCALE = 0x01A5, + + /// + /// 获取列表框的当前区域设置。 可以使用区域设置来确定列表框显示的文本 (的正确排序顺序,列表框具有 LBS_SORT 样式) 和 LB_ADDSTRING 邮件添加的文本。 + /// + LB_GETLOCALE = 0x01A6, + + /// + /// 设置使用 LBS_NODATA 样式创建的列表框中的项目计数,而不用 LBS_HASSTRINGS 样式创建。 + /// + LB_SETCOUNT = 0x01A7, + + /// + /// 分配用于存储列表框项的内存。 在应用程序向列表框添加大量项目之前,将使用此消息。 + /// + LB_INITSTORAGE = 0x01A8, + + /// + /// 获取列表框中最接近指定点的项的从零开始的索引。 + /// + LB_ITEMFROMPOINT = 0x01A9, + + LB_INSERTSTRINGUPPER = 0x01AA, + + LB_INSERTSTRINGLOWER = 0x01AB, + + LB_ADDSTRINGUPPER = 0x01AC, + + LB_ADDSTRINGLOWER = 0x01AD, + + LBCB_STARTTRACK = 0x01AE, + + LBCB_ENDTRACK = 0x01AF, + + LB_MSGMAX_OLD = 0x01B0, + + LB_MULTIPLEADDSTRING = 0x01B1, + + /// + /// 获取指定列表框中每列的项数。 + /// + LB_GETLISTBOXINFO = 0x01B2, + + LB_MSGMAX = 0x01B3, + + // 0x01B4 - 0x01DF 消息未定义 + + MN_FIRST = 0x01E0, + + /// + /// 检索当前窗口的菜单句柄。 + /// + MN_GETHMENU = 0x01E1, + + // 0x01E2 - 0x01FF 消息未定义 + + /// + /// 使用 WM_MOUSEFIRST 指定第一条鼠标消息。使用 PeekMessage() 函数。 + /// + WM_MOUSEFIRST = 0x0200, + + /// + /// 当光标移动时,WM_MOUSEMOVE 消息被发送到窗口。如果没有捕获鼠标,则将消息发送到包含光标的窗口。否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_MOUSEMOVE = WM_MOUSEFIRST, + + /// + /// WM_LBUTTONDOWN 消息是当用户按下鼠标左键,而光标位于窗口的客户端区域时发出的。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_LBUTTONDOWN = 0x0201, + + /// + /// WM_LBUTTONUP 消息是在用户释放鼠标左键时发出的,而光标位于窗口的客户端区域。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_LBUTTONUP = 0x0202, + + /// + /// WM_LBUTTONDBLCLK 消息是在用户双击鼠标左键时发出的,而光标位于窗口的客户端区域。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_LBUTTONDBLCLK = 0x0203, + + /// + /// WM_RBUTTONDOWN 消息是当用户在窗口的客户端区域按下鼠标右键时发出的。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_RBUTTONDOWN = 0x0204, + + /// + /// WM_RBUTTONUP 消息是在用户释放鼠标右键时发出的,而光标位于窗口的客户端区域。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_RBUTTONUP = 0x0205, + + /// + /// 当用户在窗口的客户端区域内双击鼠标右键时,WM_RBUTTONDBLCLK 消息将被发布。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_RBUTTONDBLCLK = 0x0206, + + /// + /// WM_MBUTTONDOWN消息是当用户在窗口的客户端区域按下鼠标中键时发出的。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_MBUTTONDOWN = 0x0207, + + /// + /// WM_MBUTTONUP 消息是在用户释放鼠标中键时发出的,而光标位于窗口的客户端区域。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_MBUTTONUP = 0x0208, + + /// + /// WM_MBUTTONDBLCLK 消息是当用户双击鼠标中间按钮,而光标位于窗口的客户端区域时发出的。如果没有捕获鼠标,则消息将被发送到光标下方的窗口。 + /// 否则,消息将被发送到捕获了鼠标的窗口。 + /// + WM_MBUTTONDBLCLK = 0x0209, + + /// + /// 当鼠标滚轮旋转时,发送到焦点窗口。 DefWindowProc 函数将消息传播到窗口的父级。 不应有消息的内部转发,因为 DefWindowProc 会将其传播到父链上,直到找到处理它的窗口。 + /// + WM_MOUSEWHEEL = 0x020A, + + /// + /// 当用户按下第一个或第二个 X 按钮时,光标位于窗口的工作区时发布。 如果未捕获鼠标,则会将消息发布到光标下方的窗口。 否则,消息将发布到捕获了鼠标的窗口。 + /// + WM_XBUTTONDOWN = 0x020B, + + /// + /// 当用户释放第一个或第二个 X 按钮时,光标位于窗口的工作区时发布。 如果未捕获鼠标,消息将发布到光标下方的窗口中。 否则,消息将发布到捕获了鼠标的窗口。 + /// + WM_XBUTTONUP = 0x020C, + + /// + /// 当用户在光标位于窗口的工作区时双击第一个或第二个 X 按钮时发布。 如果未捕获鼠标,消息将发布到光标下方的窗口中。 否则,消息将发布到捕获了鼠标的窗口。 + /// + WM_XBUTTONDBLCLK = 0x020D, + + /// + /// 当鼠标的水平滚轮倾斜或旋转时,发送到活动窗口。 DefWindowProc 函数将消息传播到窗口的父级。 不应有消息的内部转发,因为 DefWindowProc 会将其传播到父链上,直到找到处理它的窗口。 + /// + WM_MOUSEHWHEEL = 0x020E, + + /// + /// 使用 WM_MOUSELAST 指定最后一条鼠标消息。与 PeekMessage() 函数一起使用。 + /// + WM_MOUSELAST = WM_MOUSEHWHEEL, + + // 0x020F 消息未定义 + + /// + /// 当子代窗口上发生重大操作时,发送到窗口。 此消息现已扩展为包含 WM_POINTERDOWN 事件。 创建子窗口时,系统会在创建该窗口的 CreateWindow 或 CreateWindowEx 函数返回之前发送 WM_PARENTNOTIFY。 当子窗口被销毁时,系统会在进行任何销毁窗口的处理之前发送消息。 + /// + WM_PARENTNOTIFY = 0x0210, + + /// + /// 通知应用程序的主窗口过程已输入菜单模式循环。 + /// + WM_ENTERMENULOOP = 0x0211, + + /// + /// 通知应用程序的主窗口过程已退出菜单模式循环。 + /// + WM_EXITMENULOOP = 0x0212, + + /// + /// 当使用向右键或向左键在菜单栏和系统菜单之间切换时发送到应用程序。 + /// + WM_NEXTMENU = 0x0213, + + /// + /// 发送到用户正在调整大小的窗口。 通过处理此消息,应用程序可以监视拖动矩形的大小和位置,并根据需要更改其大小或位置。 + /// + WM_SIZING = 0x0214, + + /// + /// 发送到丢失鼠标捕获的窗口。 + /// + WM_CAPTURECHANGED = 0x0215, + + /// + /// 发送到用户正在移动的窗口。 通过处理此消息,应用程序可以监视拖动矩形的位置,并根据需要更改其位置。 + /// + WM_MOVING = 0x0216, + + // 0x0217 消息未定义 + + /// + /// 通知应用程序电源管理事件已发生。 + /// + WM_POWERBROADCAST = 0x0218, + + /// + /// 通知应用程序更改设备或计算机的硬件配置。 + /// + WM_DEVICECHANGE = 0x0219, + + // 0x021A - 0x021F 消息未定义 + + /// + /// 应用程序将 WM_MDICREATE 消息发送到多文档接口, (MDI) 客户端窗口创建 MDI 子窗口。 + /// + WM_MDICREATE = 0x0220, + + /// + /// 应用程序将 WM_MDIDESTROY 消息发送到多文档接口, (MDI) 客户端窗口关闭 MDI 子窗口。 + /// + WM_MDIDESTROY = 0x0221, + + /// + /// 应用程序将 WM_MDIGETACTIVE 消息发送到多文档接口 (MDI) 客户端窗口,以检索活动 MDI 子窗口的句柄。 + /// + WM_MDIACTIVATE = 0x0222, + + /// + /// 应用程序将 WM_MDIRESTORE 消息发送到多文档接口, (MDI) 客户端窗口,以便从最大化或最小化的大小还原 MDI 子窗口。 + /// + WM_MDIRESTORE = 0x0223, + + /// + /// 应用程序将 WM_MDINEXT 消息发送到多文档接口 (MDI) 客户端窗口以激活下一个或上一个子窗口。 + /// + WM_MDINEXT = 0x0224, + + /// + /// 应用程序将 WM_MDIMAXIMIZE 消息发送到多文档接口, (MDI) 客户端窗口最大化 MDI 子窗口。 系统调整子窗口的大小,使其工作区填充客户端窗口。 系统将子窗口的窗口菜单图标置于框架窗口菜单栏的最右侧位置,并将子窗口的还原图标置于最左侧的位置。 系统还会将子窗口的标题栏文本追加到框架窗口的标题栏文本。 + /// + WM_MDIMAXIMIZE = 0x0225, + + /// + /// 应用程序将 WM_MDITILE 消息发送到多文档界面, (MDI) 客户端窗口,以磁贴格式排列其所有 MDI 子窗口。 + /// + WM_MDITILE = 0x0226, + + /// + /// 应用程序将 WM_MDICASCADE 消息发送到多文档接口 (MDI) 客户端窗口,以级联格式排列其所有子窗口。 + /// + WM_MDICASCADE = 0x0227, + + /// + /// 应用程序将 WM_MDIICONARRANGE 消息发送到多文档接口, (MDI) 客户端窗口排列所有最小化的 MDI 子窗口。 它不会影响未最小化的子窗口。 + /// + WM_MDIICONARRANGE = 0x0228, + + /// + /// 应用程序将 WM_MDIGETACTIVE 消息发送到多文档接口 (MDI) 客户端窗口,以检索活动 MDI 子窗口的句柄。 + /// + WM_MDIGETACTIVE = 0x0229, + + WM_DROPOBJECT = 0x022A, + + WM_QUERYDROPOBJECT = 0x022B, + + WM_BEGINDRAG = 0x022C, + + WM_DRAGLOOP = 0x022D, + + WM_DRAGSELECT = 0x022E, + + WM_DRAGMOVE = 0x022F, + + /// + /// 应用程序将 WM_MDISETMENU 消息发送到多文档界面, (MDI) 客户端窗口替换 MDI 框架窗口的整个菜单,替换框架窗口的窗口菜单,或两者。 + /// + WM_MDISETMENU = 0x0230, + + /// + /// 在窗口进入移动模式循环或调整大小循环后,将一次发送到窗口。 当用户单击窗口的标题栏或大小调整边框或窗口将 WM_SYSCOMMAND 消息传递到 DefWindowProc 函数和消息 的 wParam 参数指定 SC_MOVE 或 SC_SIZE 值时,窗口将输入移动或调整模式循环。 + /// 当 DefWindowProc 返回时,该操作已完成。 + /// + WM_ENTERSIZEMOVE = 0x0231, + + /// + /// 在窗口退出移动或调整模式循环后,将一次发送到窗口。 当用户单击窗口的标题栏或大小调整边框或窗口将 WM_SYSCOMMAND 消息传递到 DefWindowProc 函数时,窗口将输入移动或调整模式循环,而消息的 wParam 参数指定 SC_MOV E 或 SC_SIZE 值。 当 DefWindowProc 返回时,此操作将完成。 + /// + WM_EXITSIZEMOVE = 0x0232, + + /// + /// 当用户在已将自己注册为已删除文件的收件人的应用程序窗口上删除文件时发送。 + /// + WM_DROPFILES = 0x0233, + + /// + /// 应用程序将 WM_MDIREFRESHMENU 消息发送到多文档接口, (MDI) 客户端窗口刷新 MDI 框架窗口的窗口菜单。 + /// + WM_MDIREFRESHMENU = 0x0234, + + // 0x0235 - 0x0237 消息未定义 + + /// + /// 当附加了数字化仪的监视器的设置发生更改时,发送到窗口。 此消息包含有关显示模式缩放的信息。 + /// + WM_POINTERDEVICECHANGE = 0x0238, + + /// + /// 在输入数字化器范围内检测到指针设备时发送到窗口。 此消息包含有关设备及其邻近度的信息。 + /// + WM_POINTERDEVICEINRANGE = 0x0239, + + /// + /// 当指针设备离开输入数字化器的范围时,发送到窗口。 此消息包含有关设备及其邻近度的信息。 + /// + WM_POINTERDEVICEOUTOFRANGE = 0x023A, + + WM_STOPINERTIA = 0x023B, + + WM_ENDINERTIA = 0x023C, + + WM_EDGYINERTIA = 0x023D, + + // 0x023E - 0x023F 消息未定义 + + /// + /// 当一个或多个触摸点(如手指或笔)触摸触摸敏感数字化器表面时,通知窗口。 + /// + WM_TOUCH = 0x0240, + + /// + /// 发布以在指针上提供一个更新,该指针在窗口的非工作区上或在悬停未捕获的联系人移动到窗口的非工作区时进行接触。 指针悬停时,消息以指针恰好悬停在哪个窗口为目标。 当指针与表面接触时,指针会隐式捕获到指针接触的窗口,并且该窗口继续接收指针的输入,直到它断开接触。 + /// 如果窗口捕获了此指针,则不会发布此消息。 相反, WM_POINTERUPDATE 将发布到捕获此指针的窗口。 + /// + WM_NCPOINTERUPDATE = 0x0241, + + /// + /// 当指针在窗口的非工作区上进行接触时发布。 消息以指针联系的窗口为目标。 指针隐式捕获到窗口,以便窗口继续接收指针的输入,直到它中断接触。 + /// 如果窗口捕获了此指针,则不会发布此消息。 相反, WM_POINTERDOWN 会发布到捕获此指针的窗口。 + /// + WM_NCPOINTERDOWN = 0x0242, + + /// + /// 在窗口的非工作区上建立接触的指针断开联系人时发布。 该消息以指针在其中进行接触的窗口为目标,此时指针被隐式捕获到窗口,以便窗口继续接收指针的输入,直到它中断接触,包括 WM_NCPOINTERUP 通知。 + /// 如果窗口捕获了此指针,则不会发布此消息。 相反, WM_NCPOINTERUP 将发布到已捕获此指针的窗口。 + /// + WM_NCPOINTERUP = 0x0243, + + WM_NCPOINTERLAST = 0x0244, + + /// + /// 发布以提供在窗口工作区上方的指针或悬停在窗口工作区上的未捕获指针上的接触的更新。 指针悬停时,消息以指针恰好悬停在哪个窗口为目标。 当指针与表面接触时,指针会隐式捕获到指针接触的窗口,并且该窗口继续接收指针的输入,直到它断开接触。 + /// + WM_POINTERUPDATE = 0x0245, + + /// + /// 当指针在窗口的工作区上进行接触时发布。 此输入消息以指针接触的窗口为目标,指针隐式捕获到窗口,以便窗口继续接收指针的输入,直到它中断接触。 + /// + WM_POINTERDOWN = 0x0246, + + /// + /// 在窗口工作区上建立接触的指针中断联系人时发布。 此输入消息以指针进行接触的窗口为目标,指针在该时间点隐式捕获到窗口,以便窗口继续接收输入消息,包括指针的 WM_POINTERUP 通知,直到它中断联系人。 + /// + WM_POINTERUP = 0x0247, + + WM_POINTER_reserved_248 = 0x0248, + + /// + /// 当新指针进入窗口上方的检测范围 (悬停) 或现有指针在窗口边界内移动时,发送到窗口。 + /// + WM_POINTERENTER = 0x0249, + + /// + /// 当指针离开窗口上的检测范围时, (将鼠标悬停) 或指针移动到窗口边界之外时,发送到窗口。 + /// + WM_POINTERLEAVE = 0x024A, + + /// + /// 当主指针在窗口上生成 WM_POINTERDOWN 时发送到非活动窗口。 只要邮件保持未处理状态,它才会到达父窗口链,直到到达顶级窗口。 应用程序可以响应此消息,以指定是否要激活它们。 + /// + WM_POINTERACTIVATE = 0x024B, + + /// + /// 发送到丢失输入指针捕获的窗口。 + /// + WM_POINTERCAPTURECHANGED = 0x024C, + + /// + /// 发送到向下触摸的窗口,以确定最可能的触摸目标。 + /// + WM_TOUCHHITTESTING = 0x024D, + + /// + /// 旋转滚轮时,使用前台键盘焦点发布到窗口。 + /// + WM_POINTERWHEEL = 0x024E, + + /// + /// 在水平滚轮旋转时,使用前台键盘焦点发布到窗口。 + /// + WM_POINTERHWHEEL = 0x024F, + + WM_POINTER_reserved_250 = 0x0250, + + WM_POINTER_reserved_251 = 0x0251, + + WM_POINTER_reserved_252 = 0x0252, + + WM_POINTER_reserved_253 = 0x0253, + + WM_POINTER_reserved_254 = 0x0254, + + WM_POINTER_reserved_255 = 0x0255, + + WM_POINTER_reserved_256 = 0x0256, + + WM_POINTERLAST = 0x0257, + + // 0x0258 - 0x026F 消息未定义 + + WM_VISIBILITYCHANGED = 0x0270, + + WM_VIEWSTATECHANGED = 0x0271, + + WM_UNREGISTER_WINDOW_SERVICES = 0x0272, + + WM_CONSOLIDATED = 0x0273, + + // 0x0274 - 0x027F 消息未定义 + + WM_IME_REPORT = 0x0280, + + /// + /// 激活窗口时发送到应用程序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_SETCONTEXT = 0x0281, + + /// + /// 发送到应用程序以通知应用程序对 IME 窗口所做的更改。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_NOTIFY = 0x0282, + + /// + /// 应用程序发送以指示 IME 窗口执行请求的命令。 应用程序使用此消息来控制已创建的 IME 窗口。 若要发送此消息,应用程序使用以下参数调用 PostMessage 函数。 + /// + WM_IME_CONTROL = 0x0283, + + /// + /// 当 IME 窗口没有空间扩展合成窗口的区域时发送到应用程序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_COMPOSITIONFULL = 0x0284, + + /// + /// 当操作系统即将更改当前 IME 时发送到应用程序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_SELECT = 0x0285, + + /// + /// 当 IME 获取转换结果的字符时发送到应用程序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_CHAR = 0x0286, + + WM_IME_SYSTEM = 0x0287, + + /// + /// 发送到应用程序以提供命令和请求信息。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_REQUEST = 0x0288, + + WM_KANJI_reserved_289 = 0x0289, + + WM_KANJI_reserved_28a = 0x028A, + + WM_KANJI_reserved_28b = 0x028B, + + WM_KANJI_reserved_28c = 0x028C, + + WM_KANJI_reserved_28d = 0x028D, + + WM_KANJI_reserved_28e = 0x028E, + + WM_KANJI_reserved_28f = 0x028F, + + /// + /// IME 发送到应用程序以通知应用程序按下键并保留消息顺序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_KEYDOWN = 0x0290, + + /// + /// 通过 IME 发送到应用程序以通知应用程序密钥发布并保留消息顺序。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_IME_KEYUP = 0x0291, + + WM_KANJI_reserved_292 = 0x0292, + + WM_KANJI_reserved_293 = 0x0293, + + WM_KANJI_reserved_294 = 0x0294, + + WM_KANJI_reserved_295 = 0x0295, + + WM_KANJI_reserved_296 = 0x0296, + + WM_KANJI_reserved_297 = 0x0297, + + WM_KANJI_reserved_298 = 0x0298, + + WM_KANJI_reserved_299 = 0x0299, + + WM_KANJI_reserved_29a = 0x029A, + + WM_KANJI_reserved_29b = 0x029B, + + WM_KANJI_reserved_29c = 0x029C, + + WM_KANJI_reserved_29d = 0x029D, + + WM_KANJI_reserved_29e = 0x029E, + + WM_KANJILAST = 0x029F, + + /// + /// 在之前调用 TrackMouseEvent 中指定的时间段内,光标悬停在窗口的非工作区上时,发布到窗口。 + /// + WM_NCMOUSEHOVER = 0x02A0, + + /// + /// 当光标悬停在窗口的工作区上之前调用 TrackMouseEvent 中指定的时间段时,将发布到窗口。 + /// + WM_MOUSEHOVER = 0x02A1, + + /// + /// 当光标离开之前对 TrackMouseEvent 的调用中指定的窗口的非client 区域时,发布到窗口。 + /// + WM_NCMOUSELEAVE = 0x02A2, + + /// + /// 当光标离开之前对 TrackMouseEvent 调用中指定的窗口的工作区时,发布到窗口。 + /// + WM_MOUSELEAVE = 0x02A3, + + WM_TRACKMOUSEEVENT__reserved_2a4 = 0x02A4, + + WM_TRACKMOUSEEVENT__reserved_2a5 = 0x02A5, + + WM_TRACKMOUSEEVENT__reserved_2a6 = 0x02A6, + + WM_TRACKMOUSEEVENT__reserved_2a7 = 0x02A7, + + WM_TRACKMOUSEEVENT__reserved_2a8 = 0x02A8, + + WM_TRACKMOUSEEVENT__reserved_2a9 = 0x02A9, + + WM_TRACKMOUSEEVENT__reserved_2aa = 0x02AA, + + WM_TRACKMOUSEEVENT__reserved_2ab = 0x02AB, + + WM_TRACKMOUSEEVENT__reserved_2ac = 0x02AC, + + WM_TRACKMOUSEEVENT__reserved_2ad = 0x02AD, + + WM_TRACKMOUSEEVENT__reserved_2ae = 0x02AE, + + WM_TRACKMOUSEEVENT_LAST = 0x02AF, + + // 0x02B0 消息未定义 + + /// + /// 通知应用程序会话状态的更改。 + /// + WM_WTSSESSION_CHANGE = 0x02B1, + + // 0x02B2 - 0x02BF 消息未定义 + + WM_TABLET_FIRST = 0x02C0, + + WM_TABLET__reserved_2c1 = 0x02C1, + + WM_TABLET__reserved_2c2 = 0x02C2, + + WM_TABLET__reserved_2c3 = 0x02C3, + + WM_TABLET__reserved_2c4 = 0x02C4, + + WM_TABLET__reserved_2c5 = 0x02C5, + + WM_TABLET__reserved_2c6 = 0x02C6, + + WM_TABLET__reserved_2c7 = 0x02C7, + + WM_POINTERDEVICEADDED = 0x02C8, + + WM_POINTERDEVICEDELETED = 0x02C9, + + WM_TABLET__reserved_2ca = 0x02CA, + + WM_FLICK = 0x02CB, + + WM_TABLET__reserved_2cc = 0x02CC, + + WM_FLICKINTERNAL = 0x02CD, + + WM_BRIGHTNESSCHANGED = 0x02CE, + + WM_TABLET__reserved_2cf = 0x02CF, + + WM_TABLET__reserved_2d0 = 0x02D0, + + WM_TABLET__reserved_2d1 = 0x02D1, + + WM_TABLET__reserved_2d2 = 0x02D2, + + WM_TABLET__reserved_2d3 = 0x02D3, + + WM_TABLET__reserved_2d4 = 0x02D4, + + WM_TABLET__reserved_2d5 = 0x02D5, + + WM_TABLET__reserved_2d6 = 0x02D6, + + WM_TABLET__reserved_2d7 = 0x02D7, + + WM_TABLET__reserved_2d8 = 0x02D8, + + WM_TABLET__reserved_2d9 = 0x02D9, + + WM_TABLET__reserved_2da = 0x02DA, + + WM_TABLET__reserved_2db = 0x02DB, + + WM_TABLET__reserved_2dc = 0x02DC, + + WM_TABLET__reserved_2dd = 0x02DD, + + WM_TABLET__reserved_2de = 0x02DE, + + WM_TABLET_LAST = 0x02DF, + + /// + /// 当窗口的有效点数 (dpi) 更改时发送。 DPI 是窗口的规模因子。 有多个事件可能导致 DPI 更改。 以下列表指示 DPI 更改的可能原因。 + /// 窗口将移动到具有不同 DPI 的新监视器。 + /// 承载窗口的监视器的 DPI 会更改。 + /// 窗口的当前 DPI 始终等于 WM_DPICHANGED 发送的最后 一个 DPI。 对于知道 DPI 更改的线程,窗口应缩放到的缩放因子。 + /// + WM_DPICHANGED = 0x02E0, + + // 0x02E1 消息未定义 + + /// + /// 对于 Per Monitor v2 顶级窗口,此消息将发送到正在发生 DPI 更改的窗口的子 HWDN 树中的所有 HWND。 此消息发生在顶层窗口接收 WM_DPICHANGED 之前,并从上到下遍历子树。 + /// + WM_DPICHANGED_BEFOREPARENT = 0x02E2, + + /// + /// 对于 Per Monitor v2 顶级窗口,此消息将发送到正在更改 DPI 的窗口的子 HWDN 树中的所有 HWND。 在顶层窗口收到 WM_DPICHANGED 并遍历从上到下子树之后,会出现此消息。 + /// + WM_DPICHANGED_AFTERPARENT = 0x02E3, + + /// + /// 此消息告知操作系统,窗口的大小将调整为默认值以外的维度。 + /// 在发送 WM_DPICHANGED 消息之前,此消息将发送到具有每个监视器 v2 DPI_AWARENESS_CONTEXT的顶级窗口,并允许窗口计算其挂起 DPI 更改所需的大小。 由于线性 DPI 缩放是默认行为,因此仅在窗口想要以非线性方式缩放的情况下才有用。 如果应用程序响应此消息,生成的大小将是发送到 WM_DPICHANGED 的候选矩形。 + /// 使用此消息可更改 随 WM_DPICHANGED 一起提供的 rect 大小。 + /// + WM_GETDPISCALEDSIZE = 0x02E4, + + // 0x02E5 - 0x02FF 消息未定义 + + /// + /// 应用程序将 WM_CUT 消息发送到编辑控件或组合框,以删除 (剪切) 当前所选内容(如果有),并在编辑控件中以 CF_TEXT 格式将已删除的文本复制到剪贴板。 + /// + WM_CUT = 0x0300, + + /// + /// 应用程序将 WM_COPY 消息发送到编辑控件或组合框,以 CF_TEXT 格式将当前选定内容复制到剪贴板。 + /// + WM_COPY = 0x0301, + + /// + /// 应用程序将 WM_PASTE 消息发送到编辑控件或组合框,以将剪贴板的当前内容复制到位于当前插入点位置的编辑控件。 仅当剪贴板包含 CF_TEXT 格式的数据时,才会插入数据。 + /// + WM_PASTE = 0x0302, + + /// + /// 应用程序将 WM_CLEAR 消息发送到编辑控件或组合框,以从编辑控件中删除 (清除) 当前所选内容(如果有)。 + /// + WM_CLEAR = 0x0303, + + /// + /// 应用程序将 WM_UNDO 消息发送到编辑控件以撤消最后一个操作。 当此消息发送到编辑控件时,将还原以前删除的文本或删除以前添加的文本。 + /// + WM_UNDO = 0x0304, + + /// + /// 如果剪贴板所有者延迟呈现特定剪贴板格式,并且应用程序已请求采用该格式的数据,则将其发送到剪贴板所有者。 剪贴板所有者必须以指定的格式呈现数据,并通过调用 SetClipboardData 函数将其置于剪贴板上。 + /// + WM_RENDERFORMAT = 0x0305, + + /// + /// 如果剪贴板所有者延迟呈现一个或多个剪贴板格式,则将其发送到剪贴板所有者,然后再将其销毁。 若要使剪贴板的内容可供其他应用程序使用,剪贴板所有者必须以能够生成的所有格式呈现数据,并通过调用 SetClipboardData 函数将数据放置在剪贴板上。 + /// + WM_RENDERALLFORMATS = 0x0306, + + /// + /// 当对 EmptyClipboard 函数的调用耗尽剪贴板时,发送到剪贴板所有者。 + /// + WM_DESTROYCLIPBOARD = 0x0307, + + /// + /// 当剪贴板的内容发生更改时,发送到剪贴板查看器链中的第一个窗口。 这使剪贴板查看器窗口能够显示剪贴板的新内容。 + /// + WM_DRAWCLIPBOARD = 0x0308, + + /// + /// 当剪贴板包含 CF_OWNERDISPLAY 格式的数据并且剪贴板查看器的工作区需要重新绘制时,由剪贴板查看器的剪贴板所有者窗口发送到剪贴板所有者。 + /// + WM_PAINTCLIPBOARD = 0x0309, + + /// + /// 当剪贴板包含 CF_OWNERDISPLAY 格式的数据并且剪贴板查看器的垂直滚动条中发生事件时,由剪贴板查看器的剪贴板查看器窗口发送到剪贴板所有者。 所有者应滚动剪贴板图像并更新滚动条值。 + /// + WM_VSCROLLCLIPBOARD = 0x030A, + + /// + /// 当剪贴板包含 采用CF_OWNERDISPLAY 格式的数据并且剪贴板查看器的工作区已更改大小时,剪贴板查看器窗口将发送给剪贴板所有者。 + /// + WM_SIZECLIPBOARD = 0x030B, + + /// + /// 通过剪贴板查看器窗口发送到剪贴板所有者,以请求 CF_OWNERDISPLAY 剪贴板格式的名称。 + /// + WM_ASKCBFORMATNAME = 0x030C, + + /// + /// 从链中删除窗口时,发送到剪贴板查看器链中的第一个窗口。 + /// + WM_CHANGECBCHAIN = 0x030D, + + /// + /// 通过剪贴板查看器窗口发送到剪贴板所有者。 当剪贴板包含 CF_OWNERDISPLAY 格式的数据,并且剪贴板查看器的水平滚动条中发生事件时,会发生此情况。 所有者应滚动剪贴板图像并更新滚动条值。 + /// + WM_HSCROLLCLIPBOARD = 0x030E, + + /// + /// WM_QUERYNEWPALETTE 消息通知一个窗口,它即将接收键盘焦点,使窗口有机会在收到焦点时实现其逻辑调色板。 + /// + WM_QUERYNEWPALETTE = 0x030F, + + /// + /// WM_PALETTEISCHANGING 消息通知应用程序应用程序要实现其逻辑调色板。 + /// + WM_PALETTEISCHANGING = 0x0310, + + /// + /// 当窗口具有键盘焦点的窗口已实现其逻辑调色板后, WM_PALETTECHANGED 消息将发送到所有顶级和重叠窗口,从而更改系统调色板。 此消息启用使用调色板但没有键盘焦点的窗口来实现其逻辑调色板并更新其工作区。 + /// + WM_PALETTECHANGED = 0x0311, + + /// + /// 当用户按下 RegisterHotKey 函数注册的热键时发布。 消息放置在与注册热键的线程关联的消息队列的顶部。 + /// + WM_HOTKEY = 0x0312, + + /// + /// 任务栏窗口右键单击时弹出菜单的消息 + /// + WM_SYSMENU = 0x0313, + + WM_HOOKMSG = 0x0314, + + WM_EXITPROCESS = 0x0315, + + WM_WAKETHREAD = 0x0316, + + /// + /// WM_PRINT 消息将发送到窗口,以请求它在指定的设备上下文中绘制自身,这通常是打印机设备上下文中的。 + /// + WM_PRINT = 0x0317, + + /// + /// 将 WM_PRINTCLIENT 消息发送到窗口,以请求它在指定的设备上下文中绘制其工作区,通常位于打印机设备上下文中。 + /// 与 WM_PRINT 不同,DefWindowProc 不会处理 WM_PRINTCLIENT。 窗口应通过应用程序定义的 WndProc 函数处理 WM_PRINTCLIENT 消息,以便其正确使用。 + /// + WM_PRINTCLIENT = 0x0318, + + /// + /// 通知窗口用户生成应用程序命令事件,例如,使用鼠标单击应用程序命令按钮或在键盘上键入应用程序命令键。 + /// + WM_APPCOMMAND = 0x0319, + + /// + /// 在主题更改事件之后广播到每个窗口。 主题更改事件的示例包括主题的激活、主题停用或从一个主题过渡到另一个主题。 + /// + WM_THEMECHANGED = 0x031A, + + WM_UAHINIT = 0x031B, + + WM_DESKTOPNOTIFY = 0x031C, + + /// + /// 剪贴板的内容发生更改时发送。 + /// + WM_CLIPBOARDUPDATE = 0x031D, + + /// + /// 通知所有顶级窗口,桌面窗口管理器 (DWM) 组合已启用或禁用。 + /// + WM_DWMCOMPOSITIONCHANGED = 0x031E, + + /// + /// 当非工作区呈现策略发生更改时发送。 + /// + WM_DWMNCRENDERINGCHANGED = 0x031F, + + /// + /// 通知所有顶级窗口着色颜色已更改。 + /// + WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320, + + /// + /// 当桌面窗口管理器 (DWM) 组合窗口最大化时发送。 + /// + WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321, + + WM_DWMEXILEFRAME = 0x0322, + + /// + /// 指示窗口提供静态位图以用作该窗口的缩略图表示形式。 + /// + WM_DWMSENDICONICTHUMBNAIL = 0x0323, + + WM_MAGNIFICATION_STARTED = 0x0324, + + WM_MAGNIFICATION_ENDED = 0x0325, + + /// + /// 指示窗口提供静态位图以用作实时预览 (也称为该窗口的 速览预览) 。 + /// + WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, + + WM_DWMTHUMBNAILSIZECHANGED = 0x0327, + + WM_MAGNIFICATION_OUTPUT = 0x0328, + + WM_BSDRDATA = 0x0329, + + WM_DWMTRANSITIONSTATECHANGED = 0x032A, + + // 0x032B 消息未定义 + + WM_KEYBOARDCORRECTIONCALLOUT = 0x032C, + + WM_KEYBOARDCORRECTIONACTION = 0x032D, + + WM_UIACTION = 0x032E, + + WM_ROUTED_UI_EVENT = 0x032F, + + WM_MEASURECONTROL = 0x0330, + + WM_GETACTIONTEXT = 0x0331, + + WM_CE_ONLY__reserved_332 = 0x0332, + + WM_FORWARDKEYDOWN = 0x0333, + + WM_FORWARDKEYUP = 0x0334, + + WM_CE_ONLY__reserved_335 = 0x0335, + + WM_CE_ONLY__reserved_336 = 0x0336, + + WM_CE_ONLY__reserved_337 = 0x0337, + + WM_CE_ONLY__reserved_338 = 0x0338, + + WM_CE_ONLY__reserved_339 = 0x0339, + + WM_CE_ONLY__reserved_33a = 0x033A, + + WM_CE_ONLY__reserved_33b = 0x033B, + + WM_CE_ONLY__reserved_33c = 0x033C, + + WM_CE_ONLY__reserved_33d = 0x033D, + + WM_CE_ONLY_LAST = 0x033E, + + /// + /// 发送到请求扩展标题栏信息。 窗口通过其 WndProc 函数接收此消息。 + /// + WM_GETTITLEBARINFOEX = 0x033F, + + WM_NOTIFYWOW = 0x0340, + + // 0x0341 - 0x0357 消息未定义 + + WM_HANDHELDFIRST = 0x0358, + + WM_HANDHELD_reserved_359 = 0x0359, + + WM_HANDHELD_reserved_35a = 0x035A, + + WM_HANDHELD_reserved_35b = 0x035B, + + WM_HANDHELD_reserved_35c = 0x035C, + + WM_HANDHELD_reserved_35d = 0x035D, + + WM_HANDHELD_reserved_35e = 0x035E, + + WM_HANDHELDLAST = 0x035F, + + WM_AFXFIRST = 0x0360, + + WM_AFX_reserved_361 = 0x0361, + + WM_AFX_reserved_362 = 0x0362, + + WM_AFX_reserved_363 = 0x0363, + + WM_AFX_reserved_364 = 0x0364, + + WM_AFX_reserved_365 = 0x0365, + + WM_AFX_reserved_366 = 0x0366, + + WM_AFX_reserved_367 = 0x0367, + + WM_AFX_reserved_368 = 0x0368, + + WM_AFX_reserved_369 = 0x0369, + + WM_AFX_reserved_36a = 0x036A, + + WM_AFX_reserved_36b = 0x036B, + + WM_AFX_reserved_36c = 0x036C, + + WM_AFX_reserved_36d = 0x036D, + + WM_AFX_reserved_36e = 0x036E, + + WM_AFX_reserved_36f = 0x036F, + + WM_AFX_reserved_370 = 0x0370, + + WM_AFX_reserved_371 = 0x0371, + + WM_AFX_reserved_372 = 0x0372, + + WM_AFX_reserved_373 = 0x0373, + + WM_AFX_reserved_374 = 0x0374, + + WM_AFX_reserved_375 = 0x0375, + + WM_AFX_reserved_376 = 0x0376, + + WM_AFX_reserved_377 = 0x0377, + + WM_AFX_reserved_378 = 0x0378, + + WM_AFX_reserved_379 = 0x0379, + + WM_AFX_reserved_37a = 0x037A, + + WM_AFX_reserved_37b = 0x037B, + + WM_AFX_reserved_37c = 0x037C, + + WM_AFX_reserved_37d = 0x037D, + + WM_AFX_reserved_37e = 0x037E, + + WM_AFXLAST = 0x037F, + + WM_PENWINFIRST = 0x0380, + + WM_PENWIN_reserved_381 = 0x0381, + + WM_PENWIN_reserved_382 = 0x0382, + + WM_PENWIN_reserved_383 = 0x0383, + + WM_PENWIN_reserved_384 = 0x0384, + + WM_PENWIN_reserved_385 = 0x0385, + + WM_PENWIN_reserved_386 = 0x0386, + + WM_PENWIN_reserved_387 = 0x0387, + + WM_PENWIN_reserved_388 = 0x0388, + + WM_PENWIN_reserved_389 = 0x0389, + + WM_PENWIN_reserved_38a = 0x038A, + + WM_PENWIN_reserved_38b = 0x038B, + + WM_PENWIN_reserved_38c = 0x038C, + + WM_PENWIN_reserved_38d = 0x038D, + + WM_PENWIN_reserved_38e = 0x038E, + + WM_PENWINLAST = 0x038F, + + WM_COALESCE_FIRST = 0x0390, + + WM_COALESCE__reserved_391 = 0x0391, + + WM_COALESCE__reserved_392 = 0x0392, + + WM_COALESCE__reserved_393 = 0x0393, + + WM_COALESCE__reserved_394 = 0x0394, + + WM_COALESCE__reserved_395 = 0x0395, + + WM_COALESCE__reserved_396 = 0x0396, + + WM_COALESCE__reserved_397 = 0x0397, + + WM_COALESCE__reserved_398 = 0x0398, + + WM_COALESCE__reserved_399 = 0x0399, + + WM_COALESCE__reserved_39a = 0x039A, + + WM_COALESCE__reserved_39b = 0x039B, + + WM_COALESCE__reserved_39c = 0x039C, + + WM_COALESCE__reserved_39d = 0x039D, + + WM_COALESCE__reserved_39e = 0x039E, + + WM_COALESCE_LAST = 0x039F, + + WM_MM_RESERVED_FIRST = 0x03A0, + + WM_MM_RESERVED__reserved_3a1 = 0x03A1, + + WM_MM_RESERVED__reserved_3a2 = 0x03A2, + + WM_MM_RESERVED__reserved_3a3 = 0x03A3, + + WM_MM_RESERVED__reserved_3a4 = 0x03A4, + + WM_MM_RESERVED__reserved_3a5 = 0x03A5, + + WM_MM_RESERVED__reserved_3a6 = 0x03A6, + + WM_MM_RESERVED__reserved_3a7 = 0x03A7, + + WM_MM_RESERVED__reserved_3a8 = 0x03A8, + + WM_MM_RESERVED__reserved_3a9 = 0x03A9, + + WM_MM_RESERVED__reserved_3aA = 0x03AA, + + WM_MM_RESERVED__reserved_3ab = 0x03AB, + + WM_MM_RESERVED__reserved_3ac = 0x03AC, + + WM_MM_RESERVED__reserved_3ad = 0x03AD, + + WM_MM_RESERVED__reserved_3ae = 0x03AE, + + WM_MM_RESERVED__reserved_3af = 0x03AF, + + WM_MM_RESERVED__reserved_3b0 = 0x03B0, + + WM_MM_RESERVED__reserved_3b1 = 0x03B1, + + WM_MM_RESERVED__reserved_3b2 = 0x03B2, + + WM_MM_RESERVED__reserved_3b3 = 0x03B3, + + WM_MM_RESERVED__reserved_3b4 = 0x03B4, + + WM_MM_RESERVED__reserved_3b5 = 0x03B5, + + WM_MM_RESERVED__reserved_3b6 = 0x03B6, + + WM_MM_RESERVED__reserved_3b7 = 0x03B7, + + WM_MM_RESERVED__reserved_3b8 = 0x03B8, + + WM_MM_RESERVED__reserved_3b9 = 0x03B9, + + WM_MM_RESERVED__reserved_3ba = 0x03BA, + + WM_MM_RESERVED__reserved_3bb = 0x03BB, + + WM_MM_RESERVED__reserved_3bc = 0x03BC, + + WM_MM_RESERVED__reserved_3bd = 0x03BD, + + WM_MM_RESERVED__reserved_3be = 0x03BE, + + WM_MM_RESERVED__reserved_3bf = 0x03BF, + + WM_MM_RESERVED__reserved_3c0 = 0x03C0, + + WM_MM_RESERVED__reserved_3c1 = 0x03C1, + + WM_MM_RESERVED__reserved_3c2 = 0x03C2, + + WM_MM_RESERVED__reserved_3c3 = 0x03C3, + + WM_MM_RESERVED__reserved_3c4 = 0x03C4, + + WM_MM_RESERVED__reserved_3c5 = 0x03C5, + + WM_MM_RESERVED__reserved_3c6 = 0x03C6, + + WM_MM_RESERVED__reserved_3c7 = 0x03C7, + + WM_MM_RESERVED__reserved_3c8 = 0x03C8, + + WM_MM_RESERVED__reserved_3c9 = 0x03C9, + + WM_MM_RESERVED__reserved_3ca = 0x03CA, + + WM_MM_RESERVED__reserved_3cb = 0x03CB, + + WM_MM_RESERVED__reserved_3cc = 0x03CC, + + WM_MM_RESERVED__reserved_3cd = 0x03CD, + + WM_MM_RESERVED__reserved_3ce = 0x03CE, + + WM_MM_RESERVED__reserved_3cf = 0x03CF, + + WM_MM_RESERVED__reserved_3d0 = 0x03D0, + + WM_MM_RESERVED__reserved_3d1 = 0x03D1, + + WM_MM_RESERVED__reserved_3d2 = 0x03D2, + + WM_MM_RESERVED__reserved_3d3 = 0x03D3, + + WM_MM_RESERVED__reserved_3d4 = 0x03D4, + + WM_MM_RESERVED__reserved_3d5 = 0x03D5, + + WM_MM_RESERVED__reserved_3d6 = 0x03D6, + + WM_MM_RESERVED__reserved_3d7 = 0x03D7, + + WM_MM_RESERVED__reserved_3d8 = 0x03D8, + + WM_MM_RESERVED__reserved_3d9 = 0x03D9, + + WM_MM_RESERVED__reserved_3da = 0x03DA, + + WM_MM_RESERVED__reserved_3db = 0x03DB, + + WM_MM_RESERVED__reserved_3dc = 0x03DC, + + WM_MM_RESERVED__reserved_3dd = 0x03DD, + + WM_MM_RESERVED__reserved_3de = 0x03DE, + + WM_MM_RESERVED_LAST = 0x03DF, + + WM_INTERNAL_DDE_FIRST = 0x03E0, + + WM_INTERNAL_DDE__reserved_3e1 = 0x03E1, + + WM_INTERNAL_DDE__reserved_3e2 = 0x03E2, + + WM_INTERNAL_DDE__reserved_3e3 = 0x03E3, + + WM_INTERNAL_DDE__reserved_3e4 = 0x03E4, + + WM_INTERNAL_DDE__reserved_3e5 = 0x03E5, + + WM_INTERNAL_DDE__reserved_3e6 = 0x03E6, + + WM_INTERNAL_DDE__reserved_3e7 = 0x03E7, + + WM_INTERNAL_DDE__reserved_3e8 = 0x03E8, + + WM_INTERNAL_DDE__reserved_3e9 = 0x03E9, + + WM_INTERNAL_DDE__reserved_3ea = 0x03EA, + + WM_INTERNAL_DDE__reserved_3eb = 0x03EB, + + WM_INTERNAL_DDE__reserved_3ec = 0x03EC, + + WM_INTERNAL_DDE__reserved_3ed = 0x03ED, + + WM_INTERNAL_DDE__reserved_3ee = 0x03EE, + + WM_INTERNAL_DDE_LAST = 0x03EF, + + WM_CBT_RESERVED_FIRST = 0x03F0, + + WM_CBT_RESERVED__reserved_3f1 = 0x03F1, + + WM_CBT_RESERVED__reserved_3f2 = 0x03F2, + + WM_CBT_RESERVED__reserved_3f3 = 0x03F3, + + WM_CBT_RESERVED__reserved_3f4 = 0x03F4, + + WM_CBT_RESERVED__reserved_3f5 = 0x03F5, + + WM_CBT_RESERVED__reserved_3f6 = 0x03F6, + + WM_CBT_RESERVED__reserved_3f7 = 0x03F7, + + WM_CBT_RESERVED__reserved_3f8 = 0x03F8, + + WM_CBT_RESERVED__reserved_3f9 = 0x03F9, + + WM_CBT_RESERVED__reserved_3fa = 0x03FA, + + WM_CBT_RESERVED__reserved_3fb = 0x03FB, + + WM_CBT_RESERVED__reserved_3fc = 0x03FC, + + WM_CBT_RESERVED__reserved_3fd = 0x03FD, + + WM_CBT_RESERVED__reserved_3fe = 0x03FE, + + WM_CBT_RESERVED_LAST = 0x03FF, + + /// + /// 用于定义专用窗口类使用的专用消息,通常为 WM_USER+x 格式,其中 x 是整数值。 + /// + WM_USER = 0x0400, + + /// + /// 用于定义专用消息,通常为 WM_APP+x 形式的专用消息,其中 x 是整数值。 + /// + WM_APP = 0x8000 + } +} diff --git a/GetStoreAppPackage/Package.appxmanifest b/GetStoreAppPackage/Package.appxmanifest index 998835fe2..1ad05e8aa 100644 --- a/GetStoreAppPackage/Package.appxmanifest +++ b/GetStoreAppPackage/Package.appxmanifest @@ -13,7 +13,7 @@ + Version="5.0.1001.0" /> ms-resource:PackageDisplayName diff --git a/GetStoreAppShellExtension/Properties/AssemblyInfo.cs b/GetStoreAppShellExtension/Properties/AssemblyInfo.cs index 7b1db29c1..765b7e23f 100644 --- a/GetStoreAppShellExtension/Properties/AssemblyInfo.cs +++ b/GetStoreAppShellExtension/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ [assembly: AssemblyCompany("高怡飞")] [assembly: AssemblyCopyright("Copyright ©2022-2024 高怡飞, All Rights Reserved.")] [assembly: AssemblyDescription("获取商店应用 右键菜单扩展")] -[assembly: AssemblyFileVersion("5.0.929.0")] -[assembly: AssemblyInformationalVersion("5.0.929.0")] +[assembly: AssemblyFileVersion("5.0.1001.0")] +[assembly: AssemblyInformationalVersion("5.0.1001.0")] [assembly: AssemblyProduct("获取商店应用 右键菜单扩展")] [assembly: AssemblyTitle("获取商店应用 右键菜单扩展")] -[assembly: AssemblyVersion("5.0.929.0")] +[assembly: AssemblyVersion("5.0.1001.0")] // 应用程序默认区域性的资源控制器设置 [assembly: NeutralResourcesLanguage("en-us")] diff --git a/GetStoreAppShellExtension/WindowsAPI/ComTypes/IEnumExplorerCommand.cs b/GetStoreAppShellExtension/WindowsAPI/ComTypes/IEnumExplorerCommand.cs index da3d3460e..9a5d0e58b 100644 --- a/GetStoreAppShellExtension/WindowsAPI/ComTypes/IEnumExplorerCommand.cs +++ b/GetStoreAppShellExtension/WindowsAPI/ComTypes/IEnumExplorerCommand.cs @@ -18,7 +18,7 @@ public partial interface IEnumExplorerCommand /// 此方法返回时,包含指向实际检索的元素数的指针。 如果不需要此信息,则此指针可以为 NULL 。 /// 如果该方法成功,则返回 S_OK。 否则,将返回 HRESULT 错误代码。 [PreserveSig] - int Next(uint celt, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0), Out] IExplorerCommand[] pUICommand, out uint pceltFetched); + int Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] IExplorerCommand[] pUICommand, out uint pceltFetched); /// /// 目前尚未实现。 diff --git a/GetStoreAppWebView/GetStoreAppWebView.res b/GetStoreAppWebView/GetStoreAppWebView.res index 3ed010d294e08bd734f76d7fd61e74d5ebeca3d6..e44eb1422143834d6fd4a93ea6b7dac8a6e5592a 100644 GIT binary patch delta 150 zcmX?ePwK`!sfHHD7N!>F7M2#)Eo^6IGR~NOb|#xVka|0l&6M*cGXn!F0|Ud$>Dsf{ zWEp=<_ngJ1%y?yb?kqNOW;+J%>Fu-Fba@RK41my(K@UhWOy4_;Z85VMP%e2kn<}c@ a_KCCEvKg7JfRg{`uxX-68qQ^t76Jg&Nhlxy delta 138 zcmca{PwLD)sfHHD7N!>F7M2#)Eo^6IGWJYAJCjWwNWGoOX3DvcnSp_ofq`M+bnRJe zvW#!0d(L80W;`)HcNUvCvke2+^!8b7x}25_Mhun=dJG2B56)s+%xnS_PoK@EiV)vE Yb2eKxBeMlif_*NVCX$5hTsCPT0O@un761SM diff --git a/GetStoreAppWebView/UI/Backdrop/MicaBrush.cs b/GetStoreAppWebView/UI/Backdrop/MicaBrush.cs index f882f6ab5..6dd968e1d 100644 --- a/GetStoreAppWebView/UI/Backdrop/MicaBrush.cs +++ b/GetStoreAppWebView/UI/Backdrop/MicaBrush.cs @@ -170,7 +170,6 @@ private void UpdateBrush() } CompositionBrush newBrush = useSolidColorFallback ? compositor.CreateColorBrush(fallbackColor) : BuildMicaEffectBrush(compositor, tintColor, tintOpacity, luminosityOpacity); - CompositionBrush oldBrush = CompositionBrush; if (oldBrush is null || CompositionBrush.Comment is "Crossfade") diff --git a/GetStoreAppWidget/GetStoreAppWidget.csproj b/GetStoreAppWidget/GetStoreAppWidget.csproj index edacc7fb0..adbb709fc 100644 --- a/GetStoreAppWidget/GetStoreAppWidget.csproj +++ b/GetStoreAppWidget/GetStoreAppWidget.csproj @@ -50,7 +50,7 @@ - + diff --git a/GetStoreAppWidget/GetStoreAppWidget.res b/GetStoreAppWidget/GetStoreAppWidget.res index dad9a097cb9fad035e95e76ef77971980991e271..be8cc0e80b01270c3c018570bccd3e1ddad6f12b 100644 GIT binary patch delta 185 zcmaEHp7YCj&W0AoElg8_7;~mi4Puf9Qd@(VOx0g9Gcd3+FfhDiwg-|RzyidKU>1Tn zGhHy4Nm+UY6G+Mc4ow)6fNTZ^I|lCQ{=rPTyoO*YLk2yN@buPTrrFG9Ksn_QCRJ3q e?SUao?u?99(-T9Pgr~0wWs*RXKO4#1Tn zFkLX1Nm+Uh6G+Mc4ow)6fNTZ^8wRfF{=rPToR$nm43-Rf3Lzy&@ByNT>Necl0^Zy=( diff --git a/GetStoreAppWidget/Properties/AssemblyInfo.cs b/GetStoreAppWidget/Properties/AssemblyInfo.cs index 4f48ffaa3..dab3f11ae 100644 --- a/GetStoreAppWidget/Properties/AssemblyInfo.cs +++ b/GetStoreAppWidget/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ [assembly: AssemblyCompany("高怡飞")] [assembly: AssemblyCopyright("Copyright ©2022-2024 高怡飞, All Rights Reserved.")] [assembly: AssemblyDescription("获取商店应用 小组件")] -[assembly: AssemblyFileVersion("5.0.929.0")] -[assembly: AssemblyInformationalVersion("5.0.929.0")] +[assembly: AssemblyFileVersion("5.0.1001.0")] +[assembly: AssemblyInformationalVersion("5.0.1001.0")] [assembly: AssemblyProduct("获取商店应用 小组件")] [assembly: AssemblyTitle("获取商店应用 小组件")] -[assembly: AssemblyVersion("5.0.929.0")] +[assembly: AssemblyVersion("5.0.1001.0")] // 应用程序默认区域性的资源控制器设置 [assembly: NeutralResourcesLanguage("en-us")] diff --git a/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs b/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs index 8800d0ffe..5c945ed3d 100644 --- a/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs +++ b/Microsoft.Management.Deployment.Projection/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ [assembly: AssemblyCompany("高怡飞")] [assembly: AssemblyCopyright("©Copyright ©2022-2024 高怡飞, All Rights Reserved.")] [assembly: AssemblyDescription("获取商店应用 WinGet WinRT 扩展")] -[assembly: AssemblyFileVersion("5.0.929.0")] -[assembly: AssemblyInformationalVersion("5.0.929.0")] +[assembly: AssemblyFileVersion("5.0.1001.0")] +[assembly: AssemblyInformationalVersion("5.0.1001.0")] [assembly: AssemblyProduct("获取商店应用 WinGet WinRT 扩展")] [assembly: AssemblyTitle("获取商店应用 WinGet WinRT 扩展")] -[assembly: AssemblyVersion("5.0.929.0")] +[assembly: AssemblyVersion("5.0.1001.0")] // 应用程序默认区域性的资源控制器设置 [assembly: NeutralResourcesLanguage("en-us")] diff --git a/README.md b/README.md index c401ecdf3..3883763b7 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ > * [Microsoft.Windows.SDK.BuildTools](https://aka.ms/WinSDKProjectURL)  > * [Microsoft.WindowsAppSDK](https://github.com/microsoft/windowsappsdk)  > * [Microsoft.WindowsPackageManager.ComInterop](https://github.com/microsoft/winget-cli)  +> * [Mile.Xaml](https://github.com/ProjectMile/Mile.Xaml)  [学习过程中参考或使用的代码](https://github.com/Gaoyifei1011/GetStoreApp/blob/main/Description/StudyReferenceCode.md)  [辅助工具](https://github.com/Gaoyifei1011/GetStoreApp/blob/main/Description/AuxiliaryTools.md)