简单的通用向导






4.50/5 (6投票s)
2003年5月13日
3分钟阅读

68195

893
一个自定义 AppWizard 应用程序,用于创建简单的基于 CTreePropSheet 的向导。
引言
这是一个使用 MSVC 内置的自定义 AppWizard 创建的 AppWizard。 它被称为 GenWiz,可以与 MSVC 一起使用来创建简单的通用向导框架。 它基于 Sven Wiegand 开发的 CTreePropSheet 类。
这个向导基本上是 MSVC 的自定义 AppWizard 的克隆,通过使用模板和宏来创建应用程序框架。 开发这样一个向导的主要原因是因为我希望向导是独立的执行文件,而不是 AWX 执行文件,后者只能在 MSVC IDE 下执行。
在创建这个简单的通用向导之前,我在 Internet 上搜索有关如何访问 AppWizard 的功能(在 MFCAPWZ.DLL 中实现)的信息。 我没有找到任何信息,因此我想出了我自己的版本,关于如何解析模板和替换宏。
使用 GenWiz 创建的向导示例可以在另一篇文章中找到:PIC C 向导。
如何安装
下载包含源代码的 zip 文件,并将\release 文件夹下的 GenWiz.AWX 文件解压到 Program Files\Microsoft Visual Studio\Common\MSDev98\Template 文件夹中。 下次您启动 MSVC IDE 时,genwiz AppWizard 应该会在新建项目选项卡中列出。
GenWiz 中的重要“内容”
关于 AppWizard 如何工作的参考资料在 Internet 和 MSDN 本身中有很多,因此我将主要关注我编写的用于实现此向导的一组函数。 这些函数将成为任何 GenWiz 生成的向导的一部分。
CMapStringToString m_Dictionary;
/**< Holds the macros that are later replaced by values.*/
/**
It creates each of the files found to be templates and
that are included in the wizard's project file. The files
are created in a folder with the same name as the project
name gave by the user. This function should be call by one
of the wizard's page OnOK() function.
*/
BOOL CreateProjectFiles();
/**
It processes the wizard's project file to determine
which templates to load into memory. It also calls the
function FileStatusInProject() to determine how the files
are going to be handled in the project.
This function should be the first one to be called by one
of the wizard's page OnOK() function.
*/
BOOL LoadProjectInfo();
/** It retrieves the text information that is placed in one the templates to provide the user project information just before its creation. This text information could be passed to a "project information" dialog box. \param sText A reference to a CString object to hold the text information. */ void GetConfirmText( CString& sText );
/** It processes the templates that are going to be part of the project and still contain the macros. It then replaces these macros by the values given by the user through the wizard's user interface. This function should be called before the CreateProjectFiles() function. */ void ProcessTemplates();
protected: CString m_sTemplatesFolder; /**< Holds the macros that are later replaced by values.*/
CString m_sConfirmBuf;
/**< The information text displayed before the
project creation.*/
CStringArray m_saTemplates;
/**< The names of the templates to be included in the
project.*/
CStringArray m_saTemplatesBuf;
/**< The contents of the templates before and after
macros.*/
/** It adds the macros in the macros dictionary. This function is called by ProcessTemplates(). The user can add all the wizard's macros in this function. */ void CreateAndFillMacros();
/**
It verifies if the wizard's project template file exists.
This function is called before showing the wizard GUI; if
the project file does not exist, it asks the user to create
default templates.
\return
TRUE if file exists, FALSE if user did not want to
create default templates and wizard will abort execution.
*/
BOOL VerifyWizardConfigFile();
/**
It determines the status of a template file in the project.
The user should add code here if two or more different types
of files can be generated by the wizard. This function is
called by LoadProjectInfo().
*/
DWORD FileStatusInProject( CString& sFName );
/**
It reads the contents of a template file
\param lpszTemplateName
It specifies the file name of the template
to load. This function is called by the LoadProjectInfo().
\return
PTCHAR, a pointer to a char buffer where the file has
been loaded. NULL if the function failed.
*/
PTCHAR LoadTemplate( LPCTSTR lpszTemplateName );
/** It adds a macro to the dictionary in which the value comes from an integer type of variable. \param lpszMacro Name of the new macro. \param value Integer value that should be passed to the new macro. */ void AddMacroFromInt( LPCTSTR lpszMacro, int value );
/** It adds a macro to the dictionary in which the value comes from a floating point type of variable. \param lpszMacro Name of the new macro. \param value Floating point value that should be passed to the new macro. */ void AddMacroFromDouble( LPCTSTR lpszMacro, double value );
/** Callback function used to open "TEMPLATES" resources and create the wizard's default templates. This function is called when the wizard is re-creating the default templates. See Window's API for more reference information. \param hModule Module handle. \param lpszType Pointer to resource type. \param lpszName Pointer to resource name. \param lParam Application-defined parameter. */ static BOOL MyEnumResNameProc( HANDLE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG lParam );
/**
It enumerates the "TEMPLATE" resources and setup
MyEnumResNameProc() as the callback function. This function
is called by LoadWizardConfigFile() when the wizard's project
file is not found in the users' folder.
\return
TRUE if the resource "TEMPLATE" was found. FALSE otherwise.
*/
BOOL CreateDefaultTemplatesFromResources();
/**
It shows a dialog box asking the user to create or not the
default templates. This function is called by
LoadWizardConfigFile() when the wizard's project file is
not found in the user's folder.
\return
TRUE if the user responded YES. FALSE otherwise.
*/
BOOL AskCreateDefaultTemplates();
/** It asks the OS for the actual user logged in. It then creates the templates folder for this user and set it as the current folder. It is run in InitInstance() before showing the wizard. */ void InitTemplatesFolder();
下一节将展示向导如何根据您提供的模板创建框架
void CWizDlg1::OnOK() { // This is the function where all the macros // replacement is done and templates creation // takes place. if ( !pApp->LoadProjectInfo() ) { CPropertyPage::OnCancel(); } pApp->ProcessTemplates(); // this is the dialog where the text information about // the project will be displayed before its creation. CWizInfoDlg cdlg; pApp->GetConfirmText( cdlg.m_sText ); int iRet = cdlg.DoModal(); if ( IDOK == iRet ) { pApp->CreateProjectFiles(); CPropertyPage::OnOK(); } else { CPropertyPage::OnCancel(); } }
以下代码可以在向导的 InitInstance()
中找到
// make sure the user's folder exists InitTemplatesFolder(); // TODO: determine if the configuration files exist under // the user's folder. if ( !VerifyWizardConfigFile() ) { return FALSE; } m_pMainWnd = &wizardWnd; int iRes = wizardWnd.DoModal(); if ( IDOK == iRes ) {} else {}
在向导的每个属性页中重写这两个函数:CPropertyPage::OnKillActive()
和 CPropertyPage::OnSetActive()
。 在 OnSetActive()
中添加代码以从 WIZARDINFO
数据结构更新页面的值。 在 OnKillActive()
中添加代码以将用户的数据输入到 WIZARDINFO
数据结构中。 请参阅向导中的示例代码。
模板
- wizconfig.inf: 提供此模板作为示例,说明向导如何读取直接进入
WIZARDINFO
结构的信息。 - wizproj.inf: 它包含将成为生成项目一部分的模板文件列表。 对于您添加到向导的每个模板文件,如果此文件在生成项目中需要,则应在此文件中添加一行。
- wizinfo.inf: 包含将在您的向导即将创建新项目之前显示的文本信息。
删除其他三个模板,因为它们是作为示例提供的。
添加新模板
- 转到资源部分,然后选择“TEMPLATE”资源。
- 右键单击并选择插入“TEMPLATE”。
- 将添加一个新的 TEMPLATE 资源,并将其命名为:
IDR_TEMPLATE1
。 将此名称更改为其他名称,例如模板的文件名,并确保它在引号之间,例如:“MYFILE.CPP”。 此外,将位置从 res\ 更改为 template\.
支持的指令
您的向导将支持以下可以在您的模板中使用的指令
$$IF
$$ENDIF
$$BEGINLOOP
$$ENDLOOP
$$//
:表示注释。它只能位于行的开头,并且整行将被视为注释。
请查看 MSDN 文档以获取有关如何在模板中使用这些指令的更多信息。
注释
GenWiz 将创建一个默认框架,在第一个对话框中包含一个 CGridCtrl。 这只是一个示例,如果您的向导中不需要,可以安全地将其删除。
要向您的向导添加更多对话框或子部分,或修改属性表样式,请参阅此文章中的“使用 CTreePropSheet”。
历史
2003 年 5 月 14 日:初始版本。