[译]更好的课堂向导
By robot-v1.0
本文链接 https://www.kyfws.com/applications/a-better-class-wizard-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 10 分钟阅读 - 4932 个词 阅读量 0[译]更好的课堂向导
原文地址:https://www.codeproject.com/Articles/8559/A-better-class-wizard
原文作者:sinusx
译文由本站 robot-v1.0 翻译
前言
How to fix the annoying path problems with the "Add Class" wizard.
如何使用"添加类"向导解决烦人的路径问题.
介绍(Introduction)
当您想使用通用类向导在C ++项目中添加类时,通常会因无法提供用于创建类文件的"默认"路径而烦恼.大多数项目使用分开的源," cpp"和" h"与" sln"和" vcproj"文件不在同一个目录中.当您想在目录中添加许多类时,由于必须同时单击" .h"和" .cpp"浏览按钮并选择目录,因此浪费了很多时间.向导始终从存储项目配置文件的目录中启动.每次要添加类时,都必须执行这两个浏览步骤,并且IDE不会存储向导中使用的最后一个路径.对于下一课,您必须再次浏览层次结构.如果您有很多目录和深层嵌套的文件夹,则可能很快变成一场噩梦.(When you want to add a class in a C++ project using the generic class wizard, one is often annoyed by the fact that you can’t provide a “default” path where the class files will be created. Most projects use separated sources, “cpp” and “h” aren’t kept in the same directory as the “sln” and “vcproj” files. When you want to add many classes in a directory, you waste a lot of time because you have to click on both “.h” and “.cpp” browse buttons and select a directory. The wizard always starts in the directory where project configuration files are stored. These two browsing steps have to be performed each time you want to add a class, and the IDE doesn’t store the last path used in the wizard. For the next class, you have to browse again through your hierarchy. If you have a lot of directories and deep-nested folders, this may quickly turn into a nightmare.)
Visual Studio .NET向导(Visual Studio .NET wizards)
幸运的是,有一种简单的方法可以修复标准向导.向导实际上由与HTML文件和Visual Studio .NET IDE通信的JavaScript文件组成.该文件是您在IDE中看到的对话框的模板. HTML还包含一些JavaScript函数来处理字段和按钮.您可以轻松地在向导中添加一些字段,并通过JavaScript方法对其进行扩展.所有向导均存储在Visual Studio .NET文件夹中,您可以在"(Fortunately, there’s an easy way to fix a standard wizard. Wizards are in fact composed of a JavaScript file communicating with a HTML file and Visual Studio .NET IDE. This file is a template for the dialog box you see in the IDE. The HTML also contains some JavaScript functions to deal with fields and buttons. You can easily add some fields in your wizard and extend it through JavaScript methods. All wizards are stored in the Visual Studio .NET folder, you will find them in the “)Microsoft Visual Studio .NET/VC7/VCWizards(Microsoft Visual Studio .NET/VC7/VCWizards)目录中.“添加类"向导位于”(” directory. The “Add class” wizard is available in the “)类向导(ClassWiz)“文件夹.此文件夹包含名为”(” folder. This folder contains directories called “)ATL(ATL)”,"(", “)泛型(Generic)“和”(” and “)MFC(MFC)",我们将修改”(", we will modify the “)泛型(Generic)“文件夹.(” folder. The “)泛型(Generic)“文件夹包含三个文件夹:"(” folder contains three folders: “)的HTML(HTML)”,"(”, “)图片(Images)“和”(” and “)剧本(Scripts)".您将在”(”. You will find the dialog template in “)default.htm(default.htm)"((” ()/HTML/1033(/HTML/1033*)*),相应的JavaScript为"(*) and the corresponding JavaScript is “*)*default.js(*default.js*)*"((*” (*)*/sScripts/1033(*/sScripts/1033*)*).(*).*)
HTML模板(The HTML template)
打开"(Opening the “)default.htm(default.htm)浏览器中的文件将带您进入熟悉的界面.这就是您所看到的(在Firefox中,背景为紫色).(” file in a browser will bring you into a familiar interface. Here’s what you can see (in Firefox, the background will be violet).)
现在,如果您检查"(Now, if you check the source of “)default.htm(default.htm)",您将找到定义HTML表单的第一部分,然后是JavaScript部分.(”, you will find a first part defining the HTML form followed by a JavaScript section. The “) <HEAD>
文件开头的"“部分包含向导中使用的字段的定义.您可以添加一个(” section at the beginning of the file contains the definition of the fields used in the wizard. You can add a) <SYMBOL>
具有给定类型.我们将添加一个”(with a given type. We will add a “) PATH
“文本字段,其默认值为空字符串.此字段将接收由使用(” textfield with an empty string as default value. This field will receive the path returned by the dialog created using the) GetDirectoryViaBrowseDlg
功能.稍后再详细介绍.(function. More on this later.)
<SYMBOL NAME="HEADER_FILE_VALID" TYPE=bool VALUE=false></SYMBOL>
<SYMBOL NAME="IMPL_FILE_VALID" TYPE=bool VALUE=false></SYMBOL>
<SYMBOL NAME="PATH" TYPE="text" VALUE=""></SYMBOL>
JavaScript使用这些符号来访问字段值.下一步是在表单中添加字段.如果您有一些HTML知识,这很容易.表单布局基于表格,您会发现一些”(These symbols are used by the JavaScript to access the fields values. Next step is to add the field in the form. This is quite easy if you have some HTML knowledge. The form layout is based on a table, you will find some “) TD
“和”(” and “) TR
标签.我们将在基类字段下方添加该字段.我们还必须在该字段之后添加一个按钮,单击此按钮将打开浏览目录对话框,此行为是使用(” tags. We will add the field just below the base class field. We must also add a button after the field, clicking on this button will open the browse directory dialog, this behavior is defined using the) onClick
属性.每个控件必须具有唯一的ID,您还可以定义键盘快捷键来访问该字段((attribute. Each control must have a unique ID, you can also define the keyboard shortcut to access the field () ACCESSKEY
属性).文本字段称为(attribute). The text field called) sideBtn666ThreeColumn
会将其价值发送到(will send its value into the) PATH
我们在上面定义的符号.请注意,我们定义了一个名为(symbol we defined above. Note that we defined a new function called) OnBrowsePath()
当按下按钮时将调用它,我们必须实现此功能.(which will be called when the button is pressed, we have to implement this function.)
<SPAN CLASS="itemText" TITLE="">
<LABEL FOR="BASE_CLASS_NAME" ID="BASE_CLASS_NAME_LABEL"
TITLE="Enter the name for the base class from
which the class is to be derived.">
<U>B</U>ase class:
</LABEL>
<BR>
<INPUT CLASS="sideBtnThreeColumn" ID="BASE_CLASS_NAME"
TYPE="text" ACCESSKEY="b"
TITLE="Enter the name for the base class from
which the class is to be derived."
TABINDEX="6">
</SPAN>
<!--<span class="code-comment"> new code --></span>
<SPAN CLASS="itemText" TITLE="">
<P>
<LABEL FOR="PATH" ID="PATH_LABEL"
TITLE="Enter the path where the class files will be stored">
<U>P</U>ath</LABEL>
<BR>
<INPUT CLASS="sideBtn666ThreeColumn" ID="PATH" TYPE="text" ACCESSKEY="p"
TITLE="Enter the path where class will be stored" TABINDEX="6">
<BUTTON CLASS="buttonClass666Custom" ID="BrowsePathBtn" TYPE="BUTTON"
TITLE="Browse for the path." onClick="OnBrowsePath();"
TABINDEX="6">...</BUTTON>
</SPAN>
<!--<span class="code-comment"> end of new code --></span>
我们还删除了" .h文件"和" .cpp文件"字段后面的两个按钮.我总是将" .h"和" .cpp"放到同一目录中.您可以更改它,如果发现此问题很烦人,那就是复制路径字段和相应的代码.(We also remove the two buttons which follow the “.h file” and “.cpp file” fields. I always put the “.h” and “.cpp” together in the same directory. You could change that if you find this annoying, it’s a matter of duplicating the path field and the corresponding code.)
在浏览器中,现在看起来应该像这样:(In a browser, this should look like this now:)
default.htm的JavaScript部分(The JavaScript section of default.htm)
我们添加(We add the) OnBrowsePath()
功能与已经存在的文件浏览功能非常相似(function which is quite similar to the files browsing functions already present in)default.htm(defaut.htm).它基本上称为(. It basically calls the) GetDirectoryViaBrowseDlg
默认路径为2的函数(function with a default path as the 2)nd(nd)论据.该路径将从cookie中读取,我将在下一节中讨论它.的(argument. This path will be read from a cookie, I will talk about this in the next section. The) OnBrowsePath()
返回包含目录的完整路径的字符串.此路径将附加到(returns a string containing the full path of the directory. This path will be appended to the).H(.h*)*和(*and*)*.cpp(*.cpp*)*文件在另一个地方((*files at another place (*)*default.js(*default.js*)*).(*).*)
// new function added to the wizard, to allow path definition
function OnBrowsePath()
{
var strFile;
try
{
L_Title1_Text = "VS Wizards Select Path to store class files";
strPath = window.external.GetDirectoryViaBrowseDlg (L_Title1_Text,
cookieData.thePath);
}
catch(e)
{
if (e.number != OLE_E_PROMPTSAVECANCELLED)
{
var L_ErrMsg1_Text = "Error in OnBrowsePath()";
if (e.description.length != 0)
{
L_ErrMsg1_Text += ": ";
L_ErrMsg1_Text += e.description;
}
window.external.ReportError(L_ErrMsg1_Text);
}
return;
}
// store path in the textfield
PATH.value = strPath;
}
我没有添加任何代码来验证目录,我希望从中返回目录(I didn’t add any code to validate the directory, I expect the returned directory from) GetDirectoryViaBrowseDlg
是有效的.为了产生更强大的向导,您可以在(to be valid. To produce a more robust wizard, you could add a case in the) switch
存在于(present in the) Validate(obj)
功能.(function.)
下次存储路径(Storing the path for next time)
我不是JavaScript专家,所以尝试了各种解决方案.在MSDN上有一个教程(I’m not a JavaScript expert, and tried various solutions. There’s a tutorial on MSDN*) (Scripting) Working with files*)(脚本)使用文件( 但它使用ActiveX控件,并且每次您调用向导时,Visual Studio .NET都会打开一个授权窗口.出于安全原因,您不能使用JavaScript编写文件,而必须使用ActiveX控件或applet来修改内容.更好和干净的方法是使用cookie.我找到了一些cookie的JavaScript代码,这些代码直接取自O’Reilly关于JavaScript的"权威指南":(but it uses ActiveX controls, and Visual Studio .NET will open an authorization window each time you call the wizard. You can’t write files with JavaScript for security reasons, you have to hack the things using an ActiveX control or an applet. A better and clean way is to use cookies. I found some JavaScript code for cookies, it’s taken straight from the O’Reilly “Definitive Guide” about JavaScript:) Cookies代码(cookies code) .我只是将其代码剪切并粘贴到(. I just cut and paste their code into)default.htm(default.htm).(.)
我们首先定义一个全局变量(We first define a global variable) cookieData
实例化于(which is instantiated at the beginning of) InitDocument(document)
.我们首次提供使用向导的默认位置,即cookie("(. We provide a default location for the first time the wizard is used, the cookie (") last_path
“)还需要表明其有效期.(") also needs an indication about its expiration.)
// COOKIE CODE FROM OREILLY
// ............
//
// cookie for whole document
var cookieData;
function InitDocument(document)
{
setDirection();
CLASS_NAME.focus();
// create a cookie for 10 years, should be enough :)
cookieData = new Cookie(document, "last_path", 24*365*10);
// if cookie doesn't exist or is invalid, create it.
if (!cookieData.load() || !cookieData.name) {
cookieData.name = "last_path";
}
// store a default value for first session
if (cookieData.thePath==null)
{ cookieData.thePath="C:\\"; cookieData.store();}
if (window.external.FindSymbol("DOCUMENT_FIRST_LOAD"))
{
var L_WizardDialogTitle_Text = "Generic C++ Class Wizard";
window.external.AddSymbol("WIZARD_DIALOG_TITLE",
L_WizardDialogTitle_Text);
window.external.SetDefaults(document);
}
window.external.Load(document);
// store the cookie value into the textfield in the form
PATH.value = cookieData.thePath;
}
完成后,我们不应忘记将路径存储在cookie中.致电(We should not forget to store the path in the cookie when we have finished. A call to the) store()
的方法(method of the) cookieData
会很好的(will be fine in) OnFinish(document)
.(.)
function OnFinish(document)
{
if (!ValidateInput())
return;
cookieData.thePath = PATH.value;
cookieData.store();
// ....
}
default.js文件(The default.js file)
我们仍然需要修改充当IDE和模板之间桥梁的脚本,即”(We still have to modify the script that acts as a bridge between the IDE and the template, namely “)default.js(default.js)".您必须在开头添加一个变量:(”. One has to add a variable at the beginning:) var strPath = wizard.FindSymbol("PATH");
,其目的是获取(, its purpose is to get the value of the) PATH
从模板.现在非常简单,我们只需将路径附加到(from the template. It’s now quite easy, we just have to append the path to the).cpp(.cpp*)*和(*and*)*.H(*.h*)*文件.(*files.*)
var strProjectName = wizard.FindSymbol("PROJECT_NAME");
var strClassName = wizard.FindSymbol("CLASS_NAME");
var strHeader = wizard.FindSymbol("HEADER_FILE");
var strImpl = wizard.FindSymbol("IMPL_FILE");
var strBaseName = wizard.FindSymbol("BASE_CLASS_NAME");
var strPath = wizard.FindSymbol("PATH");
// ...
var newclass = oCM.AddClass(strClassName, strPath+"/"+strHeader,
vsCMAddPositionEnd, "", "", vsCMAccessDefault);
// ...
newclass.AddFunction(strClassName, vsCMFunctionConstructor, "",
vsCMAddPositionEnd, vsCMAccessPublic, strPath+"/"+strImpl);
var oDestructor = newclass.AddFunction("~"+strClassName,
vsCMFunctionDestructor, "", vsCMAddPositionEnd,
vsCMAccessPublic, strPath+"/"+strImpl);
安装(Installation)
打开zip文件并复制(Open the zip file and copy the)*default.js(default.js)*和(and)*default.htm(default.htm)*在正确的位置(我已经确定了整个路径,您可能必须将它们移动到正确的位置).我建议您在遇到问题时备份当前向导.您无需重新启动Visual Studio .NET即可设置新向导.如果您以与这些修补程序之前相同的方式在C ++项目中调用"添加类"向导,则应该看到新版本.(at the correct location (I included the whole path to be sure, you will probably have to move them to the correct place). I suggest that you make a backup of your current wizard in case you have a problem. You won’t have to restart Visual Studio .NET to setup the new wizard. If you call the “Add Class” wizard in a C++ project the same way as you did before these fixes, you should see the new version.)
结论(Conclusion)
我在Visual Studio .NET 2003中开发和测试了该向导.我猜想它可以与Visual Studio .NET的早期版本(Microsoft的原始版本写于2001年)一起使用.如果您可以对其进行改进,请随时在董事会:)正如我之前所说,我根本不是JavaScript专家,这是我第二次使用JavaScript代码,这是一种学习有关此脚本语言的好方法(并提出了事实上,我更喜欢Python;)).(I developed and tested the wizard in Visual Studio .NET 2003. I guess it will work with previous versions of Visual Studio .NET, the original version of Microsoft was written in 2001. If you can improve it, feel free to post your modifications in the board :) As I said before, I’m not a JavaScript expert at all, this was the second time I worked with JavaScript code and it was a good way to learn a bit about this scripting language (and to come up with the fact that I prefer Python ;)).)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
Javascript C++ Windows Visual-Studio VS.NET2003 Dev 新闻 翻译