Visual Studio .NET 中的 OpenGL 自定义向导






4.20/5 (2投票s)
2006 年 12 月 21 日
4分钟阅读

79980

2533
在 Visual Studio .NET 中使用 MFC 创建 OpenGL 窗口
- 下载 VS 2003 源文件 - 1249 Kb
- 下载 VS 2003 演示项目 - 379 Kb
- 下载 VS 2005 源代码 - 679.7 Kb
- 下载 VS 2005 演示代码 - 672.8 Kb

引言
本文将介绍如何使用 MFC 自定义向导在 Visual Studio .NET 2003 中创建自定义向导和 OpenGL 自定义向导。许多人都有关于 Visual Studio .NET 自定义向导的问题。这个问题的原因是发生了从对话框编码方法到 HTML 定义方法的公式变化。本文将介绍“如何在 Visual .NET 环境中创建自定义向导?”
比较 Visual Studio 6.0 和 Visual Studio .NET 的自定义向导
与 Visual Studio 6.0 不同,我们使用对话框资源来创建自定义向导。我们使用资源控件来定义属性和条件。
 
 
这张图片展示了 Visual Studio 6 中的资源编辑过程。但是 Visual Studio .NET IDE(集成开发环境)不再支持自定义向导的对话框资源编辑过程。此时,VS.NET 2003 或 VS.NET 2005 IDE 环境使用 HTML 编辑环境来代替对话框编辑环境。
 
 
Visual C++ 自定义向导概述
它解释了自定义向导最常见的功能。典型的项目向导模板包含以下文件:
[name].vsz
标识向导引擎,并提供上下文和可选的自定义参数。
    VSWIZARD 7.0
    Wizard=VsWizard.VsWizardEngine.7.1
    
    Param="WIZARD_NAME = OpenGL Wizard"
    Param="FALLBACK_LCID = 1033"
    Param="SOURCE_FILTER = cpp;.. and other options"
    Param="HEADER_FILTER = h; .. and other options"
    Param="RESOURCE_FILTER = rc; .. and other options"
[name].vsdir
此文件在 Visual Studio Shell 和向导项目中的项之间提供路由服务。
    OpenGL Wizard.vsz| |OpenGL Wizard|1|OpenGL MFC Application| |6777| |OpenGL Wizard
    
Templates.inf
Templates.inf 是一个文本文件,其中包含用于项目的模板列表。请注意,Template.inf 本身就是一个模板文件(您可以使用指令指定要包含在项目中的文件)。
default.vcproj
XML 文件包含项目类型信息。
    <?xml version="1.0" encoding="Windows-1252"?>
    <VisualStudioProject ProjectType="Visual C++" Version="7.10">
     <Platforms>
      <Platform
       Name="Win32"/>
     </Platforms>
     <Configurations>
      <Configuration Name="Debug|Win32"></Configuration>
      <Configuration Name="Release|Win32"></Configuration>
     </Configurations>
    </VisualStudioProject>
"Template file" 文件夹
此文件夹包含将包含在项目中的文件。请注意,硬盘上的位置是“$(ProjectDir)\Template Files\1033”。
    readme.txt
    sample.txt
    stdafx.h
    stdafx.cpp
    OpenGLView.h
    OpenGLView.cpp
    OpenGLDoc.h
    OpenGLDoc.cpp
    OpenGL.h
    OpenGL.cpp
    MainFrm.h
    MainFrm.cpp
    OpenGL.rc
    Res/OpenGL.ico
    Res/OpenGL.rc2
    Res/OpenGLDoc.ico
    Res/Toolbar.bmp
    Res/OpenGL.manifest
    Resource.h
    earth.bmp
"HTML files" 文件夹
包含向导使用的 HTML 文件(用户界面),每个页面一个向导文件。第一个文件是“Default.htm”。硬盘上的位置是“$(ProjectDir)\Html\1033”。
"Script Files" 文件夹
自定义向导为每个项目创建一个名为“Default.js”的 JScript 文件。
它还包括“Common.js”。这些文件包含 JScript 函数,让您可以访问 Visual C++ 对象模型来定制向导。
    function OnFinish(selProj, selObj) { ... etc } 
    function CreateCustomProject(strProjectName, strProjectPath) { ... etc } 
    function CreateCustomProject(strProjectName, strProjectPath) { ... etc }
    
    function AddFilters(proj) { ... ect } 
    function AddConfig(proj, strProjectName) { ... etc } 
    function DelFile(fso, strWizTempFile) { ... etc }
    
    function CreateCustomInfFile() { ... etc }
    
    function GetTargetName(strName, strProjectName) { ... etc }
    
    function AddFilesToCustomProj(proj, strProjectName, strProjectPath, InfFile) { ... etc }
如何创建项目结构
 
 
对于本文,我选择创建一个 MFC 应用程序项目来创建 C 项目。我的要求是:
- 预编译源文件:“stdafx.cpp”,“stdafx.h”- 定义 OpenGL 头文件
 
- 应用程序源文件:“OpenGL.cpp”,“OpenGL.h”
- MainFrame 源文件:“MainFrm.cpp”,“MainFrm.h”
- Document 源文件:“OpenGLDoc.cpp”,“OpenGLDoc.h”
- View 源文件:“OpenGLView.cpp”,“OpenGLView.h”
- 资源文件:“OpenGL.rc”,“res/OpenGL.ico”,“res/OpenGLDoc.ico”,“res/Toolbar.bmp”,“res/OpenGL.rc2”,“OpeGL.manifest”,“Earth.bmp”
- 文件 -> 新建 -> 项目:选择自定义向导
- 添加项目名称
- 添加项目位置
编辑 HTML

这张图片展示了 HTML 编辑的截图。我从工具箱创建了 HTML 资源。并定义了一个 HTML 资源 ID。它使用条件来指定源文件到模板文件。
例如:
如果我在 html 中定义了 SUPPORT_FOG_SUPPORT,它会为源代码设置条件。它以这种方式用于源文件:[!if id_value] 一些源代码 [!endif]
void C[!output PROJECT_NAME]View::InitOpenGL(void) // output project class { [!if SUPPORT_ALPHA_BLEND] glEnable(GL_DEPTH_TEST); // depth buffering(z-buffering) 가동 [!endif] glEnable(GL_NORMALIZE); // unit vector change glEnable(GL_COLOR_MATERIAL); Obj=gluNewQuadric(); [!if SUPPORT_OMNI_LIGHT || SUPPORT_SPOT_LIGHT] InitLight(); [!endif] [!if SUPPORT_TEXTURE_EFFECT] InitTexture(); [!endif] [!if SUPPORT_ALPHA_BLEND] InitAlphaTest(); [!endif] <blink>[!if SUPPORT_FOG_EFFECT]</blink> InitFog(); [!endif] [!if NOSUPPORT_FOG_EFFECT] glClearColor(0.0f, 0.0f, 0.0f, 1.0f); [!endif] InitShadingModel(); glMatrixMode(GL_PROJECTION); // initialize projection matrix glLoadIdentity(); InitProjection(); glMatrixMode(GL_MODELVIEW); // initialize modelview matrix glLoadIdentity(); }
如何编写脚本
脚本文件决定了创建项目路径、项目名称、项目选项和文件的关键因素。
OnFinish 函数使用项目向导中的输入参数来创建项目名称和项目路径。
    
function OnFinish(selProj, selObj)
    {
     try
     {
      var strProjectPath = wizard.FindSymbol('PROJECT_PATH');
      var strProjectName = wizard.FindSymbol('PROJECT_NAME'); 
      selProj = CreateCustomProject(strProjectName, strProjectPath);
      AddConfig(selProj, strProjectName);
      AddFilters(selProj); 
      var InfFile = CreateCustomInfFile();
      AddFilesToCustomProj(selProj, strProjectName, strProjectPath, InfFile);
      PchSettings(selProj);
      InfFile.Delete(); 
      selProj.Object.Save();
     }
     catch(e)
     {
      if (e.description.length != 0)
       SetErrorInfo(e);
      return e.number
     }
    } 
    
CreateCustomProject 函数使用 default.vcproj 和向导类型来创建自定义项目向导。
function CreateCustomProject(strProjectName, strProjectPath)
    {
     try
     {
      var strProjTemplatePath = wizard.FindSymbol('PROJECT_TEMPLATE_PATH');
      var strProjTemplate = '';
      strProjTemplate = strProjTemplatePath + '\\default.vcproj'; 
      var Solution = dte.Solution;
      var strSolutionName = "";
      if (wizard.FindSymbol("CLOSE_SOLUTION"))
      {
       Solution.Close();
       strSolutionName = wizard.FindSymbol("VS_SOLUTION_NAME");
       if (strSolutionName.length)
       {
        var strSolutionPath = strProjectPath.substr(0, strProjectPath.length - strProjectName.length);
        Solution.Create(strSolutionPath, strSolutionName);
       }
      } 
      var strProjectNameWithExt = '';
      strProjectNameWithExt = strProjectName + '.vcproj'; 
      var oTarget = wizard.FindSymbol("TARGET");
      var prj;
      if (wizard.FindSymbol("WIZARD_TYPE") == vsWizardAddSubProject)  // vsWizardAddSubProject
      {
       var prjItem = oTarget.AddFromTemplate(strProjTemplate, strProjectNameWithExt);
       prj = prjItem.SubProject;
      }
      else
      {
       prj = oTarget.AddFromTemplate(strProjTemplate, strProjectPath, strProjectNameWithExt);
      }
      return prj;
     }
     catch(e)
     {
      throw e;
     }
    } 
    AddFilter 函数过滤模板文件中的每种类型。    function AddFilters(proj)
    {
     try
     {
      // Add the folders to your project using Templates.inf
      var strSrcFilter1 = wizard.FindSymbol('SOURCE_FILTER'); 
      var strSrcFilter2 = wizard.FindSymbol('HEADER_FILTER');  
      var strSrcFilter3 = wizard.FindSymbol('RESOURCE_FILTER');
      
      var group1 = proj.Object.AddFilter('Source Files');  // Source Files Group create
      var group2 = proj.Object.AddFilter('Header Files');  // Header Files Group create
      var group3 = proj.Object.AddFilter('Resource Files');   // Resource files Group create
    
    
      // Apply Filter
      group1.Filter = strSrcFilter1; 
      group2.Filter = strSrcFilter2;
      group3.Filter = strSrcFilter3;   
     }
     catch(e)
     {
      throw e;
     }
    }
这次是 AddConfig 函数。此函数对于项目属性非常重要。此函数决定编译类型。对象获取编译类型(如 Debug 和 Release)的配置。config 变化会在项目属性中插入选项,例如字符集、库类型、使用 mfc 库。CLTool 变体是“编译选项”变体。此变体决定编译选项,例如 debugenabled、多线程、编译级别、预编译头和预处理选项。LinkTool 变体是“链接选项”变体。此变体决定链接
选项,例如数据库文件、附加库。
    function AddConfig(proj, strProjectName)
    {
     try
     {
      var config = proj.Object.Configurations('Debug');
      config.IntermediateDirectory = 'Debug';
      config.OutputDirectory = 'Debug';
      config.CharacterSet = charSetMBCS;
      config.useOfMfc = useOfMfc.useMfcDynamic; 
      var CLTool = config.Tools('VCCLCompilerTool');
      // TODO: Add compiler settings 
      CLTool.DebugInformationFormat = debugEnabled; 
      CLTool.DebugInformationFormat = debugOption.debugEditAndContinue;
      CLTool.SuppressStartupBanner = true; 
      CLTool.RuntimeLibrary = runtimeLibraryOption.rtMultiThreadedDebugDLL; 
      CLTool.WarningLevel = warningLevelOption.warningLevel_3; 
      CLTool.Optimization = optimizeOption.optimizeDisabled;
      CLTool.MinimalRebuild = true;
      CLTool.DebugInformationFormat = debugOption.debugEditAndContinue;
      CLTool.PreprocessorDefinitions = "WIN32;_WINDOWS;_DEBUG";
      CLTool.UsePrecompiledHeader = pchGenerateAuto;  
      var LinkTool = config.Tools('VCLinkerTool');
      // TODO: Add linker settings 
      LinkTool.ProgramDatabaseFile = "$(OutDir)/$(ProjectName).pdb"; 
      LinkTool.GenerateDebugInformation = true;
      LinkTool.LinkIncremental = linkIncrementalYes; 
      LinkTool.OutputFile = "$(OutDir)/$(ProjectName).exe";
      LinkTool.SuppressStartupBanner=true;  // nologo
      LinkTool.AdditionalDependencies="opengl32.lib glu32.lib glut32.lib";
      LinkTool.SubSystem = subSystemOption.subSystemWindows; 
      
      config = proj.Object.Configurations('Release');
      config.IntermediateDirectory = 'Release';
      config.OutputDirectory = 'Release';
      config.CharacterSet = charSetMBCS; 
      config.useOfMfc = useOfMfc.useMfcDynamic;
      
      var CLTool = config.Tools('VCCLCompilerTool');
      // TODO: Add compiler settings 
      CLTool.DebugInformationFormat = debugEnabled; 
      CLTool.DebugInformationFormat = debugOption.debugEnabled; 
      CLTool.SuppressStartupBanner = true; 
      CLTool.RuntimeLibrary = runtimeLibraryOption.rtMultiThreadedDLL; 
      CLTool.WarningLevel = warningLevelOption.warningLevel_3; 
      CLTool.Optimization = optimizeOption.optimizeMaximizeSpeed;
      CLTool.MinimalRebuild = true;
      CLTool.PreprocessorDefinitions = "WIN32;_WINDOWS;NDEBUG";
      CLTool.UsePrecompiledHeader = pchGenerateAuto;  
      var LinkTool = config.Tools('VCLinkerTool');
      // TODO: Add linker settings 
      LinkTool.ProgramDatabaseFile = "$(OutDir)/$(ProjectName).pdb"; 
      LinkTool.GenerateDebugInformation = true;
      LinkTool.LinkIncremental = linkIncrementalYes; 
      LinkTool.OutputFile = "$(OutDir)/$(ProjectName).exe";
      LinkTool.SuppressStartupBanner=true;  // nologo
      LinkTool.AdditionalDependencies="opengl32.lib glu32.lib glut32.lib";
      LinkTool.SubSystem = subSystemOption.subSystemWindows; 
     }
     catch(e)
     {
      throw e;
     }
    }
      
最后,我修改了 GetTargetName 函数。此函数使用项目名称创建目标项目文件。首先,我从项目向导中获取项目名称。然后此函数将模板文件更改为目标文件。
    function GetTargetName(strName, strProjectName)
    {
     try
     {
      // TODO: set the name of the rendered file based on the template filename
      var strTarget = strName;
      var strProjectName = wizard.FindSymbol('PROJECT_NAME');
    
      if (strName == 'readme.txt')
       strTarget = 'ReadMe.txt';
    
      if (strName == 'sample.txt')
       strTarget = 'Sample.txt';
       
      if (strName == 'stdafx.cpp')
       strTarget =  'stdafx.cpp';
     
      if (strName == 'stdafx.h')
       strTarget =  'stdafx.h'; 
    
      if (strName == 'OpenGL.h')
       strTarget =  strProjectName + '.h';  
       
      if (strName == 'OpenGL.cpp')
       strTarget =  strProjectName + '.cpp';     
    
      if (strName == 'MainFrm.h')
       strTarget =  'MainFrm.h';  
       
      if (strName == 'MainFrm.cpp')
       strTarget =  'MainFrm.cpp';     
    
      if (strName == 'OpenGLView.h')
       strTarget =  strProjectName + 'View.h';  
       
      if (strName == 'OpenGLView.cpp')
       strTarget =  strProjectName + 'View.cpp';     
    
      if (strName == 'OpenGLDoc.h')
       strTarget =  strProjectName + 'Doc.h';  
       
      if (strName == 'OpenGLDoc.cpp')
       strTarget =  strProjectName + 'Doc.cpp';     
    
      if (strName == 'OpenGL.rc')
       strTarget =  strProjectName + '.rc';
    
      if (strName == 'resource.h')
       strTarget =  'Resource.h';  
       
      if (strName == 'Res/OpenGL.ico')
       strTarget =  'Res/' + strProjectName + '.ico';     
    
      if (strName == 'earth.bmp')
       strTarget =  'earth.bmp';     
    
      if (strName == 'Res/OpenGL.rc2')
       strTarget =  'Res/' + strProjectName + '.rc2';
       
      if (strName == 'Res/OpenGLDoc.ico')
       strTarget =  'Res/' + strProjectName + 'Doc.ico';     
          
      if (strName == 'Res/OpenGL.manifest')
       strTarget =  'Res/' + strProjectName + '.manifest';       
      
      return strTarget; 
     }
     catch(e)
     {
      throw e;
     }
    }
安装指南
您解压演示 zip 文件。它会创建一个 Visual Studio .NET 2003 文件夹。此文件夹的组成如下:
    vc 7-> vcprojects
    
                 -> OpenGL Wizard.ico : icon file
    
                 -> OpenGL Wizard.vsz : Project Wizard connection file
    
          -> VCWizards
    
                 ->  OpenGL Wizard
    
                       -> 1033 : html style css file
    
                       -> HTML : html files
    
                       -> Images : wizard image fles
    
                       -> Scripts : script for wizard 
    
                       -> Templates : project template source files for creating project
然后将其复制到 Visual Studio .NET 文件夹。如果您复制了这些文件,您将在新建项目创建向导中看到 OpenGL 向导。OpenGL 向导包含九个步骤。第一步是文档类型。它描述了该程序。其他选项与 OpenGL 库相关,例如光照、投影、着色、Alpha 混合、雾、纹理、动画、拾取。