[FancyZones] Move FancyZones out of the runner process (#11818)

* rename dll -> FancyZonesModuleInterface (#11488)

* [FancyZones] Rename "fancyzones/tests" -> "fancyzones/FancyZonesTests" (#11492)

* [FancyZones] Rename "fancyzones/lib" -> "fancyzones/FancyZonesLib" (#11489)

* [FancyZones] New FancyZones project. (#11544)

* [FancyZones] Allow single instance of "PowerToys.FancyZones.exe" (#11558)

* [FancyZones] Updated bug reports (#11571)

* [FancyZones] Updated installer (#11572)

* [FancyZones] Update string resources (#11596)

* [FancyZones] Terminate FancyZones with runner (#11696)

* [FancyZones] Drop support for the module interface API to save settings (#11661)

* Settings telemetry for FancyZones (#11766)

* commented out test

* enable dpi awareness for the process
This commit is contained in:
Seraphima Zykova 2021-06-23 15:48:54 +03:00 committed by GitHub
parent bdf85989fc
commit c93eb92cd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
110 changed files with 5753 additions and 5293 deletions

View file

@ -39,14 +39,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interface", "interface", "{
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fancyzones", "fancyzones", "{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesLib", "src\modules\fancyzones\lib\FancyZonesLib.vcxproj", "{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesLib", "src\modules\fancyzones\FancyZonesLib\FancyZonesLib.vcxproj", "{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fancyzones", "src\modules\fancyzones\dll\FancyZonesModule.vcxproj", "{48804216-2A0E-4168-A6D8-9CD068D14227}"
ProjectSection(ProjectDependencies) = postProject
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {5CCC8468-DEC8-4D36-99D4-5C891BEBD481}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-FancyZones", "src\modules\fancyzones\tests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-FancyZones", "src\modules\fancyzones\FancyZonesTests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
ProjectSection(ProjectDependencies) = postProject
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}
EndProjectSection
@ -345,6 +340,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuideModuleInterfac
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShortcutGuide", "src\modules\ShortcutGuide\ShortcutGuide\ShortcutGuide.vcxproj", "{2EDB3EB4-FA92-4BFF-B2D8-566584837231}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesModuleInterface", "src\modules\fancyzones\FancyZonesModuleInterface\FancyZonesModuleInterface.vcxproj", "{48804216-2A0E-4168-A6D8-9CD068D14227}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZones", "src\modules\fancyzones\FancyZones\FancyZones.vcxproj", "{390AE700-B55F-4202-91EA-A822EB75B9BD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.Update", "src\Update\PowerToys.Update.vcxproj", "{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.WindowsSettings", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\Microsoft.PowerToys.Run.Plugin.WindowsSettings.csproj", "{5043CECE-E6A7-4867-9CBE-02D27D83747A}"
@ -363,10 +362,6 @@ Global
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.Build.0 = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.Build.0 = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.Build.0 = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.Build.0 = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.ActiveCfg = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|x64.Build.0 = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.ActiveCfg = Release|x64
@ -701,6 +696,14 @@ Global
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Debug|x64.Build.0 = Debug|x64
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.ActiveCfg = Release|x64
{2EDB3EB4-FA92-4BFF-B2D8-566584837231}.Release|x64.Build.0 = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|x64.Build.0 = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.Build.0 = Release|x64
{390AE700-B55F-4202-91EA-A822EB75B9BD}.Debug|x64.ActiveCfg = Debug|x64
{390AE700-B55F-4202-91EA-A822EB75B9BD}.Debug|x64.Build.0 = Debug|x64
{390AE700-B55F-4202-91EA-A822EB75B9BD}.Release|x64.ActiveCfg = Release|x64
{390AE700-B55F-4202-91EA-A822EB75B9BD}.Release|x64.Build.0 = Release|x64
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Debug|x64.ActiveCfg = Debug|x64
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Debug|x64.Build.0 = Debug|x64
{44CE9AE1-4390-42C5-BACC-0FD6B40AA203}.Release|x64.ActiveCfg = Release|x64
@ -717,7 +720,6 @@ Global
{3BB8493E-D18E-4485-A320-CB40F90F55AE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{48804216-2A0E-4168-A6D8-9CD068D14227} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{1A066C63-64B3-45F8-92FE-664E1CCE8077} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
@ -814,6 +816,8 @@ Global
{106CBECA-0701-4FC3-838C-9DF816A19AE2} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
{2EDB3EB4-FA92-4BFF-B2D8-566584837231} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
{48804216-2A0E-4168-A6D8-9CD068D14227} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{390AE700-B55F-4202-91EA-A822EB75B9BD} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{5043CECE-E6A7-4867-9CBE-02D27D83747A} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution

View file

@ -418,11 +418,12 @@
<!-- FancyZone -->
<DirectoryRef Id="FancyZonesInstallFolder" FileSource="$(var.BinX64Dir)modules\">
<Component Id="Module_FancyZones" Guid="C6B5272E-6ED4-4B80-B0E7-2FF0355D8CF4" Win64="yes">
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\fancyzones.dll" KeyPath="yes" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\FancyZonesModuleInterface.dll" KeyPath="yes" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\FancyZonesEditor.dll" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\FancyZonesEditor.runtimeconfig.json" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\FancyZonesEditor.deps.json" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\FancyZonesEditor.exe" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\PowerToys.FancyZones.exe" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\ControlzEx.dll" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\Microsoft.Xaml.Behaviors.dll" />
<File Source="$(var.BinX64Dir)modules\$(var.FancyZonesProjectName)\ModernWpf.dll" />

View file

@ -26,6 +26,8 @@ namespace CommonSharedConstants
const wchar_t SHORTCUT_GUIDE_EXIT_EVENT[] = L"Local\\ShortcutGuide-ExitEvent-35697cdd-a3d2-47d6-a246-34efcc73eac0";
const wchar_t FANCY_ZONES_EDITOR_TOGGLE_EVENT[] = L"Local\\FancyZones-ToggleEditorEvent-1e174338-06a3-472b-874d-073b21c62f14";
// Max DWORD for key code to disable keys.
const DWORD VK_DISABLED = 0x100;
}

View file

@ -1,8 +1,12 @@
#pragma once
#include <Windows.h>
#include <DbgHelp.h>
#include <signal.h>
#include <sstream>
#include <stdio.h>
#include "winapi_error.h"
#include "../logger/logger.h"
static IMAGEHLP_SYMBOL64* pSymbol = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + MAX_PATH * sizeof(TCHAR));

View file

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Project configurations -->
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<!-- Props that should be disabled while building on CI server -->
<ItemDefinitionGroup Condition="'$(CIBuild)'!='true'">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for all configurations -->
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<WarningLevel>Level3</WarningLevel>
<ConformanceMode>false</ConformanceMode>
<TreatWarningAsError>true</TreatWarningAsError>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for Debug/Release configurations -->
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>MaxSpeed</Optimization>
<SDLCheck>false</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<!-- Global props -->
<PropertyGroup Label="Globals" Condition="'$(OverrideWindowsTargetPlatformVersion)'!='True'">
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{ff1d7936-842a-4bbb-8bea-e9fe796de700}</ProjectGuid>
<RootNamespace>FancyZones</RootNamespace>
</PropertyGroup>
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>Spectre</SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetName>PowerToys.$(MSBuildProjectName)</TargetName>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>PowerToys.$(MSBuildProjectName)</TargetName>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>./../;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src\common;$(SolutionDir)src\;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>shcore.lib;shlwapi.lib;DbgHelp.lib;uxtheme.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>./../;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src\common;$(SolutionDir)src\;./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>shcore.lib;shlwapi.lib;DbgHelp.lib;uxtheme.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="FancyZonesApp.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="FancyZonesApp.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\FancyZonesLib\Generated Files\fancyzones.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\FancyZonesLib\FancyZonesLib.vcxproj">
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.210204.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesApp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesApp.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\FancyZonesLib\Generated Files\fancyzones.rc" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,183 @@
#include "pch.h"
#include "FancyZonesApp.h"
#include <common/display/dpi_aware.h>
#include <common/utils/logger_helper.h>
#include <common/utils/resources.h>
#include <common/utils/UnhandledExceptionHandler_x64.h>
#include <FancyZonesLib/Generated Files/resource.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
#include <FancyZonesLib/trace.h>
FancyZonesApp::FancyZonesApp(const std::wstring& appName, const std::wstring& appKey)
{
DPIAware::EnableDPIAwarenessForThisProcess();
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), appName.c_str(), appKey.c_str());
FancyZonesDataInstance().LoadFancyZonesData();
InitializeWinhookEventIds();
m_app = MakeFancyZones(reinterpret_cast<HINSTANCE>(&__ImageBase), m_settings, std::bind(&FancyZonesApp::DisableModule, this));
InitHooks();
s_instance = this;
}
FancyZonesApp::~FancyZonesApp()
{
if (m_app)
{
m_app->Destroy();
m_app = nullptr;
if (s_llKeyboardHook)
{
if (UnhookWindowsHookEx(s_llKeyboardHook))
{
s_llKeyboardHook = nullptr;
}
}
m_staticWinEventHooks.erase(std::remove_if(begin(m_staticWinEventHooks),
end(m_staticWinEventHooks),
[](const HWINEVENTHOOK hook) {
return UnhookWinEvent(hook);
}),
end(m_staticWinEventHooks));
if (m_objectLocationWinEventHook)
{
if (UnhookWinEvent(m_objectLocationWinEventHook))
{
m_objectLocationWinEventHook = nullptr;
}
}
}
}
void FancyZonesApp::Run()
{
if (m_app)
{
m_app->Run();
}
}
void FancyZonesApp::InitHooks()
{
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
const bool hook_disabled = IsDebuggerPresent();
#else
const bool hook_disabled = false;
#endif
if (!hook_disabled)
{
s_llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), NULL);
if (!s_llKeyboardHook)
{
DWORD errorCode = GetLastError();
show_last_error_message(L"SetWindowsHookEx", errorCode, GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str());
auto errorMessage = get_last_error_message(errorCode);
Trace::FancyZones::Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"enable.SetWindowsHookEx");
}
}
std::array<DWORD, 6> events_to_subscribe = {
EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND,
EVENT_OBJECT_NAMECHANGE,
EVENT_OBJECT_UNCLOAKED,
EVENT_OBJECT_SHOW,
EVENT_OBJECT_CREATE
};
for (const auto event : events_to_subscribe)
{
auto hook = SetWinEventHook(event, event, nullptr, WinHookProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
if (hook)
{
m_staticWinEventHooks.emplace_back(hook);
}
else
{
MessageBoxW(NULL,
GET_RESOURCE_STRING(IDS_WINDOW_EVENT_LISTENER_ERROR).c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK | MB_ICONERROR);
}
}
}
void FancyZonesApp::DisableModule() noexcept
{
PostQuitMessage(0);
}
void FancyZonesApp::HandleWinHookEvent(WinHookEvent* data) noexcept
{
auto fzCallback = m_app.as<IFancyZonesCallback>();
switch (data->event)
{
case EVENT_SYSTEM_MOVESIZESTART:
{
fzCallback->HandleWinHookEvent(data);
if (!m_objectLocationWinEventHook)
{
m_objectLocationWinEventHook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE,
EVENT_OBJECT_LOCATIONCHANGE,
nullptr,
WinHookProc,
0,
0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
}
}
break;
case EVENT_SYSTEM_MOVESIZEEND:
{
if (UnhookWinEvent(m_objectLocationWinEventHook))
{
m_objectLocationWinEventHook = nullptr;
}
fzCallback->HandleWinHookEvent(data);
}
break;
case EVENT_OBJECT_LOCATIONCHANGE:
{
fzCallback->HandleWinHookEvent(data);
}
break;
case EVENT_OBJECT_NAMECHANGE:
{
// The accessibility name of the desktop window changes whenever the user
// switches virtual desktops.
if (data->hwnd == GetDesktopWindow())
{
m_app.as<IFancyZonesCallback>()->VirtualDesktopChanged();
}
}
break;
case EVENT_OBJECT_UNCLOAKED:
case EVENT_OBJECT_SHOW:
case EVENT_OBJECT_CREATE:
{
fzCallback->HandleWinHookEvent(data);
}
break;
default:
break;
}
}
intptr_t FancyZonesApp::HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept
{
return m_app.as<IFancyZonesCallback>()->OnKeyDown(data->lParam);
}

View file

@ -0,0 +1,63 @@
#pragma once
#include <common/hooks/LowlevelKeyboardEvent.h>
#include <FancyZonesLib/FancyZones.h>
class FancyZonesApp
{
public:
FancyZonesApp(const std::wstring& appName, const std::wstring& appKey);
~FancyZonesApp();
void Run();
private:
static inline FancyZonesApp* s_instance = nullptr;
static inline HHOOK s_llKeyboardHook = nullptr;
winrt::com_ptr<IFancyZones> m_app;
HWINEVENTHOOK m_objectLocationWinEventHook = nullptr;
std::vector<HWINEVENTHOOK> m_staticWinEventHooks;
winrt::com_ptr<IFancyZonesSettings> m_settings;
void DisableModule() noexcept;
void InitHooks();
void HandleWinHookEvent(WinHookEvent* data) noexcept;
intptr_t HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept;
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LowlevelKeyboardEvent event;
if (nCode == HC_ACTION && wParam == WM_KEYDOWN)
{
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
event.wParam = wParam;
if (s_instance)
{
if (s_instance->HandleKeyboardHookEvent(&event) == 1)
{
return 1;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static void CALLBACK WinHookProc(HWINEVENTHOOK winEventHook,
DWORD event,
HWND window,
LONG object,
LONG child,
DWORD eventThread,
DWORD eventTime)
{
WinHookEvent data{ event, window, object, child, eventThread, eventTime };
if (s_instance)
{
s_instance->HandleWinHookEvent(&data);
}
}
};

View file

@ -0,0 +1,73 @@
#include "pch.h"
#include <common/utils/ProcessWaiter.h>
#include <common/utils/window.h>
#include <common/utils/UnhandledExceptionHandler_x64.h>
#include <FancyZonesLib/trace.h>
#include <FancyZonesLib/Generated Files/resource.h>
#include <common/utils/logger_helper.h>
#include <common/hooks/LowlevelKeyboardEvent.h>
#include <common/utils/resources.h>
#include <FancyZonesLib/FancyZones.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
#include <FancyZonesApp.h>
// Non-localizable
const std::wstring moduleName = L"FancyZones";
const std::wstring internalPath = L"";
const std::wstring instanceMutexName = L"Local\\PowerToys_FancyZones_InstanceMutex";
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ int nCmdShow)
{
winrt::init_apartment();
InitUnhandledExceptionHandler_x64();
LoggerHelpers::init_logger(moduleName, internalPath, LogSettings::fancyZonesLoggerName);
auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str());
if (mutex == nullptr)
{
Logger::error(L"Failed to create mutex. {}", get_last_error_or_default(GetLastError()));
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
Logger::warn(L"FancyZones instance is already running");
return 0;
}
std::wstring pid = std::wstring(lpCmdLine);
if (!pid.empty())
{
auto mainThreadId = GetCurrentThreadId();
ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) {
if (err != ERROR_SUCCESS)
{
Logger::error(L"Failed to wait for parent process exit. {}", get_last_error_or_default(err));
}
else
{
Logger::trace(L"PowerToys runner exited.");
}
Logger::trace(L"Exiting FancyZones");
PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);
});
}
Trace::RegisterProvider();
FancyZonesApp app(GET_RESOURCE_STRING(IDS_FANCYZONES), NonLocalizable::FancyZonesStr);
app.Run();
run_message_loop();
Trace::UnregisterProvider();
return 0;
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" />
</packages>

View file

@ -0,0 +1 @@
#include "pch.h"

View file

@ -0,0 +1,10 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ProjectTelemetry.h>
#include <shlwapi.h>
#include <stdexcept>
#include <winrt/base.h>
#include <filesystem>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/logger/logger.h>

View file

@ -7,7 +7,7 @@
#include "CallTracer.h"
#include <common/utils/json.h>
#include <fancyzones/lib/util.h>
#include <FancyZonesLib/util.h>
#include <shlwapi.h>
#include <filesystem>
@ -22,9 +22,9 @@
// Non-localizable strings
namespace NonLocalizable
{
const wchar_t FancyZonesStr[] = L"FancyZones";
const wchar_t NullStr[] = L"null";
const wchar_t FancyZonesSettingsFile[] = L"settings.json";
const wchar_t FancyZonesDataFile[] = L"zones-settings.json";
const wchar_t FancyZonesAppZoneHistoryFile[] = L"app-zone-history.json";
const wchar_t FancyZonesEditorParametersFile[] = L"editor-parameters.json";
@ -149,6 +149,7 @@ FancyZonesData::FancyZonesData()
{
std::wstring saveFolderPath = PTSettingsHelper::get_module_save_folder_location(NonLocalizable::FancyZonesStr);
settingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesSettingsFile);
zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesDataFile);
appZoneHistoryFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesAppZoneHistoryFile);
editorParametersFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesEditorParametersFile);

View file

@ -11,7 +11,13 @@
#include <optional>
#include <vector>
#include <winnt.h>
#include <lib/JsonHelpers.h>
#include <FancyZonesLib/JsonHelpers.h>
// Non-localizable strings
namespace NonLocalizable
{
const wchar_t FancyZonesStr[] = L"FancyZones";
}
namespace FancyZonesDataTypes
{
@ -59,6 +65,11 @@ public:
return zonesSettingsFileName;
}
inline const std::wstring& GetSettingsFileName() const
{
return settingsFileName;
}
bool AddDevice(const std::wstring& deviceId);
void CloneDeviceInfo(const std::wstring& source, const std::wstring& destination);
void UpdatePrimaryDesktopData(const std::wstring& desktopId);
@ -130,6 +141,7 @@ private:
// Maps zoneset UUID with quick access keys
JSONHelpers::TLayoutQuickKeysMap quickKeysMap{};
std::wstring settingsFileName;
std::wstring zonesSettingsFileName;
std::wstring appZoneHistoryFileName;
std::wstring editorParametersFileName;

View file

@ -1,114 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h fancyzones.base.rc fancyzones.rc" />
</Target>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>lib</RootNamespace>
<ProjectName>FancyZonesLib</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CallTracer.h" />
<ClInclude Include="FancyZones.h" />
<ClInclude Include="FancyZonesDataTypes.h" />
<ClInclude Include="FancyZonesWinHookEventIDs.h" />
<ClInclude Include="FileWatcher.h" />
<ClInclude Include="GenericKeyHook.h" />
<ClInclude Include="FancyZonesData.h" />
<ClInclude Include="JsonHelpers.h" />
<ClInclude Include="KeyState.h" />
<ClInclude Include="MonitorWorkAreaHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Generated Files/resource.h" />
<None Include="resource.base.h" />
<ClInclude Include="SecondaryMouseButtonsHook.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="trace.h" />
<ClInclude Include="util.h" />
<ClInclude Include="VirtualDesktopUtils.h" />
<ClInclude Include="WindowMoveHandler.h" />
<ClInclude Include="Zone.h" />
<ClInclude Include="ZoneSet.h" />
<ClInclude Include="ZoneWindow.h" />
<ClInclude Include="ZoneWindowDrawing.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CallTracer.cpp" />
<ClCompile Include="FancyZones.cpp" />
<ClCompile Include="FancyZonesDataTypes.cpp" />
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
<ClCompile Include="FancyZonesData.cpp" />
<ClCompile Include="FileWatcher.cpp" />
<ClCompile Include="JsonHelpers.cpp" />
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
<ClCompile Include="OnThreadExecutor.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
<ClCompile Include="Settings.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="util.cpp" />
<ClCompile Include="VirtualDesktopUtils.cpp" />
<ClCompile Include="WindowMoveHandler.cpp" />
<ClCompile Include="Zone.cpp" />
<ClCompile Include="ZoneSet.cpp" />
<ClCompile Include="ZoneWindow.cpp" />
<ClCompile Include="ZoneWindowDrawing.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="fancyzones.base.rc" />
<ProjectReference Include="..\..\..\common\notifications\notifications.vcxproj">
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
</ProjectReference>
<ResourceCompile Include="Generated Files/fancyzones.rc" />
<None Include="packages.config" />
<None Include="Resources.resx" />
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h fancyzones.base.rc fancyzones.rc" />
</Target>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>FancyZonesLib</RootNamespace>
<ProjectName>FancyZonesLib</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CallTracer.h" />
<ClInclude Include="FancyZones.h" />
<ClInclude Include="FancyZonesDataTypes.h" />
<ClInclude Include="FancyZonesWinHookEventIDs.h" />
<ClInclude Include="FileWatcher.h" />
<ClInclude Include="GenericKeyHook.h" />
<ClInclude Include="FancyZonesData.h" />
<ClInclude Include="JsonHelpers.h" />
<ClInclude Include="KeyState.h" />
<ClInclude Include="MonitorWorkAreaHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Generated Files/resource.h" />
<None Include="resource.base.h" />
<ClInclude Include="SecondaryMouseButtonsHook.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="trace.h" />
<ClInclude Include="util.h" />
<ClInclude Include="VirtualDesktopUtils.h" />
<ClInclude Include="WindowMoveHandler.h" />
<ClInclude Include="Zone.h" />
<ClInclude Include="ZoneSet.h" />
<ClInclude Include="ZoneWindow.h" />
<ClInclude Include="ZoneWindowDrawing.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CallTracer.cpp" />
<ClCompile Include="FancyZones.cpp" />
<ClCompile Include="FancyZonesDataTypes.cpp" />
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
<ClCompile Include="FancyZonesData.cpp" />
<ClCompile Include="FileWatcher.cpp" />
<ClCompile Include="JsonHelpers.cpp" />
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
<ClCompile Include="OnThreadExecutor.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
<ClCompile Include="Settings.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="util.cpp" />
<ClCompile Include="VirtualDesktopUtils.cpp" />
<ClCompile Include="WindowMoveHandler.cpp" />
<ClCompile Include="Zone.cpp" />
<ClCompile Include="ZoneSet.cpp" />
<ClCompile Include="ZoneWindow.cpp" />
<ClCompile Include="ZoneWindowDrawing.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="fancyzones.base.rc" />
<ProjectReference Include="..\..\..\common\Display\Display.vcxproj">
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\notifications\notifications.vcxproj">
<Project>{1d5be09d-78c0-4fd7-af00-ae7c1af7c525}</Project>
</ProjectReference>
<ResourceCompile Include="Generated Files/fancyzones.rc" />
<None Include="packages.config" />
<None Include="Resources.resx" />
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View file

@ -1,167 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{093625ff-2415-4c2c-842c-0ee7fcb1d203}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Zone.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZones.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Settings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="trace.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VirtualDesktopUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WindowMoveHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesWinHookEventIDs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SecondaryMouseButtonsHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonitorWorkAreaHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GenericKeyHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JsonHelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesDataTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Generated Files/resource.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="KeyState.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneWindowDrawing.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileWatcher.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CallTracer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Zone.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZones.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Settings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="trace.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VirtualDesktopUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WindowMoveHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MonitorWorkAreaHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JsonHelpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesDataTypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindowDrawing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OnThreadExecutor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FileWatcher.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CallTracer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="resource.base.h">
<Filter>Header Files</Filter>
</None>
<None Include="fancyzones.base.rc">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources.resx">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Generated Files/fancyzones.rc">
<Filter>Generated Files</Filter>
</ResourceCompile>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{093625ff-2415-4c2c-842c-0ee7fcb1d203}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Zone.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZones.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Settings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="trace.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VirtualDesktopUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WindowMoveHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesWinHookEventIDs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SecondaryMouseButtonsHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonitorWorkAreaHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GenericKeyHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JsonHelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FancyZonesDataTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Generated Files/resource.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="KeyState.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZoneWindowDrawing.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileWatcher.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CallTracer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Zone.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZones.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Settings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="trace.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VirtualDesktopUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WindowMoveHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MonitorWorkAreaHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JsonHelpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesDataTypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindowDrawing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OnThreadExecutor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FileWatcher.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CallTracer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="resource.base.h">
<Filter>Header Files</Filter>
</None>
<None Include="fancyzones.base.rc">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources.resx">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Generated Files/fancyzones.rc">
<Filter>Generated Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View file

@ -4,9 +4,9 @@
"LanguageSet": "Azure_Languages",
"LocItems": [
{
"SourceFile": "src\\modules\\fancyzones\\lib\\Resources.resx",
"SourceFile": "src\\modules\\fancyzones\\FancyZonesLib\\Resources.resx",
"CopyOption": "LangIDOnName",
"OutputPath": "src\\modules\\fancyzones\\lib"
"OutputPath": "src\\modules\\fancyzones\\FancyZonesLib"
}
]
}

View file

@ -1,297 +1,280 @@
#include "pch.h"
#include <common/SettingsAPI/settings_objects.h>
#include <common/utils/resources.h>
#include "lib/Settings.h"
#include "lib/FancyZones.h"
#include "trace.h"
// Non-Localizable strings
namespace NonLocalizable
{
// FancyZones settings descriptions are localized, but underlying toggle (spinner, color picker) names are not.
const wchar_t ShiftDragID[] = L"fancyzones_shiftDrag";
const wchar_t MouseSwitchID[] = L"fancyzones_mouseSwitch";
const wchar_t OverrideSnapHotKeysID[] = L"fancyzones_overrideSnapHotkeys";
const wchar_t MoveWindowAcrossMonitorsID[] = L"fancyzones_moveWindowAcrossMonitors";
const wchar_t MoveWindowsBasedOnPositionID[] = L"fancyzones_moveWindowsBasedOnPosition";
const wchar_t OverlappingZonesAlgorithmID[] = L"fancyzones_overlappingZonesAlgorithm";
const wchar_t DisplayChangeMoveWindowsID[] = L"fancyzones_displayChange_moveWindows";
const wchar_t ZoneSetChangeMoveWindowsID[] = L"fancyzones_zoneSetChange_moveWindows";
const wchar_t AppLastZoneMoveWindowsID[] = L"fancyzones_appLastZone_moveWindows";
const wchar_t OpenWindowOnActiveMonitorID[] = L"fancyzones_openWindowOnActiveMonitor";
const wchar_t RestoreSizeID[] = L"fancyzones_restoreSize";
const wchar_t QuickLayoutSwitch[] = L"fancyzones_quickLayoutSwitch";
const wchar_t FlashZonesOnQuickSwitch[] = L"fancyzones_flashZonesOnQuickSwitch";
const wchar_t UseCursorPosEditorStartupScreenID[] = L"use_cursorpos_editor_startupscreen";
const wchar_t ShowOnAllMonitorsID[] = L"fancyzones_show_on_all_monitors";
const wchar_t SpanZonesAcrossMonitorsID[] = L"fancyzones_span_zones_across_monitors";
const wchar_t MakeDraggedWindowTransparentID[] = L"fancyzones_makeDraggedWindowTransparent";
const wchar_t ZoneColorID[] = L"fancyzones_zoneColor";
const wchar_t ZoneBorderColorID[] = L"fancyzones_zoneBorderColor";
const wchar_t ZoneHighlightColorID[] = L"fancyzones_zoneHighlightColor";
const wchar_t EditorHotkeyID[] = L"fancyzones_editor_hotkey";
const wchar_t ExcludedAppsID[] = L"fancyzones_excluded_apps";
const wchar_t ZoneHighlightOpacityID[] = L"fancyzones_highlight_opacity";
const wchar_t ToggleEditorActionID[] = L"ToggledFZEditor";
const wchar_t IconKeyID[] = L"pt-fancy-zones";
const wchar_t OverviewURL[] = L"https://aka.ms/PowerToysOverview_FancyZones";
const wchar_t VideoURL[] = L"https://youtu.be/rTtGzZYAXgY";
const wchar_t PowerToysIssuesURL[] = L"https://aka.ms/powerToysReportBug";
}
struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSettings>
{
public:
FancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) :
m_hinstance(hinstance),
m_moduleName(name),
m_moduleKey(key)
{
LoadSettings(name, true);
}
IFACEMETHODIMP_(void)
SetCallback(IFancyZonesCallback* callback) { m_callback = callback; }
IFACEMETHODIMP_(void)
ResetCallback() { m_callback = nullptr; }
IFACEMETHODIMP_(bool)
GetConfig(_Out_ PWSTR buffer, _Out_ int* buffer_sizeg) noexcept;
IFACEMETHODIMP_(void)
SetConfig(PCWSTR config) noexcept;
IFACEMETHODIMP_(void)
CallCustomAction(PCWSTR action) noexcept;
IFACEMETHODIMP_(const Settings*)
GetSettings() const noexcept { return &m_settings; }
private:
void LoadSettings(PCWSTR config, bool fromFile) noexcept;
void SaveSettings() noexcept;
IFancyZonesCallback* m_callback{};
const HINSTANCE m_hinstance;
PCWSTR m_moduleName{};
PCWSTR m_moduleKey{};
Settings m_settings;
struct
{
PCWSTR name;
bool* value;
int resourceId;
} m_configBools[16] = {
{ NonLocalizable::ShiftDragID, &m_settings.shiftDrag, IDS_SETTING_DESCRIPTION_SHIFTDRAG },
{ NonLocalizable::MouseSwitchID, &m_settings.mouseSwitch, IDS_SETTING_DESCRIPTION_MOUSESWITCH },
{ NonLocalizable::OverrideSnapHotKeysID, &m_settings.overrideSnapHotkeys, IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS },
{ NonLocalizable::MoveWindowAcrossMonitorsID, &m_settings.moveWindowAcrossMonitors, IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS },
{ NonLocalizable::MoveWindowsBasedOnPositionID, &m_settings.moveWindowsBasedOnPosition, IDS_SETTING_DESCRIPTION_MOVE_WINDOWS_BASED_ON_POSITION },
{ NonLocalizable::DisplayChangeMoveWindowsID, &m_settings.displayChange_moveWindows, IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS },
{ NonLocalizable::ZoneSetChangeMoveWindowsID, &m_settings.zoneSetChange_moveWindows, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS },
{ NonLocalizable::AppLastZoneMoveWindowsID, &m_settings.appLastZone_moveWindows, IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS },
{ NonLocalizable::OpenWindowOnActiveMonitorID, &m_settings.openWindowOnActiveMonitor, IDS_SETTING_DESCRIPTION_OPEN_WINDOW_ON_ACTIVE_MONITOR },
{ NonLocalizable::RestoreSizeID, &m_settings.restoreSize, IDS_SETTING_DESCRIPTION_RESTORESIZE },
{ NonLocalizable::QuickLayoutSwitch, &m_settings.quickLayoutSwitch, IDS_SETTING_DESCRIPTION_QUICKLAYOUTSWITCH },
{ NonLocalizable::FlashZonesOnQuickSwitch, &m_settings.flashZonesOnQuickSwitch, IDS_SETTING_DESCRIPTION_FLASHZONESONQUICKSWITCH },
{ NonLocalizable::UseCursorPosEditorStartupScreenID, &m_settings.use_cursorpos_editor_startupscreen, IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN },
{ NonLocalizable::ShowOnAllMonitorsID, &m_settings.showZonesOnAllMonitors, IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS },
{ NonLocalizable::SpanZonesAcrossMonitorsID, &m_settings.spanZonesAcrossMonitors, IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS },
{ NonLocalizable::MakeDraggedWindowTransparentID, &m_settings.makeDraggedWindowTransparent, IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT },
};
};
IFACEMETHODIMP_(bool)
FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ int* buffer_size) noexcept
{
PowerToysSettings::Settings settings(m_hinstance, m_moduleName);
// Pass a string literal or a resource id to Settings::set_description().
settings.set_description(IDS_SETTING_DESCRIPTION);
settings.set_icon_key(NonLocalizable::IconKeyID);
settings.set_overview_link(NonLocalizable::OverviewURL);
settings.set_video_link(NonLocalizable::VideoURL);
// Add a custom action property. When using this settings type, the "PowertoyModuleIface::call_custom_action()"
// method should be overridden as well.
settings.add_custom_action(
NonLocalizable::ToggleEditorActionID, // action name.
IDS_SETTING_LAUNCH_EDITOR_LABEL,
IDS_SETTING_LAUNCH_EDITOR_BUTTON,
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION);
settings.add_hotkey(NonLocalizable::EditorHotkeyID, IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, m_settings.editorHotkey);
for (auto const& setting : m_configBools)
{
settings.add_bool_toggle(setting.name, setting.resourceId, *setting.value);
}
settings.add_color_picker(NonLocalizable::ZoneHighlightColorID, IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, m_settings.zoneHighlightColor);
settings.add_color_picker(NonLocalizable::ZoneColorID, IDS_SETTING_DESCRIPTION_ZONECOLOR, m_settings.zoneColor);
settings.add_color_picker(NonLocalizable::ZoneBorderColorID, IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, m_settings.zoneBorderColor);
settings.add_int_spinner(NonLocalizable::ZoneHighlightOpacityID, IDS_SETTINGS_HIGHLIGHT_OPACITY, m_settings.zoneHighlightOpacity, 0, 100, 1);
settings.add_multiline_string(NonLocalizable::ExcludedAppsID, IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, m_settings.excludedApps);
return settings.serialize_to_buffer(buffer, buffer_size);
}
IFACEMETHODIMP_(void)
FancyZonesSettings::SetConfig(PCWSTR serializedPowerToysSettingsJson) noexcept
{
LoadSettings(serializedPowerToysSettingsJson, false /*fromFile*/);
SaveSettings();
if (m_callback)
{
m_callback->SettingsChanged();
}
Trace::SettingsChanged(m_settings);
}
IFACEMETHODIMP_(void)
FancyZonesSettings::CallCustomAction(PCWSTR action) noexcept
{
try
{
// Parse the action values, including name.
PowerToysSettings::CustomActionObject action_object =
PowerToysSettings::CustomActionObject::from_json_string(action);
if (m_callback && action_object.get_name() == NonLocalizable::ToggleEditorActionID)
{
m_callback->ToggleEditor();
}
}
catch (...)
{
// Currently only custom action coming from main PowerToys window is request to launch editor.
// If new custom action is added, error message need to be modified.
std::wstring errorMessage = GET_RESOURCE_STRING(IDS_FANCYZONES_EDITOR_LAUNCH_ERROR) + L" " + NonLocalizable::PowerToysIssuesURL;
MessageBox(NULL,
errorMessage.c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK);
}
}
void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept
{
try
{
PowerToysSettings::PowerToyValues values = fromFile ?
PowerToysSettings::PowerToyValues::load_from_settings_file(m_moduleKey) :
PowerToysSettings::PowerToyValues::from_json_string(config, m_moduleKey);
for (auto const& setting : m_configBools)
{
if (const auto val = values.get_bool_value(setting.name))
{
*setting.value = *val;
}
}
if (auto val = values.get_string_value(NonLocalizable::ZoneColorID))
{
m_settings.zoneColor = std::move(*val);
}
if (auto val = values.get_string_value(NonLocalizable::ZoneBorderColorID))
{
m_settings.zoneBorderColor = std::move(*val);
}
if (auto val = values.get_string_value(NonLocalizable::ZoneHighlightColorID))
{
m_settings.zoneHighlightColor = std::move(*val);
}
if (const auto val = values.get_json(NonLocalizable::EditorHotkeyID))
{
m_settings.editorHotkey = PowerToysSettings::HotkeyObject::from_json(*val);
}
if (auto val = values.get_string_value(NonLocalizable::ExcludedAppsID))
{
m_settings.excludedApps = std::move(*val);
m_settings.excludedAppsArray.clear();
auto excludedUppercase = m_settings.excludedApps;
CharUpperBuffW(excludedUppercase.data(), (DWORD)excludedUppercase.length());
std::wstring_view view(excludedUppercase);
while (view.starts_with('\n') || view.starts_with('\r'))
{
view.remove_prefix(1);
}
while (!view.empty())
{
auto pos = (std::min)(view.find_first_of(L"\r\n"), view.length());
m_settings.excludedAppsArray.emplace_back(view.substr(0, pos));
view.remove_prefix(pos);
while (view.starts_with('\n') || view.starts_with('\r'))
{
view.remove_prefix(1);
}
}
}
if (auto val = values.get_int_value(NonLocalizable::ZoneHighlightOpacityID))
{
m_settings.zoneHighlightOpacity = *val;
}
if (auto val = values.get_int_value(NonLocalizable::OverlappingZonesAlgorithmID))
{
// Avoid undefined behavior
if (*val >= 0 || *val < (int)Settings::OverlappingZonesAlgorithm::EnumElements)
{
m_settings.overlappingZonesAlgorithm = (Settings::OverlappingZonesAlgorithm)*val;
}
}
}
catch (...)
{
// Failure to load settings does not break FancyZones functionality. Display error message and continue with default settings.
MessageBox(NULL,
GET_RESOURCE_STRING(IDS_FANCYZONES_SETTINGS_LOAD_ERROR).c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK);
}
}
void FancyZonesSettings::SaveSettings() noexcept
{
try
{
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
for (auto const& setting : m_configBools)
{
values.add_property(setting.name, *setting.value);
}
values.add_property(NonLocalizable::ZoneColorID, m_settings.zoneColor);
values.add_property(NonLocalizable::ZoneBorderColorID, m_settings.zoneBorderColor);
values.add_property(NonLocalizable::ZoneHighlightColorID, m_settings.zoneHighlightColor);
values.add_property(NonLocalizable::ZoneHighlightOpacityID, m_settings.zoneHighlightOpacity);
values.add_property(NonLocalizable::OverlappingZonesAlgorithmID, (int)m_settings.overlappingZonesAlgorithm);
values.add_property(NonLocalizable::EditorHotkeyID, m_settings.editorHotkey.get_json());
values.add_property(NonLocalizable::ExcludedAppsID, m_settings.excludedApps);
values.save_to_settings_file();
}
catch (...)
{
// Failure to save settings does not break FancyZones functionality. Display error message and continue with currently cached settings.
std::wstring errorMessage = GET_RESOURCE_STRING(IDS_FANCYZONES_SETTINGS_LOAD_ERROR) + L" " + NonLocalizable::PowerToysIssuesURL;
MessageBox(NULL,
errorMessage.c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK);
}
}
winrt::com_ptr<IFancyZonesSettings> MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) noexcept
{
return winrt::make_self<FancyZonesSettings>(hinstance, name, key);
}
#include "pch.h"
#include <common/SettingsAPI/settings_objects.h>
#include <common/utils/resources.h>
#include "FancyZonesLib/Settings.h"
#include "FancyZonesLib/FancyZones.h"
#include "trace.h"
// Non-Localizable strings
namespace NonLocalizable
{
// FancyZones settings descriptions are localized, but underlying toggle (spinner, color picker) names are not.
const wchar_t ShiftDragID[] = L"fancyzones_shiftDrag";
const wchar_t MouseSwitchID[] = L"fancyzones_mouseSwitch";
const wchar_t OverrideSnapHotKeysID[] = L"fancyzones_overrideSnapHotkeys";
const wchar_t MoveWindowAcrossMonitorsID[] = L"fancyzones_moveWindowAcrossMonitors";
const wchar_t MoveWindowsBasedOnPositionID[] = L"fancyzones_moveWindowsBasedOnPosition";
const wchar_t OverlappingZonesAlgorithmID[] = L"fancyzones_overlappingZonesAlgorithm";
const wchar_t DisplayChangeMoveWindowsID[] = L"fancyzones_displayChange_moveWindows";
const wchar_t ZoneSetChangeMoveWindowsID[] = L"fancyzones_zoneSetChange_moveWindows";
const wchar_t AppLastZoneMoveWindowsID[] = L"fancyzones_appLastZone_moveWindows";
const wchar_t OpenWindowOnActiveMonitorID[] = L"fancyzones_openWindowOnActiveMonitor";
const wchar_t RestoreSizeID[] = L"fancyzones_restoreSize";
const wchar_t QuickLayoutSwitch[] = L"fancyzones_quickLayoutSwitch";
const wchar_t FlashZonesOnQuickSwitch[] = L"fancyzones_flashZonesOnQuickSwitch";
const wchar_t UseCursorPosEditorStartupScreenID[] = L"use_cursorpos_editor_startupscreen";
const wchar_t ShowOnAllMonitorsID[] = L"fancyzones_show_on_all_monitors";
const wchar_t SpanZonesAcrossMonitorsID[] = L"fancyzones_span_zones_across_monitors";
const wchar_t MakeDraggedWindowTransparentID[] = L"fancyzones_makeDraggedWindowTransparent";
const wchar_t ZoneColorID[] = L"fancyzones_zoneColor";
const wchar_t ZoneBorderColorID[] = L"fancyzones_zoneBorderColor";
const wchar_t ZoneHighlightColorID[] = L"fancyzones_zoneHighlightColor";
const wchar_t EditorHotkeyID[] = L"fancyzones_editor_hotkey";
const wchar_t ExcludedAppsID[] = L"fancyzones_excluded_apps";
const wchar_t ZoneHighlightOpacityID[] = L"fancyzones_highlight_opacity";
const wchar_t ToggleEditorActionID[] = L"ToggledFZEditor";
const wchar_t IconKeyID[] = L"pt-fancy-zones";
const wchar_t OverviewURL[] = L"https://aka.ms/PowerToysOverview_FancyZones";
const wchar_t VideoURL[] = L"https://youtu.be/rTtGzZYAXgY";
const wchar_t PowerToysIssuesURL[] = L"https://aka.ms/powerToysReportBug";
}
struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSettings>
{
public:
FancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) :
m_hinstance(hinstance),
m_moduleName(name),
m_moduleKey(key)
{
LoadSettings(name, true);
}
IFACEMETHODIMP_(void)
SetCallback(IFancyZonesCallback* callback) { m_callback = callback; }
IFACEMETHODIMP_(void)
ResetCallback() { m_callback = nullptr; }
IFACEMETHODIMP_(bool)
GetConfig(_Out_ PWSTR buffer, _Out_ int* buffer_sizeg) noexcept;
IFACEMETHODIMP_(void)
SetConfig(PCWSTR config) noexcept;
IFACEMETHODIMP_(void)
ReloadSettings() noexcept;
IFACEMETHODIMP_(const Settings*)
GetSettings() const noexcept { return &m_settings; }
private:
void LoadSettings(PCWSTR config, bool fromFile) noexcept;
void SaveSettings() noexcept;
IFancyZonesCallback* m_callback{};
const HINSTANCE m_hinstance;
std::wstring m_moduleName{};
std::wstring m_moduleKey{};
Settings m_settings;
struct
{
PCWSTR name;
bool* value;
int resourceId;
} m_configBools[16] = {
{ NonLocalizable::ShiftDragID, &m_settings.shiftDrag, IDS_SETTING_DESCRIPTION_SHIFTDRAG },
{ NonLocalizable::MouseSwitchID, &m_settings.mouseSwitch, IDS_SETTING_DESCRIPTION_MOUSESWITCH },
{ NonLocalizable::OverrideSnapHotKeysID, &m_settings.overrideSnapHotkeys, IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS },
{ NonLocalizable::MoveWindowAcrossMonitorsID, &m_settings.moveWindowAcrossMonitors, IDS_SETTING_DESCRIPTION_MOVE_WINDOW_ACROSS_MONITORS },
{ NonLocalizable::MoveWindowsBasedOnPositionID, &m_settings.moveWindowsBasedOnPosition, IDS_SETTING_DESCRIPTION_MOVE_WINDOWS_BASED_ON_POSITION },
{ NonLocalizable::DisplayChangeMoveWindowsID, &m_settings.displayChange_moveWindows, IDS_SETTING_DESCRIPTION_DISPLAYCHANGE_MOVEWINDOWS },
{ NonLocalizable::ZoneSetChangeMoveWindowsID, &m_settings.zoneSetChange_moveWindows, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_MOVEWINDOWS },
{ NonLocalizable::AppLastZoneMoveWindowsID, &m_settings.appLastZone_moveWindows, IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS },
{ NonLocalizable::OpenWindowOnActiveMonitorID, &m_settings.openWindowOnActiveMonitor, IDS_SETTING_DESCRIPTION_OPEN_WINDOW_ON_ACTIVE_MONITOR },
{ NonLocalizable::RestoreSizeID, &m_settings.restoreSize, IDS_SETTING_DESCRIPTION_RESTORESIZE },
{ NonLocalizable::QuickLayoutSwitch, &m_settings.quickLayoutSwitch, IDS_SETTING_DESCRIPTION_QUICKLAYOUTSWITCH },
{ NonLocalizable::FlashZonesOnQuickSwitch, &m_settings.flashZonesOnQuickSwitch, IDS_SETTING_DESCRIPTION_FLASHZONESONQUICKSWITCH },
{ NonLocalizable::UseCursorPosEditorStartupScreenID, &m_settings.use_cursorpos_editor_startupscreen, IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN },
{ NonLocalizable::ShowOnAllMonitorsID, &m_settings.showZonesOnAllMonitors, IDS_SETTING_DESCRIPTION_SHOW_FANCY_ZONES_ON_ALL_MONITORS },
{ NonLocalizable::SpanZonesAcrossMonitorsID, &m_settings.spanZonesAcrossMonitors, IDS_SETTING_DESCRIPTION_SPAN_ZONES_ACROSS_MONITORS },
{ NonLocalizable::MakeDraggedWindowTransparentID, &m_settings.makeDraggedWindowTransparent, IDS_SETTING_DESCRIPTION_MAKE_DRAGGED_WINDOW_TRANSPARENT },
};
};
IFACEMETHODIMP_(bool)
FancyZonesSettings::GetConfig(_Out_ PWSTR buffer, _Out_ int* buffer_size) noexcept
{
PowerToysSettings::Settings settings(m_hinstance, m_moduleName);
// Pass a string literal or a resource id to Settings::set_description().
settings.set_description(IDS_SETTING_DESCRIPTION);
settings.set_icon_key(NonLocalizable::IconKeyID);
settings.set_overview_link(NonLocalizable::OverviewURL);
settings.set_video_link(NonLocalizable::VideoURL);
// Add a custom action property. When using this settings type, the "PowertoyModuleIface::call_custom_action()"
// method should be overridden as well.
settings.add_custom_action(
NonLocalizable::ToggleEditorActionID, // action name.
IDS_SETTING_LAUNCH_EDITOR_LABEL,
IDS_SETTING_LAUNCH_EDITOR_BUTTON,
IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION);
settings.add_hotkey(NonLocalizable::EditorHotkeyID, IDS_SETTING_LAUNCH_EDITOR_HOTKEY_LABEL, m_settings.editorHotkey);
for (auto const& setting : m_configBools)
{
settings.add_bool_toggle(setting.name, setting.resourceId, *setting.value);
}
settings.add_color_picker(NonLocalizable::ZoneHighlightColorID, IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR, m_settings.zoneHighlightColor);
settings.add_color_picker(NonLocalizable::ZoneColorID, IDS_SETTING_DESCRIPTION_ZONECOLOR, m_settings.zoneColor);
settings.add_color_picker(NonLocalizable::ZoneBorderColorID, IDS_SETTING_DESCRIPTION_ZONE_BORDER_COLOR, m_settings.zoneBorderColor);
settings.add_int_spinner(NonLocalizable::ZoneHighlightOpacityID, IDS_SETTINGS_HIGHLIGHT_OPACITY, m_settings.zoneHighlightOpacity, 0, 100, 1);
settings.add_multiline_string(NonLocalizable::ExcludedAppsID, IDS_SETTING_EXCLUDED_APPS_DESCRIPTION, m_settings.excludedApps);
return settings.serialize_to_buffer(buffer, buffer_size);
}
IFACEMETHODIMP_(void)
FancyZonesSettings::SetConfig(PCWSTR serializedPowerToysSettingsJson) noexcept
{
LoadSettings(serializedPowerToysSettingsJson, false /*fromFile*/);
SaveSettings();
if (m_callback)
{
m_callback->SettingsChanged();
}
}
IFACEMETHODIMP_(void)
FancyZonesSettings::ReloadSettings() noexcept
{
LoadSettings(m_moduleKey.c_str(), true /*fromFile*/);
if (m_callback)
{
m_callback->SettingsChanged();
}
}
void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept
{
try
{
PowerToysSettings::PowerToyValues values = fromFile ?
PowerToysSettings::PowerToyValues::load_from_settings_file(m_moduleKey) :
PowerToysSettings::PowerToyValues::from_json_string(config, m_moduleKey);
for (auto const& setting : m_configBools)
{
if (const auto val = values.get_bool_value(setting.name))
{
*setting.value = *val;
}
}
if (auto val = values.get_string_value(NonLocalizable::ZoneColorID))
{
m_settings.zoneColor = std::move(*val);
}
if (auto val = values.get_string_value(NonLocalizable::ZoneBorderColorID))
{
m_settings.zoneBorderColor = std::move(*val);
}
if (auto val = values.get_string_value(NonLocalizable::ZoneHighlightColorID))
{
m_settings.zoneHighlightColor = std::move(*val);
}
if (const auto val = values.get_json(NonLocalizable::EditorHotkeyID))
{
m_settings.editorHotkey = PowerToysSettings::HotkeyObject::from_json(*val);
}
if (auto val = values.get_string_value(NonLocalizable::ExcludedAppsID))
{
m_settings.excludedApps = std::move(*val);
m_settings.excludedAppsArray.clear();
auto excludedUppercase = m_settings.excludedApps;
CharUpperBuffW(excludedUppercase.data(), (DWORD)excludedUppercase.length());
std::wstring_view view(excludedUppercase);
while (view.starts_with('\n') || view.starts_with('\r'))
{
view.remove_prefix(1);
}
while (!view.empty())
{
auto pos = (std::min)(view.find_first_of(L"\r\n"), view.length());
m_settings.excludedAppsArray.emplace_back(view.substr(0, pos));
view.remove_prefix(pos);
while (view.starts_with('\n') || view.starts_with('\r'))
{
view.remove_prefix(1);
}
}
}
if (auto val = values.get_int_value(NonLocalizable::ZoneHighlightOpacityID))
{
m_settings.zoneHighlightOpacity = *val;
}
if (auto val = values.get_int_value(NonLocalizable::OverlappingZonesAlgorithmID))
{
// Avoid undefined behavior
if (*val >= 0 || *val < (int)Settings::OverlappingZonesAlgorithm::EnumElements)
{
m_settings.overlappingZonesAlgorithm = (Settings::OverlappingZonesAlgorithm)*val;
}
}
}
catch (...)
{
// Failure to load settings does not break FancyZones functionality. Display error message and continue with default settings.
MessageBox(NULL,
GET_RESOURCE_STRING(IDS_FANCYZONES_SETTINGS_LOAD_ERROR).c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK);
}
}
void FancyZonesSettings::SaveSettings() noexcept
{
try
{
PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey);
for (auto const& setting : m_configBools)
{
values.add_property(setting.name, *setting.value);
}
values.add_property(NonLocalizable::ZoneColorID, m_settings.zoneColor);
values.add_property(NonLocalizable::ZoneBorderColorID, m_settings.zoneBorderColor);
values.add_property(NonLocalizable::ZoneHighlightColorID, m_settings.zoneHighlightColor);
values.add_property(NonLocalizable::ZoneHighlightOpacityID, m_settings.zoneHighlightOpacity);
values.add_property(NonLocalizable::OverlappingZonesAlgorithmID, (int)m_settings.overlappingZonesAlgorithm);
values.add_property(NonLocalizable::EditorHotkeyID, m_settings.editorHotkey.get_json());
values.add_property(NonLocalizable::ExcludedAppsID, m_settings.excludedApps);
values.save_to_settings_file();
}
catch (...)
{
// Failure to save settings does not break FancyZones functionality. Display error message and continue with currently cached settings.
std::wstring errorMessage = GET_RESOURCE_STRING(IDS_FANCYZONES_SETTINGS_LOAD_ERROR) + L" " + NonLocalizable::PowerToysIssuesURL;
MessageBox(NULL,
errorMessage.c_str(),
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
MB_OK);
}
}
winrt::com_ptr<IFancyZonesSettings> MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) noexcept
{
return winrt::make_self<FancyZonesSettings>(hinstance, name, key);
}

View file

@ -57,8 +57,8 @@ interface __declspec(uuid("{BA4E77C4-6F44-4C5D-93D3-CBDE880495C2}")) IFancyZones
IFACEMETHOD_(void, SetCallback)(interface IFancyZonesCallback* callback) = 0;
IFACEMETHOD_(void, ResetCallback)() = 0;
IFACEMETHOD_(bool, GetConfig)(_Out_ PWSTR buffer, _Out_ int *buffer_size) = 0;
IFACEMETHOD_(void, SetConfig)(PCWSTR serializedPowerToysSettingsJson) = 0;
IFACEMETHOD_(void, CallCustomAction)(PCWSTR action) = 0;
IFACEMETHOD_(void, SetConfig)(PCWSTR serializedPowerToysSettings) = 0;
IFACEMETHOD_(void, ReloadSettings)() = 0;
IFACEMETHOD_(const Settings*, GetSettings)() const = 0;
};

View file

@ -1,361 +1,361 @@
#include "pch.h"
#include "WindowMoveHandler.h"
#include <common/display/dpi_aware.h>
#include <common/notifications/notifications.h>
#include <common/notifications/dont_show_again.h>
#include <common/utils/elevation.h>
#include <common/utils/resources.h>
#include "FancyZonesData.h"
#include "Settings.h"
#include "ZoneWindow.h"
#include "util.h"
// Non-Localizable strings
namespace NonLocalizable
{
const wchar_t FancyZonesRunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp";
const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/";
}
namespace WindowMoveHandlerUtils
{
bool IsCursorTypeIndicatingSizeEvent()
{
CURSORINFO cursorInfo = { 0 };
cursorInfo.cbSize = sizeof(cursorInfo);
if (::GetCursorInfo(&cursorInfo))
{
if (::LoadCursor(NULL, IDC_SIZENS) == cursorInfo.hCursor)
{
return true;
}
if (::LoadCursor(NULL, IDC_SIZEWE) == cursorInfo.hCursor)
{
return true;
}
if (::LoadCursor(NULL, IDC_SIZENESW) == cursorInfo.hCursor)
{
return true;
}
if (::LoadCursor(NULL, IDC_SIZENWSE) == cursorInfo.hCursor)
{
return true;
}
}
return false;
}
}
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, const std::function<void()>& keyUpdateCallback) :
m_settings(settings),
m_mouseState(false),
m_mouseHook(std::bind(&WindowMoveHandler::OnMouseDown, this)),
m_shiftKeyState(keyUpdateCallback),
m_ctrlKeyState(keyUpdateCallback),
m_keyUpdateCallback(keyUpdateCallback)
{
}
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
if (!FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
{
return;
}
m_moveSizeWindowInfo.hasNoVisibleOwner = FancyZonesUtils::HasNoVisibleOwner(window);
m_moveSizeWindowInfo.isStandardWindow = FancyZonesUtils::IsStandardWindow(window);
m_inMoveSize = true;
auto iter = zoneWindowMap.find(monitor);
if (iter == end(zoneWindowMap))
{
return;
}
m_windowMoveSize = window;
if (m_settings->GetSettings()->mouseSwitch)
{
m_mouseHook.enable();
}
m_shiftKeyState.enable();
m_ctrlKeyState.enable();
// This updates m_dragEnabled depending on if the shift key is being held down
UpdateDragState();
// Notifies user if unable to drag elevated window
WarnIfElevationIsRequired(window);
if (m_dragEnabled)
{
m_zoneWindowMoveSize = iter->second;
SetWindowTransparency(m_windowMoveSize);
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
if (m_settings->GetSettings()->showZonesOnAllMonitors)
{
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
// Skip calling ShowZoneWindow for iter->second (m_zoneWindowMoveSize) since it
// was already called in MoveSizeEnter
const bool moveSizeEnterCalled = zoneWindow == m_zoneWindowMoveSize;
if (zoneWindow && !moveSizeEnterCalled)
{
zoneWindow->ShowZoneWindow();
}
}
}
}
else if (m_zoneWindowMoveSize)
{
ResetWindowTransparency();
m_zoneWindowMoveSize = nullptr;
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
if (zoneWindow)
{
zoneWindow->HideZoneWindow();
}
}
}
}
void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
if (!m_inMoveSize)
{
return;
}
// This updates m_dragEnabled depending on if the shift key is being held down.
UpdateDragState();
if (m_zoneWindowMoveSize)
{
// Update the ZoneWindow already handling move/size
if (!m_dragEnabled)
{
// Drag got disabled, tell it to cancel and hide all windows
m_zoneWindowMoveSize = nullptr;
ResetWindowTransparency();
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
if (zoneWindow)
{
zoneWindow->HideZoneWindow();
}
}
}
else
{
auto iter = zoneWindowMap.find(monitor);
if (iter != zoneWindowMap.end())
{
if (iter->second != m_zoneWindowMoveSize)
{
// The drag has moved to a different monitor.
m_zoneWindowMoveSize->ClearSelectedZones();
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
{
m_zoneWindowMoveSize->HideZoneWindow();
}
m_zoneWindowMoveSize = iter->second;
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
}
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
zoneWindow->MoveSizeUpdate(ptScreen, m_dragEnabled, m_ctrlKeyState.state());
}
}
}
}
else if (m_dragEnabled)
{
// We'll get here if the user presses/releases shift while dragging.
// Restart the drag on the ZoneWindow that m_windowMoveSize is on
MoveSizeStart(m_windowMoveSize, monitor, ptScreen, zoneWindowMap);
// m_dragEnabled could get set to false if we're moving an elevated window.
// In that case do not proceed.
if (m_dragEnabled)
{
MoveSizeUpdate(monitor, ptScreen, zoneWindowMap);
}
}
}
void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
if (window != m_windowMoveSize)
{
return;
}
m_mouseHook.disable();
m_shiftKeyState.disable();
m_ctrlKeyState.disable();
if (m_zoneWindowMoveSize)
{
auto zoneWindow = std::move(m_zoneWindowMoveSize);
ResetWindowTransparency();
bool hasNoVisibleOwner = FancyZonesUtils::HasNoVisibleOwner(window);
bool isStandardWindow = FancyZonesUtils::IsStandardWindow(window);
if ((isStandardWindow == false && hasNoVisibleOwner == true &&
m_moveSizeWindowInfo.isStandardWindow == true && m_moveSizeWindowInfo.hasNoVisibleOwner == true) ||
FancyZonesUtils::IsWindowMaximized(window))
{
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
// or if the window is maximized by Windows when the cursor hits the screen top border
}
else
{
zoneWindow->MoveSizeEnd(m_windowMoveSize, ptScreen);
}
}
else
{
if (m_settings->GetSettings()->restoreSize)
{
if (WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
{
::RemoveProp(window, ZonedWindowProperties::PropertyRestoreSizeID);
}
else if (!FancyZonesUtils::IsWindowMaximized(window))
{
FancyZonesUtils::RestoreWindowSize(window);
}
}
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
if (monitor)
{
auto zoneWindow = zoneWindowMap.find(monitor);
if (zoneWindow != zoneWindowMap.end())
{
const auto zoneWindowPtr = zoneWindow->second;
const auto activeZoneSet = zoneWindowPtr->ActiveZoneSet();
if (activeZoneSet)
{
wil::unique_cotaskmem_string guidString;
if (SUCCEEDED_LOG(StringFromCLSID(activeZoneSet->Id(), &guidString)))
{
FancyZonesDataInstance().RemoveAppLastZone(window, zoneWindowPtr->UniqueId(), guidString.get());
}
}
}
}
::RemoveProp(window, ZonedWindowProperties::PropertyMultipleZoneID);
}
m_inMoveSize = false;
m_dragEnabled = false;
m_mouseState = false;
m_windowMoveSize = nullptr;
// Also, hide all windows (regardless of settings)
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
if (zoneWindow)
{
zoneWindow->HideZoneWindow();
}
}
}
void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
if (window != m_windowMoveSize)
{
zoneWindow->MoveWindowIntoZoneByIndexSet(window, indexSet);
}
}
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, cycle);
}
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle);
}
bool WindowMoveHandler::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
return zoneWindow && zoneWindow->ExtendWindowByDirectionAndPosition(window, vkCode);
}
void WindowMoveHandler::WarnIfElevationIsRequired(HWND window) noexcept
{
using namespace notifications;
using namespace NonLocalizable;
using namespace FancyZonesUtils;
static bool warning_shown = false;
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
{
m_dragEnabled = false;
if (!warning_shown && !is_toast_disabled(CantDragElevatedDontShowAgainRegistryPath, CantDragElevatedDisableIntervalInDays))
{
std::vector<action_t> actions = {
link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), FancyZonesRunAsAdminInfoPage },
link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), ToastNotificationButtonUrl }
};
show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED),
GET_RESOURCE_STRING(IDS_FANCYZONES),
{},
std::move(actions));
warning_shown = true;
}
}
}
void WindowMoveHandler::UpdateDragState() noexcept
{
if (m_settings->GetSettings()->shiftDrag)
{
m_dragEnabled = (m_shiftKeyState.state() ^ m_mouseState);
}
else
{
m_dragEnabled = !(m_shiftKeyState.state() ^ m_mouseState);
}
}
void WindowMoveHandler::SetWindowTransparency(HWND window) noexcept
{
if (m_settings->GetSettings()->makeDraggedWindowTransparent)
{
m_windowTransparencyProperties.draggedWindowExstyle = GetWindowLong(window, GWL_EXSTYLE);
m_windowTransparencyProperties.draggedWindow = window;
SetWindowLong(window,
GWL_EXSTYLE,
m_windowTransparencyProperties.draggedWindowExstyle | WS_EX_LAYERED);
GetLayeredWindowAttributes(window, &m_windowTransparencyProperties.draggedWindowCrKey, &m_windowTransparencyProperties.draggedWindowInitialAlpha, &m_windowTransparencyProperties.draggedWindowDwFlags);
SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA);
}
}
void WindowMoveHandler::ResetWindowTransparency() noexcept
{
if (m_settings->GetSettings()->makeDraggedWindowTransparent && m_windowTransparencyProperties.draggedWindow != nullptr)
{
SetLayeredWindowAttributes(m_windowTransparencyProperties.draggedWindow, m_windowTransparencyProperties.draggedWindowCrKey, m_windowTransparencyProperties.draggedWindowInitialAlpha, m_windowTransparencyProperties.draggedWindowDwFlags);
SetWindowLong(m_windowTransparencyProperties.draggedWindow, GWL_EXSTYLE, m_windowTransparencyProperties.draggedWindowExstyle);
m_windowTransparencyProperties.draggedWindow = nullptr;
}
}
#include "pch.h"
#include "WindowMoveHandler.h"
#include <common/display/dpi_aware.h>
#include <common/notifications/notifications.h>
#include <common/notifications/dont_show_again.h>
#include <common/utils/elevation.h>
#include <common/utils/resources.h>
#include "FancyZonesData.h"
#include "Settings.h"
#include "ZoneWindow.h"
#include "util.h"
// Non-Localizable strings
namespace NonLocalizable
{
const wchar_t FancyZonesRunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp";
const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/";
}
namespace WindowMoveHandlerUtils
{
bool IsCursorTypeIndicatingSizeEvent()
{
CURSORINFO cursorInfo = { 0 };
cursorInfo.cbSize = sizeof(cursorInfo);
if (::GetCursorInfo(&cursorInfo))
{
if (::LoadCursor(NULL, IDC_SIZENS) == cursorInfo.hCursor)
{
return true;
}
if (::LoadCursor(NULL, IDC_SIZEWE) == cursorInfo.hCursor)
{
return true;
}
if (::LoadCursor(NULL, IDC_SIZENESW) == cursorInfo.hCursor)
{
return true;
}
if (::LoadCursor(NULL, IDC_SIZENWSE) == cursorInfo.hCursor)
{
return true;
}
}
return false;
}
}
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, const std::function<void()>& keyUpdateCallback) :
m_settings(settings),
m_mouseState(false),
m_mouseHook(std::bind(&WindowMoveHandler::OnMouseDown, this)),
m_shiftKeyState(keyUpdateCallback),
m_ctrlKeyState(keyUpdateCallback),
m_keyUpdateCallback(keyUpdateCallback)
{
}
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
if (!FancyZonesUtils::IsCandidateForZoning(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
{
return;
}
m_moveSizeWindowInfo.hasNoVisibleOwner = FancyZonesUtils::HasNoVisibleOwner(window);
m_moveSizeWindowInfo.isStandardWindow = FancyZonesUtils::IsStandardWindow(window);
m_inMoveSize = true;
auto iter = zoneWindowMap.find(monitor);
if (iter == end(zoneWindowMap))
{
return;
}
m_windowMoveSize = window;
if (m_settings->GetSettings()->mouseSwitch)
{
m_mouseHook.enable();
}
m_shiftKeyState.enable();
m_ctrlKeyState.enable();
// This updates m_dragEnabled depending on if the shift key is being held down
UpdateDragState();
// Notifies user if unable to drag elevated window
WarnIfElevationIsRequired(window);
if (m_dragEnabled)
{
m_zoneWindowMoveSize = iter->second;
SetWindowTransparency(m_windowMoveSize);
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
if (m_settings->GetSettings()->showZonesOnAllMonitors)
{
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
// Skip calling ShowZoneWindow for iter->second (m_zoneWindowMoveSize) since it
// was already called in MoveSizeEnter
const bool moveSizeEnterCalled = zoneWindow == m_zoneWindowMoveSize;
if (zoneWindow && !moveSizeEnterCalled)
{
zoneWindow->ShowZoneWindow();
}
}
}
}
else if (m_zoneWindowMoveSize)
{
ResetWindowTransparency();
m_zoneWindowMoveSize = nullptr;
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
if (zoneWindow)
{
zoneWindow->HideZoneWindow();
}
}
}
}
void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
if (!m_inMoveSize)
{
return;
}
// This updates m_dragEnabled depending on if the shift key is being held down.
UpdateDragState();
if (m_zoneWindowMoveSize)
{
// Update the ZoneWindow already handling move/size
if (!m_dragEnabled)
{
// Drag got disabled, tell it to cancel and hide all windows
m_zoneWindowMoveSize = nullptr;
ResetWindowTransparency();
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
if (zoneWindow)
{
zoneWindow->HideZoneWindow();
}
}
}
else
{
auto iter = zoneWindowMap.find(monitor);
if (iter != zoneWindowMap.end())
{
if (iter->second != m_zoneWindowMoveSize)
{
// The drag has moved to a different monitor.
m_zoneWindowMoveSize->ClearSelectedZones();
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
{
m_zoneWindowMoveSize->HideZoneWindow();
}
m_zoneWindowMoveSize = iter->second;
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
}
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
zoneWindow->MoveSizeUpdate(ptScreen, m_dragEnabled, m_ctrlKeyState.state());
}
}
}
}
else if (m_dragEnabled)
{
// We'll get here if the user presses/releases shift while dragging.
// Restart the drag on the ZoneWindow that m_windowMoveSize is on
MoveSizeStart(m_windowMoveSize, monitor, ptScreen, zoneWindowMap);
// m_dragEnabled could get set to false if we're moving an elevated window.
// In that case do not proceed.
if (m_dragEnabled)
{
MoveSizeUpdate(monitor, ptScreen, zoneWindowMap);
}
}
}
void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
{
if (window != m_windowMoveSize)
{
return;
}
m_mouseHook.disable();
m_shiftKeyState.disable();
m_ctrlKeyState.disable();
if (m_zoneWindowMoveSize)
{
auto zoneWindow = std::move(m_zoneWindowMoveSize);
ResetWindowTransparency();
bool hasNoVisibleOwner = FancyZonesUtils::HasNoVisibleOwner(window);
bool isStandardWindow = FancyZonesUtils::IsStandardWindow(window);
if ((isStandardWindow == false && hasNoVisibleOwner == true &&
m_moveSizeWindowInfo.isStandardWindow == true && m_moveSizeWindowInfo.hasNoVisibleOwner == true) ||
FancyZonesUtils::IsWindowMaximized(window))
{
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
// or if the window is maximized by Windows when the cursor hits the screen top border
}
else
{
zoneWindow->MoveSizeEnd(m_windowMoveSize, ptScreen);
}
}
else
{
if (m_settings->GetSettings()->restoreSize)
{
if (WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
{
::RemoveProp(window, ZonedWindowProperties::PropertyRestoreSizeID);
}
else if (!FancyZonesUtils::IsWindowMaximized(window))
{
FancyZonesUtils::RestoreWindowSize(window);
}
}
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
if (monitor)
{
auto zoneWindow = zoneWindowMap.find(monitor);
if (zoneWindow != zoneWindowMap.end())
{
const auto zoneWindowPtr = zoneWindow->second;
const auto activeZoneSet = zoneWindowPtr->ActiveZoneSet();
if (activeZoneSet)
{
wil::unique_cotaskmem_string guidString;
if (SUCCEEDED_LOG(StringFromCLSID(activeZoneSet->Id(), &guidString)))
{
FancyZonesDataInstance().RemoveAppLastZone(window, zoneWindowPtr->UniqueId(), guidString.get());
}
}
}
}
::RemoveProp(window, ZonedWindowProperties::PropertyMultipleZoneID);
}
m_inMoveSize = false;
m_dragEnabled = false;
m_mouseState = false;
m_windowMoveSize = nullptr;
// Also, hide all windows (regardless of settings)
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
{
if (zoneWindow)
{
zoneWindow->HideZoneWindow();
}
}
}
void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
if (window != m_windowMoveSize)
{
zoneWindow->MoveWindowIntoZoneByIndexSet(window, indexSet);
}
}
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, cycle);
}
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle);
}
bool WindowMoveHandler::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
{
return zoneWindow && zoneWindow->ExtendWindowByDirectionAndPosition(window, vkCode);
}
void WindowMoveHandler::WarnIfElevationIsRequired(HWND window) noexcept
{
using namespace notifications;
using namespace NonLocalizable;
using namespace FancyZonesUtils;
static bool warning_shown = false;
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
{
m_dragEnabled = false;
if (!warning_shown && !is_toast_disabled(CantDragElevatedDontShowAgainRegistryPath, CantDragElevatedDisableIntervalInDays))
{
std::vector<action_t> actions = {
link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), FancyZonesRunAsAdminInfoPage },
link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), ToastNotificationButtonUrl }
};
show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED),
GET_RESOURCE_STRING(IDS_FANCYZONES),
{},
std::move(actions));
warning_shown = true;
}
}
}
void WindowMoveHandler::UpdateDragState() noexcept
{
if (m_settings->GetSettings()->shiftDrag)
{
m_dragEnabled = (m_shiftKeyState.state() ^ m_mouseState);
}
else
{
m_dragEnabled = !(m_shiftKeyState.state() ^ m_mouseState);
}
}
void WindowMoveHandler::SetWindowTransparency(HWND window) noexcept
{
if (m_settings->GetSettings()->makeDraggedWindowTransparent)
{
m_windowTransparencyProperties.draggedWindowExstyle = GetWindowLong(window, GWL_EXSTYLE);
m_windowTransparencyProperties.draggedWindow = window;
SetWindowLong(window,
GWL_EXSTYLE,
m_windowTransparencyProperties.draggedWindowExstyle | WS_EX_LAYERED);
GetLayeredWindowAttributes(window, &m_windowTransparencyProperties.draggedWindowCrKey, &m_windowTransparencyProperties.draggedWindowInitialAlpha, &m_windowTransparencyProperties.draggedWindowDwFlags);
SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA);
}
}
void WindowMoveHandler::ResetWindowTransparency() noexcept
{
if (m_settings->GetSettings()->makeDraggedWindowTransparent && m_windowTransparencyProperties.draggedWindow != nullptr)
{
SetLayeredWindowAttributes(m_windowTransparencyProperties.draggedWindow, m_windowTransparencyProperties.draggedWindowCrKey, m_windowTransparencyProperties.draggedWindowInitialAlpha, m_windowTransparencyProperties.draggedWindowDwFlags);
SetWindowLong(m_windowTransparencyProperties.draggedWindow, GWL_EXSTYLE, m_windowTransparencyProperties.draggedWindowExstyle);
m_windowTransparencyProperties.draggedWindow = nullptr;
}
}

View file

@ -1,81 +1,81 @@
#pragma once
#include "KeyState.h"
#include "SecondaryMouseButtonsHook.h"
#include <functional>
interface IFancyZonesSettings;
interface IZoneWindow;
class WindowMoveHandler
{
public:
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, const std::function<void()>& keyUpdateCallback);
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
inline void OnMouseDown() noexcept
{
m_mouseState = !m_mouseState;
m_keyUpdateCallback();
}
inline bool IsDragEnabled() const noexcept
{
return m_dragEnabled;
}
inline bool InMoveSize() const noexcept
{
return m_inMoveSize;
}
private:
struct WindowTransparencyProperties
{
HWND draggedWindow = nullptr;
long draggedWindowExstyle = 0;
COLORREF draggedWindowCrKey = RGB(0, 0, 0);
DWORD draggedWindowDwFlags = 0;
BYTE draggedWindowInitialAlpha = 0;
};
// MoveSize related window properties
struct MoveSizeWindowInfo
{
// True if from the styles the window looks like a standard window
bool isStandardWindow = false;
// True if the window is a top-level window that does not have a visible owner
bool hasNoVisibleOwner = false;
};
void WarnIfElevationIsRequired(HWND window) noexcept;
void UpdateDragState() noexcept;
void SetWindowTransparency(HWND window) noexcept;
void ResetWindowTransparency() noexcept;
winrt::com_ptr<IFancyZonesSettings> m_settings{};
HWND m_windowMoveSize{}; // The window that is being moved/sized
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
MoveSizeWindowInfo m_moveSizeWindowInfo; // MoveSizeWindowInfo of the window at the moment when dragging started
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
WindowTransparencyProperties m_windowTransparencyProperties;
std::atomic<bool> m_mouseState;
SecondaryMouseButtonsHook m_mouseHook;
KeyState<VK_LSHIFT, VK_RSHIFT> m_shiftKeyState;
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
std::function<void()> m_keyUpdateCallback;
};
#pragma once
#include "KeyState.h"
#include "SecondaryMouseButtonsHook.h"
#include <functional>
interface IFancyZonesSettings;
interface IZoneWindow;
class WindowMoveHandler
{
public:
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, const std::function<void()>& keyUpdateCallback);
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
inline void OnMouseDown() noexcept
{
m_mouseState = !m_mouseState;
m_keyUpdateCallback();
}
inline bool IsDragEnabled() const noexcept
{
return m_dragEnabled;
}
inline bool InMoveSize() const noexcept
{
return m_inMoveSize;
}
private:
struct WindowTransparencyProperties
{
HWND draggedWindow = nullptr;
long draggedWindowExstyle = 0;
COLORREF draggedWindowCrKey = RGB(0, 0, 0);
DWORD draggedWindowDwFlags = 0;
BYTE draggedWindowInitialAlpha = 0;
};
// MoveSize related window properties
struct MoveSizeWindowInfo
{
// True if from the styles the window looks like a standard window
bool isStandardWindow = false;
// True if the window is a top-level window that does not have a visible owner
bool hasNoVisibleOwner = false;
};
void WarnIfElevationIsRequired(HWND window) noexcept;
void UpdateDragState() noexcept;
void SetWindowTransparency(HWND window) noexcept;
void ResetWindowTransparency() noexcept;
winrt::com_ptr<IFancyZonesSettings> m_settings{};
HWND m_windowMoveSize{}; // The window that is being moved/sized
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
MoveSizeWindowInfo m_moveSizeWindowInfo; // MoveSizeWindowInfo of the window at the moment when dragging started
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
WindowTransparencyProperties m_windowTransparencyProperties;
std::atomic<bool> m_mouseState;
SecondaryMouseButtonsHook m_mouseHook;
KeyState<VK_LSHIFT, VK_RSHIFT> m_shiftKeyState;
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
std::function<void()> m_keyUpdateCallback;
};

View file

@ -1,6 +1,6 @@
#pragma once
#include "FancyZones.h"
#include "lib/ZoneSet.h"
#include "FancyZonesLib/ZoneSet.h"
/**
* Class representing single work area, which is defined by monitor and virtual desktop.

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="cs-CZ" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="cs-CZ" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="de-DE" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="de-DE" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="es-ES" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="es-ES" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="fr-FR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="fr-FR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="hu-HU" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="hu-HU" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="it-IT" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="it-IT" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="ja-JP" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="ja-JP" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="ko-KR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="ko-KR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="nl-NL" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="nl-NL" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="pl-PL" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="pl-PL" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="pt-BR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="pt-BR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="pt-PT" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="pt-PT" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="ru-RU" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="ru-RU" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="sv-SE" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="sv-SE" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="tr-TR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="tr-TR" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="zh-CN" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="zh-CN" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\lib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="zh-TW" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<LCX SchemaVersion="6.0" Name="S:\src\modules\fancyzones\FancyZonesLib\Resources.resx" PsrId="211" FileType="1" SrcCul="en-US" TgtCul="zh-TW" xmlns="http://schemas.microsoft.com/locstudio/2006/6/lcx">
<OwnedComments>
<Cmt Name="Dev" />
<Cmt Name="LcxAdmin" />

View file

@ -1,5 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View file

@ -1,29 +1,29 @@
#pragma once
#include "Generated Files/resource.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Unknwn.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <windows.h>
#include <windowsx.h>
#include <dwmapi.h>
#include <ProjectTelemetry.h>
#include <shellapi.h>
#include <ShellScalingApi.h>
#include <strsafe.h>
#include <TraceLoggingActivity.h>
#include <wil\resource.h>
#include <wil\result.h>
#include <winrt/windows.foundation.h>
#include <psapi.h>
#include <shared_mutex>
#include <functional>
#include <unordered_set>
#include <ShObjIdl.h>
#include <optional>
namespace winrt
{
using namespace ::winrt;
#pragma once
#include "Generated Files/resource.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Unknwn.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <windows.h>
#include <windowsx.h>
#include <dwmapi.h>
#include <ProjectTelemetry.h>
#include <shellapi.h>
#include <ShellScalingApi.h>
#include <strsafe.h>
#include <TraceLoggingActivity.h>
#include <wil\resource.h>
#include <wil\result.h>
#include <winrt/windows.foundation.h>
#include <psapi.h>
#include <shared_mutex>
#include <functional>
#include <unordered_set>
#include <ShObjIdl.h>
#include <optional>
namespace winrt
{
using namespace ::winrt;
}

View file

@ -6,8 +6,8 @@
// Non-localizable
#define FILE_DESCRIPTION "PowerToys FancyZones"
#define INTERNAL_NAME "fancyzones"
#define ORIGINAL_FILENAME "fancyzones.dll"
#define INTERNAL_NAME "FancyZones"
#define ORIGINAL_FILENAME "PowerToys.FancyZones.exe"
// Non-localizable
//////////////////////////////

View file

@ -1,9 +1,9 @@
#include "pch.h"
#include "trace.h"
#include "lib/ZoneSet.h"
#include "lib/Settings.h"
#include "lib/FancyZonesData.h"
#include "lib/FancyZonesDataTypes.h"
#include "FancyZonesLib/ZoneSet.h"
#include "FancyZonesLib/Settings.h"
#include "FancyZonesLib/FancyZonesData.h"
#include "FancyZonesLib/FancyZonesDataTypes.h"
// Telemetry strings should not be localized.
#define LoggingProviderKey "Microsoft.PowerToys"
@ -12,7 +12,7 @@
#define EventKeyDownKey "FancyZones_OnKeyDown"
#define EventZoneSettingsChangedKey "FancyZones_ZoneSettingsChanged"
#define EventEditorLaunchKey "FancyZones_EditorLaunch"
#define EventSettingsChangedKey "FancyZones_SettingsChanged"
#define EventSettingsKey "FancyZones_Settings"
#define EventDesktopChangedKey "FancyZones_VirtualDesktopChanged"
#define EventZoneWindowKeyUpKey "FancyZones_ZoneWindowKeyUp"
#define EventMoveSizeEndKey "FancyZones_MoveSizeEnd"
@ -244,7 +244,7 @@ void Trace::FancyZones::QuickLayoutSwitched(bool shortcutUsed) noexcept
TraceLoggingBoolean(shortcutUsed, QuickLayoutSwitchedWithShortcutUsed));
}
void Trace::SettingsChanged(const Settings& settings) noexcept
void Trace::SettingsTelemetry(const Settings& settings) noexcept
{
const auto& editorHotkey = settings.editorHotkey;
std::wstring hotkeyStr = L"alt:" + std::to_wstring(editorHotkey.alt_pressed())
@ -256,7 +256,7 @@ void Trace::SettingsChanged(const Settings& settings) noexcept
TraceLoggingWrite(
g_hProvider,
EventSettingsChangedKey,
EventSettingsKey,
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(settings.shiftDrag, ShiftDragKey),

View file

@ -20,7 +20,7 @@ public:
static void QuickLayoutSwitched(bool shortcutUsed) noexcept;
};
static void SettingsChanged(const Settings& settings) noexcept;
static void SettingsTelemetry(const Settings& settings) noexcept;
static void VirtualDesktopChanged() noexcept;
class ZoneWindow

View file

@ -11,7 +11,7 @@
#include <complex>
#include <wil/Resource.h>
#include <fancyzones/lib/FancyZonesDataTypes.h>
#include <fancyzones/FancyZonesLib/FancyZonesDataTypes.h>
// Non-Localizable strings
namespace NonLocalizable

View file

@ -1,79 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{48804216-2A0E-4168-A6D8-9CD068D14227}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>fancyzones</RootNamespace>
<ProjectName>fancyzones</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>FANCYZONES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>gdiplus.lib;dwmapi.lib;shlwapi.lib;uxtheme.lib;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\Display\Display.vcxproj">
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\FancyZonesLib.vcxproj">
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\lib\Generated Files\fancyzones.rc" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{48804216-2A0E-4168-A6D8-9CD068D14227}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>fancyzones</RootNamespace>
<ProjectName>FancyZonesModuleInterface</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>FANCYZONES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>gdiplus.lib;dwmapi.lib;shlwapi.lib;uxtheme.lib;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\Display\Display.vcxproj">
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\FancyZonesLib\FancyZonesLib.vcxproj">
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View file

@ -1,39 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{21926bf1-03b3-482d-8f60-8bc4fbfc6564}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{2f10207d-d8d1-4a42-8027-8ca597b3cb23}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{a4241930-ecae-44e2-be82-25eff2499fcd}</UniqueIdentifier>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{8d479404-964b-4eb1-8fe8-554be3e68c9b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\lib\Generated Files\fancyzones.rc" />
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{21926bf1-03b3-482d-8f60-8bc4fbfc6564}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{2f10207d-d8d1-4a42-8027-8ca597b3cb23}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{a4241930-ecae-44e2-be82-25eff2499fcd}</UniqueIdentifier>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{8d479404-964b-4eb1-8fe8-554be3e68c9b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,187 @@
#include "pch.h"
#include <interface/powertoy_module_interface.h>
#include <common/interop/shared_constants.h>
#include <common/logger/logger.h>
#include <common/utils/resources.h>
#include <common/utils/winapi_error.h>
#include <FancyZonesLib/Generated Files/resource.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/trace.h>
#include <FancyZonesLib/Settings.h>
#include <shellapi.h>
// Non-localizable
const std::wstring fancyZonesPath = L"modules\\FancyZones\\PowerToys.FancyZones.exe";
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Trace::RegisterProvider();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
Trace::UnregisterProvider();
break;
}
return TRUE;
}
class FancyZonesModuleInterface : public PowertoyModuleIface
{
public:
// Return the localized display name of the powertoy
virtual PCWSTR get_name() override
{
return app_name.c_str();
}
// Return the non localized key of the powertoy, this will be cached by the runner
virtual const wchar_t* get_key() override
{
return app_key.c_str();
}
// Return JSON with the configuration options.
// These are the settings shown on the settings page along with their current values.
virtual bool get_config(_Out_ PWSTR buffer, _Out_ int* buffer_size) override
{
return m_settings->GetConfig(buffer, buffer_size);
}
// Passes JSON with the configuration settings for the powertoy.
// This is called when the user hits Save on the settings page.
virtual void set_config(PCWSTR config) override
{
m_settings->SetConfig(config);
}
// Signal from the Settings editor to call a custom action.
// This can be used to spawn more complex editors.
virtual void call_custom_action(const wchar_t* action) override
{
SetEvent(m_toggleEditorEvent);
}
// Enable the powertoy
virtual void enable()
{
Logger::info("FancyZones enabling");
Enable();
}
// Disable the powertoy
virtual void disable()
{
Logger::info("FancyZones disabling");
Disable(true);
}
// Returns if the powertoy is enabled
virtual bool is_enabled() override
{
return m_enabled;
}
// Destroy the powertoy and free memory
virtual void destroy() override
{
Disable(false);
delete this;
}
virtual void send_settings_telemetry() override
{
Logger::info("Send settings telemetry");
Trace::SettingsTelemetry(*m_settings->GetSettings());
}
FancyZonesModuleInterface()
{
app_name = GET_RESOURCE_STRING(IDS_FANCYZONES);
app_key = NonLocalizable::FancyZonesStr;
m_settings = MakeFancyZonesSettings(reinterpret_cast<HINSTANCE>(&__ImageBase), FancyZonesModuleInterface::get_name(), FancyZonesModuleInterface::get_key());
m_toggleEditorEvent = CreateDefaultEvent(CommonSharedConstants::FANCY_ZONES_EDITOR_TOGGLE_EVENT);
}
private:
void Enable()
{
m_enabled = true;
// Log telemetry
Trace::FancyZones::EnableFancyZones(true);
unsigned long powertoys_pid = GetCurrentProcessId();
std::wstring executable_args = L"";
executable_args.append(std::to_wstring(powertoys_pid));
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = fancyZonesPath.c_str();
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = executable_args.data();
if (ShellExecuteExW(&sei) == false)
{
Logger::error(L"Failed to start FancyZones");
auto message = get_last_error_message(GetLastError());
if (message.has_value())
{
Logger::error(message.value());
}
}
else
{
m_hProcess = sei.hProcess;
}
}
void Disable(bool const traceEvent)
{
m_enabled = false;
// Log telemetry
if (traceEvent)
{
Trace::FancyZones::EnableFancyZones(false);
}
ResetEvent(m_toggleEditorEvent);
CloseHandle(m_toggleEditorEvent);
if (m_hProcess)
{
TerminateProcess(m_hProcess, 0);
m_hProcess = nullptr;
}
}
std::wstring app_name;
//contains the non localized key of the powertoy
std::wstring app_key;
bool m_enabled = false;
HANDLE m_hProcess = nullptr;
// Handle to event used to invoke FancyZones Editor
HANDLE m_toggleEditorEvent;
winrt::com_ptr<IFancyZonesSettings> m_settings;
};
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new FancyZonesModuleInterface();
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200902.2" targetFramework="native" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200902.2" targetFramework="native" />
</packages>

View file

@ -1,17 +1,17 @@
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Unknwn.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
#include <wil\common.h>
#include <wil\result.h>
namespace winrt
{
using namespace ::winrt;
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Unknwn.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <ProjectTelemetry.h>
#include <TraceLoggingActivity.h>
#include <wil\common.h>
#include <wil\result.h>
namespace winrt
{
using namespace ::winrt;
}

View file

@ -2,9 +2,9 @@
#include <filesystem>
#include <lib/FancyZones.h>
#include <lib/FancyZonesData.h>
#include <lib/Settings.h>
#include <FancyZonesLib/FancyZones.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/Settings.h>
#include "util.h"

View file

@ -2,8 +2,8 @@
#include <filesystem>
#include <fstream>
#include <lib/Settings.h>
#include <lib/FancyZones.h>
#include <FancyZonesLib/Settings.h>
#include <FancyZonesLib/FancyZones.h>
#include <common/SettingsAPI/settings_helpers.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@ -524,34 +524,6 @@ namespace FancyZonesUnitTests
Assert::IsTrue(flag);
}
TEST_METHOD (CallbackCallCustomAction)
{
bool flag = false;
winrt::com_ptr<FZCallback> callback = winrt::make_self<FZCallback>(&flag);
json::JsonObject action{};
action.SetNamedValue(L"action_name", json::JsonValue::CreateStringValue(L"ToggledFZEditor"));
m_settings->SetCallback(callback.get());
m_settings->CallCustomAction(action.Stringify().c_str());
Assert::IsTrue(flag);
}
TEST_METHOD (CallbackCallCustomActionNotToggle)
{
bool flag = false;
winrt::com_ptr<FZCallback> callback = winrt::make_self<FZCallback>(&flag);
json::JsonObject action{};
action.SetNamedValue(L"action_name", json::JsonValue::CreateStringValue(L"NOT_ToggledFZEditor"));
m_settings->SetCallback(callback.get());
m_settings->CallCustomAction(action.Stringify().c_str());
Assert::IsFalse(flag);
}
TEST_METHOD (CallbackGetConfig)
{
bool flag = false;

View file

@ -3,10 +3,10 @@
#include <fstream>
#include <utility>
#include <lib/FancyZonesData.h>
#include <lib/FancyZonesDataTypes.h>
#include <lib/JsonHelpers.h>
#include <lib/util.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/FancyZonesDataTypes.h>
#include <FancyZonesLib/JsonHelpers.h>
#include <FancyZonesLib/util.h>
#include "util.h"

View file

@ -1,87 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>UnitTests</RootNamespace>
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
<ProjectName>UnitTests-FancyZones</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\..\common\Telemetry;..\..\..\..\;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>UNIT_TESTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>gdiplus.lib;dwmapi.lib;shlwapi.lib;uxtheme.lib;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="FancyZones.Spec.cpp" />
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
<ClCompile Include="JsonHelpers.Tests.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Util.Spec.cpp" />
<ClCompile Include="Util.cpp" />
<ClCompile Include="Zone.Spec.cpp" />
<ClCompile Include="ZoneSet.Spec.cpp" />
<ClCompile Include="ZoneWindow.Spec.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Util.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\Display\Display.vcxproj">
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\FancyZonesLib.vcxproj">
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UnitTests-FancyZones.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>UnitTests</RootNamespace>
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
<ProjectName>UnitTests-FancyZones</ProjectName>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones\$(ProjectName)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\..\common\Telemetry;..\..\..\..\;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>UNIT_TESTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>gdiplus.lib;dwmapi.lib;shlwapi.lib;uxtheme.lib;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="FancyZones.Spec.cpp" />
<ClCompile Include="FancyZonesSettings.Spec.cpp" />
<ClCompile Include="JsonHelpers.Tests.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Util.Spec.cpp" />
<ClCompile Include="Util.cpp" />
<ClCompile Include="Zone.Spec.cpp" />
<ClCompile Include="ZoneSet.Spec.cpp" />
<ClCompile Include="ZoneWindow.Spec.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Util.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\Display\Display.vcxproj">
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\FancyZonesLib\FancyZonesLib.vcxproj">
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UnitTests-FancyZones.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200902.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200729.8\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View file

@ -1,67 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneSet.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Zone.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Util.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindow.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JsonHelpers.Tests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesSettings.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZones.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UnitTests-FancyZones.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneSet.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Zone.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Util.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZoneWindow.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JsonHelpers.Tests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZonesSettings.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FancyZones.Spec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="UnitTests-FancyZones.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View file

@ -1,6 +1,6 @@
#include "pch.h"
#include "Util.h"
#include "lib\util.h"
#include "FancyZonesLib\util.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;

View file

@ -1,77 +1,77 @@
#pragma once
#include "lib/FancyZonesDataTypes.h"
namespace CustomAssert
{
static void AreEqual(const RECT& r1, const RECT& r2)
{
const bool equal = ((r1.left == r2.left) && (r1.right == r2.right) && (r1.top == r2.top) && (r1.bottom == r2.bottom));
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(equal);
}
static void AreEqual(GUID g1, GUID g2)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(g1 == g2);
}
static void AreEqual(FancyZonesDataTypes::ZoneSetLayoutType t1, FancyZonesDataTypes::ZoneSetLayoutType t2)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(t1 == t2);
}
static void AreEqual(const std::vector<std::pair<HMONITOR, RECT>>& a1, const std::vector<std::pair<HMONITOR, RECT>>& a2)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(a1.size() == a2.size());
for (size_t i = 0; i < a1.size(); i++)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(a1[i].first == a2[i].first);
}
}
}
namespace Mocks
{
static HWND Window()
{
static UINT_PTR s_nextWindow = 0;
return reinterpret_cast<HWND>(++s_nextWindow);
}
static HMONITOR Monitor()
{
static UINT_PTR s_nextMonitor = 0;
return reinterpret_cast<HMONITOR>(++s_nextMonitor);
}
static HINSTANCE Instance()
{
static UINT_PTR s_nextInstance = 0;
return reinterpret_cast<HINSTANCE>(++s_nextInstance);
}
HWND WindowCreate(HINSTANCE hInst);
}
namespace Helpers
{
std::wstring GuidToString(const GUID& guid);
std::wstring CreateGuidString();
std::optional<GUID> StringToGuid(const std::wstring& str);
}
template<>
std::wstring Microsoft::VisualStudio::CppUnitTestFramework::ToString(const std::vector<int>& vec)
{
std::wstring str = L"{";
for (size_t i = 0; i < vec.size(); i++)
{
str += std::to_wstring(vec[i]);
if (i != vec.size() - 1)
{
str += L",";
}
}
str += L"}";
return str;
}
#pragma once
#include "FancyZonesLib/FancyZonesDataTypes.h"
namespace CustomAssert
{
static void AreEqual(const RECT& r1, const RECT& r2)
{
const bool equal = ((r1.left == r2.left) && (r1.right == r2.right) && (r1.top == r2.top) && (r1.bottom == r2.bottom));
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(equal);
}
static void AreEqual(GUID g1, GUID g2)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(g1 == g2);
}
static void AreEqual(FancyZonesDataTypes::ZoneSetLayoutType t1, FancyZonesDataTypes::ZoneSetLayoutType t2)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(t1 == t2);
}
static void AreEqual(const std::vector<std::pair<HMONITOR, RECT>>& a1, const std::vector<std::pair<HMONITOR, RECT>>& a2)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(a1.size() == a2.size());
for (size_t i = 0; i < a1.size(); i++)
{
Microsoft::VisualStudio::CppUnitTestFramework::Assert::IsTrue(a1[i].first == a2[i].first);
}
}
}
namespace Mocks
{
static HWND Window()
{
static UINT_PTR s_nextWindow = 0;
return reinterpret_cast<HWND>(++s_nextWindow);
}
static HMONITOR Monitor()
{
static UINT_PTR s_nextMonitor = 0;
return reinterpret_cast<HMONITOR>(++s_nextMonitor);
}
static HINSTANCE Instance()
{
static UINT_PTR s_nextInstance = 0;
return reinterpret_cast<HINSTANCE>(++s_nextInstance);
}
HWND WindowCreate(HINSTANCE hInst);
}
namespace Helpers
{
std::wstring GuidToString(const GUID& guid);
std::wstring CreateGuidString();
std::optional<GUID> StringToGuid(const std::wstring& str);
}
template<>
std::wstring Microsoft::VisualStudio::CppUnitTestFramework::ToString(const std::vector<int>& vec)
{
std::wstring str = L"{";
for (size_t i = 0; i < vec.size(); i++)
{
str += std::to_wstring(vec[i]);
if (i != vec.size() - 1)
{
str += L",";
}
}
str += L"}";
return str;
}

View file

@ -1,46 +1,46 @@
#include "pch.h"
#include "lib\Zone.h"
#include "lib\Settings.h"
#include "Util.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace FancyZonesUnitTests
{
TEST_CLASS(ZoneUnitTests)
{
private:
RECT m_zoneRect{ 10, 10, 200, 200 };
HINSTANCE m_hInst{};
TEST_METHOD_INITIALIZE(Init)
{
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
}
public:
TEST_METHOD(TestCreateZone)
{
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect, 1);
Assert::IsNotNull(&zone);
CustomAssert::AreEqual(m_zoneRect, zone->GetZoneRect());
}
TEST_METHOD(TestCreateZoneZeroRect)
{
RECT zoneRect{ 0, 0, 0, 0 };
winrt::com_ptr<IZone> zone = MakeZone(zoneRect, 1);
Assert::IsNotNull(&zone);
CustomAssert::AreEqual(zoneRect, zone->GetZoneRect());
}
TEST_METHOD(GetSetId)
{
constexpr size_t zoneId = 123;
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect, zoneId);
Assert::AreEqual(zone->Id(), zoneId);
}
};
}
#include "pch.h"
#include "FancyZonesLib\Zone.h"
#include "FancyZonesLib\Settings.h"
#include "Util.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace FancyZonesUnitTests
{
TEST_CLASS(ZoneUnitTests)
{
private:
RECT m_zoneRect{ 10, 10, 200, 200 };
HINSTANCE m_hInst{};
TEST_METHOD_INITIALIZE(Init)
{
m_hInst = (HINSTANCE)GetModuleHandleW(nullptr);
}
public:
TEST_METHOD(TestCreateZone)
{
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect, 1);
Assert::IsNotNull(&zone);
CustomAssert::AreEqual(m_zoneRect, zone->GetZoneRect());
}
TEST_METHOD(TestCreateZoneZeroRect)
{
RECT zoneRect{ 0, 0, 0, 0 };
winrt::com_ptr<IZone> zone = MakeZone(zoneRect, 1);
Assert::IsNotNull(&zone);
CustomAssert::AreEqual(zoneRect, zone->GetZoneRect());
}
TEST_METHOD(GetSetId)
{
constexpr size_t zoneId = 123;
winrt::com_ptr<IZone> zone = MakeZone(m_zoneRect, zoneId);
Assert::AreEqual(zone->Id(), zoneId);
}
};
}

View file

@ -2,13 +2,13 @@
#include <filesystem>
#include <lib/util.h>
#include <lib/ZoneSet.h>
#include <lib/ZoneWindow.h>
#include <lib/FancyZones.h>
#include <lib/FancyZonesData.h>
#include <lib/FancyZonesDataTypes.h>
#include <lib/JsonHelpers.h>
#include <FancyZonesLib/util.h>
#include <FancyZonesLib/ZoneSet.h>
#include <FancyZonesLib/ZoneWindow.h>
#include <FancyZonesLib/FancyZones.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/FancyZonesDataTypes.h>
#include <FancyZonesLib/JsonHelpers.h>
#include "Util.h"
#include <common/utils/process_path.h>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200902.2" targetFramework="native" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200729.8" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.200902.2" targetFramework="native" />
</packages>

View file

@ -1,5 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View file

@ -1,18 +1,18 @@
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include <Windows.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include "lib/pch.h"
#include "CppUnitTest.h"
#endif //PCH_H
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include <Windows.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include "FancyZonesLib/pch.h"
#include "CppUnitTest.h"
#endif //PCH_H

Some files were not shown because too many files have changed in this diff Show more