Visual Studio 2010 的 OpenGL 自定义向导
本文是关于“如何在 Visual Studio 2010 上制作 OpenGL 自定义向导?”的指南

引言
本文介绍了使用 MFC 自定义向导在 Visual Studio 2010 中创建自定义向导和 OpenGL 自定义向导的方法。许多人对 Visual Studio 2010 中的自定义向导有疑问。本文解释了“如何在 Visual Studio 2010 中使用 OpenGL 创建自定义向导?”。
背景
之前在 "Visual Studio .NET 中 OpenGL 的自定义向导" 中,我解释了 Visual Studio 2003/2005 的自定义向导。 Visual Studio 2008 与 Visual Studio 2003/2005 之间没有区别。 Visual Studio 2010 环境与 Visual Studio 2008 非常相似。但是,Visual Studio 2010 环境非常多变。
首先,项目 XML 文件格式从 *.vcproj 变为 *.vcxproj。 其次,“项目属性”非常多变。
概述
您必须将源代码从 zip 文件复制到 Visual Studio 2010 文件夹。如果您将 Visual Studio 2010 安装到 *C* 盘,那么您的 Visual Studio 2010 路径是 *C:\Program Files\Microsoft Visual Studio 10.0*。
- 您可以在 *C:\Program Files\Microsoft Visual Studio 10.0\VC* 中找到 Visual C++ 文件夹。
- 将 zip 文件中的文件夹“vcprojects”和“VCwizards”复制到 VC。
然后,您就可以创建自定义向导了。
创建自定义向导
如果您了解自定义向导的创建过程,则必须使用“文件 > 新建 > 项目”菜单在 Visual Studio 2010 中创建一个自定义向导项目。 然后,您可以在 Visual C++ 项目列表中选择自定义向导项目。 最后,单击“完成”按钮。
恭喜! 您已成功创建了您的第一个自定义向导文件。
更改您的自定义向导文件
自定义向导文件由 HTML 文件、图像文件、杂项文件、脚本文件和模板文件组成。
首先,HTML 文件使用 HTML 标记创建向导主框架。 Visual Studio 2010 默认创建一个 *default.htm* 文件。 但是,此文件对您的 OpenGL 自定义向导没有用。 因此,您必须从解决方案资源管理器中删除 *default.htm* 文件。 接下来,源文件从本文 zip 文件导入 HTM 文件。
C:\Program Files\Microsoft Visual Studio 10.0\VC\VCWizards\AppWiz\
OpenGL\Application\html\1033
其次,当 Visual Studio 2010 自定义向导创建默认自定义向导时,图像文件为空。 图像文件用于在您编辑自定义向导时创建图像屏幕。 OpenGL 向导图像文件用于帮助选择理解 Alpha、Fog、Perspective 等属性。 所有文件都使用 Visual Studio 2010 解决方案资源管理器插入到图像文件中。
C:\Program Files\Microsoft Visual Studio
10.0\VC\VCWizards\AppWiz\OpenGL\Application\images
第三,杂项文件是自定义向导属性的属性。 例如,样式文件是 HTML 上的向导样式。
C:\Program Files\Microsoft Visual Studio 10.0\VC\VCWizards\1033\NewStyle.css
例如,在 HTM 上
<HEAD>
<TITLE>'OpenGL Wizard'</TITLE>
<META NAME="vs_targetSchema" CONTENT="http://schemas.microsoft.com/intellisense/ie5">
<LINK ID="LINKURL" REL="stylesheet" HREF="../../../../../1033/NewStyles.css">
<!-- -->
<!-- The SYMBOL tag is used to set the default values for the user-defined symbols.-->
<!-- -->
<SYMBOL NAME='WIZARD_DIALOG_TITLE' TYPE=text VALUE='OpenGL Wizard'></SYMBOL>
<SYMBOL NAME='SAMPLE_CHECKBOX' TYPE=checkbox VALUE=true></SYMBOL>
<SYMBOL NAME='SAMPLE_RADIO_OPTION1' TYPE=checkbox VALUE=true></SYMBOL>
<SYMBOL NAME='SAMPLE_RADIO_OPTION2' TYPE=checkbox VALUE=false></SYMBOL>
<SYMBOL NAME='SAMPLE_LISTBOX' TYPE=select-one VALUE='option1'></SYMBOL>
<SYMBOL NAME='SOURCE_FILTER' TYPE=text VALUE='txt'></SYMBOL>
<SYMBOL NAME='APP_TYPE_SUMMARY' TYPE=text VALUE='//TODO: Application summary'></SYMBOL>
</HEAD>
*.vsdir 扩展名文件是您在 Visual Studio 中创建一个新项目时的自定义向导文件路径。
C:\Program Files\Microsoft Visual Studio 10.0\VC\vcprojects\OpenGL\OpenGL_Wizard.vsdir
*vsdir* 文件内容
. ..\OpenGL_Wizard.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|
#2000|100|#2001|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
*.vsz 扩展名文件是一个属性文件,您的自定义向导脚本在其中定义。
C:\Program Files\Microsoft Visual Studio 10.0\VC\vcprojects\OpenGL_Wizard.vsz
*vsz* 文件内容
VSWIZARD 7.0
Wizard=VsWizard.VsWizardEngine.10.0
Param="WIZARD_NAME = Application"
Param="RELATIVE_PATH = VCWizards\AppWiz\OpenGL"
Param="CONSOLE_TYPE_ONLY = false"
Param="WIZARD_ID = 103"
*Template.inf* 文件是自定义向导的文件列表。 此 INF 扩展名文件对于来自模板文件信息的新项目非常重要。
C:\Program Files\Microsoft Visual Studio 10.0\VC\VCWizards\
AppWiz\OpenGL\Application\templates\1033.Template.inf
*Template.inf* 文件内容
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
targetver.h
Res/OpenGL.ico
Res/OpenGL.rc2
Res/OpenGLDoc.ico
Res/Toolbar.bmp
Res/OpenGL.manifest
Resource.h
earth.bmp
编辑自定义向导脚本文件
*C:\Program Files\Microsoft Visual Studio 10.0\VC\VCWizards\AppWiz\OpenGL\Application\scripts\1033\default.js* 文件非常~ 非常~ 非常~ 重要。 此文件在 Visual Studio 2003/2005/2008 和 Visual Studio 2010 之间相似。 但是,脚本文件是不同的项目扩展名、目标 .NET Framework 版本以及 Visual Studio 2010 上的附加配置属性。 但其他的与 Visual Studio 2003/2005/2008 中相同。
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
}
}
function CreateCustomProject(strProjectName, strProjectPath)
{
try
{
var strProjTemplatePath = wizard.FindSymbol('PROJECT_TEMPLATE_PATH');
var strProjTemplate = '';
strProjTemplate = strProjTemplatePath + '\\default.vcxproj';
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 + '.vcxproj';
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);
}
var fxtarget = wizard.FindSymbol("TARGET_FRAMEWORK_VERSION");
if (fxtarget != null && fxtarget != "")
{
fxtarget = fxtarget.split('.', 2);
if (fxtarget.length == 2)
prj.Object.TargetFrameworkVersion = parseInt(fxtarget[0]) *
0x10000 + parseInt(fxtarget[1])
}
return prj;
}
catch(e)
{
throw e;
}
}
function AddFilters(proj)
{
try
{
// Add the folders to your project
var group;
group = proj.Object.AddFilter('Source Files');
group.Filter = 'cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx';
group = proj.Object.AddFilter('Header Files');
group.Filter = 'h;hpp;hxx;hm;inl;inc;xsd';
group = proj.Object.AddFilter('Resource Files');
group.Filter = 'rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;
jpe;resx;tiff;tif;png;wav';
}
catch(e)
{
throw e;
}
}
function AddConfig(proj, strProjectName)
{
try
{
var config = proj.Object.Configurations('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 = pchOption.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;
var MIDLTool = config.Tools('VCMIDLTool');
MIDLTool.PreprocessorDefinitions = '_DEBUG';
MIDLTool.MkTypLibCompatible = 'false';
MIDLTool.ValidateParameters = 'false';
var ResourceTool = config.Tools('VCResourceCompilerTool');
// TODO: Add Resource Compiler settings
ResourceTool.Culture = enumResourceLangID.rcEnglishUS;
ResourceTool.PreprocessorDefinitions = "_DEBUG";
ResourceTool.ResourceOutputFileName = "$(IntDir)/$(InputName).res"
config = proj.Object.Configurations('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 = pchOption.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;
var MIDLTool = config.Tools('VCMIDLTool');
MIDLTool.PreprocessorDefinitions = 'NDEBUG';
MIDLTool.MkTypLibCompatible = 'false';
MIDLTool.ValidateParameters = 'false';
var ResourceTool = config.Tools('VCResourceCompilerTool');
// TODO: Add Resource Compiler settings
ResourceTool.Culture = enumResourceLangID.rcEnglishUS;
ResourceTool.PreprocessorDefinitions = "";
ResourceTool.ResourceOutputFileName = "$(IntDir)/$(InputName).res"
}
catch(e)
{
throw e;
}
}
function PchSettings(proj)
{
// TODO: specify pch settings
}
function DelFile(fso, strWizTempFile)
{
try
{
if (fso.FileExists(strWizTempFile))
{
var tmpFile = fso.GetFile(strWizTempFile);
tmpFile.Delete();
}
}
catch(e)
{
throw e;
}
}
function CreateCustomInfFile()
{
try
{
var fso, TemplatesFolder, TemplateFiles, strTemplate;
fso = new ActiveXObject('Scripting.FileSystemObject');
var TemporaryFolder = 2;
var tfolder = fso.GetSpecialFolder(TemporaryFolder);
var strTempFolder = tfolder.Drive + '\\' + tfolder.Name;
var strWizTempFile = strTempFolder + "\\" + fso.GetTempName();
var strTemplatePath = wizard.FindSymbol('TEMPLATES_PATH');
var strInfFile = strTemplatePath + '\\Templates.inf';
wizard.RenderTemplate(strInfFile, strWizTempFile);
var WizTempFile = fso.GetFile(strWizTempFile);
return WizTempFile;
}
catch(e)
{
throw e;
}
}
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;
}
}
function AddFilesToCustomProj(proj, strProjectName, strProjectPath, InfFile)
{
try
{
var projItems = proj.ProjectItems
var strTemplatePath = wizard.FindSymbol('TEMPLATES_PATH');
var strTpl = '';
var strName = '';
var strTextStream = InfFile.OpenAsTextStream(1, -2);
while (!strTextStream.AtEndOfStream)
{
strTpl = strTextStream.ReadLine();
if (strTpl != '')
{
strName = strTpl;
var strTarget = GetTargetName(strName, strProjectName);
var strTemplate = strTemplatePath + '\\' + strTpl;
var strFile = strProjectPath + '\\' + strTarget;
var bCopyOnly = false; //"true" will only copy the file
// from strTemplate to strTarget without rendering/adding to the project
var strExt = strName.substr(strName.lastIndexOf("."));
if(strExt==".bmp" || strExt==".ico" || strExt==".gif" ||
strExt==".rtf" || strExt==".css")
bCopyOnly = true;
wizard.RenderTemplate(strTemplate, strFile, bCopyOnly);
proj.Object.AddFile(strFile);
}
}
strTextStream.Close();
}
catch(e)
{
throw e;
}
}
Visual Studio 向导插入
最后,如果您创建自定义向导项目,则必须构建此项目。 但是,如果您不创建自定义向导,则应将自定义向导插入到 Visual Studio 2010 向导列表。 *C:\Program Files\Microsoft Visual Studio 10.0\VC\vcprojects\vc.svdir* 文件是 Visual Studio 2010 的列表。 您必须更改 OpenGL 自定义向导文件的自定义向导安装路径。
ATL|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1041|10
vcNET|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1040|20
General|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1044|30
MFC|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1042|40
SmartDevice|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1045|50
Win32|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1043|60
Win32Console.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1204|10|
#1205|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MFCAppWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1161|20|
#1162|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
Win32Wiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1171|30|
#1172|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
EmptyProj.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1279|40|
#1280|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
ATLWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1155|50|#1156|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MFCDLLWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1163|60|#1164|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MC++WinApp.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1221|70|#1222|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|FormApp
MC++AppWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1173|80|#1174|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MC++EmptyProj.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1177|90|#1178|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MakefileAppWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1183|100|#1184|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MFCCtlWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1165|100|#1166|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MC++ClassLib.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1175|100|#1176|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
MC++WinCtrlLib.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1243|100|#1244|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
SDWin32Wiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1404|100|#1405|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
SDATLWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1400|100|#1401|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
SDMFCAppWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1402|100|#1403|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
SDMFCCtlWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1406|100|#1407|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
SDMFCDLLWiz.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1408|100|#1409|
{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
OpenGL_Wizard.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#2000|100|
#2001|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|0|4096|#1154
兴趣点和历史记录
如果您想要详细说明,则必须查看我之前关于“Visual Studio .NET 中 OpenGL 的自定义向导”的文章。