Bläddra i källkod

Merge topic 'vs-windows-forms'

79ec786 VS: Add Windows Forms Support
Brad King 12 år sedan
förälder
incheckning
f292ffb62c

+ 12 - 0
Source/cmGeneratorTarget.cxx

@@ -98,6 +98,18 @@ void cmGeneratorTarget::ClassifySources()
       this->IDLSources.push_back(sf);
       if(isObjLib) { badObjLib.push_back(sf); }
       }
+    else if(ext == "resx")
+      {
+      // Build and save the name of the corresponding .h 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 resx = sf->GetFullPath();
+      std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
+      this->ExpectedResxHeaders.insert(hFileName);
+      this->ResxSources.push_back(sf);
+      }
     else if(header.find(sf->GetFullPath().c_str()))
       {
       this->HeaderSources.push_back(sf);

+ 4 - 0
Source/cmGeneratorTarget.h

@@ -44,11 +44,15 @@ public:
   std::vector<cmSourceFile*> ObjectSources;
   std::vector<cmSourceFile*> ExternalObjects;
   std::vector<cmSourceFile*> IDLSources;
+  std::vector<cmSourceFile*> ResxSources;
+
   std::string ModuleDefinitionFile;
 
   std::map<cmSourceFile const*, std::string> Objects;
   std::set<cmSourceFile const*> ExplicitObjectName;
 
+  std::set<std::string> ExpectedResxHeaders;
+
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */

+ 64 - 2
Source/cmVisualStudio10TargetGenerator.cxx

@@ -291,6 +291,7 @@ void cmVisualStudio10TargetGenerator::Generate()
   this->WriteCustomCommands();
   this->WriteAllSources();
   this->WriteDotNetReferences();
+
   this->WriteWinRTReferences();
   this->WriteProjectReferences();
   this->WriteString(
@@ -455,6 +456,12 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
       this->WriteString("<WindowsAppContainer>true"
                         "</WindowsAppContainer>\n", 2);
       }
+
+    if(!this->GeneratorTarget->ResxSources.empty())
+      {
+      this->WriteString("<CLRSupport>true</CLRSupport>\n", 2);
+      }
+
     this->WriteString("</PropertyGroup>\n", 1);
     }
 }
@@ -647,6 +654,23 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
     this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups);
     }
 
+  std::vector<cmSourceFile*> resxObjs = this->GeneratorTarget->ResxSources;
+  if(!resxObjs.empty())
+    {
+    this->WriteString("<ItemGroup>\n", 1);
+    for(std::vector<cmSourceFile*>::iterator oi = resxObjs.begin();
+        oi != resxObjs.end(); ++oi)
+      {
+      std::string obj = (*oi)->GetFullPath();
+      this->WriteString("<EmbeddedResource Include=\"", 2);
+      this->ConvertToWindowsSlash(obj);
+      (*this->BuildFileStream ) << obj << "\">\n";
+      this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+      this->WriteString("</EmbeddedResource>\n", 2);
+      }
+    this->WriteString("</ItemGroup>\n", 1);
+    }
+
   // Add object library contents as external objects.
   std::vector<std::string> objs;
   this->GeneratorTarget->UseObjectLibraries(objs);
@@ -701,6 +725,23 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
                              << "</UniqueIdentifier>\n";
     this->WriteString("</Filter>\n", 2);
     }
+
+  if(!this->GeneratorTarget->ResxSources.empty())
+    {
+    this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
+    std::string guidName = "SG_Filter_Resource Files";
+    this->GlobalGenerator->CreateGUID(guidName.c_str());
+    this->WriteString("<UniqueIdentifier>", 3);
+    std::string guid =
+      this->GlobalGenerator->GetGUID(guidName.c_str());
+    (*this->BuildFileStream) << "{" << guid << "}"
+                             << "</UniqueIdentifier>\n";
+    this->WriteString("<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;", 3);
+    (*this->BuildFileStream) << "gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;";
+    (*this->BuildFileStream) << "mfcribbon-ms</Extensions>\n";
+    this->WriteString("</Filter>\n", 2);
+  }
+
   this->WriteString("</ItemGroup>\n", 1);
   this->WriteString("</Project>\n", 0);
   // restore stream pointer
@@ -832,8 +873,20 @@ void cmVisualStudio10TargetGenerator::WriteSource(
     }
   this->ConvertToWindowsSlash(sourceFile);
   this->WriteString("<", 2);
-  (*this->BuildFileStream ) << tool <<
-    " Include=\"" << sourceFile << "\"" << (end? end : " />\n");
+  (*this->BuildFileStream ) << tool << " Include=\"" << sourceFile << "\"";
+
+  if(sf->GetExtension() == "h" &&
+    this->IsResxHeader(sf->GetFullPath()))
+    {
+      (*this->BuildFileStream ) << ">\n";
+      this->WriteString("<FileType>CppForm</FileType>\n", 3);
+      this->WriteString("</ClInclude>\n", 2);
+    }
+  else
+    {
+      (*this->BuildFileStream ) << (end? end : " />\n");
+    }
+
   ToolSource toolSource = {sf, forceRelative};
   this->Tools[tool].push_back(toolSource);
 }
@@ -1725,3 +1778,12 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
     }
   this->WriteString("</ItemGroup>\n", 1);
 }
+
+bool cmVisualStudio10TargetGenerator::
+  IsResxHeader(const std::string& headerFile)
+{
+  std::set<std::string>::iterator it =
+      this->GeneratorTarget->ExpectedResxHeaders.find(headerFile);
+
+  return it != this->GeneratorTarget->ExpectedResxHeaders.end();
+}

+ 2 - 1
Source/cmVisualStudio10TargetGenerator.h

@@ -62,6 +62,7 @@ private:
   void WriteWinRTReferences();
   void WritePathAndIncrementalLinkOptions();
   void WriteItemDefinitionGroups();
+
   bool ComputeClOptions();
   bool ComputeClOptions(std::string const& configName);
   void WriteClOptions(std::string const& config,
@@ -91,7 +92,7 @@ private:
                          std::vector<cmSourceGroup>& );
   void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed,
                               const std::vector<cmSourceGroup>& allGroups);
-
+  bool IsResxHeader(const std::string& headerFile);
 
 private:
   typedef cmVisualStudioGeneratorOptions Options;

+ 5 - 0
Tests/CMakeLists.txt

@@ -1462,6 +1462,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       ADD_TEST_MACRO(SBCS SBCS)
     endif()
 
+    if(NOT "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [6789]( |$)"
+        AND NOT CMAKE_TEST_GENERATOR_TOOLSET)
+      ADD_TEST_MACRO(VSWindowsFormsResx VSWindowsFormsResx)
+    endif()
+
     add_test(VSExternalInclude ${CMAKE_CTEST_COMMAND}
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/VSExternalInclude"

+ 44 - 0
Tests/VSWindowsFormsResx/CMakeLists.txt

@@ -0,0 +1,44 @@
+#
+# Example CMakeLists.txt file to demonstrate how to make a designable Windows Forms project with CMake.
+#
+# Code modifications and example by John Farrier, [email protected]
+#
+
+cmake_minimum_required(VERSION 2.8.10)
+
+# Project Name
+project(VSWindowsFormsResx CXX)
+
+include(CheckFunctionExists)
+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
+
+set(TARGET_H
+  WindowsFormsResx/MyForm.h
+  WindowsFormsResx/Header.h
+  )
+
+set(TARGET_SRC
+  WindowsFormsResx/MyForm.cpp
+  WindowsFormsResx/Source.cpp
+  )
+
+set(TARGET_RESX
+  WindowsFormsResx/MyForm.resx
+  )
+
+set(TARGET_LIBRARIES ${SYSLIBS})
+add_executable(${PROJECT_NAME} ${TARGET_SRC} ${TARGET_H} ${TARGET_RESX})
+
+# Note: The property VS_GLOBAL_KEYWORD must be set.
+set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_KEYWORD "ManagedCProj")
+
+# Note: The property VS_DOTNET_REFERENCES must be set.
+set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DOTNET_REFERENCES "System" "System.Data" "System.Drawing" "System.Windows.Forms" "System.Xml")
+
+# Note: Modification of compiler flags is required for CLR compatibility now that we are using .resx files.
+string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")

+ 0 - 0
Tests/VSWindowsFormsResx/WindowsFormsResx/Header.h


+ 1 - 0
Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.cpp

@@ -0,0 +1 @@
+#include "MyForm.h"

+ 78 - 0
Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.h

@@ -0,0 +1,78 @@
+#pragma once
+
+namespace Farrier {
+
+  using namespace System;
+  using namespace System::ComponentModel;
+  using namespace System::Collections;
+  using namespace System::Windows::Forms;
+  using namespace System::Data;
+  using namespace System::Drawing;
+
+  /// <summary>
+  /// Summary for MyForm
+  /// </summary>
+  public ref class MyForm : public System::Windows::Forms::Form
+  {
+  public:
+    MyForm(void)
+    {
+      InitializeComponent();
+      //
+      //TODO: Add the constructor code here
+      //
+    }
+
+  protected:
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    ~MyForm()
+    {
+      if (components)
+      {
+        delete components;
+      }
+    }
+  private: System::Windows::Forms::Button^  button1;
+  protected:
+
+  private:
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    System::ComponentModel::Container ^components;
+
+#pragma region Windows Form Designer generated code
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    void InitializeComponent(void)
+    {
+      this->button1 = (gcnew System::Windows::Forms::Button());
+      this->SuspendLayout();
+      //
+      // button1
+      //
+      this->button1->Location = System::Drawing::Point(13, 13);
+      this->button1->Name = L"button1";
+      this->button1->Size = System::Drawing::Size(75, 23);
+      this->button1->TabIndex = 0;
+      this->button1->Text = L"button1";
+      this->button1->UseVisualStyleBackColor = true;
+      //
+      // MyForm
+      //
+      this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
+      this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
+      this->ClientSize = System::Drawing::Size(284, 261);
+      this->Controls->Add(this->button1);
+      this->Name = L"MyForm";
+      this->Text = L"MyForm";
+      this->ResumeLayout(false);
+
+    }
+#pragma endregion
+  };
+}

+ 61 - 0
Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.resx

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 4 - 0
Tests/VSWindowsFormsResx/WindowsFormsResx/Source.cpp

@@ -0,0 +1,4 @@
+int main(int argc, char **argv)
+{
+  return 0;
+}