diff --git a/Scratch.sln b/Scratch.sln new file mode 100644 index 000000000..ac6caf341 --- /dev/null +++ b/Scratch.sln @@ -0,0 +1,221 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31205.134 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Package", "scratch\ScratchIslandApp\Package\Package.wapproj", "{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleAppLib", "scratch\ScratchIslandApp\SampleApp\SampleAppLib.vcxproj", "{A4394404-37F7-41C1-802B-49788D3720E3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp", "scratch\ScratchIslandApp\SampleApp\dll\SampleApp.vcxproj", "{26C51792-41A3-4FE0-AB5E-8B69D557BF91}" + ProjectSection(ProjectDependencies) = postProject + {A4394404-37F7-41C1-802B-49788D3720E3} = {A4394404-37F7-41C1-802B-49788D3720E3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowExe", "scratch\ScratchIslandApp\WindowExe\WindowExe.vcxproj", "{B4427499-9FDE-4208-B456-5BC580637633}" + ProjectSection(ProjectDependencies) = postProject + {26C51792-41A3-4FE0-AB5E-8B69D557BF91} = {26C51792-41A3-4FE0-AB5E-8B69D557BF91} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Props", "Common Props", "{53DD5520-E64C-4C06-B472-7CE62CA539C9}" + ProjectSection(SolutionItems) = preProject + src\common.build.post.props = src\common.build.post.props + src\common.build.pre.props = src\common.build.pre.props + src\common.build.tests.props = src\common.build.tests.props + common.openconsole.props = common.openconsole.props + src\cppwinrt.build.post.props = src\cppwinrt.build.post.props + src\cppwinrt.build.pre.props = src\cppwinrt.build.pre.props + src\wap-common.build.post.props = src\wap-common.build.post.props + src\wap-common.build.pre.props = src\wap-common.build.pre.props + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxproj", "{6BAE5851-50D5-4934-8D5E-30361A8A40F3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types", "src\types\lib\types.vcxproj", "{18D09A24-8240-42D6-8CB6-236EEE820263}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + AuditMode|ARM64 = AuditMode|ARM64 + AuditMode|x64 = AuditMode|x64 + AuditMode|x86 = AuditMode|x86 + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Fuzzing|ARM64 = Fuzzing|ARM64 + Fuzzing|x64 = Fuzzing|x64 + Fuzzing|x86 = Fuzzing|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.ActiveCfg = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Build.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Deploy.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.ActiveCfg = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Build.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Deploy.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.ActiveCfg = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Build.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Deploy.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Build.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.ActiveCfg = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Build.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Deploy.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.ActiveCfg = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Build.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Deploy.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.ActiveCfg = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Build.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Deploy.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.ActiveCfg = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Build.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Deploy.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.ActiveCfg = Release|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Build.0 = Release|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Deploy.0 = Release|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.ActiveCfg = Release|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Build.0 = Release|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Deploy.0 = Release|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.ActiveCfg = Release|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Build.0 = Release|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Deploy.0 = Release|x86 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.Build.0 = AuditMode|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.Build.0 = AuditMode|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.Build.0 = Debug|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.ActiveCfg = Debug|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.Build.0 = Debug|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.ActiveCfg = Debug|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.Build.0 = Debug|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.ActiveCfg = Release|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.Build.0 = Release|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.ActiveCfg = Release|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.Build.0 = Release|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.ActiveCfg = Release|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.Build.0 = Release|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.Build.0 = AuditMode|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.Build.0 = AuditMode|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.Build.0 = Debug|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.ActiveCfg = Debug|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.Build.0 = Debug|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.ActiveCfg = Debug|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.Build.0 = Debug|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.ActiveCfg = Release|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.Build.0 = Release|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.ActiveCfg = Release|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.Build.0 = Release|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.ActiveCfg = Release|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.Build.0 = Release|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.Build.0 = AuditMode|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.Build.0 = AuditMode|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.Build.0 = Debug|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.ActiveCfg = Debug|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.Build.0 = Debug|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.ActiveCfg = Debug|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.Build.0 = Debug|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.ActiveCfg = Release|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.Build.0 = Release|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.ActiveCfg = Release|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.Build.0 = Release|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.ActiveCfg = Release|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.Build.0 = Release|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.Build.0 = AuditMode|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.Build.0 = AuditMode|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.Build.0 = Debug|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.ActiveCfg = Debug|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.Build.0 = Debug|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.ActiveCfg = Debug|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.Build.0 = Debug|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.ActiveCfg = Release|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.Build.0 = Release|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.ActiveCfg = Release|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.Build.0 = Release|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.ActiveCfg = Release|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.Build.0 = Release|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.Build.0 = AuditMode|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.Build.0 = AuditMode|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.Build.0 = Debug|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.ActiveCfg = Debug|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.Build.0 = Debug|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.ActiveCfg = Debug|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.Build.0 = Debug|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.ActiveCfg = Release|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.Build.0 = Release|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.ActiveCfg = Release|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.Build.0 = Release|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.ActiveCfg = Release|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9} + {18D09A24-8240-42D6-8CB6-236EEE820263} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {05EAE315-9188-4D7B-B889-7D5F480A8915} + EndGlobalSection +EndGlobal diff --git a/consolegit2gitfilters.json b/consolegit2gitfilters.json index 5a760692b..5f5d0eb26 100644 --- a/consolegit2gitfilters.json +++ b/consolegit2gitfilters.json @@ -23,6 +23,8 @@ "/doc/cascadia/", "/doc/user-docs/", "/src/tools/MonarchPeasantSample/", + "/scratch/", + "Scratch.sln", ], "SuffixFilters": [ ".dbb", diff --git a/scratch/ScratchIslandApp/Package/Package.appxmanifest b/scratch/ScratchIslandApp/Package/Package.appxmanifest new file mode 100644 index 000000000..dcd54adca --- /dev/null +++ b/scratch/ScratchIslandApp/Package/Package.appxmanifest @@ -0,0 +1,68 @@ + + + + + + + + Sample App + A Lone Developer + Images\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scratch/ScratchIslandApp/Package/Package.wapproj b/scratch/ScratchIslandApp/Package/Package.wapproj new file mode 100644 index 000000000..262719541 --- /dev/null +++ b/scratch/ScratchIslandApp/Package/Package.wapproj @@ -0,0 +1,155 @@ + + + + + + + false + false + + + cf31505e-3bae-4c0a-81d7-f1eb279f40bb + ..\WindowExe\WindowExe.vcxproj + NativeOnly + + + false + Never + + + true + False + Package_TemporaryKey.pfx + + + + + + + Designer + + + + + + + + + + + + + + + + + + $(OpenConsoleCommonOutDir)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd + $(OpenConsoleCommonOutDir)TerminalConnection\TerminalConnection.dll + true + true + true + + + $(OpenConsoleCommonOutDir)Microsoft.Terminal.Control\Microsoft.Terminal.Control.winmd + $(OpenConsoleCommonOutDir)Microsoft.Terminal.Control\Microsoft.Terminal.Control.dll + true + true + true + + + + + + + + <_TemporaryFilteredWapProjOutput Include="@(_FilteredNonWapProjProjectOutput)" /> + <_FilteredNonWapProjProjectOutput Remove="@(_TemporaryFilteredWapProjOutput)" /> + <_FilteredNonWapProjProjectOutput Include="@(_TemporaryFilteredWapProjOutput)"> + + + + + + + + + + <_GenerateProjectPriFileDependsOn Condition="$(MSBuildVersion) < '16.3.0'">OpenConsoleLiftDesktopBridgePriFiles;$(_GenerateProjectPriFileDependsOn) + + + + <_PriFile Include="@(_NonWapProjProjectOutput)" Condition="'%(Extension)' == '.pri'" /> + + + + + + + + $([MSBuild]::Unescape('$(WapProjBeforeGenerateAppxManifestDependsOn.Replace('_RemoveAllNonWapUWPItems', '_OpenConsoleRemoveAllNonWapUWPItems'))')) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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}. + + + + + + + + + diff --git a/scratch/ScratchIslandApp/Package/Resources/Resources.resw b/scratch/ScratchIslandApp/Package/Resources/Resources.resw new file mode 100644 index 000000000..872f430e7 --- /dev/null +++ b/scratch/ScratchIslandApp/Package/Resources/Resources.resw @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Scratch XAML Island App + + + Scratch App + + diff --git a/scratch/ScratchIslandApp/Package/Resources/en-US/Resources.resw b/scratch/ScratchIslandApp/Package/Resources/en-US/Resources.resw new file mode 100644 index 000000000..4ffee428e --- /dev/null +++ b/scratch/ScratchIslandApp/Package/Resources/en-US/Resources.resw @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + A scratch app for XAML Islands tests + + diff --git a/scratch/ScratchIslandApp/SampleApp/App.base.h b/scratch/ScratchIslandApp/SampleApp/App.base.h new file mode 100644 index 000000000..d6da79f1b --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/App.base.h @@ -0,0 +1,40 @@ +#pragma once + +namespace winrt::SampleApp::implementation +{ + template + struct App_baseWithProvider : public App_base + { + using IXamlType = ::winrt::Windows::UI::Xaml::Markup::IXamlType; + + IXamlType GetXamlType(::winrt::Windows::UI::Xaml::Interop::TypeName const& type) + { + return AppProvider()->GetXamlType(type); + } + + IXamlType GetXamlType(::winrt::hstring const& fullName) + { + return AppProvider()->GetXamlType(fullName); + } + + ::winrt::com_array<::winrt::Windows::UI::Xaml::Markup::XmlnsDefinition> GetXmlnsDefinitions() + { + return AppProvider()->GetXmlnsDefinitions(); + } + + private: + bool _contentLoaded{ false }; + std::shared_ptr _appProvider; + std::shared_ptr AppProvider() + { + if (!_appProvider) + { + _appProvider = std::make_shared(); + } + return _appProvider; + } + }; + + template + using AppT2 = App_baseWithProvider; +} diff --git a/scratch/ScratchIslandApp/SampleApp/App.cpp b/scratch/ScratchIslandApp/SampleApp/App.cpp new file mode 100644 index 000000000..5a2ae523f --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/App.cpp @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "App.h" +#include "App.g.cpp" + +using namespace winrt; +using namespace winrt::Windows::ApplicationModel::Activation; +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::UI::Xaml::Controls; +using namespace winrt::Windows::UI::Xaml::Navigation; + +namespace winrt::SampleApp::implementation +{ + App::App() + { + // This is the same trick that Initialize() is about to use to figure out whether we're coming + // from a UWP context or from a Win32 context + // See https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/blob/52611c57d89554f357f281d0c79036426a7d9257/Microsoft.Toolkit.Win32.UI.XamlApplication/XamlApplication.cpp#L42 + const auto dispatcherQueue = ::winrt::Windows::System::DispatcherQueue::GetForCurrentThread(); + if (dispatcherQueue) + { + _isUwp = true; + } + + Initialize(); + + // Disable XAML's automatic backplating of text when in High Contrast + // mode: we want full control of and responsibility for the foreground + // and background colors that we draw in XAML. + HighContrastAdjustment(::winrt::Windows::UI::Xaml::ApplicationHighContrastAdjustment::None); + } + + SampleAppLogic App::Logic() + { + static SampleAppLogic logic; + return logic; + } + + /// + /// Invoked when the application is launched normally by the end user. Other entry points + /// will be used such as when the application is launched to open a specific file. + /// + /// Details about the launch request and process. + void App::OnLaunched(LaunchActivatedEventArgs const& /*e*/) + { + // if this is a UWP... it means its our problem to hook up the content to the window here. + if (_isUwp) + { + auto content = Window::Current().Content(); + if (content == nullptr) + { + auto logic = Logic(); + logic.Create(); + + auto page = logic.GetRoot().as(); + + Window::Current().Content(page); + Window::Current().Activate(); + } + } + } +} diff --git a/scratch/ScratchIslandApp/SampleApp/App.h b/scratch/ScratchIslandApp/SampleApp/App.h new file mode 100644 index 000000000..fb6235d75 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/App.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +#include "App.g.h" +#include "App.base.h" + +namespace winrt::SampleApp::implementation +{ + struct App : AppT2 + { + public: + App(); + void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&); + + SampleApp::SampleAppLogic Logic(); + + private: + bool _isUwp = false; + }; +} + +namespace winrt::SampleApp::factory_implementation +{ + struct App : AppT + { + }; +} diff --git a/scratch/ScratchIslandApp/SampleApp/App.idl b/scratch/ScratchIslandApp/SampleApp/App.idl new file mode 100644 index 000000000..e51a73332 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/App.idl @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import "SampleAppLogic.idl"; + +namespace SampleApp +{ + // ADD ARBITRARY APP LOGIC TO SampleAppLogic.idl, NOT HERE. + // This is for XAML platform setup only. + [default_interface] runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication + { + App(); + + SampleAppLogic Logic { get; }; + } +} diff --git a/scratch/ScratchIslandApp/SampleApp/App.xaml b/scratch/ScratchIslandApp/SampleApp/App.xaml new file mode 100644 index 000000000..c6a2328f4 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/App.xaml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + 8,0,8,0 + + + + + + + + + + + + + + + + + + + + + diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.cpp b/scratch/ScratchIslandApp/SampleApp/MyPage.cpp new file mode 100644 index 000000000..d4af3d80e --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MyPage.cpp @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "MyPage.h" +#include +#include "MyPage.g.cpp" +#include "..\..\..\src\cascadia\UnitTests_Control\MockControlSettings.h" + +using namespace std::chrono_literals; +using namespace winrt::Microsoft::Terminal; + +namespace winrt +{ + namespace MUX = Microsoft::UI::Xaml; + namespace WUX = Windows::UI::Xaml; + using IInspectable = Windows::Foundation::IInspectable; +} + +namespace winrt::SampleApp::implementation +{ + MyPage::MyPage() + { + InitializeComponent(); + } + + void MyPage::Create() + { + TerminalConnection::EchoConnection conn{}; + auto settings = winrt::make_self(); + + Control::TermControl control{ *settings, conn }; + + InProcContent().Children().Append(control); + + // Once the control loads (and not before that), write some text for debugging: + control.Initialized([conn](auto&&, auto&&) { + conn.WriteInput(L"This TermControl is hosted in-proc..."); + }); + } + + // Method Description: + // - Gets the title of the currently focused terminal control. If there + // isn't a control selected for any reason, returns "Windows Terminal" + // Arguments: + // - + // Return Value: + // - the title of the focused control if there is one, else "Windows Terminal" + hstring MyPage::Title() + { + return { L"Sample Application" }; + } + +} diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.h b/scratch/ScratchIslandApp/SampleApp/MyPage.h new file mode 100644 index 000000000..c16c02bb3 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MyPage.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +#include "MyPage.g.h" +#include "../../../src/cascadia/inc/cppwinrt_utils.h" + +namespace winrt::SampleApp::implementation +{ + struct MyPage : MyPageT + { + public: + MyPage(); + + void Create(); + + hstring Title(); + + private: + friend struct MyPageT; // for Xaml to bind events + }; +} + +namespace winrt::SampleApp::factory_implementation +{ + BASIC_FACTORY(MyPage); +} diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.idl b/scratch/ScratchIslandApp/SampleApp/MyPage.idl new file mode 100644 index 000000000..d3d0645b5 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MyPage.idl @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace SampleApp +{ + [default_interface] runtimeclass MyPage : Windows.UI.Xaml.Controls.Page + { + MyPage(); + } +} diff --git a/scratch/ScratchIslandApp/SampleApp/MyPage.xaml b/scratch/ScratchIslandApp/SampleApp/MyPage.xaml new file mode 100644 index 000000000..f6e129ee7 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MyPage.xaml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scratch/ScratchIslandApp/SampleApp/MySettings.cpp b/scratch/ScratchIslandApp/SampleApp/MySettings.cpp new file mode 100644 index 000000000..c042a34e7 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MySettings.cpp @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" + +#include "MySettings.h" +#include "MySettings.g.cpp" + +namespace winrt::SampleApp::implementation +{ +} diff --git a/scratch/ScratchIslandApp/SampleApp/MySettings.h b/scratch/ScratchIslandApp/SampleApp/MySettings.h new file mode 100644 index 000000000..170c9b540 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MySettings.h @@ -0,0 +1,97 @@ +/*++ +Copyright (c) Microsoft Corporation +Licensed under the MIT license. +--*/ +#pragma once +#include "../../inc/cppwinrt_utils.h" +#include +#include +#include "MySettings.g.h" + +namespace winrt::SampleApp::implementation +{ + struct MySettings : MySettingsT + { + public: + MySettings() = default; + + // --------------------------- Core Settings --------------------------- + // All of these settings are defined in ICoreSettings. + + WINRT_PROPERTY(til::color, DefaultForeground, DEFAULT_FOREGROUND); + WINRT_PROPERTY(til::color, DefaultBackground, DEFAULT_BACKGROUND); + WINRT_PROPERTY(til::color, SelectionBackground, DEFAULT_FOREGROUND); + WINRT_PROPERTY(int32_t, HistorySize, DEFAULT_HISTORY_SIZE); + WINRT_PROPERTY(int32_t, InitialRows, 30); + WINRT_PROPERTY(int32_t, InitialCols, 80); + + WINRT_PROPERTY(bool, SnapOnInput, true); + WINRT_PROPERTY(bool, AltGrAliasing, true); + WINRT_PROPERTY(til::color, CursorColor, DEFAULT_CURSOR_COLOR); + WINRT_PROPERTY(winrt::Microsoft::Terminal::Core::CursorStyle, CursorShape, winrt::Microsoft::Terminal::Core::CursorStyle::Vintage); + WINRT_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT); + WINRT_PROPERTY(winrt::hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS); + WINRT_PROPERTY(bool, CopyOnSelect, false); + WINRT_PROPERTY(bool, InputServiceWarning, true); + WINRT_PROPERTY(bool, FocusFollowMouse, false); + + WINRT_PROPERTY(winrt::Windows::Foundation::IReference, TabColor, nullptr); + + WINRT_PROPERTY(winrt::Windows::Foundation::IReference, StartingTabColor, nullptr); + + winrt::Microsoft::Terminal::Core::ICoreAppearance UnfocusedAppearance() { return {}; }; + + WINRT_PROPERTY(bool, TrimBlockSelection, false); + // ------------------------ End of Core Settings ----------------------- + + WINRT_PROPERTY(winrt::hstring, ProfileName); + WINRT_PROPERTY(bool, UseAcrylic, false); + WINRT_PROPERTY(double, TintOpacity, 0.5); + WINRT_PROPERTY(winrt::hstring, Padding, DEFAULT_PADDING); + WINRT_PROPERTY(winrt::hstring, FontFace, L"Consolas"); + WINRT_PROPERTY(int32_t, FontSize, DEFAULT_FONT_SIZE); + + WINRT_PROPERTY(winrt::Windows::UI::Text::FontWeight, FontWeight); + + WINRT_PROPERTY(winrt::hstring, BackgroundImage); + WINRT_PROPERTY(double, BackgroundImageOpacity, 1.0); + + WINRT_PROPERTY(winrt::Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill); + WINRT_PROPERTY(winrt::Windows::UI::Xaml::HorizontalAlignment, BackgroundImageHorizontalAlignment, winrt::Windows::UI::Xaml::HorizontalAlignment::Center); + WINRT_PROPERTY(winrt::Windows::UI::Xaml::VerticalAlignment, BackgroundImageVerticalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment::Center); + + WINRT_PROPERTY(winrt::Microsoft::Terminal::Control::IKeyBindings, KeyBindings, nullptr); + + WINRT_PROPERTY(winrt::hstring, Commandline); + WINRT_PROPERTY(winrt::hstring, StartingDirectory); + WINRT_PROPERTY(winrt::hstring, StartingTitle); + WINRT_PROPERTY(bool, SuppressApplicationTitle); + WINRT_PROPERTY(winrt::hstring, EnvironmentVariables); + + WINRT_PROPERTY(winrt::Microsoft::Terminal::Control::ScrollbarState, ScrollState, winrt::Microsoft::Terminal::Control::ScrollbarState::Visible); + + WINRT_PROPERTY(winrt::Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode, winrt::Microsoft::Terminal::Control::TextAntialiasingMode::Grayscale); + + WINRT_PROPERTY(bool, RetroTerminalEffect, false); + WINRT_PROPERTY(bool, ForceFullRepaintRendering, false); + WINRT_PROPERTY(bool, SoftwareRendering, false); + WINRT_PROPERTY(bool, ForceVTInput, false); + + WINRT_PROPERTY(winrt::hstring, PixelShaderPath); + + WINRT_PROPERTY(bool, DetectURLs, true); + + private: + std::array _ColorTable; + + public: + winrt::Microsoft::Terminal::Core::Color GetColorTableEntry(int32_t index) noexcept { return _ColorTable.at(index); } + std::array ColorTable() { return _ColorTable; } + void ColorTable(std::array /*colors*/) {} + }; +} + +namespace winrt::SampleApp::factory_implementation +{ + BASIC_FACTORY(MySettings); +} diff --git a/scratch/ScratchIslandApp/SampleApp/MySettings.idl b/scratch/ScratchIslandApp/SampleApp/MySettings.idl new file mode 100644 index 000000000..42422b21a --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/MySettings.idl @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace SampleApp +{ + [default_interface] runtimeclass MySettings : Microsoft.Terminal.Core.ICoreSettings, + Microsoft.Terminal.Control.IControlSettings, + Microsoft.Terminal.Core.ICoreAppearance, + Microsoft.Terminal.Control.IControlAppearance + + { + MySettings(); + } +} diff --git a/scratch/ScratchIslandApp/SampleApp/Resources/en-US/Resources.resw b/scratch/ScratchIslandApp/SampleApp/Resources/en-US/Resources.resw new file mode 100644 index 000000000..f4af46df5 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/Resources/en-US/Resources.resw @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/scratch/ScratchIslandApp/SampleApp/SampleAppLib.vcxproj b/scratch/ScratchIslandApp/SampleApp/SampleAppLib.vcxproj new file mode 100644 index 000000000..c16d6be6f --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/SampleAppLib.vcxproj @@ -0,0 +1,181 @@ + + + + {a4394404-37f7-41c1-802b-49788d3720e3} + Win32Proj + SampleApp + SampleAppLib + SampleAppLib + StaticLibrary + Console + true + + false + nested + + + + + + + + + true + + + + + + + + Designer + + + + + + Designer + + + + + + + + MyPage.xaml + Code + + + App.xaml + + + SampleAppLogic.idl + + + + + + + + MyPage.xaml + Code + + + Create + + + App.xaml + + + SampleAppLogic.idl + + + + + + + + + App.xaml + + + + + MyPage.xaml + Code + + + + + + + + + + + + Warning + + + + + + $(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd + true + false + false + + + $(OpenConsoleCommonOutDir)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd + true + false + false + + + $(OpenConsoleCommonOutDir)Microsoft.Terminal.Control\Microsoft.Terminal.Control.winmd + true + false + false + + + + + + pch.h + ..;%(AdditionalIncludeDirectories); + + 4702;%(DisableSpecificWarnings) + + + $(OpenConsoleCommonOutDir)\ConTypes.lib;WindowsApp.lib;shell32.lib;%(AdditionalDependencies) + + + + + + + + + + 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}. + + + + + + + + <_GenerateProjectPriFileDependsOn>OpenConsolePlaceAppXbfAtRootOfResourceTree;$(_GenerateProjectPriFileDependsOn) + + + + <_RelocatedAppXamlData Include="@(PackagingOutputs)" Condition="'%(Filename)' == 'App' and ('%(Extension)' == '.xaml' or '%(Extension)' == '.xbf')" /> + + + %(Filename)%(Extension) + + + + + + diff --git a/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.cpp b/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.cpp new file mode 100644 index 000000000..4498f70df --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.cpp @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "SampleAppLogic.h" +#include "SampleAppLogic.g.cpp" + +#include + +using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::UI::Xaml::Controls; +using namespace winrt::Windows::UI::Core; +using namespace winrt::Windows::System; + +namespace winrt +{ + namespace MUX = Microsoft::UI::Xaml; + using IInspectable = Windows::Foundation::IInspectable; +} + +namespace winrt::SampleApp::implementation +{ + // Function Description: + // - Get the SampleAppLogic for the current active Xaml application, or null if there isn't one. + // Return value: + // - A pointer (bare) to the SampleAppLogic, or nullptr. The app logic outlives all other objects, + // unless the application is in a terrible way, so this is "safe." + SampleAppLogic* SampleAppLogic::Current() noexcept + try + { + if (auto currentXamlApp{ winrt::Windows::UI::Xaml::Application::Current().try_as() }) + { + if (auto SampleAppLogicPointer{ winrt::get_self(currentXamlApp.Logic()) }) + { + return SampleAppLogicPointer; + } + } + return nullptr; + } + catch (...) + { + LOG_CAUGHT_EXCEPTION(); + return nullptr; + } + + SampleAppLogic::SampleAppLogic() + { + // For your own sanity, it's better to do setup outside the ctor. + // If you do any setup in the ctor that ends up throwing an exception, + // then it might look like App just failed to activate, which will + // cause you to chase down the rabbit hole of "why is App not + // registered?" when it definitely is. + + // The MyPage has to be constructed during our construction, to + // make sure that there's a terminal page for callers of + // SetTitleBarContent + _root = winrt::make_self(); + } + + // Method Description: + // - Build the UI for the terminal app. Before this method is called, it + // should not be assumed that the SampleApp is usable. The Settings + // should be loaded before this is called, either with LoadSettings or + // GetLaunchDimensions (which will call LoadSettings) + // Arguments: + // - + // Return Value: + // - + void SampleAppLogic::Create() + { + _root->Create(); + } + + UIElement SampleAppLogic::GetRoot() noexcept + { + return _root.as(); + } + + hstring SampleAppLogic::Title() + { + return _root->Title(); + } + +} diff --git a/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.h b/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.h new file mode 100644 index 000000000..8b8642a8e --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.h @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +#include "SampleAppLogic.g.h" +#include "MyPage.h" +#include "../../../src/cascadia/inc/cppwinrt_utils.h" + +namespace winrt::SampleApp::implementation +{ + struct SampleAppLogic : SampleAppLogicT + { + public: + static SampleAppLogic* Current() noexcept; + + SampleAppLogic(); + ~SampleAppLogic() = default; + + void Create(); + + Windows::UI::Xaml::UIElement GetRoot() noexcept; + + winrt::hstring Title(); + + private: + // If you add controls here, but forget to null them either here or in + // the ctor, you're going to have a bad time. It'll mysteriously fail to + // activate the SampleAppLogic. + // ALSO: If you add any UIElements as roots here, make sure they're + // updated in _ApplyTheme. The root currently is _root. + winrt::com_ptr _root{ nullptr }; + }; +} + +namespace winrt::SampleApp::factory_implementation +{ + struct SampleAppLogic : SampleAppLogicT + { + }; +} diff --git a/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.idl b/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.idl new file mode 100644 index 000000000..9b7d49e1a --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/SampleAppLogic.idl @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + + +namespace SampleApp +{ + + [default_interface] runtimeclass SampleAppLogic + { + SampleAppLogic(); + + void Create(); + + Windows.UI.Xaml.UIElement GetRoot(); + + String Title { get; }; + + } +} diff --git a/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.def b/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.def new file mode 100644 index 000000000..8c1a02932 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj b/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj new file mode 100644 index 000000000..1b1961fac --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj @@ -0,0 +1,101 @@ + + + + {26c51792-41a3-4fe0-ab5e-8b69d557bf91} + SampleApp + SampleApp + + + DynamicLibrary + Console + + true + + + + + + + + + + + + + + + + + + Create + + + + + + + + + + + + + + + true + true + + + + + + + + $(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd + true + false + false + + + $(OpenConsoleCommonOutDir)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd + true + false + false + + + $(OpenConsoleCommonOutDir)Microsoft.Terminal.Control\Microsoft.Terminal.Control.winmd + true + false + false + + + + + + + + + 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}. + + + + + + + + $(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories); + + + WindowsApp.lib;%(AdditionalDependencies) + + /INCLUDE:_DllMain@12 %(AdditionalOptions) + /INCLUDE:DllMain %(AdditionalOptions) + + + + diff --git a/scratch/ScratchIslandApp/SampleApp/dll/pch.cpp b/scratch/ScratchIslandApp/SampleApp/dll/pch.cpp new file mode 100644 index 000000000..3c27d44d5 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/dll/pch.cpp @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" diff --git a/scratch/ScratchIslandApp/SampleApp/dll/pch.h b/scratch/ScratchIslandApp/SampleApp/dll/pch.h new file mode 100644 index 000000000..76004c88f --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/dll/pch.h @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +// pch.h +// Header for platform projection include files +// + +#pragma once + +// This file can be empty - the pch.h in SampleApp/lib does the heavy lifting +// of including all the headers we need. As this project is just a dll wrapper, +// we don't actually need anything in here. diff --git a/scratch/ScratchIslandApp/SampleApp/init.cpp b/scratch/ScratchIslandApp/SampleApp/init.cpp new file mode 100644 index 000000000..1c169d9d9 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/init.cpp @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +#include "pch.h" +#include +#include + +BOOL WINAPI DllMain(HINSTANCE /*hInstDll*/, DWORD /*reason*/, LPVOID /*reserved*/) +{ + return TRUE; +} + +UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"SampleApp/Resources") diff --git a/scratch/ScratchIslandApp/SampleApp/packages.config b/scratch/ScratchIslandApp/SampleApp/packages.config new file mode 100644 index 000000000..a6c68340a --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/packages.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/scratch/ScratchIslandApp/SampleApp/pch.cpp b/scratch/ScratchIslandApp/SampleApp/pch.cpp new file mode 100644 index 000000000..3c27d44d5 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/pch.cpp @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" diff --git a/scratch/ScratchIslandApp/SampleApp/pch.h b/scratch/ScratchIslandApp/SampleApp/pch.h new file mode 100644 index 000000000..fd9d893f9 --- /dev/null +++ b/scratch/ScratchIslandApp/SampleApp/pch.h @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +// pch.h +// Header for platform projection include files +// + +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOHELP +#define NOCOMM + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#define BLOCK_TIL +#include +// This is inexplicable, but for whatever reason, cppwinrt conflicts with the +// SDK definition of this function, so the only fix is to undef it. +// from WinBase.h +// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime +#ifdef GetCurrentTime +#undef GetCurrentTime +#endif + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "winrt/Windows.UI.Xaml.Markup.h" +#include "winrt/Windows.UI.ViewManagement.h" + +#include +#include +#include +#include + +#include + +// Including TraceLogging essentials for the binary +#include +#include +TRACELOGGING_DECLARE_PROVIDER(g_hSampleAppProvider); +#include +#include + +#include +#include + +#include +#include +#include + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#include "til.h" diff --git a/scratch/ScratchIslandApp/WindowExe/SampleAppHost.cpp b/scratch/ScratchIslandApp/WindowExe/SampleAppHost.cpp new file mode 100644 index 000000000..2d3afefc5 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/SampleAppHost.cpp @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "SampleAppHost.h" +#include "../types/inc/Viewport.hpp" +#include "../types/inc/utils.hpp" +#include "../types/inc/User32Utils.hpp" +#include "resource.h" + +using namespace winrt::Windows::UI; +using namespace winrt::Windows::UI::Composition; +using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::UI::Xaml::Hosting; +using namespace winrt::Windows::Foundation::Numerics; +using namespace ::Microsoft::Console; +using namespace ::Microsoft::Console::Types; + +SampleAppHost::SampleAppHost() noexcept : + _app{}, + _logic{ nullptr }, // don't make one, we're going to take a ref on app's + _window{ nullptr } +{ + _logic = _app.Logic(); // get a ref to app's logic + + _window = std::make_unique(); + _window->MakeWindow(); +} + +SampleAppHost::~SampleAppHost() +{ + // destruction order is important for proper teardown here + _window = nullptr; + _app.Close(); + _app = nullptr; +} +// Method Description: +// - Initializes the XAML island, creates the terminal app, and sets the +// island's content to that of the terminal app's content. Also registers some +// callbacks with TermApp. +// !!! IMPORTANT!!! +// This must be called *AFTER* WindowsXamlManager::InitializeForCurrentThread. +// If it isn't, then we won't be able to create the XAML island. +// Arguments: +// - +// Return Value: +// - +void SampleAppHost::Initialize() +{ + _window->Initialize(); + + _logic.Create(); + + _window->UpdateTitle(_logic.Title()); + + // Set up the content of the application. If the app has a custom titlebar, + // set that content as well. + _window->SetContent(_logic.GetRoot()); + + _window->OnAppInitialized(); + + // THIS IS A HACK + // + // We've got a weird crash that happens terribly inconsistently, only in + // Debug mode. Apparently, there's some weird ref-counting magic that goes + // on during teardown, and our Application doesn't get closed quite right, + // which can cause us to crash into the debugger. This of course, only + // happens on exit, and happens somewhere in the XamlHost.dll code. + // + // Crazily, if we _manually leak the Application_ here, then the crash + // doesn't happen. This doesn't matter, because we really want the + // Application to live for _the entire lifetime of the process_, so the only + // time when this object would actually need to get cleaned up is _during + // exit_. So we can safely leak this Application object, and have it just + // get cleaned up normally when our process exits. + ::winrt::SampleApp::App a{ _app }; + ::winrt::detach_abi(a); +} diff --git a/scratch/ScratchIslandApp/WindowExe/SampleAppHost.h b/scratch/ScratchIslandApp/WindowExe/SampleAppHost.h new file mode 100644 index 000000000..226f90a4b --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/SampleAppHost.h @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" + +#include "SampleIslandWindow.h" + +class SampleAppHost +{ +public: + SampleAppHost() noexcept; + virtual ~SampleAppHost(); + + void Initialize(); + +private: + std::unique_ptr _window; + winrt::SampleApp::App _app; + winrt::SampleApp::SampleAppLogic _logic; +}; diff --git a/scratch/ScratchIslandApp/WindowExe/SampleBaseWindow.h b/scratch/ScratchIslandApp/WindowExe/SampleBaseWindow.h new file mode 100644 index 000000000..5c25452b3 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/SampleBaseWindow.h @@ -0,0 +1,228 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +// Custom window messages +#define CM_UPDATE_TITLE (WM_USER) + +#include + +template +class BaseWindow +{ +public: + virtual ~BaseWindow() = 0; + static T* GetThisFromHandle(HWND const window) noexcept + { + return reinterpret_cast(GetWindowLongPtr(window, GWLP_USERDATA)); + } + + [[nodiscard]] static LRESULT __stdcall WndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept + { + WINRT_ASSERT(window); + + if (WM_NCCREATE == message) + { + auto cs = reinterpret_cast(lparam); + T* that = static_cast(cs->lpCreateParams); + WINRT_ASSERT(that); + WINRT_ASSERT(!that->_window); + that->_window = wil::unique_hwnd(window); + + return that->_OnNcCreate(wparam, lparam); + } + else if (T* that = GetThisFromHandle(window)) + { + return that->MessageHandler(message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); + } + + [[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept + { + switch (message) + { + case WM_DPICHANGED: + { + return HandleDpiChange(_window.get(), wparam, lparam); + } + + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + + case WM_SIZE: + { + UINT width = LOWORD(lparam); + UINT height = HIWORD(lparam); + + switch (wparam) + { + case SIZE_MAXIMIZED: + [[fallthrough]]; + case SIZE_RESTORED: + if (_minimized) + { + _minimized = false; + OnRestore(); + } + + // We always need to fire the resize event, even when we're transitioning from minimized. + // We might be transitioning directly from minimized to maximized, and we'll need + // to trigger any size-related content changes. + OnResize(width, height); + break; + case SIZE_MINIMIZED: + if (!_minimized) + { + _minimized = true; + OnMinimize(); + } + break; + default: + // do nothing. + break; + } + break; + } + case CM_UPDATE_TITLE: + { + SetWindowTextW(_window.get(), _title.c_str()); + break; + } + } + + return DefWindowProc(_window.get(), message, wparam, lparam); + } + + // DPI Change handler. on WM_DPICHANGE resize the window + [[nodiscard]] LRESULT HandleDpiChange(const HWND hWnd, const WPARAM wParam, const LPARAM lParam) + { + _inDpiChange = true; + const HWND hWndStatic = GetWindow(hWnd, GW_CHILD); + if (hWndStatic != nullptr) + { + const UINT uDpi = HIWORD(wParam); + + // Resize the window + auto lprcNewScale = reinterpret_cast(lParam); + + SetWindowPos(hWnd, nullptr, lprcNewScale->left, lprcNewScale->top, lprcNewScale->right - lprcNewScale->left, lprcNewScale->bottom - lprcNewScale->top, SWP_NOZORDER | SWP_NOACTIVATE); + + _currentDpi = uDpi; + } + _inDpiChange = false; + return 0; + } + + virtual void OnResize(const UINT width, const UINT height) = 0; + virtual void OnMinimize() = 0; + virtual void OnRestore() = 0; + + RECT GetWindowRect() const noexcept + { + RECT rc = { 0 }; + ::GetWindowRect(_window.get(), &rc); + return rc; + } + + HWND GetHandle() const noexcept + { + return _window.get(); + } + + float GetCurrentDpiScale() const noexcept + { + const auto dpi = ::GetDpiForWindow(_window.get()); + const auto scale = static_cast(dpi) / static_cast(USER_DEFAULT_SCREEN_DPI); + return scale; + } + + // Gets the physical size of the client area of the HWND in _window + SIZE GetPhysicalSize() const noexcept + { + RECT rect = {}; + GetClientRect(_window.get(), &rect); + const auto windowsWidth = rect.right - rect.left; + const auto windowsHeight = rect.bottom - rect.top; + return SIZE{ windowsWidth, windowsHeight }; + } + + // Gets the logical (in DIPs) size of a physical size specified by the parameter physicalSize + // Remarks: + // XAML coordinate system is always in Display Independent Pixels (a.k.a DIPs or Logical). However Win32 GDI (because of legacy reasons) + // in DPI mode "Per-Monitor and Per-Monitor (V2) DPI Awareness" is always in physical pixels. + // The formula to transform is: + // logical = (physical / dpi) + 0.5 // 0.5 is to ensure that we pixel snap correctly at the edges, this is necessary with odd DPIs like 1.25, 1.5, 1, .75 + // See also: + // https://docs.microsoft.com/en-us/windows/desktop/LearnWin32/dpi-and-device-independent-pixels + // https://docs.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness + winrt::Windows::Foundation::Size GetLogicalSize(const SIZE physicalSize) const noexcept + { + const auto scale = GetCurrentDpiScale(); + // 0.5 is to ensure that we pixel snap correctly at the edges, this is necessary with odd DPIs like 1.25, 1.5, 1, .75 + const auto logicalWidth = (physicalSize.cx / scale) + 0.5f; + const auto logicalHeight = (physicalSize.cy / scale) + 0.5f; + return winrt::Windows::Foundation::Size(logicalWidth, logicalHeight); + } + + winrt::Windows::Foundation::Size GetLogicalSize() const noexcept + { + return GetLogicalSize(GetPhysicalSize()); + } + + // Method Description: + // - Sends a message to our message loop to update the title of the window. + // Arguments: + // - newTitle: a string to use as the new title of the window. + // Return Value: + // - + void UpdateTitle(std::wstring_view newTitle) + { + _title = newTitle; + PostMessageW(_window.get(), CM_UPDATE_TITLE, 0, reinterpret_cast(nullptr)); + } + + // Method Description: + // Reset the current dpi of the window. This method is only called after we change the + // initial launch position. This makes sure the dpi is consistent with the monitor on which + // the window will launch + void RefreshCurrentDPI() + { + _currentDpi = GetDpiForWindow(_window.get()); + } + +protected: + using base_type = BaseWindow; + wil::unique_hwnd _window; + + unsigned int _currentDpi = 0; + bool _inDpiChange = false; + + std::wstring _title = L""; + + bool _minimized = false; + + // Method Description: + // - This method is called when the window receives the WM_NCCREATE message. + // Return Value: + // - The value returned from the window proc. + virtual [[nodiscard]] LRESULT _OnNcCreate(WPARAM wParam, LPARAM lParam) noexcept + { + SetWindowLongPtr(_window.get(), GWLP_USERDATA, reinterpret_cast(this)); + + EnableNonClientDpiScaling(_window.get()); + _currentDpi = GetDpiForWindow(_window.get()); + + return DefWindowProc(_window.get(), WM_NCCREATE, wParam, lParam); + }; +}; + +template +inline BaseWindow::~BaseWindow() +{ +} diff --git a/scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.cpp b/scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.cpp new file mode 100644 index 000000000..1c5cf10d0 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.cpp @@ -0,0 +1,220 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "SampleIslandWindow.h" +#include "../types/inc/Viewport.hpp" +#include "resource.h" +#include "icon.h" + +extern "C" IMAGE_DOS_HEADER __ImageBase; + +using namespace winrt::Windows::UI; +using namespace winrt::Windows::UI::Composition; +using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::UI::Xaml::Hosting; +using namespace winrt::Windows::Foundation::Numerics; +using namespace ::Microsoft::Console::Types; + +#define XAML_HOSTING_WINDOW_CLASS_NAME L"SCRATCH_HOSTING_WINDOW_CLASS" + +SampleIslandWindow::SampleIslandWindow() noexcept : + _interopWindowHandle{ nullptr }, + _rootGrid{ nullptr }, + _source{ nullptr } +{ +} + +SampleIslandWindow::~SampleIslandWindow() +{ + _source.Close(); +} + +// Method Description: +// - Create the actual window that we'll use for the application. +// Arguments: +// - +// Return Value: +// - +void SampleIslandWindow::MakeWindow() noexcept +{ + WNDCLASS wc{}; + wc.hCursor = LoadCursor(nullptr, IDC_ARROW); + wc.hInstance = reinterpret_cast(&__ImageBase); + wc.lpszClassName = XAML_HOSTING_WINDOW_CLASS_NAME; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WndProc; + wc.hIcon = LoadIconW(wc.hInstance, MAKEINTRESOURCEW(IDI_APPICON)); + RegisterClass(&wc); + WINRT_ASSERT(!_window); + + // Create the window with the default size here - During the creation of the + // window, the system will give us a chance to set its size in WM_CREATE. + // WM_CREATE will be handled synchronously, before CreateWindow returns. + WINRT_VERIFY(CreateWindowEx(0, + wc.lpszClassName, + L"ScratchApp", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + nullptr, + nullptr, + wc.hInstance, + this)); + + WINRT_ASSERT(_window); +} + +// Method Description: +// - Called when no tab is remaining to close the window. +// Arguments: +// - +// Return Value: +// - +void SampleIslandWindow::Close() +{ + PostQuitMessage(0); +} + +// Method Description: +// - Handles a WM_CREATE message. Calls our create callback, if one's been set. +// Arguments: +// - wParam: unused +// - lParam: the lParam of a WM_CREATE, which is a pointer to a CREATESTRUCTW +// Return Value: +// - +void SampleIslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexcept +{ + // Get proposed window rect from create structure + CREATESTRUCTW* pcs = reinterpret_cast(lParam); + RECT rc; + rc.left = pcs->x; + rc.top = pcs->y; + rc.right = rc.left + pcs->cx; + rc.bottom = rc.top + pcs->cy; + + ShowWindow(_window.get(), SW_SHOW); + + UpdateWindow(_window.get()); + + UpdateWindowIconForActiveMetrics(_window.get()); +} + +void SampleIslandWindow::Initialize() +{ + const bool initialized = (_interopWindowHandle != nullptr); + + _source = DesktopWindowXamlSource{}; + + auto interop = _source.as(); + winrt::check_hresult(interop->AttachToWindow(_window.get())); + + // stash the child interop handle so we can resize it when the main hwnd is resized + interop->get_WindowHandle(&_interopWindowHandle); + + _rootGrid = winrt::Windows::UI::Xaml::Controls::Grid(); + _source.Content(_rootGrid); +} + +void SampleIslandWindow::OnSize(const UINT width, const UINT height) +{ + // update the interop window size + SetWindowPos(_interopWindowHandle, nullptr, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOACTIVATE); + + if (_rootGrid) + { + const auto size = GetLogicalSize(); + _rootGrid.Width(size.Width); + _rootGrid.Height(size.Height); + } +} + +[[nodiscard]] LRESULT SampleIslandWindow::MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept +{ + switch (message) + { + case WM_CREATE: + { + _HandleCreateWindow(wparam, lparam); + return 0; + } + case WM_SETFOCUS: + { + if (_interopWindowHandle != nullptr) + { + // send focus to the child window + SetFocus(_interopWindowHandle); + return 0; + } + break; + } + case WM_MENUCHAR: + { + // GH#891: return this LRESULT here to prevent the app from making a + // bell when alt+key is pressed. A menu is active and the user presses a + // key that does not correspond to any mnemonic or accelerator key, + return MAKELRESULT(0, MNC_CLOSE); + } + case WM_THEMECHANGED: + UpdateWindowIconForActiveMetrics(_window.get()); + return 0; + } + + return base_type::MessageHandler(message, wparam, lparam); +} + +// Method Description: +// - Called when the window has been resized (or maximized) +// Arguments: +// - width: the new width of the window _in pixels_ +// - height: the new height of the window _in pixels_ +void SampleIslandWindow::OnResize(const UINT width, const UINT height) +{ + if (_interopWindowHandle) + { + OnSize(width, height); + } +} + +// Method Description: +// - Called when the window is minimized to the taskbar. +void SampleIslandWindow::OnMinimize() +{ +} + +// Method Description: +// - Called when the window is restored from having been minimized. +void SampleIslandWindow::OnRestore() +{ +} + +void SampleIslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content) +{ + _rootGrid.Children().Clear(); + _rootGrid.Children().Append(content); +} + +void SampleIslandWindow::OnAppInitialized() +{ + // Do a quick resize to force the island to paint + const auto size = GetPhysicalSize(); + OnSize(size.cx, size.cy); +} + +// Method Description: +// - Called when the app wants to change its theme. We'll update the root UI +// element of the entire XAML tree, so that all UI elements get the theme +// applied. +// Arguments: +// - arg: the ElementTheme to use as the new theme for the UI +// Return Value: +// - +void SampleIslandWindow::OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) +{ + _rootGrid.RequestedTheme(requestedTheme); + // Invalidate the window rect, so that we'll repaint any elements we're + // drawing ourselves to match the new theme + ::InvalidateRect(_window.get(), nullptr, false); +} diff --git a/scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.h b/scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.h new file mode 100644 index 000000000..14a62f13c --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.h @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "SampleBaseWindow.h" +#include "../../../src/cascadia/inc/cppwinrt_utils.h" + +class SampleIslandWindow : + public BaseWindow +{ +public: + SampleIslandWindow() noexcept; + virtual ~SampleIslandWindow() override; + + virtual void MakeWindow() noexcept; + void Close(); + + virtual void OnSize(const UINT width, const UINT height); + + [[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override; + void OnResize(const UINT width, const UINT height) override; + void OnMinimize() override; + void OnRestore() override; + virtual void OnAppInitialized(); + virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content); + virtual void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme); + + virtual void Initialize(); + +protected: + void ForceResize() + { + // Do a quick resize to force the island to paint + const auto size = GetPhysicalSize(); + OnSize(size.cx, size.cy); + } + + HWND _interopWindowHandle; + + winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _source; + + winrt::Windows::UI::Xaml::Controls::Grid _rootGrid; + + void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept; +}; diff --git a/scratch/ScratchIslandApp/WindowExe/SampleMain.cpp b/scratch/ScratchIslandApp/WindowExe/SampleMain.cpp new file mode 100644 index 000000000..4c09f262c --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/SampleMain.cpp @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "SampleAppHost.h" +#include "resource.h" +#include "../types/inc/User32Utils.hpp" +#include + +using namespace winrt; +using namespace winrt::Windows::UI; +using namespace winrt::Windows::UI::Composition; +using namespace winrt::Windows::UI::Xaml::Hosting; +using namespace winrt::Windows::Foundation::Numerics; + +// Routine Description: +// - Takes an image architecture and locates a string resource that maps to that architecture. +// Arguments: +// - imageArchitecture - An IMAGE_FILE_MACHINE architecture enum value +// - See https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants +// Return Value: +// - A string value representing the human-readable name of this architecture. +static std::wstring ImageArchitectureToString(USHORT imageArchitecture) +{ + // clang-format off + const auto id = imageArchitecture == IMAGE_FILE_MACHINE_I386 ? IDS_X86_ARCHITECTURE : + imageArchitecture == IMAGE_FILE_MACHINE_AMD64 ? IDS_AMD64_ARCHITECTURE : + imageArchitecture == IMAGE_FILE_MACHINE_ARM64 ? IDS_ARM64_ARCHITECTURE : + imageArchitecture == IMAGE_FILE_MACHINE_ARM ? IDS_ARM_ARCHITECTURE : + IDS_UNKNOWN_ARCHITECTURE; + // clang-format on + + return GetStringResource(id); +} + +// Routine Description: +// - Blocks the user from launching the application with a message box dialog and early exit +// if the process architecture doesn't match the system platform native architecture. +// - This is because the conhost.exe must match the condrv.sys on the system and the PTY +// infrastructure that powers everything won't work if we have a mismatch. +// Arguments: +// - +// Return Value: +// - +static void EnsureNativeArchitecture() +{ + USHORT processMachine{}; + USHORT nativeMachine{}; + THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine)); + if (processMachine != IMAGE_FILE_MACHINE_UNKNOWN && processMachine != nativeMachine) + { + const auto formatPattern = GetStringResource(IDS_ERROR_ARCHITECTURE_FORMAT); + + const auto nativeArchitecture = ImageArchitectureToString(nativeMachine); + const auto processArchitecture = ImageArchitectureToString(processMachine); + + auto buffer{ wil::str_printf(formatPattern.data(), nativeArchitecture.data(), processArchitecture.data()) }; + + MessageBoxW(nullptr, + buffer.data(), + GetStringResource(IDS_ERROR_DIALOG_TITLE).data(), + MB_OK | MB_ICONERROR); + + ExitProcess(0); + } +} + +static bool _messageIsF7Keypress(const MSG& message) +{ + return (message.message == WM_KEYDOWN || message.message == WM_SYSKEYDOWN) && message.wParam == VK_F7; +} +static bool _messageIsAltKeyup(const MSG& message) +{ + return (message.message == WM_KEYUP || message.message == WM_SYSKEYUP) && message.wParam == VK_MENU; +} + +int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) +{ + // If Terminal is spawned by a shortcut that requests that it run in a new process group + // while attached to a console session, that request is nonsense. That request will, however, + // cause WT to start with Ctrl-C disabled. This wouldn't matter, because it's a Windows-subsystem + // application. Unfortunately, that state is heritable. In short, if you start WT using cmd in + // a weird way, ^C stops working _inside_ the terminal. Mad. + SetConsoleCtrlHandler(NULL, FALSE); + + // Block the user from starting if they launched the incorrect architecture version of the project. + // This should only be applicable to developer versions. The package installation process + // should choose and install the correct one from the bundle. + EnsureNativeArchitecture(); + + // Make sure to call this so we get WM_POINTER messages. + EnableMouseInPointer(true); + + // !!! LOAD BEARING !!! + // We must initialize the main thread as a single-threaded apartment before + // constructing any Xaml objects. Failing to do so will cause some issues + // in accessibility somewhere down the line when a UIAutomation object will + // be queried on the wrong thread at the wrong time. + // We used to initialize as STA only _after_ initializing the application + // host, which loaded the settings. The settings needed to be loaded in MTA + // because we were using the Windows.Storage APIs. Since we're no longer + // doing that, we can safely init as STA before any WinRT dispatches. + winrt::init_apartment(winrt::apartment_type::single_threaded); + + // Create the SampleAppHost object, which will create both the window and the + // Terminal App. This MUST BE constructed before the Xaml manager as TermApp + // provides an implementation of Windows.UI.Xaml.Application. + SampleAppHost host; + + // Initialize the xaml content. This must be called AFTER the + // WindowsXamlManager is initialized. + host.Initialize(); + + MSG message; + + while (GetMessage(&message, nullptr, 0, 0)) + { + TranslateMessage(&message); + DispatchMessage(&message); + } + return 0; +} diff --git a/scratch/ScratchIslandApp/WindowExe/WindowExe.def b/scratch/ScratchIslandApp/WindowExe/WindowExe.def new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/WindowExe.def @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/scratch/ScratchIslandApp/WindowExe/WindowExe.manifest b/scratch/ScratchIslandApp/WindowExe/WindowExe.manifest new file mode 100644 index 000000000..9d91e543d --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/WindowExe.manifest @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + PerMonitorV2 + true + + + diff --git a/scratch/ScratchIslandApp/WindowExe/WindowExe.rc b/scratch/ScratchIslandApp/WindowExe/WindowExe.rc new file mode 100644 index 000000000..b11a8c88d --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/WindowExe.rc @@ -0,0 +1,97 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. + +IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico" +IDI_APPICON_HC_BLACK ICON "..\\..\\..\\res\\terminal\\images\\terminal_contrast-black.ico" +IDI_APPICON_HC_WHITE ICON "..\\..\\..\\res\\terminal\\images\\terminal_contrast-white.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_ERROR_DIALOG_TITLE "Error" + IDS_HELP_DIALOG_TITLE "Help" + IDS_ERROR_ARCHITECTURE_FORMAT + "This sample is designed to run on your system's native architecture (%s).\nYou are currently using the %s version.\n\nPlease use the version of this sample that matches your system's native architecture." + IDS_X86_ARCHITECTURE "i386" +END + +STRINGTABLE +BEGIN + IDS_AMD64_ARCHITECTURE "AMD64" + IDS_ARM64_ARCHITECTURE "ARM64" + IDS_ARM_ARCHITECTURE "ARM" + IDS_UNKNOWN_ARCHITECTURE "Unknown" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/scratch/ScratchIslandApp/WindowExe/WindowExe.vcxproj b/scratch/ScratchIslandApp/WindowExe/WindowExe.vcxproj new file mode 100644 index 000000000..edd372c2f --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/WindowExe.vcxproj @@ -0,0 +1,220 @@ + + + + + + {b4427499-9fde-4208-b456-5bc580637633} + Win32Proj + WindowExe + WindowExe + WindowExe + Application + false + Windows Store + true + false + Windows + + + + + + + + true + + + + + + $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories); + + + %(AdditionalDependencies) + + + + true + true + + + + + + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + $(OpenConsoleCommonOutDir)TerminalCore\Microsoft.Terminal.Core.winmd + true + true + true + + + $(OpenConsoleCommonOutDir)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd + $(OpenConsoleCommonOutDir)TerminalConnection\TerminalConnection.dll + true + true + true + + + $(OpenConsoleCommonOutDir)Microsoft.Terminal.Control\Microsoft.Terminal.Control.winmd + $(OpenConsoleCommonOutDir)Microsoft.Terminal.Control\Microsoft.Terminal.Control.dll + true + true + true + + + + + + + + + WindowsLocalDebugger + + + + + + + + + + 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}. + + + + + + + + + + <_ContinueOnError Condition="'$(BuildingProject)' == 'true'">true + <_ContinueOnError Condition="'$(BuildingProject)' != 'true'">false + + + + + + + + + + + + + x86 + $(Platform) + + + + + <_OpenConsoleVCLibToCopy Include="$(VCToolsRedistInstallDir)\$(ReasonablePlatform)\Microsoft.VC142.CRT\*.dll" /> + + + $(ProjectName) + BuiltProjectOutputGroup + %(Filename)%(Extension) + + + + + + + + + <_TerminalConnectionDlls Include="$(OpenConsoleCommonOutDir)\TerminalConnection\*.dll" /> + + + $(ProjectName) + BuiltProjectOutputGroup + %(Filename)%(Extension) + + + + + + + <_WindowsTerminalExe Include="$(OpenConsoleCommonOutDir)\WindowsTerminal\*.exe" /> + + + $(ProjectName) + BuiltProjectOutputGroup + %(Filename)%(Extension) + + + + + + + + + + + + diff --git a/scratch/ScratchIslandApp/WindowExe/icon.cpp b/scratch/ScratchIslandApp/WindowExe/icon.cpp new file mode 100644 index 000000000..ca194de06 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/icon.cpp @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "resource.h" + +static int _GetActiveAppIconResource() +{ + auto iconResource{ IDI_APPICON }; + + HIGHCONTRASTW hcInfo{}; + hcInfo.cbSize = sizeof(hcInfo); + + if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(hcInfo), &hcInfo, 0)) + { + if (WI_IsFlagSet(hcInfo.dwFlags, HCF_HIGHCONTRASTON)) + { + iconResource = IDI_APPICON_HC_BLACK; + + if (0x00FFFFFF == GetSysColor(COLOR_WINDOW)) // white window color == white high contrast + { + iconResource = IDI_APPICON_HC_WHITE; + } + } + } + + return iconResource; +} + +void UpdateWindowIconForActiveMetrics(HWND window) +{ + auto iconResource{ MAKEINTRESOURCEW(_GetActiveAppIconResource()) }; + + // These handles are loaded with LR_SHARED, so they are safe to "leak". + HANDLE smallIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) }; + LOG_LAST_ERROR_IF_NULL(smallIcon); + + HANDLE largeIcon{ LoadImageW(wil::GetModuleInstanceHandle(), iconResource, IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_SHARED) }; + LOG_LAST_ERROR_IF_NULL(largeIcon); + + if (smallIcon) + { + SendMessageW(window, WM_SETICON, ICON_SMALL, reinterpret_cast(smallIcon)); + } + if (largeIcon) + { + SendMessageW(window, WM_SETICON, ICON_BIG, reinterpret_cast(largeIcon)); + } +} diff --git a/scratch/ScratchIslandApp/WindowExe/icon.h b/scratch/ScratchIslandApp/WindowExe/icon.h new file mode 100644 index 000000000..5e418fc28 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/icon.h @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +void UpdateWindowIconForActiveMetrics(HWND window); diff --git a/scratch/ScratchIslandApp/WindowExe/packages.config b/scratch/ScratchIslandApp/WindowExe/packages.config new file mode 100644 index 000000000..409baff13 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/packages.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/scratch/ScratchIslandApp/WindowExe/pch.cpp b/scratch/ScratchIslandApp/WindowExe/pch.cpp new file mode 100644 index 000000000..398a99f66 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/pch.cpp @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" diff --git a/scratch/ScratchIslandApp/WindowExe/pch.h b/scratch/ScratchIslandApp/WindowExe/pch.h new file mode 100644 index 000000000..de08907f8 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/pch.h @@ -0,0 +1,82 @@ +/*++ +Copyright (c) Microsoft Corporation +Licensed under the MIT license. + +Module Name: +- pch.h + +Abstract: +- Contains external headers to include in the precompile phase of console build process. +- Avoid including internal project headers. Instead include them only in the classes that need them (helps with test project building). +--*/ + +#pragma once + +// Ignore checked iterators warning from VC compiler. +#define _SCL_SECURE_NO_WARNINGS + +// Block minwindef.h min/max macros to prevent conflict +#define NOMINMAX + +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOHELP +#define NOCOMM + +#include + +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) + +#include +#include +#include +#include +#include +#include +#include + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#define BLOCK_TIL +#include "../inc/LibraryIncludes.h" + +// This is inexplicable, but for whatever reason, cppwinrt conflicts with the +// SDK definition of this function, so the only fix is to undef it. +// from WinBase.h +// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime +#ifdef GetCurrentTime +#undef GetCurrentTime +#endif + +#include + +// Needed just for XamlIslands to work at all: +#include +#include +#include +#include + +// Additional headers for various xaml features. We need: +// * Core so we can resume_foreground with CoreDispatcher +// * Controls for grid +// * Media for ScaleTransform +#include +#include +#include + +#include + +#include +#include + +// Including TraceLogging essentials for the binary +#include +#include +TRACELOGGING_DECLARE_PROVIDER(g_hWindowsTerminalProvider); +#include +#include + +// For commandline argument processing +#include +#include +#include +#include "til.h" diff --git a/scratch/ScratchIslandApp/WindowExe/resource.h b/scratch/ScratchIslandApp/WindowExe/resource.h new file mode 100644 index 000000000..7e2918600 --- /dev/null +++ b/scratch/ScratchIslandApp/WindowExe/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by WindowsTerminal.rc +// +#define IDI_APPICON 101 +#define IDI_APPICON_HC_BLACK 102 +#define IDI_APPICON_HC_WHITE 103 + +#define IDS_ERROR_DIALOG_TITLE 105 +#define IDS_HELP_DIALOG_TITLE 106 +#define IDS_ERROR_ARCHITECTURE_FORMAT 110 +#define IDS_X86_ARCHITECTURE 111 +#define IDS_AMD64_ARCHITECTURE 112 +#define IDS_ARM64_ARCHITECTURE 113 +#define IDS_ARM_ARCHITECTURE 114 +#define IDS_UNKNOWN_ARCHITECTURE 115 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif