Display Unicode character for keys in HotkeySettingsControl (#2249)
* Fix HotkeyControl virtual key display * A new interop project was setup to provide wrappers for C# projects that want to access functionality in the common project. * Add assembly info * Remove WIN32 configurations
This commit is contained in:
parent
d45c4740ad
commit
93752fb6cb
|
@ -209,6 +209,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Setting
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerToys.Settings.UnitTest", "src\core\Microsoft.PowerToys.Settings.UnitTest\Microsoft.PowerToys.Settings.UnitTest.csproj", "{A80355C2-780D-4245-BD80-25B8DE698EE3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "interop", "src\common\interop\interop.vcxproj", "{F055103B-F80B-4D0C-BF48-057C55620033}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common-md-flag", "src\common\common-md-flag\common-md-flag.vcxproj", "{985B3F2F-CEED-4C0A-A249-69257E719145}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
|
@ -393,6 +397,14 @@ Global
|
|||
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x64.ActiveCfg = Release|x64
|
||||
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x64.Build.0 = Release|x64
|
||||
{A80355C2-780D-4245-BD80-25B8DE698EE3}.Release|x64.Deploy.0 = Release|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Debug|x64.Build.0 = Debug|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.ActiveCfg = Release|x64
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033}.Release|x64.Build.0 = Release|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Debug|x64.Build.0 = Debug|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x64.ActiveCfg = Release|x64
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -446,6 +458,8 @@ Global
|
|||
{C073B057-B157-40F0-8678-1DCD119D841C} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{A80355C2-780D-4245-BD80-25B8DE698EE3} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{F055103B-F80B-4D0C-BF48-057C55620033} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{985B3F2F-CEED-4C0A-A249-69257E719145} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
|
101
src/common/common-md-flag/common-md-flag.vcxproj
Normal file
101
src/common/common-md-flag/common-md-flag.vcxproj
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<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>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{985B3F2F-CEED-4C0A-A249-69257E719145}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>commonmdflag</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</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)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\keyboard_layout.h" />
|
||||
<ClInclude Include="..\keyboard_layout_impl.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\keyboard_layout.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
39
src/common/common-md-flag/common-md-flag.vcxproj.filters
Normal file
39
src/common/common-md-flag/common-md-flag.vcxproj.filters
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?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++;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>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\keyboard_layout.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\keyboard_layout_impl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\keyboard_layout.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
3
src/common/common-md-flag/framework.h
Normal file
3
src/common/common-md-flag/framework.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
5
src/common/common-md-flag/pch.cpp
Normal file
5
src/common/common-md-flag/pch.cpp
Normal file
|
@ -0,0 +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.
|
13
src/common/common-md-flag/pch.h
Normal file
13
src/common/common-md-flag/pch.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
// 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 "framework.h"
|
||||
|
||||
#endif //PCH_H
|
|
@ -121,6 +121,8 @@
|
|||
<ClInclude Include="d2d_window.h" />
|
||||
<ClInclude Include="dpi_aware.h" />
|
||||
<ClInclude Include="com_object_factory.h" />
|
||||
<ClInclude Include="keyboard_layout.h" />
|
||||
<ClInclude Include="keyboard_layout_impl.h" />
|
||||
<ClInclude Include="notifications.h" />
|
||||
<ClInclude Include="timeutil.h" />
|
||||
<ClInclude Include="VersionHelper.h" />
|
||||
|
@ -149,6 +151,7 @@
|
|||
<ClCompile Include="d2d_window.cpp" />
|
||||
<ClCompile Include="dpi_aware.cpp" />
|
||||
<ClCompile Include="json.cpp" />
|
||||
<ClCompile Include="keyboard_layout.cpp" />
|
||||
<ClCompile Include="monitors.cpp" />
|
||||
<ClCompile Include="notifications.cpp" />
|
||||
<ClCompile Include="on_thread_executor.cpp" />
|
||||
|
|
|
@ -99,6 +99,12 @@
|
|||
<ClInclude Include="com_object_factory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="keyboard_layout_impl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="keyboard_layout.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d2d_svg.cpp">
|
||||
|
@ -159,5 +165,11 @@
|
|||
<ClCompile Include="VersionHelper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="keyboard_layout.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
3
src/common/interop/Resource.h
Normal file
3
src/common/interop/Resource.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by app.rc
|
BIN
src/common/interop/app.ico
Normal file
BIN
src/common/interop/app.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
61
src/common/interop/app.rc
Normal file
61
src/common/interop/app.rc
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
⌀椀渀挀氀甀搀攀 ∀爀攀猀漀甀爀挀攀⸀栀∀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⌀搀攀昀椀渀攀 䄀倀匀吀唀䐀䤀伀开刀䔀䄀䐀伀一䰀夀开匀夀䴀䈀伀䰀匀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
⌀甀渀搀攀昀 䄀倀匀吀唀䐀䤀伀开刀䔀䄀䐀伀一䰀夀开匀夀䴀䈀伀䰀匀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ 䔀渀最氀椀猀栀 ⠀唀渀椀琀攀搀 匀琀愀琀攀猀⤀ 爀攀猀漀甀爀挀攀猀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ 䤀挀漀渀ഀ<EFBFBD>
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ 䤀挀漀渀 瀀氀愀挀攀搀 昀椀爀猀琀 漀爀 眀椀琀栀 氀漀眀攀猀琀 䤀䐀 瘀愀氀甀攀 戀攀挀漀洀攀猀 愀瀀瀀氀椀挀愀琀椀漀渀 椀挀漀渀ഀ<EFBFBD>
|
||||
䰀䄀一䜀唀䄀䜀䔀 㤀Ⰰ ഀ<EFBFBD>
|
||||
䤀䌀伀一 ∀愀瀀瀀⸀椀挀漀∀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⌀椀昀搀攀昀 䄀倀匀吀唀䐀䤀伀开䤀一嘀伀䬀䔀䐀ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ 吀䔀堀吀䤀一䌀䰀唀䐀䔀ഀ<EFBFBD>
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
吀䔀堀吀䤀一䌀䰀唀䐀䔀 ഀ<EFBFBD>
|
||||
䈀䔀䜀䤀一ഀ<EFBFBD>
|
||||
∀爀攀猀漀甀爀挀攀⸀栀尀 ∀ഀ<EFBFBD>
|
||||
∀尀 ∀ഀ<EFBFBD>
|
||||
䔀一䐀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
㈀ 吀䔀堀吀䤀一䌀䰀唀䐀䔀 ഀ<EFBFBD>
|
||||
䈀䔀䜀䤀一ഀ<EFBFBD>
|
||||
∀⌀椀渀挀氀甀搀攀 ∀∀愀昀砀爀攀猀⸀栀∀∀尀爀尀渀∀ഀ<EFBFBD>
|
||||
∀尀 ∀ഀ<EFBFBD>
|
||||
䔀一䐀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
㌀ 吀䔀堀吀䤀一䌀䰀唀䐀䔀 ഀ<EFBFBD>
|
||||
䈀䔀䜀䤀一ഀ<EFBFBD>
|
||||
∀尀 ∀ഀ<EFBFBD>
|
||||
䔀一䐀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⌀攀渀搀椀昀 ⼀⼀ 䄀倀匀吀唀䐀䤀伀开䤀一嘀伀䬀䔀䐀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⌀椀昀渀搀攀昀 䄀倀匀吀唀䐀䤀伀开䤀一嘀伀䬀䔀䐀ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
⼀⼀ 䜀攀渀攀爀愀琀攀搀 昀爀漀洀 琀栀攀 吀䔀堀吀䤀一䌀䰀唀䐀䔀 ㌀ 爀攀猀漀甀爀挀攀⸀ഀ<EFBFBD>
|
||||
⼀⼀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀⼀ഀ<EFBFBD>
|
||||
⌀攀渀搀椀昀 ⼀⼀ 渀漀琀 䄀倀匀吀唀䐀䤀伀开䤀一嘀伀䬀䔀䐀ഀ<EFBFBD>
|
||||
ഀ<EFBFBD>
|
||||
<EFBFBD>
|
4
src/common/interop/interop.cpp
Normal file
4
src/common/interop/interop.cpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include "interop.h"
|
||||
|
40
src/common/interop/interop.h
Normal file
40
src/common/interop/interop.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <common\keyboard_layout.h>
|
||||
using namespace System;
|
||||
|
||||
//https://docs.microsoft.com/en-us/cpp/dotnet/how-to-wrap-native-class-for-use-by-csharp?view=vs-2019
|
||||
namespace interop
|
||||
{
|
||||
public ref class LayoutMapManaged
|
||||
{
|
||||
public:
|
||||
LayoutMapManaged() :
|
||||
_map(new LayoutMap) {}
|
||||
|
||||
~LayoutMapManaged()
|
||||
{
|
||||
delete _map;
|
||||
}
|
||||
|
||||
String ^ GetKeyName(DWORD key)
|
||||
{
|
||||
return gcnew String(_map->GetKeyName(key).c_str());
|
||||
}
|
||||
|
||||
void Updatelayout()
|
||||
{
|
||||
_map->UpdateLayout();
|
||||
}
|
||||
|
||||
protected:
|
||||
!LayoutMapManaged()
|
||||
{
|
||||
delete _map;
|
||||
}
|
||||
|
||||
private:
|
||||
LayoutMap* _map;
|
||||
};
|
||||
}
|
||||
|
150
src/common/interop/interop.vcxproj
Normal file
150
src/common/interop/interop.vcxproj
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\installer\Version.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>PowerToysInterop</AssemblyTitle>
|
||||
<AssemblyCompany>Microsoft Corp.</AssemblyCompany>
|
||||
<AssemblyCopyright>Copyright (C) 2019 Microsoft Corp.</AssemblyCopyright>
|
||||
</PropertyGroup>
|
||||
<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>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{F055103B-F80B-4D0C-BF48-057C55620033}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>interop</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</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'">
|
||||
<TargetName>PowerToysInterop</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>PowerToysInterop</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)src\common\interop;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<OmitDefaultLibName>false</OmitDefaultLibName>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>
|
||||
</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)src\common\interop;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>
|
||||
</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<AssemblyVersionFiles Include="Generated Files\AssemblyInfo.cpp" />
|
||||
</ItemGroup>
|
||||
<Target Name="GenerateAssemblyInfo" BeforeTargets="PrepareForBuild">
|
||||
<ItemGroup>
|
||||
<HeaderLines Include="#include <pch.h> " />
|
||||
<HeaderLines Include="using namespace System%3b" />
|
||||
<HeaderLines Include="using namespace System::Reflection%3b" />
|
||||
<HeaderLines Include="using namespace System::Runtime::CompilerServices%3b" />
|
||||
<HeaderLines Include="using namespace System::Runtime::InteropServices%3b" />
|
||||
<HeaderLines Include="using namespace System::Security::Permissions%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyTitleAttribute(L"$(AssemblyTitle)")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyDescriptionAttribute("")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyConfigurationAttribute("")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyCompanyAttribute("$(AssemblyCompany)")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyCopyrightAttribute("$(AssemblyCopyright)")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyProductAttribute("$(AssemblyTitle)")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyTrademarkAttribute("")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyCultureAttribute("")]%3b" />
|
||||
<HeaderLines Include="[assembly: AssemblyVersionAttribute("$(Version).0")]%3b" />
|
||||
<HeaderLines Include="[assembly: ComVisible(false)]%3b" />
|
||||
<HeaderLines Include="[assembly:CLSCompliantAttribute(true)]%3b" />
|
||||
</ItemGroup>
|
||||
<WriteLinesToFile File="Generated Files\AssemblyInfo.cpp" Lines="@(HeaderLines)" Overwrite="true" Encoding="Unicode" WriteOnlyWhenDifferent="true" />
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="interop.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Generated Files\AssemblyInfo.cpp" />
|
||||
<ClCompile Include="interop.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="app.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="app.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\common-md-flag\common-md-flag.vcxproj">
|
||||
<Project>{985b3f2f-ceed-4c0a-a249-69257e719145}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
49
src/common/interop/interop.vcxproj.filters
Normal file
49
src/common/interop/interop.vcxproj.filters
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?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++;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>
|
||||
<ClInclude Include="interop.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="interop.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Generated Files\AssemblyInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="app.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="app.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
5
src/common/interop/pch.cpp
Normal file
5
src/common/interop/pch.cpp
Normal file
|
@ -0,0 +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.
|
12
src/common/interop/pch.h
Normal file
12
src/common/interop/pch.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
// 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
|
||||
|
||||
#endif //PCH_H
|
|
@ -1,276 +1,302 @@
|
|||
#include "pch.h"
|
||||
#include "LayoutMap.h"
|
||||
|
||||
// Function to return the unicode string name of the key
|
||||
std::wstring LayoutMap::GetKeyName(DWORD key)
|
||||
{
|
||||
std::wstring result = L"Undefined";
|
||||
std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);
|
||||
UpdateLayout();
|
||||
|
||||
auto it = keyboardLayoutMap.find(key);
|
||||
if (it != keyboardLayoutMap.end())
|
||||
{
|
||||
result = it->second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Update Keyboard layout according to input locale identifier
|
||||
void LayoutMap::UpdateLayout()
|
||||
{
|
||||
// Get keyboard layout for current thread
|
||||
HKL layout = GetKeyboardLayout(0);
|
||||
if (layout == previousLayout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
previousLayout = layout;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
unicodeKeys.clear();
|
||||
unknownKeys.clear();
|
||||
}
|
||||
|
||||
unsigned char* btKeys = new unsigned char[256]{ 0 };
|
||||
GetKeyboardState(btKeys);
|
||||
|
||||
// Iterate over all the virtual key codes. virtual key 0 is not used
|
||||
for (int i = 1; i < 256; i++)
|
||||
{
|
||||
// Get the scan code from the virtual key code
|
||||
UINT scanCode = MapVirtualKeyExW(i, MAPVK_VK_TO_VSC, layout);
|
||||
// Get the unicode representation from the virtual key code and scan code pair to
|
||||
wchar_t szBuffer[3] = { 0 };
|
||||
int result = ToUnicodeEx(i, scanCode, (BYTE*)btKeys, szBuffer, 3, 0, layout);
|
||||
// If a representation is returned
|
||||
if (result > 0)
|
||||
{
|
||||
keyboardLayoutMap[i] = szBuffer;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
unicodeKeys[i] = szBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store the virtual key code as string
|
||||
std::wstring vk = L"VK ";
|
||||
vk += std::to_wstring(i);
|
||||
keyboardLayoutMap[i] = vk;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
unknownKeys[i] = vk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] btKeys;
|
||||
|
||||
// Override special key names like Shift, Ctrl etc because they don't have unicode mappings and key names like Enter, Space as they appear as "\r", " "
|
||||
// To do: localization
|
||||
keyboardLayoutMap[VK_CANCEL] = L"Break";
|
||||
keyboardLayoutMap[VK_BACK] = L"Backspace";
|
||||
keyboardLayoutMap[VK_TAB] = L"Tab";
|
||||
keyboardLayoutMap[VK_CLEAR] = L"Clear";
|
||||
keyboardLayoutMap[VK_RETURN] = L"Enter";
|
||||
keyboardLayoutMap[VK_SHIFT] = L"Shift";
|
||||
keyboardLayoutMap[VK_CONTROL] = L"Ctrl";
|
||||
keyboardLayoutMap[VK_MENU] = L"Alt";
|
||||
keyboardLayoutMap[VK_PAUSE] = L"Pause";
|
||||
keyboardLayoutMap[VK_CAPITAL] = L"Caps Lock";
|
||||
keyboardLayoutMap[VK_ESCAPE] = L"Esc";
|
||||
keyboardLayoutMap[VK_SPACE] = L"Space";
|
||||
keyboardLayoutMap[VK_PRIOR] = L"PgUp";
|
||||
keyboardLayoutMap[VK_NEXT] = L"PgDn";
|
||||
keyboardLayoutMap[VK_END] = L"End";
|
||||
keyboardLayoutMap[VK_HOME] = L"Home";
|
||||
keyboardLayoutMap[VK_LEFT] = L"Left";
|
||||
keyboardLayoutMap[VK_UP] = L"Up";
|
||||
keyboardLayoutMap[VK_RIGHT] = L"Right";
|
||||
keyboardLayoutMap[VK_DOWN] = L"Down";
|
||||
keyboardLayoutMap[VK_SELECT] = L"Select";
|
||||
keyboardLayoutMap[VK_PRINT] = L"Print";
|
||||
keyboardLayoutMap[VK_EXECUTE] = L"Execute";
|
||||
keyboardLayoutMap[VK_SNAPSHOT] = L"Print Screen";
|
||||
keyboardLayoutMap[VK_INSERT] = L"Insert";
|
||||
keyboardLayoutMap[VK_DELETE] = L"Delete";
|
||||
keyboardLayoutMap[VK_HELP] = L"Help";
|
||||
keyboardLayoutMap[VK_LWIN] = L"LWin";
|
||||
keyboardLayoutMap[VK_RWIN] = L"RWin";
|
||||
keyboardLayoutMap[VK_APPS] = L"Menu";
|
||||
keyboardLayoutMap[VK_SLEEP] = L"Sleep";
|
||||
keyboardLayoutMap[VK_NUMPAD0] = L"NumPad 0";
|
||||
keyboardLayoutMap[VK_NUMPAD1] = L"NumPad 1";
|
||||
keyboardLayoutMap[VK_NUMPAD2] = L"NumPad 2";
|
||||
keyboardLayoutMap[VK_NUMPAD3] = L"NumPad 3";
|
||||
keyboardLayoutMap[VK_NUMPAD4] = L"NumPad 4";
|
||||
keyboardLayoutMap[VK_NUMPAD5] = L"NumPad 5";
|
||||
keyboardLayoutMap[VK_NUMPAD6] = L"NumPad 6";
|
||||
keyboardLayoutMap[VK_NUMPAD7] = L"NumPad 7";
|
||||
keyboardLayoutMap[VK_NUMPAD8] = L"NumPad 8";
|
||||
keyboardLayoutMap[VK_NUMPAD9] = L"NumPad 9";
|
||||
keyboardLayoutMap[VK_SEPARATOR] = L"Separator";
|
||||
keyboardLayoutMap[VK_F1] = L"F1";
|
||||
keyboardLayoutMap[VK_F2] = L"F2";
|
||||
keyboardLayoutMap[VK_F3] = L"F3";
|
||||
keyboardLayoutMap[VK_F4] = L"F4";
|
||||
keyboardLayoutMap[VK_F5] = L"F5";
|
||||
keyboardLayoutMap[VK_F6] = L"F6";
|
||||
keyboardLayoutMap[VK_F7] = L"F7";
|
||||
keyboardLayoutMap[VK_F8] = L"F8";
|
||||
keyboardLayoutMap[VK_F9] = L"F9";
|
||||
keyboardLayoutMap[VK_F10] = L"F10";
|
||||
keyboardLayoutMap[VK_F11] = L"F11";
|
||||
keyboardLayoutMap[VK_F12] = L"F12";
|
||||
keyboardLayoutMap[VK_F13] = L"F13";
|
||||
keyboardLayoutMap[VK_F14] = L"F14";
|
||||
keyboardLayoutMap[VK_F15] = L"F15";
|
||||
keyboardLayoutMap[VK_F16] = L"F16";
|
||||
keyboardLayoutMap[VK_F17] = L"F17";
|
||||
keyboardLayoutMap[VK_F18] = L"F18";
|
||||
keyboardLayoutMap[VK_F19] = L"F19";
|
||||
keyboardLayoutMap[VK_F20] = L"F20";
|
||||
keyboardLayoutMap[VK_F21] = L"F21";
|
||||
keyboardLayoutMap[VK_F22] = L"F22";
|
||||
keyboardLayoutMap[VK_F23] = L"F23";
|
||||
keyboardLayoutMap[VK_F24] = L"F24";
|
||||
keyboardLayoutMap[VK_NUMLOCK] = L"Num Lock";
|
||||
keyboardLayoutMap[VK_SCROLL] = L"Scroll Lock";
|
||||
keyboardLayoutMap[VK_LSHIFT] = L"LShift";
|
||||
keyboardLayoutMap[VK_RSHIFT] = L"RShift";
|
||||
keyboardLayoutMap[VK_LCONTROL] = L"LCtrl";
|
||||
keyboardLayoutMap[VK_RCONTROL] = L"RCtrl";
|
||||
keyboardLayoutMap[VK_LMENU] = L"LAlt";
|
||||
keyboardLayoutMap[VK_RMENU] = L"RAlt";
|
||||
keyboardLayoutMap[VK_BROWSER_BACK] = L"Browser Back";
|
||||
keyboardLayoutMap[VK_BROWSER_FORWARD] = L"Browser Forward";
|
||||
keyboardLayoutMap[VK_BROWSER_REFRESH] = L"Browser Refresh";
|
||||
keyboardLayoutMap[VK_BROWSER_STOP] = L"Browser Stop";
|
||||
keyboardLayoutMap[VK_BROWSER_SEARCH] = L"Browser Search";
|
||||
keyboardLayoutMap[VK_BROWSER_FAVORITES] = L"Browser Favorites";
|
||||
keyboardLayoutMap[VK_BROWSER_HOME] = L"Browser Start & Home";
|
||||
keyboardLayoutMap[VK_VOLUME_MUTE] = L"Volume Mute";
|
||||
keyboardLayoutMap[VK_VOLUME_DOWN] = L"Volume Down";
|
||||
keyboardLayoutMap[VK_VOLUME_UP] = L"Volume Up";
|
||||
keyboardLayoutMap[VK_MEDIA_NEXT_TRACK] = L"Next Track";
|
||||
keyboardLayoutMap[VK_MEDIA_PREV_TRACK] = L"Previous Track";
|
||||
keyboardLayoutMap[VK_MEDIA_STOP] = L"Stop Media";
|
||||
keyboardLayoutMap[VK_MEDIA_PLAY_PAUSE] = L"Play/Pause Media";
|
||||
keyboardLayoutMap[VK_LAUNCH_MAIL] = L"Start Mail";
|
||||
keyboardLayoutMap[VK_LAUNCH_MEDIA_SELECT] = L"Select Media";
|
||||
keyboardLayoutMap[VK_LAUNCH_APP1] = L"Start Application 1";
|
||||
keyboardLayoutMap[VK_LAUNCH_APP2] = L"Start Application 2";
|
||||
keyboardLayoutMap[VK_PACKET] = L"Packet";
|
||||
keyboardLayoutMap[VK_ATTN] = L"Attn";
|
||||
keyboardLayoutMap[VK_CRSEL] = L"CrSel";
|
||||
keyboardLayoutMap[VK_EXSEL] = L"ExSel";
|
||||
keyboardLayoutMap[VK_EREOF] = L"Erase EOF";
|
||||
keyboardLayoutMap[VK_PLAY] = L"Play";
|
||||
keyboardLayoutMap[VK_ZOOM] = L"Zoom";
|
||||
keyboardLayoutMap[VK_PA1] = L"PA1";
|
||||
keyboardLayoutMap[VK_OEM_CLEAR] = L"Clear";
|
||||
keyboardLayoutMap[0xFF] = L"Undefined";
|
||||
// To do: Add IME key names
|
||||
}
|
||||
|
||||
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
|
||||
std::vector<DWORD> LayoutMap::GetKeyCodeList(const bool isShortcut)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);
|
||||
UpdateLayout();
|
||||
std::vector<DWORD> keyCodes;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
// Add modifier keys
|
||||
keyCodes.push_back(VK_LWIN);
|
||||
keyCodes.push_back(VK_RWIN);
|
||||
keyCodes.push_back(VK_CONTROL);
|
||||
keyCodes.push_back(VK_LCONTROL);
|
||||
keyCodes.push_back(VK_RCONTROL);
|
||||
keyCodes.push_back(VK_MENU);
|
||||
keyCodes.push_back(VK_LMENU);
|
||||
keyCodes.push_back(VK_RMENU);
|
||||
keyCodes.push_back(VK_SHIFT);
|
||||
keyCodes.push_back(VK_LSHIFT);
|
||||
keyCodes.push_back(VK_RSHIFT);
|
||||
// Add character keys
|
||||
for (auto& it : unicodeKeys)
|
||||
{
|
||||
// If it was not renamed with a special name
|
||||
if (it.second == keyboardLayoutMap[it.first])
|
||||
{
|
||||
keyCodes.push_back(it.first);
|
||||
}
|
||||
}
|
||||
// Add all other special keys
|
||||
for (int i = 1; i < 256; i++)
|
||||
{
|
||||
// If it is not already been added (i.e. it was either a modifier or had a unicode representation)
|
||||
if (std::find(keyCodes.begin(), keyCodes.end(), i) == keyCodes.end())
|
||||
{
|
||||
// If it is any other key but it is not named as VK #
|
||||
auto it = unknownKeys.find(i);
|
||||
if (it == unknownKeys.end())
|
||||
{
|
||||
keyCodes.push_back(i);
|
||||
}
|
||||
else if (unknownKeys[i] != keyboardLayoutMap[i])
|
||||
{
|
||||
keyCodes.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add unknown keys
|
||||
for (auto& it : unknownKeys)
|
||||
{
|
||||
// If it was not renamed with a special name
|
||||
if (it.second == keyboardLayoutMap[it.first])
|
||||
{
|
||||
keyCodes.push_back(it.first);
|
||||
}
|
||||
}
|
||||
keyCodeList = keyCodes;
|
||||
isKeyCodeListGenerated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyCodes = keyCodeList;
|
||||
}
|
||||
|
||||
// If it is a key list for the shortcut control then we add a "None" key at the start
|
||||
if (isShortcut)
|
||||
{
|
||||
keyCodes.insert(keyCodes.begin(), 0);
|
||||
}
|
||||
|
||||
return keyCodes;
|
||||
}
|
||||
|
||||
Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> LayoutMap::GetKeyNameList(const bool isShortcut)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(keyboardLayoutMap_mutex);
|
||||
UpdateLayout();
|
||||
lock.unlock();
|
||||
Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> keyNames = single_threaded_vector<Windows::Foundation::IInspectable>();
|
||||
std::vector<DWORD> keyCodes = GetKeyCodeList(isShortcut);
|
||||
lock.lock();
|
||||
// If it is a key list for the shortcut control then we add a "None" key at the start
|
||||
if (isShortcut)
|
||||
{
|
||||
keyNames.Append(winrt::box_value(L"None"));
|
||||
for (int i = 1; i < keyCodes.size(); i++)
|
||||
{
|
||||
keyNames.Append(winrt::box_value(keyboardLayoutMap[keyCodes[i]].c_str()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < keyCodes.size(); i++)
|
||||
{
|
||||
keyNames.Append(winrt::box_value(keyboardLayoutMap[keyCodes[i]].c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
return keyNames;
|
||||
}
|
||||
#include "pch.h"
|
||||
#include "keyboard_layout_impl.h"
|
||||
|
||||
LayoutMap::LayoutMap() :
|
||||
impl(new LayoutMap::LayoutMapImpl())
|
||||
{
|
||||
}
|
||||
|
||||
LayoutMap::~LayoutMap()
|
||||
{
|
||||
delete impl;
|
||||
}
|
||||
|
||||
void LayoutMap::UpdateLayout()
|
||||
{
|
||||
impl->UpdateLayout();
|
||||
}
|
||||
|
||||
std::wstring LayoutMap::GetKeyName(DWORD key)
|
||||
{
|
||||
return impl->GetKeyName(key);
|
||||
}
|
||||
|
||||
std::vector<DWORD> LayoutMap::GetKeyCodeList(const bool isShortcut)
|
||||
{
|
||||
return impl->GetKeyCodeList(isShortcut);
|
||||
}
|
||||
|
||||
std::vector<std::wstring> LayoutMap::GetKeyNameList(const bool isShortcut)
|
||||
{
|
||||
return impl->GetKeyNameList(isShortcut);
|
||||
}
|
||||
|
||||
// Function to return the unicode string name of the key
|
||||
std::wstring LayoutMap::LayoutMapImpl::GetKeyName(DWORD key)
|
||||
{
|
||||
std::wstring result = L"Undefined";
|
||||
std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);
|
||||
UpdateLayout();
|
||||
|
||||
auto it = keyboardLayoutMap.find(key);
|
||||
if (it != keyboardLayoutMap.end())
|
||||
{
|
||||
result = it->second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Update Keyboard layout according to input locale identifier
|
||||
void LayoutMap::LayoutMapImpl::UpdateLayout()
|
||||
{
|
||||
// Get keyboard layout for current thread
|
||||
HKL layout = GetKeyboardLayout(0);
|
||||
if (layout == previousLayout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
previousLayout = layout;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
unicodeKeys.clear();
|
||||
unknownKeys.clear();
|
||||
}
|
||||
|
||||
unsigned char* btKeys = new unsigned char[256]{ 0 };
|
||||
GetKeyboardState(btKeys);
|
||||
|
||||
// Iterate over all the virtual key codes. virtual key 0 is not used
|
||||
for (int i = 1; i < 256; i++)
|
||||
{
|
||||
// Get the scan code from the virtual key code
|
||||
UINT scanCode = MapVirtualKeyExW(i, MAPVK_VK_TO_VSC, layout);
|
||||
// Get the unicode representation from the virtual key code and scan code pair to
|
||||
wchar_t szBuffer[3] = { 0 };
|
||||
int result = ToUnicodeEx(i, scanCode, (BYTE*)btKeys, szBuffer, 3, 0, layout);
|
||||
// If a representation is returned
|
||||
if (result > 0)
|
||||
{
|
||||
keyboardLayoutMap[i] = szBuffer;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
unicodeKeys[i] = szBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store the virtual key code as string
|
||||
std::wstring vk = L"VK ";
|
||||
vk += std::to_wstring(i);
|
||||
keyboardLayoutMap[i] = vk;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
unknownKeys[i] = vk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] btKeys;
|
||||
|
||||
// Override special key names like Shift, Ctrl etc because they don't have unicode mappings and key names like Enter, Space as they appear as "\r", " "
|
||||
// To do: localization
|
||||
keyboardLayoutMap[VK_CANCEL] = L"Break";
|
||||
keyboardLayoutMap[VK_BACK] = L"Backspace";
|
||||
keyboardLayoutMap[VK_TAB] = L"Tab";
|
||||
keyboardLayoutMap[VK_CLEAR] = L"Clear";
|
||||
keyboardLayoutMap[VK_RETURN] = L"Enter";
|
||||
keyboardLayoutMap[VK_SHIFT] = L"Shift";
|
||||
keyboardLayoutMap[VK_CONTROL] = L"Ctrl";
|
||||
keyboardLayoutMap[VK_MENU] = L"Alt";
|
||||
keyboardLayoutMap[VK_PAUSE] = L"Pause";
|
||||
keyboardLayoutMap[VK_CAPITAL] = L"Caps Lock";
|
||||
keyboardLayoutMap[VK_ESCAPE] = L"Esc";
|
||||
keyboardLayoutMap[VK_SPACE] = L"Space";
|
||||
keyboardLayoutMap[VK_PRIOR] = L"PgUp";
|
||||
keyboardLayoutMap[VK_NEXT] = L"PgDn";
|
||||
keyboardLayoutMap[VK_END] = L"End";
|
||||
keyboardLayoutMap[VK_HOME] = L"Home";
|
||||
keyboardLayoutMap[VK_LEFT] = L"Left";
|
||||
keyboardLayoutMap[VK_UP] = L"Up";
|
||||
keyboardLayoutMap[VK_RIGHT] = L"Right";
|
||||
keyboardLayoutMap[VK_DOWN] = L"Down";
|
||||
keyboardLayoutMap[VK_SELECT] = L"Select";
|
||||
keyboardLayoutMap[VK_PRINT] = L"Print";
|
||||
keyboardLayoutMap[VK_EXECUTE] = L"Execute";
|
||||
keyboardLayoutMap[VK_SNAPSHOT] = L"Print Screen";
|
||||
keyboardLayoutMap[VK_INSERT] = L"Insert";
|
||||
keyboardLayoutMap[VK_DELETE] = L"Delete";
|
||||
keyboardLayoutMap[VK_HELP] = L"Help";
|
||||
keyboardLayoutMap[VK_LWIN] = L"LWin";
|
||||
keyboardLayoutMap[VK_RWIN] = L"RWin";
|
||||
keyboardLayoutMap[VK_APPS] = L"Menu";
|
||||
keyboardLayoutMap[VK_SLEEP] = L"Sleep";
|
||||
keyboardLayoutMap[VK_NUMPAD0] = L"NumPad 0";
|
||||
keyboardLayoutMap[VK_NUMPAD1] = L"NumPad 1";
|
||||
keyboardLayoutMap[VK_NUMPAD2] = L"NumPad 2";
|
||||
keyboardLayoutMap[VK_NUMPAD3] = L"NumPad 3";
|
||||
keyboardLayoutMap[VK_NUMPAD4] = L"NumPad 4";
|
||||
keyboardLayoutMap[VK_NUMPAD5] = L"NumPad 5";
|
||||
keyboardLayoutMap[VK_NUMPAD6] = L"NumPad 6";
|
||||
keyboardLayoutMap[VK_NUMPAD7] = L"NumPad 7";
|
||||
keyboardLayoutMap[VK_NUMPAD8] = L"NumPad 8";
|
||||
keyboardLayoutMap[VK_NUMPAD9] = L"NumPad 9";
|
||||
keyboardLayoutMap[VK_SEPARATOR] = L"Separator";
|
||||
keyboardLayoutMap[VK_F1] = L"F1";
|
||||
keyboardLayoutMap[VK_F2] = L"F2";
|
||||
keyboardLayoutMap[VK_F3] = L"F3";
|
||||
keyboardLayoutMap[VK_F4] = L"F4";
|
||||
keyboardLayoutMap[VK_F5] = L"F5";
|
||||
keyboardLayoutMap[VK_F6] = L"F6";
|
||||
keyboardLayoutMap[VK_F7] = L"F7";
|
||||
keyboardLayoutMap[VK_F8] = L"F8";
|
||||
keyboardLayoutMap[VK_F9] = L"F9";
|
||||
keyboardLayoutMap[VK_F10] = L"F10";
|
||||
keyboardLayoutMap[VK_F11] = L"F11";
|
||||
keyboardLayoutMap[VK_F12] = L"F12";
|
||||
keyboardLayoutMap[VK_F13] = L"F13";
|
||||
keyboardLayoutMap[VK_F14] = L"F14";
|
||||
keyboardLayoutMap[VK_F15] = L"F15";
|
||||
keyboardLayoutMap[VK_F16] = L"F16";
|
||||
keyboardLayoutMap[VK_F17] = L"F17";
|
||||
keyboardLayoutMap[VK_F18] = L"F18";
|
||||
keyboardLayoutMap[VK_F19] = L"F19";
|
||||
keyboardLayoutMap[VK_F20] = L"F20";
|
||||
keyboardLayoutMap[VK_F21] = L"F21";
|
||||
keyboardLayoutMap[VK_F22] = L"F22";
|
||||
keyboardLayoutMap[VK_F23] = L"F23";
|
||||
keyboardLayoutMap[VK_F24] = L"F24";
|
||||
keyboardLayoutMap[VK_NUMLOCK] = L"Num Lock";
|
||||
keyboardLayoutMap[VK_SCROLL] = L"Scroll Lock";
|
||||
keyboardLayoutMap[VK_LSHIFT] = L"LShift";
|
||||
keyboardLayoutMap[VK_RSHIFT] = L"RShift";
|
||||
keyboardLayoutMap[VK_LCONTROL] = L"LCtrl";
|
||||
keyboardLayoutMap[VK_RCONTROL] = L"RCtrl";
|
||||
keyboardLayoutMap[VK_LMENU] = L"LAlt";
|
||||
keyboardLayoutMap[VK_RMENU] = L"RAlt";
|
||||
keyboardLayoutMap[VK_BROWSER_BACK] = L"Browser Back";
|
||||
keyboardLayoutMap[VK_BROWSER_FORWARD] = L"Browser Forward";
|
||||
keyboardLayoutMap[VK_BROWSER_REFRESH] = L"Browser Refresh";
|
||||
keyboardLayoutMap[VK_BROWSER_STOP] = L"Browser Stop";
|
||||
keyboardLayoutMap[VK_BROWSER_SEARCH] = L"Browser Search";
|
||||
keyboardLayoutMap[VK_BROWSER_FAVORITES] = L"Browser Favorites";
|
||||
keyboardLayoutMap[VK_BROWSER_HOME] = L"Browser Start & Home";
|
||||
keyboardLayoutMap[VK_VOLUME_MUTE] = L"Volume Mute";
|
||||
keyboardLayoutMap[VK_VOLUME_DOWN] = L"Volume Down";
|
||||
keyboardLayoutMap[VK_VOLUME_UP] = L"Volume Up";
|
||||
keyboardLayoutMap[VK_MEDIA_NEXT_TRACK] = L"Next Track";
|
||||
keyboardLayoutMap[VK_MEDIA_PREV_TRACK] = L"Previous Track";
|
||||
keyboardLayoutMap[VK_MEDIA_STOP] = L"Stop Media";
|
||||
keyboardLayoutMap[VK_MEDIA_PLAY_PAUSE] = L"Play/Pause Media";
|
||||
keyboardLayoutMap[VK_LAUNCH_MAIL] = L"Start Mail";
|
||||
keyboardLayoutMap[VK_LAUNCH_MEDIA_SELECT] = L"Select Media";
|
||||
keyboardLayoutMap[VK_LAUNCH_APP1] = L"Start Application 1";
|
||||
keyboardLayoutMap[VK_LAUNCH_APP2] = L"Start Application 2";
|
||||
keyboardLayoutMap[VK_PACKET] = L"Packet";
|
||||
keyboardLayoutMap[VK_ATTN] = L"Attn";
|
||||
keyboardLayoutMap[VK_CRSEL] = L"CrSel";
|
||||
keyboardLayoutMap[VK_EXSEL] = L"ExSel";
|
||||
keyboardLayoutMap[VK_EREOF] = L"Erase EOF";
|
||||
keyboardLayoutMap[VK_PLAY] = L"Play";
|
||||
keyboardLayoutMap[VK_ZOOM] = L"Zoom";
|
||||
keyboardLayoutMap[VK_PA1] = L"PA1";
|
||||
keyboardLayoutMap[VK_OEM_CLEAR] = L"Clear";
|
||||
keyboardLayoutMap[0xFF] = L"Undefined";
|
||||
// To do: Add IME key names
|
||||
}
|
||||
|
||||
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
|
||||
std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcut)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);
|
||||
UpdateLayout();
|
||||
std::vector<DWORD> keyCodes;
|
||||
if (!isKeyCodeListGenerated)
|
||||
{
|
||||
// Add modifier keys
|
||||
keyCodes.push_back(VK_LWIN);
|
||||
keyCodes.push_back(VK_RWIN);
|
||||
keyCodes.push_back(VK_CONTROL);
|
||||
keyCodes.push_back(VK_LCONTROL);
|
||||
keyCodes.push_back(VK_RCONTROL);
|
||||
keyCodes.push_back(VK_MENU);
|
||||
keyCodes.push_back(VK_LMENU);
|
||||
keyCodes.push_back(VK_RMENU);
|
||||
keyCodes.push_back(VK_SHIFT);
|
||||
keyCodes.push_back(VK_LSHIFT);
|
||||
keyCodes.push_back(VK_RSHIFT);
|
||||
// Add character keys
|
||||
for (auto& it : unicodeKeys)
|
||||
{
|
||||
// If it was not renamed with a special name
|
||||
if (it.second == keyboardLayoutMap[it.first])
|
||||
{
|
||||
keyCodes.push_back(it.first);
|
||||
}
|
||||
}
|
||||
// Add all other special keys
|
||||
for (int i = 1; i < 256; i++)
|
||||
{
|
||||
// If it is not already been added (i.e. it was either a modifier or had a unicode representation)
|
||||
if (std::find(keyCodes.begin(), keyCodes.end(), i) == keyCodes.end())
|
||||
{
|
||||
// If it is any other key but it is not named as VK #
|
||||
auto it = unknownKeys.find(i);
|
||||
if (it == unknownKeys.end())
|
||||
{
|
||||
keyCodes.push_back(i);
|
||||
}
|
||||
else if (unknownKeys[i] != keyboardLayoutMap[i])
|
||||
{
|
||||
keyCodes.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add unknown keys
|
||||
for (auto& it : unknownKeys)
|
||||
{
|
||||
// If it was not renamed with a special name
|
||||
if (it.second == keyboardLayoutMap[it.first])
|
||||
{
|
||||
keyCodes.push_back(it.first);
|
||||
}
|
||||
}
|
||||
keyCodeList = keyCodes;
|
||||
isKeyCodeListGenerated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyCodes = keyCodeList;
|
||||
}
|
||||
|
||||
// If it is a key list for the shortcut control then we add a "None" key at the start
|
||||
if (isShortcut)
|
||||
{
|
||||
keyCodes.insert(keyCodes.begin(), 0);
|
||||
}
|
||||
|
||||
return keyCodes;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut)
|
||||
{
|
||||
std::vector<std::wstring> keyNames;
|
||||
std::vector<DWORD> keyCodes = GetKeyCodeList(isShortcut);
|
||||
// If it is a key list for the shortcut control then we add a "None" key at the start
|
||||
if (isShortcut)
|
||||
{
|
||||
keyNames.push_back(L"None");
|
||||
for (int i = 1; i < keyCodes.size(); i++)
|
||||
{
|
||||
keyNames.push_back(GetKeyName(keyCodes[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < keyCodes.size(); i++)
|
||||
{
|
||||
keyNames.push_back(GetKeyName(keyCodes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return keyNames;
|
||||
}
|
20
src/common/keyboard_layout.h
Normal file
20
src/common/keyboard_layout.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <Windows.h>
|
||||
|
||||
class LayoutMap
|
||||
{
|
||||
public:
|
||||
LayoutMap();
|
||||
~LayoutMap();
|
||||
void UpdateLayout();
|
||||
std::wstring GetKeyName(DWORD key);
|
||||
std::vector<DWORD> GetKeyCodeList(const bool isShortcut = false);
|
||||
std::vector<std::wstring> GetKeyNameList(const bool isShortcut = false);
|
||||
|
||||
private:
|
||||
class LayoutMapImpl;
|
||||
LayoutMapImpl* impl;
|
||||
};
|
|
@ -1,51 +1,52 @@
|
|||
#pragma once
|
||||
#include <interface/lowlevel_keyboard_event_data.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <windows.h>
|
||||
|
||||
using namespace winrt;
|
||||
|
||||
// Wrapper class to handle keyboard layout
|
||||
class LayoutMap
|
||||
{
|
||||
private:
|
||||
// Stores mappings for all the virtual key codes to the name of the key
|
||||
std::mutex keyboardLayoutMap_mutex;
|
||||
|
||||
// Stores the previous layout
|
||||
HKL previousLayout = 0;
|
||||
|
||||
// Stores the keys which have a unicode representation
|
||||
std::map<DWORD, std::wstring> unicodeKeys;
|
||||
|
||||
// Stores the keys which do not have a name
|
||||
std::map<DWORD, std::wstring> unknownKeys;
|
||||
|
||||
// Stores true if the fixed ordering key code list has already been set
|
||||
bool isKeyCodeListGenerated = false;
|
||||
|
||||
// Stores a fixed order key code list for the drop down menus. It is kept fixed to change in ordering due to languages
|
||||
std::vector<DWORD> keyCodeList;
|
||||
|
||||
public:
|
||||
std::map<DWORD, std::wstring> keyboardLayoutMap;
|
||||
|
||||
// Update Keyboard layout according to input locale identifier
|
||||
void UpdateLayout();
|
||||
|
||||
LayoutMap()
|
||||
{
|
||||
UpdateLayout();
|
||||
}
|
||||
|
||||
// Function to return the unicode string name of the key
|
||||
std::wstring GetKeyName(DWORD key);
|
||||
|
||||
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
|
||||
std::vector<DWORD> GetKeyCodeList(const bool isShortcut = false);
|
||||
|
||||
// Function to return the list of key name in the order for the drop down based on the key codes
|
||||
Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> GetKeyNameList(const bool isShortcut = false);
|
||||
};
|
||||
#pragma once
|
||||
#include "keyboard_layout.h"
|
||||
#include "..\modules\interface\lowlevel_keyboard_event_data.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
|
||||
using namespace winrt;
|
||||
|
||||
// Wrapper class to handle keyboard layout
|
||||
class LayoutMap::LayoutMapImpl
|
||||
{
|
||||
private:
|
||||
// Stores mappings for all the virtual key codes to the name of the key
|
||||
std::mutex keyboardLayoutMap_mutex;
|
||||
|
||||
// Stores the previous layout
|
||||
HKL previousLayout = 0;
|
||||
|
||||
// Stores the keys which have a unicode representation
|
||||
std::map<DWORD, std::wstring> unicodeKeys;
|
||||
|
||||
// Stores the keys which do not have a name
|
||||
std::map<DWORD, std::wstring> unknownKeys;
|
||||
|
||||
// Stores true if the fixed ordering key code list has already been set
|
||||
bool isKeyCodeListGenerated = false;
|
||||
|
||||
// Stores a fixed order key code list for the drop down menus. It is kept fixed to change in ordering due to languages
|
||||
std::vector<DWORD> keyCodeList;
|
||||
|
||||
public:
|
||||
std::map<DWORD, std::wstring> keyboardLayoutMap;
|
||||
|
||||
// Update Keyboard layout according to input locale identifier
|
||||
void UpdateLayout();
|
||||
|
||||
LayoutMapImpl()
|
||||
{
|
||||
UpdateLayout();
|
||||
}
|
||||
|
||||
// Function to return the unicode string name of the key
|
||||
std::wstring GetKeyName(DWORD key);
|
||||
|
||||
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
|
||||
std::vector<DWORD> GetKeyCodeList(const bool isShortcut);
|
||||
|
||||
// Function to return the list of key name in the order for the drop down based on the key codes
|
||||
std::vector<std::wstring> GetKeyNameList(const bool isShortcut);
|
||||
};
|
|
@ -31,4 +31,8 @@
|
|||
<PackageReference Include="System.Text.Json" Version="4.7.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\interop\interop.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -64,5 +64,12 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities
|
|||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool AllowSetForegroundWindow(int dwProcessId);
|
||||
|
||||
private static interop.LayoutMapManaged layoutMap = new interop.LayoutMapManaged();
|
||||
|
||||
public static string GetKeyName(uint key)
|
||||
{
|
||||
return layoutMap.GetKeyName(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
|||
settings.Shift = true;
|
||||
}
|
||||
|
||||
settings.Key = e.Key.ToString();
|
||||
settings.Key = Lib.Utilities.Helper.GetKeyName((uint)e.Key);
|
||||
|
||||
// TODO: Check that e.OriginalKey is the ScanCode. It is not clear from docs.
|
||||
settings.Code = (int)e.OriginalKey;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "Helpers.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
|
||||
namespace KeyboardManagerHelper
|
||||
{
|
||||
// Function to split a wstring based on a delimiter and return a vector of split strings
|
||||
|
@ -14,12 +16,12 @@ namespace KeyboardManagerHelper
|
|||
{
|
||||
splittedStrings.push_back(item);
|
||||
}
|
||||
|
||||
|
||||
return splittedStrings;
|
||||
}
|
||||
|
||||
|
||||
// Function to return the next sibling element for an element under a stack panel
|
||||
winrt::Windows::Foundation::IInspectable getSiblingElement(winrt::Windows::Foundation::IInspectable const& element)
|
||||
IInspectable getSiblingElement(IInspectable const& element)
|
||||
{
|
||||
FrameworkElement frameworkElement = element.as<FrameworkElement>();
|
||||
StackPanel parentElement = frameworkElement.Parent().as<StackPanel>();
|
||||
|
@ -28,7 +30,7 @@ namespace KeyboardManagerHelper
|
|||
parentElement.Children().IndexOf(frameworkElement, index);
|
||||
return parentElement.Children().GetAt(index + 1);
|
||||
}
|
||||
|
||||
|
||||
// Function to check if the key is a modifier key
|
||||
bool IsModifierKey(DWORD key)
|
||||
{
|
||||
|
@ -75,4 +77,14 @@ namespace KeyboardManagerHelper
|
|||
return false;
|
||||
}
|
||||
}
|
||||
Collections::IVector<IInspectable> ToBoxValue(const std::vector<std::wstring>& list)
|
||||
{
|
||||
Collections::IVector<IInspectable> boxList = single_threaded_vector<IInspectable>();
|
||||
for (auto& val : list)
|
||||
{
|
||||
boxList.Append(winrt::box_value(val));
|
||||
}
|
||||
|
||||
return boxList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
|
||||
namespace KeyboardManagerHelper
|
||||
{
|
||||
|
@ -56,4 +57,7 @@ namespace KeyboardManagerHelper
|
|||
|
||||
// Function to return if the key is an extended key which requires the use of the extended key flag
|
||||
bool isExtendedKey(DWORD key);
|
||||
}
|
||||
|
||||
// Function to return the list of key name in the order for the drop down based on the key codes
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable> ToBoxValue(const std::vector<std::wstring>& list);
|
||||
}
|
|
@ -90,7 +90,6 @@
|
|||
<ClCompile Include="Helpers.cpp" />
|
||||
<ClCompile Include="KeyboardManagerState.cpp" />
|
||||
<ClCompile Include="KeyDelay.cpp" />
|
||||
<ClCompile Include="LayoutMap.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
|
@ -103,7 +102,6 @@
|
|||
<ClInclude Include="KeyboardManagerConstants.h" />
|
||||
<ClInclude Include="KeyboardManagerState.h" />
|
||||
<ClInclude Include="KeyDelay.h" />
|
||||
<ClInclude Include="LayoutMap.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="RemapShortcut.h" />
|
||||
<ClInclude Include="Shortcut.h" />
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LayoutMap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Shortcut.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -47,9 +44,6 @@
|
|||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LayoutMap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Shortcut.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include "Helpers.h"
|
||||
#include "LayoutMap.h"
|
||||
#include "..\common\keyboard_layout.h"
|
||||
#include "Shortcut.h"
|
||||
#include "RemapShortcut.h"
|
||||
#include "KeyDelay.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "Helpers.h"
|
||||
#include "LayoutMap.h"
|
||||
#include "KeyboardManagerConstants.h"
|
||||
#include "..\common\keyboard_layout.h"
|
||||
#include <interface/lowlevel_keyboard_event_data.h>
|
||||
|
||||
// Enum type to store different states of the win key
|
||||
|
@ -155,9 +155,6 @@ public:
|
|||
// Function to reset the state of a shortcut key based on the passed key code argument. Since there is no VK_WIN code, use the second argument for setting common win key.
|
||||
void ResetKey(const DWORD& input, const bool& isWinBoth = false);
|
||||
|
||||
// Function to return the string representation of the shortcut
|
||||
winrt::hstring ToHstring(LayoutMap& keyboardMap);
|
||||
|
||||
// Function to return the string representation of the shortcut in virtual key codes appended in a string by ";" separator.
|
||||
winrt::hstring ToHstringVK() const;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "pch.h"
|
||||
#include "KeyDropDownControl.h"
|
||||
#include "keyboardmanager/common/Helpers.h"
|
||||
|
||||
// Initialized to null
|
||||
KeyboardManagerState* KeyDropDownControl::keyboardManagerState = nullptr;
|
||||
|
@ -12,7 +13,7 @@ void KeyDropDownControl::SetDefaultProperties(bool isShortcut)
|
|||
// Initialise layout attribute
|
||||
previousLayout = GetKeyboardLayout(0);
|
||||
keyCodeList = keyboardManagerState->keyboardMap.GetKeyCodeList(isShortcut);
|
||||
dropDown.ItemsSource(keyboardManagerState->keyboardMap.GetKeyNameList(isShortcut));
|
||||
dropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(keyboardManagerState->keyboardMap.GetKeyNameList(isShortcut)));
|
||||
// drop down open handler - to reload the items with the latest layout
|
||||
dropDown.DropDownOpened([&, isShortcut](winrt::Windows::Foundation::IInspectable const& sender, auto args) {
|
||||
ComboBox currentDropDown = sender.as<ComboBox>();
|
||||
|
@ -30,7 +31,7 @@ void KeyDropDownControl::CheckAndUpdateKeyboardLayout(ComboBox currentDropDown,
|
|||
if (previousLayout != layout)
|
||||
{
|
||||
keyCodeList = keyboardManagerState->keyboardMap.GetKeyCodeList(isShortcut);
|
||||
currentDropDown.ItemsSource(keyboardManagerState->keyboardMap.GetKeyNameList(isShortcut));
|
||||
currentDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(keyboardManagerState->keyboardMap.GetKeyNameList(isShortcut)));
|
||||
previousLayout = layout;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "pch.h"
|
||||
#include "SingleKeyRemapControl.h"
|
||||
#include "keyboardmanager/common/Helpers.h"
|
||||
|
||||
//Both static members are initialized to null
|
||||
HWND SingleKeyRemapControl::EditKeyboardWindowHandle = nullptr;
|
||||
|
@ -114,7 +115,7 @@ void SingleKeyRemapControl::createDetectKeyWindow(winrt::Windows::Foundation::II
|
|||
{
|
||||
std::vector<DWORD> keyCodeList = keyboardManagerState.keyboardMap.GetKeyCodeList();
|
||||
// Update the drop down list with the new language to ensure that the correct key is displayed
|
||||
linkedRemapDropDown.ItemsSource(keyboardManagerState.keyboardMap.GetKeyNameList());
|
||||
linkedRemapDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(keyboardManagerState.keyboardMap.GetKeyNameList()));
|
||||
auto it = std::find(keyCodeList.begin(), keyCodeList.end(), detectedKey);
|
||||
if (it != keyCodeList.end())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue