Move keyboard manager POC code to dev branch (#1455)

* Created PowerKeys project

* Swapping tab with shift

* Added hash map and iterators for remapping code

* Added PowerKeys flag and added toggletomod function

* Added shortcut base code

* Fixed os level shortcut functionality

* Added 1 extra event

* Added check for same modifier and comments

* Added app-specific remapping for 4 apps including UWP apps

* Changed foreground window logic

* Added a separate hook for PowerKeys which can be re-hooked by enabling and disabling

* Added a separate hook for PowerKeys which can be re-hooked by enabling and disabling

* Fixed all priority issues and changed injection flags

* Added another msedge.exe shortcut

* Added a UI which is linked to the backend hook

* Cleaned code and added comments

* Added second button

* Renamed some files/variables and added an extra button
This commit is contained in:
Arjun Balgovind 2020-03-05 15:52:59 -08:00 committed by Udit Singh
parent bc4ea885dc
commit fc7e7074ce
20 changed files with 1475 additions and 2 deletions

View File

@ -147,6 +147,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerExt", "src\modu
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageResizerUITest", "src\modules\imageresizer\tests\ImageResizerUITest.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerKeys", "src\modules\PowerKeys\PowerKeys.vcxproj", "{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerKeysUI", "src\modules\PowerKeysUI\PowerKeysUI.vcxproj", "{EAF23649-EF6E-478B-980E-81FAD96CCA2A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "action_runner", "src\action_runner\action_runner.vcxproj", "{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}"
ProjectSection(ProjectDependencies) = postProject
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {17DA04DF-E393-4397-9CF0-84DABE11032E}
@ -201,94 +205,215 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Setting
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|ARM.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x64.Build.0 = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Debug|x86.ActiveCfg = Debug|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|ARM.ActiveCfg = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.ActiveCfg = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x64.Build.0 = Release|x64
{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}.Release|x86.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|ARM.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x64.Build.0 = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Debug|x86.ActiveCfg = Debug|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|ARM.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.ActiveCfg = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x64.Build.0 = Release|x64
{74485049-C722-400F-ABE5-86AC52D929B3}.Release|x86.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|ARM.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x64.Build.0 = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Debug|x86.ActiveCfg = Debug|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|ARM.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.ActiveCfg = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x64.Build.0 = Release|x64
{A46629C4-1A6C-40FA-A8B6-10E5102BB0BA}.Release|x86.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|ARM.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x64.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x64.Build.0 = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Debug|x86.ActiveCfg = Debug|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|ARM.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x64.ActiveCfg = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x64.Build.0 = Release|x64
{44CC9375-3E6E-4D99-8913-7FB748807EBD}.Release|x86.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|ARM.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x64.Build.0 = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Debug|x86.ActiveCfg = Debug|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|ARM.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.ActiveCfg = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x64.Build.0 = Release|x64
{07C389E3-6BC8-41CF-923E-307B1265FA2D}.Release|x86.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|ARM.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x64.Build.0 = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Debug|x86.ActiveCfg = Debug|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|ARM.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.ActiveCfg = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x64.Build.0 = Release|x64
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}.Release|x86.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Debug|ARM.ActiveCfg = Debug|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}.Debug|x86.ActiveCfg = Debug|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|ARM.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.ActiveCfg = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x64.Build.0 = Release|x64
{48804216-2A0E-4168-A6D8-9CD068D14227}.Release|x86.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Debug|ARM.ActiveCfg = Debug|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}.Debug|x86.ActiveCfg = Debug|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|ARM.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.ActiveCfg = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x64.Build.0 = Release|x64
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}.Release|x86.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|ARM.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x64.Build.0 = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Debug|x86.ActiveCfg = Debug|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|ARM.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.ActiveCfg = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x64.Build.0 = Release|x64
{1A066C63-64B3-45F8-92FE-664E1CCE8077}.Release|x86.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|ARM.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x64.Build.0 = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Debug|x86.ActiveCfg = Debug|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|ARM.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.ActiveCfg = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x64.Build.0 = Release|x64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}.Release|x86.ActiveCfg = Release|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|ARM.ActiveCfg = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x64.ActiveCfg = Debug|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x64.Build.0 = Debug|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x86.ActiveCfg = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Debug|x86.Build.0 = Debug|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|ARM.ActiveCfg = Release|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x64.ActiveCfg = Release|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x64.Build.0 = Release|x64
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x86.ActiveCfg = Release|Win32
{B25AC7A5-FB9F-4789-B392-D5C85E948670}.Release|x86.Build.0 = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|ARM.ActiveCfg = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x64.ActiveCfg = Debug|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x64.Build.0 = Debug|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x86.ActiveCfg = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Debug|x86.Build.0 = Debug|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|ARM.ActiveCfg = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x64.ActiveCfg = Release|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x64.Build.0 = Release|x64
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x86.ActiveCfg = Release|Win32
{51920F1F-C28C-4ADF-8660-4238766796C2}.Release|x86.Build.0 = Release|Win32
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|ARM.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x64.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x64.Build.0 = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Debug|x86.ActiveCfg = Debug|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|ARM.ActiveCfg = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x64.ActiveCfg = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x64.Build.0 = Release|x64
{0E072714-D127-460B-AFAD-B4C40B412798}.Release|x86.ActiveCfg = Release|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|ARM.ActiveCfg = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x64.ActiveCfg = Debug|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x64.Build.0 = Debug|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x86.ActiveCfg = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Debug|x86.Build.0 = Debug|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|ARM.ActiveCfg = Release|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x64.ActiveCfg = Release|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x64.Build.0 = Release|x64
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x86.ActiveCfg = Release|Win32
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}.Release|x86.Build.0 = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|ARM.ActiveCfg = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x64.ActiveCfg = Debug|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x64.Build.0 = Debug|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x86.ActiveCfg = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Debug|x86.Build.0 = Debug|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|ARM.ActiveCfg = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x64.ActiveCfg = Release|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x64.Build.0 = Release|x64
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x86.ActiveCfg = Release|Win32
{2151F984-E006-4A9F-92EF-C6DDE3DC8413}.Release|x86.Build.0 = Release|Win32
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|ARM.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x64.Build.0 = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Debug|x86.ActiveCfg = Debug|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|ARM.ActiveCfg = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.ActiveCfg = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x64.Build.0 = Release|x64
{64A80062-4D8B-4229-8A38-DFA1D7497749}.Release|x86.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|ARM.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x64.Build.0 = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Debug|x86.ActiveCfg = Debug|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|ARM.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.ActiveCfg = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x64.Build.0 = Release|x64
{0485F45C-EA7A-4BB5-804B-3E8D14699387}.Release|x86.ActiveCfg = Release|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|ARM.ActiveCfg = Debug|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|ARM.Build.0 = Debug|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x64.ActiveCfg = Debug|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x64.Build.0 = Debug|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x86.ActiveCfg = Debug|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Debug|x86.Build.0 = Debug|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|ARM.ActiveCfg = Release|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|ARM.Build.0 = Release|ARM
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x64.ActiveCfg = Release|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x64.Build.0 = Release|x64
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x86.ActiveCfg = Release|Win32
{0B593A6C-4143-4337-860E-DB5710FB87DB}.Release|x86.Build.0 = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|ARM.ActiveCfg = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x64.ActiveCfg = Debug|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x64.Build.0 = Debug|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x86.ActiveCfg = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Debug|x86.Build.0 = Debug|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|ARM.ActiveCfg = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x64.ActiveCfg = Release|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x64.Build.0 = Release|x64
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x86.ActiveCfg = Release|Win32
{031AC72E-FA28-4AB7-B690-6F7B9C28AA73}.Release|x86.Build.0 = Release|Win32
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|ARM.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|x64.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|x64.Build.0 = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Debug|x86.ActiveCfg = Debug|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|ARM.ActiveCfg = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|x64.ActiveCfg = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|x64.Build.0 = Release|x64
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB}.Release|x86.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|ARM.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x64.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x64.Build.0 = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Debug|x86.ActiveCfg = Debug|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|ARM.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x64.ActiveCfg = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x64.Build.0 = Release|x64
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6}.Release|x86.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|ARM.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x64.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x64.Build.0 = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Debug|x86.ActiveCfg = Debug|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|ARM.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x64.ActiveCfg = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x64.Build.0 = Release|x64
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9}.Release|x86.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|ARM.ActiveCfg = Debug|Win32
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.ActiveCfg = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x64.Build.0 = Debug|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x86.ActiveCfg = Debug|Win32
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Debug|x86.Build.0 = Debug|Win32
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|ARM.ActiveCfg = Release|Win32
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.ActiveCfg = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x64.Build.0 = Release|x64
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x86.ActiveCfg = Release|Win32
{EAF23649-EF6E-478B-980E-81FAD96CCA2A}.Release|x86.Build.0 = Release|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|ARM.ActiveCfg = Debug|Win32
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.ActiveCfg = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.Build.0 = Debug|x64
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x64.ActiveCfg = Release|x64
@ -303,12 +428,23 @@ Global
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.Build.0 = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.ActiveCfg = Debug|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x64.Build.0 = Debug|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x86.ActiveCfg = Debug|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Debug|x86.Build.0 = Debug|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|ARM.ActiveCfg = Release|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.ActiveCfg = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x64.Build.0 = Release|x64
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x86.ActiveCfg = Release|Win32
{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}.Release|x86.Build.0 = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|ARM.ActiveCfg = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.ActiveCfg = Debug|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x64.Build.0 = Debug|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x86.ActiveCfg = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Debug|x86.Build.0 = Debug|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|ARM.ActiveCfg = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.ActiveCfg = Release|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x64.Build.0 = Release|x64
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x86.ActiveCfg = Release|Win32
{17DA04DF-E393-4397-9CF0-84DABE11032E}.Release|x86.Build.0 = Release|Win32
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x64.ActiveCfg = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Debug|x64.Build.0 = Debug|x64
{880ED251-9E16-4713-9A70-D35FE0C01669}.Release|x64.ActiveCfg = Release|x64
@ -399,6 +535,8 @@ Global
{8DC78AF7-DC3E-4C57-A8FB-7E347DE74A03} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{B9BDF8BE-FED7-49B5-A7AE-DD4D1CA2D9EB} = {8DC78AF7-DC3E-4C57-A8FB-7E347DE74A03}
{51D3BD1F-07A8-48EB-B2A0-0A249CD4E1A6} = {8DC78AF7-DC3E-4C57-A8FB-7E347DE74A03}
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{EAF23649-EF6E-478B-980E-81FAD96CCA2A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{6C7F47CC-2151-44A3-A546-41C70025132C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {6C7F47CC-2151-44A3-A546-41C70025132C}

View File

@ -24,6 +24,7 @@
<File DestinationPath="modules\GalaSoft.MvvmLight.Extras.dll" SourcePath="..\..\x64\Release\modules\GalaSoft.MvvmLight.Extras.dll"/>
<File DestinationPath="modules\System.Windows.Interactivity.dll" SourcePath="..\..\x64\Release\modules\System.Windows.Interactivity.dll"/>
<File DestinationPath="modules\Newtonsoft.Json.dll" SourcePath="..\..\x64\Release\modules\Newtonsoft.Json.dll"/>
<File DestinationPath="modules\PowerKeys.dll" SourcePath="..\..\x64\Release\modules\PowerKeys.dll"/>
<File DestinationPath="modules\System.Text.Json.dll" SourcePath="..\..\x64\Release\modules\System.Text.Json.dll"/>
<File DestinationPath="modules\System.Memory.dll" SourcePath="..\..\x64\Release\modules\System.Memory.dll"/>
<File DestinationPath="modules\System.Buffers.dll" SourcePath="..\..\x64\Release\modules\System.Buffers.dll"/>

View File

@ -0,0 +1,32 @@
1 VERSIONINFO
FILEVERSION 0,1,0,0
PRODUCTVERSION 0,1,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Company Name"
VALUE "FileDescription", "$projectname$ Module"
VALUE "FileVersion", "0.1.0.0"
VALUE "InternalName", "$projectname$"
VALUE "LegalCopyright", "Copyright (C) 2019 Company Name"
VALUE "OriginalFilename", "$projectname$.dll"
VALUE "ProductName", "$projectname$"
VALUE "ProductVersion", "0.1.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" 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>15.0</VCProjectVersion>
<ProjectGuid>{89f34af7-1c34-4a72-aa6e-534bcf972bd9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PowerKeys</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>PowerKeys</ProjectName>
</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>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</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)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)src\;$(SolutionDir)src\modules;$(SolutionDir)src\common\Telemetry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)src\common\common.vcxproj">
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
</ProjectReference>
<ProjectReference Include="..\PowerKeysUI\PowerKeysUI.vcxproj">
<Project>{eaf23649-ef6e-478b-980e-81fad96cca2a}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="PowerKeys.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,602 @@
#include "pch.h"
#include <interface/powertoy_module_interface.h>
#include <interface/lowlevel_keyboard_event_data.h>
#include <interface/win_hook_event_data.h>
#include <common/settings_objects.h>
#include "trace.h"
#include <PowerKeysUI/MainWindow.h>
extern "C" IMAGE_DOS_HEADER __ImageBase;
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;
}
// The PowerToy name that will be shown in the settings.
const static wchar_t* MODULE_NAME = L"PowerKeys";
// Add a description that will we shown in the module settings page.
const static wchar_t* MODULE_DESC = L"Customize your experience by remapping keys or creating new shortcuts!";
// Implement the PowerToy Module Interface and all the required methods.
class PowerKeys : public PowertoyModuleIface
{
private:
// The PowerToy state.
bool m_enabled = false;
// Maps which store the remappings for each of the features. The bool fields should be initalised to false. They are used to check the current state of the shortcut (i.e is that particular shortcut currently pressed down or not).
std::unordered_map<DWORD, WORD> singleKeyReMap;
std::map<std::vector<DWORD>, std::pair<std::vector<WORD>, bool>> osLevelShortcutReMap;
// Maps application name to the shortcut map
std::map<std::wstring, std::map<std::vector<DWORD>, std::pair<std::vector<WORD>, bool>>> appSpecificShortcutReMap;
std::unordered_map<DWORD, bool> singleKeyToggleToMod;
// Flags used for distinguishing key events sent by PowerKeys
static const ULONG_PTR POWERKEYS_INJECTED_FLAG = 0x1;
static const ULONG_PTR POWERKEYS_SINGLEKEY_FLAG = 0x11;
static const ULONG_PTR POWERKEYS_SHORTCUT_FLAG = 0x101;
// Dummy key event used in between key up and down events to prevent certain global events from happening
static const DWORD DUMMY_KEY = 0xFF;
// Low level hook handles
static HHOOK hook_handle;
static HHOOK hook_handle_copy; // make sure we do use nullptr in CallNextHookEx call
// Static pointer to the current powerkeys object required for accessing the HandleKeyboardHookEvent function in the hook procedure
static PowerKeys* powerkeys_object_ptr;
// Flag used to check if the UI window is currently up. A reference to the variable can be sent while calling the UI window
bool uiFlag = false;
public:
// Constructor
PowerKeys()
{
init_map();
powerkeys_object_ptr = this;
};
// This function is used to add the hardcoded mappings
void init_map()
{
//// If mapped to 0x0 then key is disabled.
////singleKeyReMap[0x41] = 0x42;
////singleKeyReMap[0x42] = 0x43;
////singleKeyReMap[0x43] = 0x41;
//singleKeyReMap[VK_LWIN] = VK_LCONTROL;
//singleKeyReMap[VK_LCONTROL] = VK_LWIN;
//singleKeyReMap[VK_OEM_4] = 0x0;
//singleKeyToggleToMod[VK_CAPITAL] = false;
//// OS-level shortcut remappings
//osLevelShortcutReMap[std::vector<DWORD>({ VK_LMENU, 0x44 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x56 }), false);
//osLevelShortcutReMap[std::vector<DWORD>({ VK_LMENU, 0x45 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x58 }), false);
////osLevelShortcutReMap[std::vector<DWORD>({ VK_LWIN, 0x46 })] = std::make_pair(std::vector<WORD>({ VK_LWIN, 0x53 }), false);
///*osLevelShortcutReMap[std::vector<DWORD>({ VK_LWIN, 0x41 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x58 }), false);
//osLevelShortcutReMap[std::vector<DWORD>({ VK_LCONTROL, 0x58 })] = std::make_pair(std::vector<WORD>({ VK_LWIN, 0x41 }), false);*/
//osLevelShortcutReMap[std::vector<DWORD>({ VK_LWIN, 0x41 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x58 }), false);
//osLevelShortcutReMap[std::vector<DWORD>({ VK_LCONTROL, 0x58 })] = std::make_pair(std::vector<WORD>({ VK_LMENU, 0x44 }), false);
//osLevelShortcutReMap[std::vector<DWORD>({ VK_LCONTROL, 0x56 })] = std::make_pair(std::vector<WORD>({ VK_LWIN, 0x41 }), false);
////App-specific shortcut remappings
//appSpecificShortcutReMap[L"msedge.exe"][std::vector<DWORD>({ VK_LCONTROL, 0x43 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x56 }), false); // Ctrl+C to Ctrl+V
//appSpecificShortcutReMap[L"msedge.exe"][std::vector<DWORD>({ VK_LMENU, 0x44 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x46 }), false); // Alt+D to Ctrl+F
//appSpecificShortcutReMap[L"OUTLOOK.EXE"][std::vector<DWORD>({ VK_LCONTROL, 0x46 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x45 }), false); // Ctrl+F to Ctrl+E
//appSpecificShortcutReMap[L"MicrosoftEdge.exe"][std::vector<DWORD>({ VK_LCONTROL, 0x58 })] = std::make_pair(std::vector<WORD>({ VK_LCONTROL, 0x56 }), false); // Ctrl+X to Ctrl+V
//appSpecificShortcutReMap[L"Calculator.exe"][std::vector<DWORD>({ VK_LCONTROL, 0x47 })] = std::make_pair(std::vector<WORD>({ VK_LSHIFT, 0x32 }), false); // Ctrl+G to Shift+2
}
// Destroy the powertoy and free memory
virtual void destroy() override
{
stop_lowlevel_keyboard_hook();
delete this;
}
// Return the display name of the powertoy, this will be cached by the runner
virtual const wchar_t* get_name() override
{
return MODULE_NAME;
}
// Return array of the names of all events that this powertoy listens for, with
// nullptr as the last element of the array. Nullptr can also be retured for empty
// list.
virtual const wchar_t** get_events() override
{
//static const wchar_t* events[] = { nullptr };
// Available events:
// - ll_keyboard
// - win_hook_event
//
static const wchar_t* events[] = { ll_keyboard, nullptr };
return events;
}
// Return JSON with the configuration options.
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
// Create a Settings object.
PowerToysSettings::Settings settings(hinstance, get_name());
settings.set_description(MODULE_DESC);
return settings.serialize_to_buffer(buffer, buffer_size);
}
// 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
{
static UINT custom_action_num_calls = 0;
try
{
// Parse the action values, including name.
PowerToysSettings::CustomActionObject action_object =
PowerToysSettings::CustomActionObject::from_json_string(action);
//if (action_object.get_name() == L"custom_action_id") {
// // Execute your custom action
//}
}
catch (std::exception&)
{
// Improper JSON.
}
}
// Called by the runner to pass the updated settings values as a serialized JSON.
virtual void set_config(const wchar_t* config) override
{
try
{
// Parse the input JSON string.
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config);
// If you don't need to do any custom processing of the settings, proceed
// to persists the values calling:
values.save_to_settings_file();
}
catch (std::exception&)
{
// Improper JSON.
}
}
// Enable the powertoy
virtual void enable()
{
m_enabled = true;
HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
std::thread(createMainWindow, hInstance, &uiFlag).detach();
start_lowlevel_keyboard_hook();
}
// Disable the powertoy
virtual void disable()
{
m_enabled = false;
stop_lowlevel_keyboard_hook();
}
// Returns if the powertoys is enabled
virtual bool is_enabled() override
{
return m_enabled;
}
// Handle incoming event, data is event-specific
virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override
{
return 0;
}
// This methods are part of an experimental features not fully supported yet
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {}
virtual void signal_system_menu_action(const wchar_t* name) override {}
// Hook procedure definition
static LRESULT CALLBACK hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
LowlevelKeyboardEvent event;
if (nCode == HC_ACTION)
{
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
event.wParam = wParam;
if (powerkeys_object_ptr->HandleKeyboardHookEvent(&event) == 1)
{
return 1;
}
}
return CallNextHookEx(hook_handle_copy, nCode, wParam, lParam);
}
// Prevent system-wide input lagging while paused in the debugger
//#define DISABLE_LOWLEVEL_KBHOOK_WHEN_DEBUGGED
void start_lowlevel_keyboard_hook()
{
#if defined(_DEBUG) && defined(DISABLE_LOWLEVEL_KBHOOK_WHEN_DEBUGGED)
if (IsDebuggerPresent())
{
return;
}
#endif
if (!hook_handle)
{
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, hook_proc, GetModuleHandle(NULL), NULL);
hook_handle_copy = hook_handle;
if (!hook_handle)
{
throw std::runtime_error("Cannot install keyboard listener");
}
}
}
void stop_lowlevel_keyboard_hook()
{
if (hook_handle)
{
UnhookWindowsHookEx(hook_handle);
hook_handle = nullptr;
}
}
// This function can be used in HandleKeyboardHookEvent before the single key remap event to use the UI and suppress events while the remap window is active.
void DetectKeyUIBackend()
{
if (uiFlag)
{
// Disables the [ key when the UI window is up
singleKeyReMap[VK_OEM_4] = 0x0;
}
else if (singleKeyReMap.find(VK_OEM_4) == singleKeyReMap.end())
{
}
else
{
// Removes the remapping if the UI window is not up and the remapping doesn't already exist
singleKeyReMap.erase(VK_OEM_4);
}
}
intptr_t HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept
{
DetectKeyUIBackend();
intptr_t SingleKeyRemapResult = HandleSingleKeyRemapEvent(data);
// Single key remaps have priority. If a key is remapped, only the remapped version should be visible to the shortcuts
if (SingleKeyRemapResult == 1)
{
return 1;
}
intptr_t SingleKeyToggleToModResult = HandleSingleKeyToggleToModEvent(data);
intptr_t AppSpecificShortcutRemapResult = HandleAppSpecificShortcutRemapEvent(data);
if (AppSpecificShortcutRemapResult == 1)
{
return 1;
}
intptr_t OSLevelShortcutRemapResult = HandleOSLevelShortcutRemapEvent(data);
if ((SingleKeyRemapResult + SingleKeyToggleToModResult + OSLevelShortcutRemapResult + AppSpecificShortcutRemapResult) > 0)
{
return 1;
}
else
{
return 0;
}
}
intptr_t HandleSingleKeyRemapEvent(LowlevelKeyboardEvent* data) noexcept
{
if (!(data->lParam->dwExtraInfo & POWERKEYS_INJECTED_FLAG))
{
auto it = singleKeyReMap.find(data->lParam->vkCode);
if (it != singleKeyReMap.end())
{
// If mapped to 0x0 then the key is disabled
if (it->second == 0x0)
{
return 1;
}
int key_count = 1;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = it->second;
keyEventList[0].ki.dwFlags = 0;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SINGLEKEY_FLAG;
if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)
{
keyEventList[0].ki.dwFlags = KEYEVENTF_KEYUP;
}
UINT res = SendInput(key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
return 1;
}
}
return 0;
}
intptr_t HandleSingleKeyToggleToModEvent(LowlevelKeyboardEvent* data) noexcept
{
if (!(data->lParam->dwExtraInfo & POWERKEYS_INJECTED_FLAG))
{
auto it = singleKeyToggleToMod.find(data->lParam->vkCode);
if (it != singleKeyToggleToMod.end())
{
// To avoid long presses (which leads to continuous keydown messages) from toggling the key on and off
if (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN)
{
if (it->second == false)
{
singleKeyToggleToMod[data->lParam->vkCode] = true;
}
else
{
return 1;
}
}
int key_count = 2;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = (WORD)data->lParam->vkCode;
keyEventList[0].ki.dwFlags = 0;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SINGLEKEY_FLAG;
keyEventList[1].type = INPUT_KEYBOARD;
keyEventList[1].ki.wVk = (WORD)data->lParam->vkCode;
keyEventList[1].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[1].ki.dwExtraInfo = POWERKEYS_SINGLEKEY_FLAG;
UINT res = SendInput(key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
// Reset the long press flag when the key has been lifted.
if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)
{
singleKeyToggleToMod[data->lParam->vkCode] = false;
}
return 1;
}
}
return 0;
}
intptr_t HandleShortcutRemapEvent(LowlevelKeyboardEvent* data, std::map<std::vector<DWORD>, std::pair<std::vector<WORD>, bool>>& reMap) noexcept
{
for (auto& it : reMap)
{
DWORD src_1 = it.first[0];
DWORD src_2 = it.first[1];
WORD dest_1 = it.second.first[0];
WORD dest_2 = it.second.first[1];
// If the shortcut has been pressed down
if ((GetAsyncKeyState(src_1) & 0x8000) && !it.second.second)
{
if (data->lParam->vkCode == src_2 && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))
{
int key_count = 4;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
if (src_1 == dest_1)
{
key_count = 1;
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = dest_2;
keyEventList[0].ki.dwFlags = 0;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
}
else
{
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = (WORD)DUMMY_KEY;
keyEventList[0].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[1].type = INPUT_KEYBOARD;
keyEventList[1].ki.wVk = (WORD)src_1;
keyEventList[1].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[1].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[2].type = INPUT_KEYBOARD;
keyEventList[2].ki.wVk = dest_1;
keyEventList[2].ki.dwFlags = 0;
keyEventList[2].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[3].type = INPUT_KEYBOARD;
keyEventList[3].ki.wVk = dest_2;
keyEventList[3].ki.dwFlags = 0;
keyEventList[3].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
}
it.second.second = true;
UINT res = SendInput(key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
return 1;
}
}
else if (it.second.second)
{
// If the modifier key of the original shortcut is released before the normal key
if (data->lParam->vkCode == src_1 && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))
{
int key_count = 2;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = dest_2;
keyEventList[0].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[1].type = INPUT_KEYBOARD;
keyEventList[1].ki.wVk = dest_1;
keyEventList[1].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[1].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
it.second.second = false;
UINT res = SendInput(key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
return 1;
}
if (GetAsyncKeyState(dest_1) & 0x8000)
{
// If the original shortcut is still held down the keyboard will see the original normal key along with the new modifier (keys held down send repeated keydown messages)
if (data->lParam->vkCode == src_2 && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))
{
int key_count = 1;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = dest_2;
keyEventList[0].ki.dwFlags = 0;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
it.second.second = true;
UINT res = SendInput(key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
return 1;
}
// If the normal key is released from the original shortcut then revert the keyboard state to just the original modifier being held down
if (data->lParam->vkCode == src_2 && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))
{
int key_count = 4;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
if (src_1 == dest_1)
{
key_count = 1;
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = dest_2;
keyEventList[0].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
}
else
{
keyEventList[0].type = INPUT_KEYBOARD;
keyEventList[0].ki.wVk = dest_2;
keyEventList[0].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[0].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[1].type = INPUT_KEYBOARD;
keyEventList[1].ki.wVk = dest_1;
keyEventList[1].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[1].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[2].type = INPUT_KEYBOARD;
keyEventList[2].ki.wVk = (WORD)src_1;
keyEventList[2].ki.dwFlags = 0;
keyEventList[2].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
keyEventList[3].type = INPUT_KEYBOARD;
keyEventList[3].ki.wVk = (WORD)DUMMY_KEY;
keyEventList[3].ki.dwFlags = KEYEVENTF_KEYUP;
keyEventList[3].ki.dwExtraInfo = POWERKEYS_SHORTCUT_FLAG;
}
it.second.second = false;
UINT res = SendInput(key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
return 1;
}
}
}
}
return 0;
}
intptr_t HandleOSLevelShortcutRemapEvent(LowlevelKeyboardEvent* data) noexcept
{
if (data->lParam->dwExtraInfo != POWERKEYS_SHORTCUT_FLAG)
{
return HandleShortcutRemapEvent(data, osLevelShortcutReMap);
}
return 0;
}
std::wstring GetCurrentApplication(bool keepPath)
{
// Using GetGUIThreadInfo for getting the process of the window in focus. GetForegroundWindow has issues with UWP apps as it returns the Application Frame Host as its linked process
GUITHREADINFO guiThreadInfo;
guiThreadInfo.cbSize = sizeof(GUITHREADINFO);
GetGUIThreadInfo(0, &guiThreadInfo);
HWND current_window_handle = guiThreadInfo.hwndFocus;
// If no window in focus, use the active window
if (current_window_handle == nullptr)
{
current_window_handle = guiThreadInfo.hwndActive;
}
DWORD process_id;
DWORD nSize = MAX_PATH;
WCHAR buffer[MAX_PATH] = { 0 };
// Get process ID of the focus window
DWORD thread_id = GetWindowThreadProcessId(current_window_handle, &process_id);
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_id);
// Get full path of the executable
bool res = QueryFullProcessImageName(hProc, 0, buffer, &nSize);
std::wstring process_name;
CloseHandle(hProc);
process_name = buffer;
if (res)
{
PathStripPath(buffer);
if (!keepPath)
{
process_name = buffer;
}
}
return process_name;
}
intptr_t HandleAppSpecificShortcutRemapEvent(LowlevelKeyboardEvent* data) noexcept
{
if (data->lParam->dwExtraInfo != POWERKEYS_SHORTCUT_FLAG)
{
std::wstring process_name = GetCurrentApplication(false);
if (process_name.empty())
{
return 0;
}
auto it = appSpecificShortcutReMap.find(process_name);
if (it != appSpecificShortcutReMap.end())
{
return HandleShortcutRemapEvent(data, appSpecificShortcutReMap[process_name]);
}
}
return 0;
}
};
HHOOK PowerKeys::hook_handle = nullptr;
HHOOK PowerKeys::hook_handle_copy = nullptr;
PowerKeys* PowerKeys::powerkeys_object_ptr = nullptr;
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new PowerKeys();
}

View File

@ -0,0 +1,2 @@
#include "pch.h"
#pragma comment(lib, "windowsapp")

View File

@ -0,0 +1,8 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <common/common.h>
#include <ProjectTelemetry.h>
#include <shlwapi.h>
#include <stdexcept>
#include <unordered_set>

View File

View File

@ -0,0 +1,29 @@
#include "pch.h"
#include "trace.h"
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
"Microsoft.PowerToys",
// {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry());
void Trace::RegisterProvider()
{
TraceLoggingRegister(g_hProvider);
}
void Trace::UnregisterProvider()
{
TraceLoggingUnregister(g_hProvider);
}
void Trace::MyEvent()
{
TraceLoggingWrite(
g_hProvider,
"PowerToyName_MyEvent",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}

View File

@ -0,0 +1,9 @@
#pragma once
class Trace
{
public:
static void RegisterProvider();
static void UnregisterProvider();
static void MyEvent();
};

View File

@ -0,0 +1,106 @@
#include "EditKeyboardWindow.h"
LRESULT CALLBACK EditKeyboardWindowProc(HWND, UINT, WPARAM, LPARAM);
HWND hWndXamlIslandEditKeyboardWindow = nullptr;
void registerWinClass(HINSTANCE& hInst)
{
// The main window class name.
const wchar_t szWindowClass[] = L"EditKeyboardWindow";
WNDCLASSEX windowClass = {};
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.lpfnWndProc = EditKeyboardWindowProc;
windowClass.hInstance = hInst;
windowClass.lpszClassName = szWindowClass;
windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
windowClass.hIconSm = LoadIcon(windowClass.hInstance, IDI_APPLICATION);
if (RegisterClassEx(&windowClass) == NULL)
{
MessageBox(NULL, L"Windows registration failed!", L"Error", NULL);
return;
}
}
void createEditKeyboardWindow(HINSTANCE hInst)
{
// The main window class name.
const wchar_t szWindowClass[] = L"EditKeyboardWindow";
HWND _hWndEditKeyboardWindow = CreateWindow(
szWindowClass,
L"PowerKeys Remap Keyboard",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
400,
400,
NULL,
NULL,
hInst,
NULL);
if (_hWndEditKeyboardWindow == NULL)
{
MessageBox(NULL, L"Call to CreateWindow failed!", L"Error", NULL);
return;
}
// This DesktopWindowXamlSource is the object that enables a non-UWP desktop application
// to host UWP controls in any UI element that is associated with a window handle (HWND).
DesktopWindowXamlSource desktopSource;
// Get handle to corewindow
auto interop = desktopSource.as<IDesktopWindowXamlSourceNative>();
// Parent the DesktopWindowXamlSource object to current window
check_hresult(interop->AttachToWindow(_hWndEditKeyboardWindow));
// Get the new child window's hwnd
interop->get_WindowHandle(&hWndXamlIslandEditKeyboardWindow);
// Update the xaml island window size becuase initially is 0,0
SetWindowPos(hWndXamlIslandEditKeyboardWindow, 0, 0, 0, 400, 400, SWP_SHOWWINDOW);
//Creating the Xaml content
Windows::UI::Xaml::Controls::StackPanel xamlContainer;
xamlContainer.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
Windows::UI::Xaml::Controls::Button bt;
bt.Content(winrt::box_value(winrt::to_hstring("Don't Type key")));
xamlContainer.Children().Append(bt);
xamlContainer.UpdateLayout();
desktopSource.Content(xamlContainer);
////End XAML Island section
if (_hWndEditKeyboardWindow)
{
ShowWindow(_hWndEditKeyboardWindow, SW_SHOW);
UpdateWindow(_hWndEditKeyboardWindow);
}
// Message loop:
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
desktopSource.Close();
}
LRESULT CALLBACK EditKeyboardWindowProc(HWND hWnd, UINT messageCode, WPARAM wParam, LPARAM lParam)
{
RECT rcClient;
switch (messageCode)
{
case WM_PAINT:
GetClientRect(hWnd, &rcClient);
SetWindowPos(hWndXamlIslandEditKeyboardWindow, 0, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, SWP_SHOWWINDOW);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, messageCode, wParam, lParam);
break;
}
return 0;
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <winrt/Windows.system.h>
#include <winrt/windows.ui.xaml.hosting.h>
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
#include <winrt/windows.ui.xaml.controls.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.Foundation.Collections.h>
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.Foundation.Numerics.h"
#include "winrt/Windows.UI.Xaml.Controls.Primitives.h"
using namespace winrt;
using namespace Windows::UI;
using namespace Windows::UI::Composition;
using namespace Windows::UI::Xaml::Hosting;
using namespace Windows::Foundation::Numerics;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
__declspec(dllexport) void createEditKeyboardWindow(HINSTANCE hInst);
__declspec(dllexport) void registerWinClass(HINSTANCE& hInst);

View File

@ -0,0 +1,165 @@
#include "MainWindow.h"
#include "EditKeyboardWindow.h"
using namespace winrt;
using namespace Windows::UI;
using namespace Windows::UI::Composition;
using namespace Windows::UI::Xaml::Hosting;
using namespace Windows::Foundation::Numerics;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
HWND _hWndMain;
HINSTANCE _hInstance;
// This Hwnd will be the window handler for the Xaml Island: A child window that contains Xaml.
HWND hWndXamlIslandMain = nullptr;
bool isRegistrationCompleted = false;
void createMainWindow(HINSTANCE hInstance, bool* ptr)
{
_hInstance = hInstance;
// The main window class name.
const wchar_t szWindowClass[] = L"MainWindowClass";
if (!isRegistrationCompleted)
{
registerWinClass(_hInstance);
WNDCLASSEX windowClass = {};
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.lpfnWndProc = MainWindowProc;
windowClass.hInstance = hInstance;
windowClass.lpszClassName = szWindowClass;
windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
windowClass.hIconSm = LoadIcon(windowClass.hInstance, IDI_APPLICATION);
if (RegisterClassEx(&windowClass) == NULL)
{
MessageBox(NULL, L"Windows registration failed!", L"Error", NULL);
return;
}
isRegistrationCompleted = true;
}
_hWndMain = CreateWindow(
szWindowClass,
L"PowerKeys Settings",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (_hWndMain == NULL)
{
MessageBox(NULL, L"Call to CreateWindow failed!", L"Error", NULL);
return;
}
//XAML Island section
// This DesktopWindowXamlSource is the object that enables a non-UWP desktop application
// to host UWP controls in any UI element that is associated with a window handle (HWND).
DesktopWindowXamlSource desktopSource;
// Get handle to corewindow
auto interop = desktopSource.as<IDesktopWindowXamlSourceNative>();
// Parent the DesktopWindowXamlSource object to current window
check_hresult(interop->AttachToWindow(_hWndMain));
// Get the new child window's hwnd
interop->get_WindowHandle(&hWndXamlIslandMain);
// Update the xaml island window size becuase initially is 0,0
SetWindowPos(hWndXamlIslandMain, 0, 0, 0, 800, 800, SWP_SHOWWINDOW);
//Creating the Xaml content
Windows::UI::Xaml::Controls::StackPanel xamlContainer;
xamlContainer.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
Windows::UI::Xaml::Controls::StackPanel keyRow;
keyRow.Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
keyRow.Spacing(10);
keyRow.Margin({ 10 });
Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> keyNames{ single_threaded_vector<Windows::Foundation::IInspectable>(
{ winrt::box_value(L"Alt"),
winrt::box_value(L"Delete"),
winrt::box_value(L"LAlt"),
winrt::box_value(L"LWin"),
winrt::box_value(L"Shift"),
winrt::box_value(L"NumLock"),
winrt::box_value(L"LCtrl") }) };
Windows::UI::Xaml::Controls::ComboBox cb;
cb.IsEditable(true);
cb.Width(200);
cb.ItemsSource(keyNames);
Windows::UI::Xaml::Controls::Button bt;
bt.Content(winrt::box_value(winrt::to_hstring("Edit Keyboard")));
bt.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
if (ptr != nullptr)
{
*ptr = true;
}
std::thread th(createEditKeyboardWindow, _hInstance);
th.join();
if (ptr != nullptr)
{
*ptr = false;
}
});
Windows::UI::Xaml::Controls::Button bt2;
bt2.Content(winrt::box_value(winrt::to_hstring("Edit Shortcuts")));
bt2.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
});
keyRow.Children().Append(cb);
keyRow.Children().Append(bt);
keyRow.Children().Append(bt2);
xamlContainer.Children().Append(keyRow);
xamlContainer.UpdateLayout();
desktopSource.Content(xamlContainer);
//End XAML Island section
if (_hWndMain)
{
ShowWindow(_hWndMain, SW_SHOW);
UpdateWindow(_hWndMain);
}
//Message loop:
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
desktopSource.Close();
}
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT messageCode, WPARAM wParam, LPARAM lParam)
{
RECT rcClient;
switch (messageCode)
{
case WM_PAINT:
GetClientRect(hWnd, &rcClient);
SetWindowPos(hWndXamlIslandMain, 0, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, SWP_SHOWWINDOW);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, messageCode, wParam, lParam);
break;
}
return 0;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <winrt/Windows.system.h>
#include <winrt/windows.ui.xaml.hosting.h>
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
#include <winrt/windows.ui.xaml.controls.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.Foundation.Collections.h>
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.Foundation.Numerics.h"
#include "winrt/Windows.UI.Xaml.Controls.Primitives.h"
__declspec(dllexport) void createMainWindow(HINSTANCE hInstance, bool* ptr);
LRESULT CALLBACK MainWindowProc(HWND, UINT, WPARAM, LPARAM);

View File

@ -0,0 +1,173 @@
<?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.200302.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200302.1\build\native\Microsoft.Windows.CppWinRT.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<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>15.0</VCProjectVersion>
<ProjectGuid>{EAF23649-EF6E-478B-980E-81FAD96CCA2A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PowerKeysUI</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<CppWinRTEnabled>true</CppWinRTEnabled>
<ProjectName>PowerKeysUI</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</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|Win32'">
<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|Win32'">
<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)'=='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|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>UNICODE;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>windowsapp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>windowsapp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="EditKeyboardWindow.cpp" />
<ClCompile Include="MainWindow.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="EditKeyboardWindow.h" />
<ClInclude Include="MainWindow.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.200302.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.200302.1\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.CppWinRT.2.0.200302.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200302.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200302.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.200302.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="MainWindow.cpp" />
<ClCompile Include="EditKeyboardWindow.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="MainWindow.h" />
<ClInclude Include="EditKeyboardWindow.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

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

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<maxversiontested Id="10.0.18362.0"/>
</application>
</compatibility>
</assembly>

View File

@ -203,7 +203,8 @@ int runner(bool isProcessElevated)
L"PowerRenameExt.dll",
L"ImageResizerExt.dll",
L"powerpreview.dll",
L"WindowWalker.dll"
L"WindowWalker.dll",
L"PowerKeys.dll"
};
for (auto& file : std::filesystem::directory_iterator(L"modules/"))
{

View File

@ -14,7 +14,7 @@
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}</ProjectGuid>
<RootNamespace>powertoys</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<ProjectName>runner</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@ -240,6 +240,9 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Manifest Include="PowerToys.exe.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">