From fe283fc28b19fa85b6dec3aab76da86b41cbadeb Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 10 Jun 2021 12:49:12 -0500 Subject: [PATCH] Add a Scratch.sln for prototyping (#10067) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### ⚠️ This targets #10051 ## Summary of the Pull Request This PR creates a `Samples` solution which can be used for quickly testing our particular WinUI + Xaml Islands + wapproj setup, with a `TermControl`. This lets us quickly prototype and minimally repro xaml islands bugs, but also lets us iterate quickly on changes in the process model. I'll be using this in the future to prove that the out-of-proc control works (for tear-out), without having to tear up the entire `TerminalApp` all at once. While I'll be leaning on this extensively for tear-out prototyping, I've also found myself wanting this kind of sample sln many times in the past. We run into bugs all the time where we're not sure if they're XAML Islands bugs or Terminal bugs. However, standing up a scratch sln with MUX hooked up, and a `XamlApplication` from the toolkit, and XAML Islands is time consuming. This sample sln should let us validate if bugs are XI bugs or Terminal bugs much easier. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes one bullet point of https://github.com/microsoft/terminal/projects/5#card-50760312 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments This is _largely_ a copy-pasta of our existing projects, in massively simplified form. I'm gonna wontfix most comments on the code that was copy-pasta'd. If it's bad here, it's probably also bad in the real version in `OpenConsole.sln`. * I made an entirely new `.sln` for this, so that these samples wouldn't need to build in CI. They're not critical code, they're literally just for prototyping. * `TerminalAppLib` & `TerminalApp` became `SampleAppLib` and `SampleApp`. This is just a simple application hosting a single `TermControl`. It references the winmds and dlls from the main `OpenConsole.sln`, but in a way that would be more like a project consuming a nuget feed of the control, rather than a `ProjectReference`. - It still does all the `App.xaml` and `Toolkit.XamlApplication` stuff that TerminalApp does, so that it can load MUX resources, and do MUX-y things. * `WindowsTerminal` became `WindowExe`. I tore out all of the `NonClientIslandWindow` stuff - this is just a window with a xaml island. * `CascadiaPackage` became `Package`. It does the vclibs hack again for the `TerminalConnection` dlls (because this package can't actually determine that `TerminalConnection.dll` requires `cprest*.dll`), as well as for `windowsterminal.exe` (which we'll need in the future for out-of-proc controls). I got rid of all the Dev/Preview/Release asset machinations as well. Wherever possible, I changed filenames slightly so that they won't get accitdentally opened when someone tries to open a file by name in their editor (**cough** sublime's ctrl+p menu **cough**). ## Validation Steps Performed The sample app launches, and displays a TermControl. What else do you want? (_rhetorical, not a prompt for a wishlist_) (cherry picked from commit 30d6cf4839fca8ac8203f6c2489b02a4088b851e) --- Scratch.sln | 221 +++++++++++++++++ consolegit2gitfilters.json | 2 + .../Package/Package.appxmanifest | 68 ++++++ .../ScratchIslandApp/Package/Package.wapproj | 155 ++++++++++++ .../Package/Resources/Resources.resw | 126 ++++++++++ .../Package/Resources/en-US/Resources.resw | 123 ++++++++++ scratch/ScratchIslandApp/SampleApp/App.base.h | 40 +++ scratch/ScratchIslandApp/SampleApp/App.cpp | 65 +++++ scratch/ScratchIslandApp/SampleApp/App.h | 29 +++ scratch/ScratchIslandApp/SampleApp/App.idl | 16 ++ scratch/ScratchIslandApp/SampleApp/App.xaml | 71 ++++++ scratch/ScratchIslandApp/SampleApp/MyPage.cpp | 54 +++++ scratch/ScratchIslandApp/SampleApp/MyPage.h | 28 +++ scratch/ScratchIslandApp/SampleApp/MyPage.idl | 10 + .../ScratchIslandApp/SampleApp/MyPage.xaml | 56 +++++ .../ScratchIslandApp/SampleApp/MySettings.cpp | 11 + .../ScratchIslandApp/SampleApp/MySettings.h | 97 ++++++++ .../ScratchIslandApp/SampleApp/MySettings.idl | 14 ++ .../SampleApp/Resources/en-US/Resources.resw | 120 +++++++++ .../SampleApp/SampleAppLib.vcxproj | 181 ++++++++++++++ .../SampleApp/SampleAppLogic.cpp | 84 +++++++ .../SampleApp/SampleAppLogic.h | 41 ++++ .../SampleApp/SampleAppLogic.idl | 19 ++ .../SampleApp/dll/SampleApp.def | 3 + .../SampleApp/dll/SampleApp.vcxproj | 101 ++++++++ .../ScratchIslandApp/SampleApp/dll/pch.cpp | 4 + scratch/ScratchIslandApp/SampleApp/dll/pch.h | 12 + scratch/ScratchIslandApp/SampleApp/init.cpp | 13 + .../SampleApp/packages.config | 6 + scratch/ScratchIslandApp/SampleApp/pch.cpp | 4 + scratch/ScratchIslandApp/SampleApp/pch.h | 71 ++++++ .../WindowExe/SampleAppHost.cpp | 78 ++++++ .../WindowExe/SampleAppHost.h | 20 ++ .../WindowExe/SampleBaseWindow.h | 228 ++++++++++++++++++ .../WindowExe/SampleIslandWindow.cpp | 220 +++++++++++++++++ .../WindowExe/SampleIslandWindow.h | 45 ++++ .../ScratchIslandApp/WindowExe/SampleMain.cpp | 122 ++++++++++ .../ScratchIslandApp/WindowExe/WindowExe.def | 1 + .../WindowExe/WindowExe.manifest | 20 ++ .../ScratchIslandApp/WindowExe/WindowExe.rc | 97 ++++++++ .../WindowExe/WindowExe.vcxproj | 220 +++++++++++++++++ scratch/ScratchIslandApp/WindowExe/icon.cpp | 49 ++++ scratch/ScratchIslandApp/WindowExe/icon.h | 6 + .../WindowExe/packages.config | 7 + scratch/ScratchIslandApp/WindowExe/pch.cpp | 4 + scratch/ScratchIslandApp/WindowExe/pch.h | 82 +++++++ scratch/ScratchIslandApp/WindowExe/resource.h | 27 +++ 47 files changed, 3071 insertions(+) create mode 100644 Scratch.sln create mode 100644 scratch/ScratchIslandApp/Package/Package.appxmanifest create mode 100644 scratch/ScratchIslandApp/Package/Package.wapproj create mode 100644 scratch/ScratchIslandApp/Package/Resources/Resources.resw create mode 100644 scratch/ScratchIslandApp/Package/Resources/en-US/Resources.resw create mode 100644 scratch/ScratchIslandApp/SampleApp/App.base.h create mode 100644 scratch/ScratchIslandApp/SampleApp/App.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/App.h create mode 100644 scratch/ScratchIslandApp/SampleApp/App.idl create mode 100644 scratch/ScratchIslandApp/SampleApp/App.xaml create mode 100644 scratch/ScratchIslandApp/SampleApp/MyPage.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/MyPage.h create mode 100644 scratch/ScratchIslandApp/SampleApp/MyPage.idl create mode 100644 scratch/ScratchIslandApp/SampleApp/MyPage.xaml create mode 100644 scratch/ScratchIslandApp/SampleApp/MySettings.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/MySettings.h create mode 100644 scratch/ScratchIslandApp/SampleApp/MySettings.idl create mode 100644 scratch/ScratchIslandApp/SampleApp/Resources/en-US/Resources.resw create mode 100644 scratch/ScratchIslandApp/SampleApp/SampleAppLib.vcxproj create mode 100644 scratch/ScratchIslandApp/SampleApp/SampleAppLogic.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/SampleAppLogic.h create mode 100644 scratch/ScratchIslandApp/SampleApp/SampleAppLogic.idl create mode 100644 scratch/ScratchIslandApp/SampleApp/dll/SampleApp.def create mode 100644 scratch/ScratchIslandApp/SampleApp/dll/SampleApp.vcxproj create mode 100644 scratch/ScratchIslandApp/SampleApp/dll/pch.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/dll/pch.h create mode 100644 scratch/ScratchIslandApp/SampleApp/init.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/packages.config create mode 100644 scratch/ScratchIslandApp/SampleApp/pch.cpp create mode 100644 scratch/ScratchIslandApp/SampleApp/pch.h create mode 100644 scratch/ScratchIslandApp/WindowExe/SampleAppHost.cpp create mode 100644 scratch/ScratchIslandApp/WindowExe/SampleAppHost.h create mode 100644 scratch/ScratchIslandApp/WindowExe/SampleBaseWindow.h create mode 100644 scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.cpp create mode 100644 scratch/ScratchIslandApp/WindowExe/SampleIslandWindow.h create mode 100644 scratch/ScratchIslandApp/WindowExe/SampleMain.cpp create mode 100644 scratch/ScratchIslandApp/WindowExe/WindowExe.def create mode 100644 scratch/ScratchIslandApp/WindowExe/WindowExe.manifest create mode 100644 scratch/ScratchIslandApp/WindowExe/WindowExe.rc create mode 100644 scratch/ScratchIslandApp/WindowExe/WindowExe.vcxproj create mode 100644 scratch/ScratchIslandApp/WindowExe/icon.cpp create mode 100644 scratch/ScratchIslandApp/WindowExe/icon.h create mode 100644 scratch/ScratchIslandApp/WindowExe/packages.config create mode 100644 scratch/ScratchIslandApp/WindowExe/pch.cpp create mode 100644 scratch/ScratchIslandApp/WindowExe/pch.h create mode 100644 scratch/ScratchIslandApp/WindowExe/resource.h 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