From bbcb99b8a4f736354a3aa9871ca4cbef71475b7b Mon Sep 17 00:00:00 2001
From: Gilles Khouzam <gillesk@microsoft.com>
Date: Tue, 31 Mar 2015 13:49:39 -0700
Subject: [PATCH] Adding XAML support to CMake .XAML files are by default of
 type Page in the vcxproj and can be overriden by setting the VS_XAML_TYPE
 property. The .cpp and .h file of the same name are automatically added as
 depending on the XAML file.

New VSXaml test builds a basic XAML WindowsStore 8.1 app with VS2013.
---
 Help/manual/cmake-properties.7.rst             |   1 +
 Help/prop_sf/VS_XAML_TYPE.rst                  |   6 ++
 Source/cmGeneratorTarget.cxx                   |  49 ++++++++++
 Source/cmGeneratorTarget.h                     |  13 +++
 Source/cmVisualStudio10TargetGenerator.cxx     |  81 +++++++++++++++-
 Source/cmVisualStudio10TargetGenerator.h       |   3 +
 Tests/CMakeLists.txt                           |  11 +++
 Tests/VSWindowsFormsResx/CMakeLists.txt        |   2 +-
 Tests/VSXaml/App.xaml                          |   7 ++
 Tests/VSXaml/App.xaml.cpp                      | 125 +++++++++++++++++++++++++
 Tests/VSXaml/App.xaml.h                        |  27 ++++++
 Tests/VSXaml/Assets/Logo.scale-100.png         | Bin 0 -> 801 bytes
 Tests/VSXaml/Assets/SmallLogo.scale-100.png    | Bin 0 -> 329 bytes
 Tests/VSXaml/Assets/SplashScreen.scale-100.png | Bin 0 -> 2146 bytes
 Tests/VSXaml/Assets/StoreLogo.scale-100.png    | Bin 0 -> 429 bytes
 Tests/VSXaml/CMakeLists.txt                    |  52 ++++++++++
 Tests/VSXaml/MainPage.xaml                     |  14 +++
 Tests/VSXaml/MainPage.xaml.cpp                 |  27 ++++++
 Tests/VSXaml/MainPage.xaml.h                   |  21 +++++
 Tests/VSXaml/Package.appxmanifest              |  41 ++++++++
 Tests/VSXaml/VSXaml_TemporaryKey.pfx           | Bin 0 -> 2560 bytes
 Tests/VSXaml/pch.cpp                           |   6 ++
 Tests/VSXaml/pch.h                             |  11 +++
 23 files changed, 493 insertions(+), 4 deletions(-)
 create mode 100644 Help/prop_sf/VS_XAML_TYPE.rst
 create mode 100644 Tests/VSXaml/App.xaml
 create mode 100644 Tests/VSXaml/App.xaml.cpp
 create mode 100644 Tests/VSXaml/App.xaml.h
 create mode 100644 Tests/VSXaml/Assets/Logo.scale-100.png
 create mode 100644 Tests/VSXaml/Assets/SmallLogo.scale-100.png
 create mode 100644 Tests/VSXaml/Assets/SplashScreen.scale-100.png
 create mode 100644 Tests/VSXaml/Assets/StoreLogo.scale-100.png
 create mode 100644 Tests/VSXaml/CMakeLists.txt
 create mode 100644 Tests/VSXaml/MainPage.xaml
 create mode 100644 Tests/VSXaml/MainPage.xaml.cpp
 create mode 100644 Tests/VSXaml/MainPage.xaml.h
 create mode 100644 Tests/VSXaml/Package.appxmanifest
 create mode 100644 Tests/VSXaml/VSXaml_TemporaryKey.pfx
 create mode 100644 Tests/VSXaml/pch.cpp
 create mode 100644 Tests/VSXaml/pch.h

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 25f989f..8cb7f1f 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -297,6 +297,7 @@ Properties on Source Files
    /prop_sf/VS_SHADER_FLAGS
    /prop_sf/VS_SHADER_MODEL
    /prop_sf/VS_SHADER_TYPE
+   /prop_sf/VS_XAML_TYPE
    /prop_sf/WRAP_EXCLUDE
    /prop_sf/XCODE_EXPLICIT_FILE_TYPE
    /prop_sf/XCODE_LAST_KNOWN_FILE_TYPE
diff --git a/Help/prop_sf/VS_XAML_TYPE.rst b/Help/prop_sf/VS_XAML_TYPE.rst
new file mode 100644
index 0000000..ebf202a
--- /dev/null
+++ b/Help/prop_sf/VS_XAML_TYPE.rst
@@ -0,0 +1,6 @@
+VS_XAML_TYPE
+---------------------
+
+Mark a XAML source file as a different type than the default ``Page``
+The most common usage would be to set the default App.xaml file as
+ApplicationDefinition
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index a4f099b..9e57810 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -55,6 +55,7 @@ struct ResxTag {};
 struct ModuleDefinitionFileTag {};
 struct AppManifestTag{};
 struct CertificatesTag{};
+struct XamlTag{};
 
 template<typename Tag, typename OtherTag>
 struct IsSameTag
@@ -97,6 +98,20 @@ struct DoAccept<true>
     data.ExpectedResxHeaders.insert(hFileName);
     data.ResxSources.push_back(f);
     }
+  static void Do(cmGeneratorTarget::XamlData& data, cmSourceFile* f)
+    {
+    // Build and save the name of the corresponding .h and .cpp file
+    // This relationship will be used later when building the project files.
+    // Both names would have been auto generated from Visual Studio
+    // where the user supplied the file name and Visual Studio
+    // appended the suffix.
+    std::string xaml = f->GetFullPath();
+    std::string hFileName = xaml + ".h";
+    std::string cppFileName = xaml + ".cpp";
+    data.ExpectedXamlHeaders.insert(hFileName);
+    data.ExpectedXamlSources.insert(cppFileName);
+    data.XamlSources.push_back(f);
+    }
   static void Do(std::string& data, cmSourceFile* f)
     {
     data = f->GetFullPath();
@@ -185,6 +200,10 @@ struct TagVisitor
       {
       DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf);
       }
+    else if (ext == "xaml")
+      {
+      DoAccept<IsSameTag<Tag, XamlTag>::Result>::Do(this->Data, sf);
+      }
     else if(this->Header.find(sf->GetFullPath().c_str()))
       {
       DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
@@ -437,6 +456,36 @@ cmGeneratorTarget
 }
 
 //----------------------------------------------------------------------------
+void
+cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers,
+                                          const std::string& config) const
+  {
+  XamlData data;
+  IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
+  headers = data.ExpectedXamlHeaders;
+  }
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
+                                          const std::string& config) const
+{
+  XamlData data;
+  IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
+  srcs = data.ExpectedXamlSources;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget
+::GetXamlSources(std::vector<cmSourceFile const*>& srcs,
+                 const std::string& config) const
+{
+  XamlData data;
+  IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
+  srcs = data.XamlSources;
+}
+
+//----------------------------------------------------------------------------
 bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
                                               const std::string& config) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2083b88..610be59 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -58,6 +58,12 @@ public:
                       const std::string& config) const;
   void GetCertificates(std::vector<cmSourceFile const*>&,
                        const std::string& config) const;
+  void GetXamlSources(std::vector<cmSourceFile const*>&,
+                      const std::string& config) const;
+  void GetExpectedXamlHeaders(std::set<std::string>&,
+                              const std::string& config) const;
+  void GetExpectedXamlSources(std::set<std::string>&,
+                              const std::string& config) const;
 
   void ComputeObjectMapping();
 
@@ -132,6 +138,13 @@ public:
     mutable std::set<std::string> ExpectedResxHeaders;
     mutable std::vector<cmSourceFile const*> ResxSources;
   };
+
+  struct XamlData {
+    mutable std::set<std::string> ExpectedXamlHeaders;
+    mutable std::set<std::string> ExpectedXamlSources;
+    mutable std::vector<cmSourceFile const*> XamlSources;
+  };
+
 private:
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index a286049..90e279a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -461,6 +461,7 @@ void cmVisualStudio10TargetGenerator::Generate()
   this->WriteAllSources();
   this->WriteDotNetReferences();
   this->WriteEmbeddedResourceGroup();
+  this->WriteXamlFilesGroup();
   this->WriteWinRTReferences();
   this->WriteProjectReferences();
   this->WriteString(
@@ -522,8 +523,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
 
       this->WriteString("<DependentUpon>", 3);
       std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h";
-      (*this->BuildFileStream ) << hFileName;
-      this->WriteString("</DependentUpon>\n", 3);
+      (*this->BuildFileStream) << hFileName << "</DependentUpon>\n";
 
       std::vector<std::string> const * configs =
         this->GlobalGenerator->GetConfigurations();
@@ -546,6 +546,38 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
     }
 }
 
+void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
+{
+  std::vector<cmSourceFile const*> xamlObjs;
+  this->GeneratorTarget->GetXamlSources(xamlObjs, "");
+  if (!xamlObjs.empty())
+    {
+    this->WriteString("<ItemGroup>\n", 1);
+    for (std::vector<cmSourceFile const*>::const_iterator oi = xamlObjs.begin();
+      oi != xamlObjs.end(); ++oi)
+      {
+      std::string obj = (*oi)->GetFullPath();
+      std::string xamlType;
+      const char * xamlTypeProperty = (*oi)->GetProperty("VS_XAML_TYPE");
+      if (xamlTypeProperty == nullptr)
+        {
+        xamlType = "Page";
+        }
+      else
+        {
+        xamlType = xamlTypeProperty;
+        }
+
+      this->WriteSource(xamlType, *oi, ">\n");
+      this->WriteString("<SubType>Designer</SubType>\n", 3);
+      this->WriteString("</", 2);
+      (*this->BuildFileStream) << xamlType << ">\n";
+
+      }
+    this->WriteString("</ItemGroup>\n", 1);
+    }
+}
+
 void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences()
 {
   if(this->MSTools)
@@ -1192,12 +1224,22 @@ WriteGroupSources(const char* name,
 
 void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf)
 {
-  if(this->IsResxHeader(sf->GetFullPath()))
+  const std::string& fileName = sf->GetFullPath();
+  if (this->IsResxHeader(fileName))
     {
     this->WriteSource("ClInclude", sf, ">\n");
     this->WriteString("<FileType>CppForm</FileType>\n", 3);
     this->WriteString("</ClInclude>\n", 2);
     }
+  else if (this->IsXamlHeader(fileName))
+    {
+    this->WriteSource("ClInclude", sf, ">\n");
+    this->WriteString("<DependentUpon>", 3);
+    std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
+    (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n";
+
+    this->WriteString("</ClInclude>\n", 2);
+    }
   else
     {
     this->WriteSource("ClInclude", sf);
@@ -1669,6 +1711,17 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
                                               "      ", "\n", lang);
       }
     }
+  if (this->IsXamlSource(source->GetFullPath()))
+    {
+    (*this->BuildFileStream) << firstString;
+    firstString = ""; // only do firstString once
+    hasFlags = true;
+    this->WriteString("<DependentUpon>", 3);
+    const std::string& fileName = source->GetFullPath();
+    std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
+    (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n";
+    }
+
   return hasFlags;
 }
 
@@ -2747,6 +2800,28 @@ bool cmVisualStudio10TargetGenerator::
   return it != expectedResxHeaders.end();
 }
 
+bool cmVisualStudio10TargetGenerator::
+IsXamlHeader(const std::string& headerFile)
+{
+  std::set<std::string> expectedXamlHeaders;
+  this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, "");
+
+  std::set<std::string>::const_iterator it =
+    expectedXamlHeaders.find(headerFile);
+  return it != expectedXamlHeaders.end();
+}
+
+bool cmVisualStudio10TargetGenerator::
+IsXamlSource(const std::string& sourceFile)
+{
+  std::set<std::string> expectedXamlSources;
+  this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, "");
+
+  std::set<std::string>::const_iterator it =
+    expectedXamlSources.find(sourceFile);
+  return it != expectedXamlSources.end();
+}
+
 void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
 {
   bool isAppContainer = false;
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index a02dfa8..a2776de 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -69,6 +69,7 @@ private:
   void WriteEmbeddedResourceGroup();
   void WriteWinRTReferences();
   void WriteWinRTPackageCertificateKeyFile();
+  void WriteXamlFilesGroup();
   void WritePathAndIncrementalLinkOptions();
   void WriteItemDefinitionGroups();
   void VerifyNecessaryFiles();
@@ -119,6 +120,8 @@ private:
   void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed,
                               const std::vector<cmSourceGroup>& allGroups);
   bool IsResxHeader(const std::string& headerFile);
+  bool IsXamlHeader(const std::string& headerFile);
+  bool IsXamlSource(const std::string& headerFile);
 
   cmIDEFlagTable const* GetClFlagTable() const;
   cmIDEFlagTable const* GetRcFlagTable() const;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 7e7aa2e..d82cdfd 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1855,6 +1855,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
       add_test_VSWinStorePhone(vs12-store81-X86 "Visual Studio 12 2013" WindowsStore 8.1)
       add_test_VSWinStorePhone(vs12-store81-ARM "Visual Studio 12 2013 ARM" WindowsStore 8.1)
       add_test_VSWinStorePhone(vs12-store81-X64 "Visual Studio 12 2013 Win64" WindowsStore 8.1)
+
+      add_test(NAME VSXaml COMMAND ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+          "${CMake_SOURCE_DIR}/Tests/VSXaml"
+          "${CMake_BINARY_DIR}/Tests/VSXaml"
+          --build-generator "Visual Studio 12 2013"
+          --build-project VSXaml
+          --build-config $<CONFIGURATION>
+          --build-options -DCMAKE_SYSTEM_NAME=WindowsStore
+                          -DCMAKE_SYSTEM_VERSION=8.1
+        )
     endif()
     if(vs11 AND wp80)
       add_test_VSWinStorePhone(vs11-phone80-X86 "Visual Studio 11 2012" WindowsPhone 8.0)
diff --git a/Tests/VSWindowsFormsResx/CMakeLists.txt b/Tests/VSWindowsFormsResx/CMakeLists.txt
index 4373810..43c4833 100644
--- a/Tests/VSWindowsFormsResx/CMakeLists.txt
+++ b/Tests/VSWindowsFormsResx/CMakeLists.txt
@@ -14,7 +14,7 @@ include(CheckCXXSourceCompiles)
 include(CheckIncludeFile)
 
 # Note: The designable form is assumed to have a .h extension as is default in Visual Studio.
-# Node: The designable form is assumed to have a .resx file with the same name and path (save extension) as is default in Visual Studio
+# Note: The designable form is assumed to have a .resx file with the same name and path (save extension) as is default in Visual Studio
 
 set(TARGET_H
   WindowsFormsResx/MyForm.h
diff --git a/Tests/VSXaml/App.xaml b/Tests/VSXaml/App.xaml
new file mode 100644
index 0000000..eecf2c1
--- /dev/null
+++ b/Tests/VSXaml/App.xaml
@@ -0,0 +1,7 @@
+﻿<Application
+    x:Class="VSXaml.App"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:local="using:VSXaml">
+
+</Application>
diff --git a/Tests/VSXaml/App.xaml.cpp b/Tests/VSXaml/App.xaml.cpp
new file mode 100644
index 0000000..334dc1f
--- /dev/null
+++ b/Tests/VSXaml/App.xaml.cpp
@@ -0,0 +1,125 @@
+﻿//
+// App.xaml.cpp
+// Implementation of the App class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+
+using namespace VSXaml;
+
+using namespace Platform;
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Interop;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+
+// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
+
+/// <summary>
+/// Initializes the singleton application object.  This is the first line of authored code
+/// executed, and as such is the logical equivalent of main() or WinMain().
+/// </summary>
+App::App()
+{
+	InitializeComponent();
+	Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
+}
+
+/// <summary>
+/// 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.
+/// </summary>
+/// <param name="e">Details about the launch request and process.</param>
+void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
+{
+
+#if _DEBUG
+		// Show graphics profiling information while debugging.
+		if (IsDebuggerPresent())
+		{
+			// Display the current frame rate counters
+			 DebugSettings->EnableFrameRateCounter = true;
+		}
+#endif
+
+	auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
+
+	// Do not repeat app initialization when the Window already has content,
+	// just ensure that the window is active
+	if (rootFrame == nullptr)
+	{
+		// Create a Frame to act as the navigation context and associate it with
+		// a SuspensionManager key
+		rootFrame = ref new Frame();
+
+		// Set the default language
+		rootFrame->Language = Windows::Globalization::ApplicationLanguages::Languages->GetAt(0);
+
+		rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);
+
+		if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
+		{
+			// TODO: Restore the saved session state only when appropriate, scheduling the
+			// final launch steps after the restore is complete
+
+		}
+
+		if (rootFrame->Content == nullptr)
+		{
+			// When the navigation stack isn't restored navigate to the first page,
+			// configuring the new page by passing required information as a navigation
+			// parameter
+			rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
+		}
+		// Place the frame in the current Window
+		Window::Current->Content = rootFrame;
+		// Ensure the current window is active
+		Window::Current->Activate();
+	}
+	else
+	{
+		if (rootFrame->Content == nullptr)
+		{
+			// When the navigation stack isn't restored navigate to the first page,
+			// configuring the new page by passing required information as a navigation
+			// parameter
+			rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
+		}
+		// Ensure the current window is active
+		Window::Current->Activate();
+	}
+}
+
+/// <summary>
+/// Invoked when application execution is being suspended.	Application state is saved
+/// without knowing whether the application will be terminated or resumed with the contents
+/// of memory still intact.
+/// </summary>
+/// <param name="sender">The source of the suspend request.</param>
+/// <param name="e">Details about the suspend request.</param>
+void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
+{
+	(void) sender;	// Unused parameter
+	(void) e;	// Unused parameter
+
+	//TODO: Save application state and stop any background activity
+}
+
+/// <summary>
+/// Invoked when Navigation to a certain page fails
+/// </summary>
+/// <param name="sender">The Frame which failed navigation</param>
+/// <param name="e">Details about the navigation failure</param>
+void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
+{
+	throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
+}
\ No newline at end of file
diff --git a/Tests/VSXaml/App.xaml.h b/Tests/VSXaml/App.xaml.h
new file mode 100644
index 0000000..1f65bda
--- /dev/null
+++ b/Tests/VSXaml/App.xaml.h
@@ -0,0 +1,27 @@
+﻿//
+// App.xaml.h
+// Declaration of the App class.
+//
+
+#pragma once
+
+#include "App.g.h"
+
+namespace VSXaml
+{
+    /// <summary>
+    /// Provides application-specific behavior to supplement the default Application class.
+    /// </summary>
+    ref class App sealed
+    {
+    protected:
+        virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
+
+    internal:
+        App();
+
+    private:
+        void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
+        void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
+    };
+}
diff --git a/Tests/VSXaml/Assets/Logo.scale-100.png b/Tests/VSXaml/Assets/Logo.scale-100.png
new file mode 100644
index 0000000000000000000000000000000000000000..e26771cb33a49bbef824aa333737181b0a5b09a3
GIT binary patch
literal 801
zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}k|nMYCBgY=CFO}lsSJ)O`AMk?
zp1FzXsX?iUDV2pMQ*9U+m=1foIEGZ*dUJQLud<^=L*gE#63Ho!PGzwUb%GPK6&5iF
zt!p@aGNX}6<M7XW5|S^O@_K8GcU#~8zUR`ZM%|n9Dor+T`?Fc{_(!KzcM~{RrX3K9
z5Q<>(PVh|N)M-?0RNcTbjaWgEU8noxUax-n>&3Ay)#!y&O11y2s<nJ)KKpF-5>KEF
zt72@XC1)RvT6Xw=y_`Ce)`nGULLL^lI$kwi^E+dQT7YeXY4GvlRR%kj1x$VZi%Bdd
zz}2Giy=-_$h+v#(S+};)DuE4EM?_^qB_eDeo@&q%StD1F>L|*0ZC2sb-}llSMTM?O
z6{b3iid~yk@VE7q7Wb+P8?H5IYp?pSVcL<YlA&A?-VaXoY4NVHEc9LQYbtA~Rz&fG
zSq@)=-u<?`9I^cOnQHAA^#I!x>E~18m#ygK20HL@6W5woI~Fjlw$fX1U{xQA5a+t0
zH$WNIb=fNpWHo}M9#;K6eszDZKty_|-?j4iocj5#zotrWc;@;w`H@=mjsvS2wXX0_
zY}l$4@^sE?UcC)ji*L=Z&}P!xaL&2((OQlj2dv~pV-ifAS;ZsH1{`D!GY%<eyvhR<
zs$H~ebuZVtCmT*Zk#o4a&4D#MD8fBt_p}ucyx6k+LJCwHx3XyMXgVAv6j~PJY!vd_
zGBEX+sRPiQ|NU7P>yys5WH)f>ZLo5m%6XjuXdbKMR7MEHSyb{m!_{Afji&MT$_sz7
z>1{~MlIFe28FRN(GC_~;#Jp4ADipP+9hh|P#-&`vO-Upt3jE0@YLh(^55uYWl9g)Z
RA3>Rb!PC{xWt~$(69A&hN*MqE

literal 0
HcmV?d00001

diff --git a/Tests/VSXaml/Assets/SmallLogo.scale-100.png b/Tests/VSXaml/Assets/SmallLogo.scale-100.png
new file mode 100644
index 0000000000000000000000000000000000000000..1eb0d9d528c42f132872e8af4dc563081b0b9aff
GIT binary patch
literal 329
zcmV-P0k-~$P)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy>q$gGRCwC#*X;?zAP@%N+|i#I!$mrh
zlQ>KU$Rdu>|JH&931_?y6Djl{gb>4nCV5pzDJ?S!mq|4ZejKj%i@j$H{#ML~2Y{DF
z$=}bKPaz+UGt{v(4CTQQXym}&iW8{s!ew~XIE7NLjQpy#I2S$rous$~?f%DHT#B*+
zq=#!zc5=0FEqWFpB%UE(L807on!pidHPLgYO}XEgorrg;PB=8ipgQ5u5`&g_MQaRd
zaU7Ao8XQMuuN21-s0PPTs1%38x_Yl3Fs-|Y4!C-;M-8<ZZS<TqNqib^SMD<4zlFK0
b-U18&d-UZ%OI+v700000NkvXXu0mjfvyO*s

literal 0
HcmV?d00001

diff --git a/Tests/VSXaml/Assets/SplashScreen.scale-100.png b/Tests/VSXaml/Assets/SplashScreen.scale-100.png
new file mode 100644
index 0000000000000000000000000000000000000000..c951e031bdfa0d4ebe68d52647f14caf710ca471
GIT binary patch
literal 2146
zcmb_ee{2(V6#s5lN>g@n*v@1<b=M3U|6s-?wu(;ZSjSjm7Y1Z0YO=0bp{Bc`WN|E_
z-fA4z*Z`44la{D-24m8dH56jSm~E7z@kgl6qju4O{=v*9DC!?9Mttw?x}MP~ME`nw
z-+tfcectDN@4bb$w71emi;)mQw{3Q9C8V;KkczbiJ)Ath=IRufn*J6~|F+#b`v<!B
z_(@aGZl9lP<GXkHxB9z#2A}@O-$;l-*XC;4zPC94bwl5z)7;YW@U`4*p+h=!S3Y(B
z{>|s#GQ665=9@Rxy?u0YW0&WN+~=RXpPbVXXL4m7Aq=E6I0%{06TwRn=U9d8>exk>
zD-Z%M3DNQ`bTLSEF=%NFyoHcAkD*Ci<!z`e%=hWWPQScr{MpVjjS`}U#(fs{@?@s(
z=f)Rms4qw77OwBjM0H2b7}+Cp3%?zuQhI}f;W-H+<8;Y^n&WiVVsJRqR%y}ko`?mS
z6ZV-Eg7?Mm8Xq`Y%~#b19im=)8G{(UjHJNY0DdT7;zc{!=0w=e^a@}rLbQt&RR<5b
zqKoy>Xqljo*0E?o$Gi<JD3u@fm{d#YSkaM<dZ-CKSPNHhro*bWN?Pjfbl9HKhiFF5
zzF1`3t!2URK6hfsODWk))M5dXmW3+@*%daJ5ZM3=u2^Dm*o?pa+pW9}6%`$+l7$8!
zchnv%a8)cSha43PN`b6yR7~coSWrp`u<MEn9T^bl$lRnIfThNk0Y^_jNeW2{V-@G|
zT`H+l7fUBksnPWhs(5$Y$zx-Lz={JZ)n%<QrT)-}%4<S_VU(-nzq-QfYd4YAEz@=B
zW5eg)TR$_iM}DBf$jInVb)ua+&>DC4q}}|%*0WghLlK#npw?hecrM}Mw?`E(z5C8<
z8&*b^!{>5?4aT89vdrgBgSc-x6JZD3F^l#*G(@OO*^1D%Eu7?HAy<3k<n+|3Ofo=y
z3mktj2alVo?!FMUB!4yWhreJ1b7w)g;``y;ZRb2Yo`gp--tp&nV>TLqW9N{^#6vso
zVQwY48q7)m{~xQ64RV7{E7Y=&T~?^05Ky`5oNQ8bLgFCPq9co^R09BVRS1OAmH;hU
zC#q(N!gNqm!zU#%sv{r5mm-Uv8b-~a1F-;p^>)pnXfKge4s9?;;MFIr*fixPG}NBA
z6_G5BEmeO6XXh(emkciB{7tA;iwC2^s^VzyU_h0@ae84ACMY`cIDEju=<`q|2QAEv
zW_)W|i|9aknqdmS=#w73eW_csQ$8IhT^vY1^1;X3&J0{%*tcQq!gJpr3w?TJc~@5=
zKV5sM{$3k>b#S$@CTkhIF*{v*u(F&$&Yq1naHxt8Mz2N%7aQ3(^VNRZahk1||7?Bl
z*idzO_u)FhRj4cPzDO>YA>>lxAGaciEiX8Xzp1SVPv91};$OG3cC&8!v3{Jq^kH@8
UTIccK;hzT5*3#}uZuEx!0OwrBv;Y7A

literal 0
HcmV?d00001

diff --git a/Tests/VSXaml/Assets/StoreLogo.scale-100.png b/Tests/VSXaml/Assets/StoreLogo.scale-100.png
new file mode 100644
index 0000000000000000000000000000000000000000..dcb672712c6823a0c91548ded70a8acb85536b4d
GIT binary patch
literal 429
zcmV;e0aE^nP)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzPf0{URCwC#+R+KaAP@%Nc=WMjbdiqa
zBpIN?bdiqXduqTy9wJ8X{yRw&LZJomt1)*Mb<46$S7<a{qz%Y`fZ8MT{kQXRzi&4q
z`xfHmopV2n0mks~iXU^lo}4ujQU`PD&=L_i5O0M!K=@`zx}DT9M~Kp`U0m$im=?t8
zr<N9`6;bv0MPoRK>NtYJa1l)bQ5qwGXpZbs7%2oRMd4y35$s&66(fxhNg8W02!vSn
zdlrL2h^Fx+3=$z;kK{0D#MyeJ8WRWZcLSf(PcQ_mLOhrmC}O-tX^0c>5`YvCUZVsc
zG-6#78ubjJ5nA;OX&^K(q=i6ZNE3m?kTwE^AqxZoLskfB3|S&1F=UO9!cY$g2@Lgu
z;9{sJ1P9|X2L`r1#Gs8R{E^$PRrMaC86q<?teSo8;M4n2kIR(0ZXBu^kO8>|<S)Pg
XJ9Ld-yKA-b00000NkvXXu0mjfItQrL

literal 0
HcmV?d00001

diff --git a/Tests/VSXaml/CMakeLists.txt b/Tests/VSXaml/CMakeLists.txt
new file mode 100644
index 0000000..f384c82
--- /dev/null
+++ b/Tests/VSXaml/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 3.2)
+project(VSXaml)
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+set(SOURCE_FILES
+  App.xaml.cpp
+  MainPage.xaml.cpp
+  pch.cpp
+  )
+
+set(HEADER_FILES
+  App.xaml.h
+  MainPage.xaml.h
+  pch.h
+  )
+
+set(XAML_FILES
+  App.xaml
+  MainPage.xaml
+  )
+
+set(ASSET_FILES
+    Assets/Logo.scale-100.png
+    Assets/SmallLogo.scale-100.png
+    Assets/SplashScreen.scale-100.png
+    Assets/StoreLogo.scale-100.png
+    )
+
+set(CONTENT_FILES
+    Package.appxmanifest
+    )
+
+set(RESOURCE_FILES
+  ${CONTENT_FILES} ${ASSET_FILES}
+  VSXaml_TemporaryKey.pfx)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+set_property(SOURCE ${CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "Assets")
+
+set_property(SOURCE "App.xaml" PROPERTY VS_XAML_TYPE "ApplicationDefinition")
+
+source_group("Source Files" FILES ${SOURCE_FILES})
+source_group("Header Files" FILES ${HEADER_FILES})
+source_group("Resource Files" FILES ${RESOURCE_FILES})
+source_group("Xaml Files" FILES ${XAML_FILES})
+
+add_executable(VSXaml WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES} ${XAML_FILES})
+set_property(TARGET VSXaml PROPERTY VS_WINRT_COMPONENT TRUE)
diff --git a/Tests/VSXaml/MainPage.xaml b/Tests/VSXaml/MainPage.xaml
new file mode 100644
index 0000000..62139ca
--- /dev/null
+++ b/Tests/VSXaml/MainPage.xaml
@@ -0,0 +1,14 @@
+﻿<Page
+    x:Class="VSXaml.MainPage"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:local="using:VSXaml"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    mc:Ignorable="d">
+
+    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
+        <TextBlock Text="I'm a CMake XAML App" HorizontalAlignment="Center" VerticalAlignment="Center"
+                   Style="{StaticResource HeaderTextBlockStyle}"/>
+    </Grid>
+</Page>
diff --git a/Tests/VSXaml/MainPage.xaml.cpp b/Tests/VSXaml/MainPage.xaml.cpp
new file mode 100644
index 0000000..d0a64e8
--- /dev/null
+++ b/Tests/VSXaml/MainPage.xaml.cpp
@@ -0,0 +1,27 @@
+﻿//
+// MainPage.xaml.cpp
+// Implementation of the MainPage class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+
+using namespace VSXaml;
+
+using namespace Platform;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+MainPage::MainPage()
+{
+	InitializeComponent();
+}
diff --git a/Tests/VSXaml/MainPage.xaml.h b/Tests/VSXaml/MainPage.xaml.h
new file mode 100644
index 0000000..ccc781b
--- /dev/null
+++ b/Tests/VSXaml/MainPage.xaml.h
@@ -0,0 +1,21 @@
+﻿//
+// MainPage.xaml.h
+// Declaration of the MainPage class.
+//
+
+#pragma once
+
+#include "MainPage.g.h"
+
+namespace VSXaml
+{
+    /// <summary>
+    /// An empty page that can be used on its own or navigated to within a Frame.
+    /// </summary>
+    public ref class MainPage sealed
+    {
+    public:
+        MainPage();
+
+    };
+}
diff --git a/Tests/VSXaml/Package.appxmanifest b/Tests/VSXaml/Package.appxmanifest
new file mode 100644
index 0000000..873a64a
--- /dev/null
+++ b/Tests/VSXaml/Package.appxmanifest
@@ -0,0 +1,41 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
+
+  <Identity Name="19ff96f1-8379-4e14-8b9d-04648b3b36a9"
+            Publisher="CN=Microsoft"
+            Version="1.0.0.0" />
+
+  <Properties>
+    <DisplayName>VSXaml</DisplayName>
+    <PublisherDisplayName>Microsoft</PublisherDisplayName>
+    <Logo>Assets\StoreLogo.png</Logo>
+  </Properties>
+
+  <Prerequisites>
+    <OSMinVersion>6.3.0</OSMinVersion>
+    <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
+  </Prerequisites>
+
+  <Resources>
+    <Resource Language="x-generate"/>
+  </Resources>
+
+  <Applications>
+    <Application Id="App"
+        Executable="$targetnametoken$.exe"
+        EntryPoint="VSXaml.App">
+        <m2:VisualElements
+            DisplayName="VSXaml"
+            Square150x150Logo="Assets\Logo.png"
+            Square30x30Logo="Assets\SmallLogo.png"
+            Description="VSXaml"
+            ForegroundText="light"
+            BackgroundColor="#464646">
+            <m2:SplashScreen Image="Assets\SplashScreen.png" />
+        </m2:VisualElements>
+    </Application>
+  </Applications>
+  <Capabilities>
+    <Capability Name="internetClient" />
+  </Capabilities>
+</Package>
\ No newline at end of file
diff --git a/Tests/VSXaml/VSXaml_TemporaryKey.pfx b/Tests/VSXaml/VSXaml_TemporaryKey.pfx
new file mode 100644
index 0000000000000000000000000000000000000000..1cad9993d6abdb0e1bc1456b2470dd386f8f3ef2
GIT binary patch
literal 2560
zcmai03piBk8eVJGni=CZghDYRk%-pRFm7ctks|lY*luTr$)#MvxFl01mx?ZOEi>g3
zQJdOwNt3M*b5fD*5|R>%Qt4tMbXNO0r@hbfoM)f)J>UO--}`^>`qs1l@A<zU;Sm-w
zAcXJ;H*f^qG}|<>42TDdc!WxrM<_$#VuXj2_^&1GJj}y>MtIm+RA+Ef|7J-`f|w#6
zyo~VR1!N6Q@;@;8a#>hnF|U-_On!9}gTZ&hJoqsQOne(a7^Y<vmQ1{SHlC2HS=8Vq
z1Z!06v<vp{@c%l$a{a*%xVrA$36f`;>xxvRC0?&#iSJ4dzY>04ma`qIK5yv(e^KYu
z^tO-(h-s32)@;sr=5I3TaiIiy)GeNb^iX5=nIrBbuEm)7?TEH0j#G5Fps^HY9@J6V
z^mH*Rrycr0?h@xIJ??#m`R!3!y9#utp=9yeLZ?}h+r^9Nu2B~xIM_`Rcg<ak*PqBq
z*Yf1H+H<Tjb4HaMvod=wiqy>S<tA~vq;{se6;ZZFYo*H4^aj>l&3)Z7IC@l|(#Y?4
zH<A$_p*qOubXhvN9WNR-P-{J<DOfX2tX&v=N2+Qfww0dC564oR20v8n`RZHjc;dN0
zQF~2hOokBalgEqM@BUKvT+yfaA(Ih$w4v6jl(2U`pzyI*EdA;G-*0wX!v{Gk!yO;1
zj6611EiG?UNZjknR%zeROPGL6PDM<5b>F*1ql5?KE_Id!YY^o+mNR$Ay|T?YdOP&c
z%v?|X1BG@rr$@Y)uumAm$G=%yYUr61W-Kzxo-Aioo;)68ln0NlOC`??+#}A$LH*sd
zVGZ+^<hiBYm)c3*(w=N$o|#{ckp{kHzmeE>)uT91tn;Spw*Ag0z>yo-r_b0sUmqRj
z9eDN&40Xx*x+h=n_9JlWSh40#Nan=8!%Z(PIqHaY5?Wu>|K2vk@%%FGEex?B$M{P=
zSFzr%j}_dfIrTT}KE~gdYvFu{bM#FWAudb%MSHX8#@Q{d&U2Z@=CLU@tKpzRA60>q
zC~Qv9n7yZ8TRnAEunW`F!!+?wvAY^o6>mr}*2g!=hxJfD`?WPc+uO%H62YWT6wCL1
zJiwrc2%=p*l8Q3?kb))Zy^9@Ga`1_|u+%RzEAs|@t?gD1u6@{8=gn@iRD3bWU`eqJ
z)Kw<kjy)?$%Y$A=cJA`jIOmn)I$tE=lqDaK_jFsfSJV}nZIygmtG?;;wY4j1vYV%_
zm9}1tdZMOV<$`Z_EfJ`W&uR3!dIYR|2x=`1i2RM;;vQySy(PCTINZuzsf{hZ-FRPF
zxlepwWJL08(_~fNebbqQU>x@3?>M0Ms&s|&+FQ6?+*+#6DOl~1uj6J}EgNoIe)nCQ
z?cN;2Xx2Dia@PBJnO*-`$H_aRie6m>yPH?96<QQpu*%aUw;VOgp6<F(95XULvi(8f
z0<&0iOn6lDn^L}*+x{)?jSi9gzHe%2F!Sx4SiR&?q*TR>32BPETnEW{*L3!zjEQCL
zm1TdGiy;KPzG6R8GhyF)f@vG9PN{AVn{{fRY!Gb7ZFEU>v|t7<Au>woQ@MhiUVm)e
zh%>uEu}<!@UgLSs*>&~XINMSJ_SwBw*jcJ$Rvr^_MHHKEdHIQHlj>_z<16L0aj9zI
z)|}ZO;l`~MLjBX1JG2|+l_zfBT;DXL;(GU^PkhUotxgZO=xA}XIt(WBd>1n+?<H;d
z`O)gmjAi%3x*l24?kmb~TV(fY3J3M?Z@hCnq2I*D?>!e|=^v>}cos=Av=Zd|RN=oq
zjL$SMT(zr4-dPPpSFC3dyerl9$89b@NI3n){+#&a2BEG4E9Kx}-@al&7%Awwt7*Z_
z4lizZL^O@<V_+{#e0R-8{yt{bh>?CHczPi80iKdPj41p#E(uB$91Md103g0Nf*uZp
zK^{#Wq&TTN0K0(@AOMI0B7kUA_W&^f8E{3%??^ZhgnD$;P5>fNECThT048b&|G^>y
zPJhJ3qFx}t2BHx5pE(sN40R7QAQspQxB+1($rPZWf&j*7C=D<Ki~xO<76@!X)9M3M
zbT&anA7G(^pb`2gj-a+7s#Mgb0u=O9DF6%ML0LZ%eQy&G59UE!6h44z>|c8Ugf2Ru
z;I1E?fUxpA!4xGJq4;KmhfytpFdzmaS1olDvsF0pi&gx3LlwdMMMUOD5>N^YAgUB)
zWF-!Aham+beK&J2o9xDpjv>?8Q85U4l?;W7P*9;E=<~BOaWe&-{{;S)%>&o|H5rHn
zARb5r5FRLr;ejB~Im>5MEIo<-t#4zQ37u?LQoOEK&tZPfszbZ5?4xx%)7jjS(Q@cY
z`6gOoLE+7#O`nkINXLVEgJj$B0w%^fdxVfrZFb2>`(nr3XnRS1>L1A-;;CO(Y$dIu
zXPBRGOJK+ePFL4DIZ|y~43x8mzE$#lX?4O>v)|{ggluHm28QxY0_qd_<4U@a)%o+@
zvfE@0U6AKwp9-^!mi#Biaa6M9M7-wGj-SG@y$kxG6-}u}#(e>|`N_gx>typJ?-RJ1
zaD6=4h7@Q*V#`Wf4-Kaz_*kdrH(`uTxVIPIm0LlB){ok2Dle#5l+lZ~Rg3lpzc`Sk
zIA1oOQ_g;Xfj|H(jY1+3Y4rcADS+TN7=r+4iKCttER9IwB+#<PV(}1!*nI~<cspWs
zST5#^t4306K;dIjO~BYOHdMUk@AiTB|4IPe6%e2;12{%s+^>o$2Z9^;K9+%xFSwm#
z%`>)^Pq~I1&X4cY@T*}=8=4zTUv^mUclnpAtkdzs4mn_hLW)Oy^hkntHLhjatkv+<
zy27B7#8#*JWSuT!gGGtO$iO3d!hz<bcn|G_Q@&9COAS4Vy>CU8`cT6_^V5)k>;l3j
zHR7fE&#aFww`O)S>NRIJ@E1}`Lz7lYe=;F#IU8-@|GraewC^Y4!uSfgxUnuA;!O8L
z)(<InUS*y;9|@e3r-BUa<4JG7MFUSvHES96ONkj(O<Mbt^Iws*KV$drS>^20_Vnyn
z=#3q!Bl}k)`CO4&TF%ggiiBIFck-vy%bteYP?Y}n(PD;>5Ihd6CktUzVMU8E@i3jS
s`JY3V%yS<fTY<;4iu_?kclVrK52a>x()iaTKAjO&Z|Gm0{QWNWFTqk4^#A|>

literal 0
HcmV?d00001

diff --git a/Tests/VSXaml/pch.cpp b/Tests/VSXaml/pch.cpp
new file mode 100644
index 0000000..01484ff
--- /dev/null
+++ b/Tests/VSXaml/pch.cpp
@@ -0,0 +1,6 @@
+﻿//
+// pch.cpp
+// Include the standard header and generate the precompiled header.
+//
+
+#include "pch.h"
diff --git a/Tests/VSXaml/pch.h b/Tests/VSXaml/pch.h
new file mode 100644
index 0000000..2c4354d
--- /dev/null
+++ b/Tests/VSXaml/pch.h
@@ -0,0 +1,11 @@
+﻿//
+// pch.h
+// Header for standard system include files.
+//
+
+#pragma once
+
+#include <collection.h>
+#include <ppltasks.h>
+
+#include "App.xaml.h"
-- 
1.9.5.msysgit.0

