在本文中,将探讨如何在C++/CLI环境下创建Windows Forms应用程序。尽管这可能看起来是一项挑战,但通过详细的步骤和示例代码,希望能够帮助顺利完成开发任务。请注意,本文主要面向初学者和中级开发者,如果是Visual Studio开发团队的一员,那么本文可能不适合。
设想需要创建一个新的Windows Forms应用程序,并且被迫使用C++/CLI。此外,只能使用现代版本的Visual Studio(如2012或2013)。
在继续之前,想在这里达成一些共识:除非另有说明,否则当说“Visual Studio”时,指的是Visual Studio 2012/2013。
如果尝试这样做,很快就会发现Visual Studio中没有C++/CLI的模板。那么,选择“CLR控制台应用程序”并将其转换为Windows应用程序。“CLR空项目”不是首选,因为它甚至不会为应用程序创建入口点。请按照项目命名的步骤操作,这样就能找到将要引用的文件!在创建的项目中,根本没有表单。让添加一个。在解决方案资源管理器中右键单击项目节点,然后选择“添加”>“新建项”...
应用程序仍然是控制台应用程序。让进行一些魔法操作,将其转换为Windows应用程序。进入CppTutorial.cpp并进行相应的修改,使其看起来像这样:
        #include "stdafx.h"
        using namespace System;
        using namespace System::Windows::Forms;
        #include "MainForm.h"
        [STAThreadAttribute()]
        int main(array ^args)
        {
            Application::EnableVisualStyles();
            Application::SetCompatibleTextRenderingDefault(false);
            Application::Run(gcnew CppTutorial::MainForm());
            return 0;
        }
     
现在运行应用程序。会在后台看到一个难看的控制台窗口。要摆脱它,请转到项目属性,选择“配置属性”>“链接器”>“系统”部分。将“子系统”设置为“Windows”。
要使代码可编译,请转到“配置属性”>“链接器”>“高级”。将入口点设置为“Main”。同时,稍微修改CppTutorial.cpp中的代码。
        #include "stdafx.h"
        using namespace System;
        using namespace System::Windows::Forms;
        #include "MainForm.h"
        [STAThreadAttribute()]
        void Main(array ^args)
        {
            Application::EnableVisualStyles();
            Application::SetCompatibleTextRenderingDefault(false);
            Application::Run(gcnew CppTutorial::MainForm());
        }
     
构建并运行项目。恭喜!有一个全新的Windows应用程序正在运行。
刚刚创建的应用程序是32位的。可以使用配置管理器轻松地将其制作成64位的(假设知道这是什么)。但是,如果想创建一个MSIL应用程序(即Any CPU),与C#或VB.NET不同,不会在那里找到这样的选项。该怎么办?好吧,有一种方法。转到“配置属性”>“常规”并更改“公共语言运行时支持”为“/clr:pure”或“/clr:safe”:
最初创建的项目选择了.NETFramework 4.5。但如果改变主意,现在希望它是4.0。与C#或VB.NET项目不同,更改.NET版本很容易。在C++/CLI中,必须手动修改.vcxproj文件。让这样做。右键单击项目,然后选择“卸载项目”。再次右键单击它,然后选择“编辑CppTutorial.vcxproj”。找到类似这样的部分:
        <PropertyGroup Label="Globals">
            <ProjectGuid>{Some GUID here}</ProjectGuid>
            <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
            <Keyword>ManagedCProj</Keyword>
            <RootNamespace>CppTutorial</RootNamespace>
        </PropertyGroup>
    
将TargetFrameworkVersion更改为v4.0。保存,然后在解决方案资源管理器中右键单击项目,然后选择“重新加载项目”。现在项目是.NET 4.0。可以在项目属性中验证它。
打开AssemblyInfo.cpp文件。可以在这里更改很多信息。但是,在编译并查看EXE详细信息后,会发现信息不在那里。以下是C++/CLI的方式。为了方便,请添加一个名为AssemblyInfo.h的新头文件,并将以下代码放入其中(版本号和字符串内容确实由决定)。
        #pragma once
        #define Assembly_Copyright L"Copyright © Vladimir Svyatski 2015"
        #define Assembly_Description L"A sample application for CodeProject"
        #define File_Version 1,0,0,0
        #define File_Version_Str "1.0.0.0"
        //CLR assembly version
        #define Assembly_Version L"1.0.0.0"
    
现在使AssemblyInfo.cpp看起来像这样:
        #include "stdafx.h"
        using namespace System;
        using namespace System::Reflection;
        using namespace System::Runtime::InteropServices;
        #include "AssemblyInfo.h"
        [assembly:AssemblyTitleAttribute(L"CppTutorial")];
        [assembly:AssemblyDescriptionAttribute(Assembly_Description)];
        [assembly:AssemblyConfigurationAttribute(L"")];
        [assembly:AssemblyCompanyAttribute(L"")];
        [assembly:AssemblyProductAttribute(L"CppTutorial")];
        [assembly:AssemblyCopyrightAttribute(Assembly_Copyright)];
        [assembly:AssemblyTrademarkAttribute(L"")];
        [assembly:AssemblyCultureAttribute(L"")];
        [assembly:AssemblyVersionAttribute(Assembly_Version)];
        [assembly:ComVisible(false)];
        [assembly:CLSCompliantAttribute(true)];
    
这还没有结束,需要编辑app.rc。双击它,在资源视图中,右键单击app.rc节点,选择“资源包含...”。在其中包含AssemblyInfo.h,如所示。点击确定(它可能会显示警告,但没关系,只需接受它)。现在在资源视图中,添加一个新的版本资源。现在希望将定义从AssemblyInfo.h放在那里,但Visual Studio每次添加新资源时都会覆盖它们。将欺骗它。添加一个名为app.rc2的新文件到资源文件部分。再次修改资源包含:这次添加一个编译时指令。
        #include "app.rc2"
    
在文本模式下打开app.rc,剪切VERSIONINFO资源并粘贴到app.rc2中。app.rc2应该看起来像这样(带有AssemblyInfo.h中的定义):
        #ifdef APSTUDIO_INVOKED
        #error this file is not editable by Microsoft Visual C++
        #endif //APSTUDIO_INVOKED
        ///
        //////////////////////////////////////////////////////////////////////////
        // Neutral resources
        #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
        LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
        ///
        //////////////////////////////////////////////////////////////////////////
        //
        // Version
        //
        VS_VERSION_INFO VERSIONINFO
        FILEVERSION File_Version
        PRODUCTVERSION File_Version
        FILEFLAGSMASK 0x3fL
        #ifdef _DEBUG
        FILEFLAGS 0x1L
        #else
        FILEFLAGS 0x0L
        #endif
        FILEOS 0x40004L
        FILETYPE 0x0L
        FILESUBTYPE 0x0L
        BEGIN
        BLOCK
        "StringFileInfo"
        BEGIN
        BLOCK
        "041904b0"
        BEGIN
        VALUE
        "FileDescription", Assembly_Description
        VALUE
        "FileVersion", File_Version_Str
        VALUE
        "InternalName",
        "CppTutorial.exe"
        VALUE
        "LegalCopyright", Assembly_Copyright
        VALUE
        "OriginalFilename",
        "CppTutorial.exe"
        VALUE
        "ProductName",
        "CppTutorial"
        VALUE
        "ProductVersion", File_Version_Str
        END
        END
        BLOCK
        "VarFileInfo"
        BEGIN
        VALUE
        "Translation",
        0x419,
        1200
        END
        END
        #endif
    
要编译项目,请确保在vcxproj文件中将app.rc2指定为None:
        <ItemGroup>
            <None Include="app.rc2" />
        </ItemGroup>
    
构建项目,在Windows资源管理器中打开EXE详细信息,瞧!
这在C#或VB.NET中很容易完成。在C++/CLI中,它有点棘手。首先,需要一个SNK文件。可以通过两种方式创建它:
构建程序集,它现在已签名。