Implementing a custom wizard for Visual Studio for custom C++ classes

≯℡__Kan透↙ 提交于 2019-12-03 08:10:37

I have done something similar using a custom wizard.

For my purposes I just wanted to inject some simple macros into each class to insert it into a static factory object.

I didn't need to modify the actual wizard, just copied the default generic class wizard and modified the code generation javascript.

The documentation is rubbish on the topic, but here is a good place to start for the javascript (that is where you are going to get the most power):

http://msdn.microsoft.com/en-us/library/t41260xs(v=VS.71).aspx

The default class wizard javascript is located here:

C:\Program Files\Microsoft Visual Studio 10.0\VC\VCWizards\CodeWiz\Generic\Class\Scripts\1033\default.js


Duping the Project

Duplicating this is trickier than I thought, you need to copy and paste the

Microsoft Visual Studio 10.0\VC\VCWizards\CodeWiz\Generic\

folder, then head to:

C:\Program Files\Microsoft Visual Studio 10.0\VC\VCAddClass\Generic

Dupe this folder and modify the Generic.vsdir inside it to point to a dupe of ..\Simple.vsz (a file in the VCAddClass folder).

The Simple.vsz file points back to the location of the "Generic" folder in VCWizards you duped at the start, so point your new simple.vsz at that.


Code Generation

As for the actual code generation, its not all that difficult to pick up. To get things started faster, here is the General way the default.js works:

Once the wizard is finished, the code gen method kicks off from:

function OnFinish(selProj, selObj)

selProj is (as far as I can tell) an instance of EnvDTE.Project

http://msdn.microsoft.com/en-us/library/envdte.project.aspx

Getting information from the wizard seems to be based around:

wizard.FindSymbol("CLASS_NAME")

The real magic starts to happen on the selProj.CodeModel object

oCM.AddClass(strClassName, strHeader, vsCMAddPositionEnd, "", "", vsCMAccessDefault);

It seems the convention for these methods to add anything to a file simply modifies the file as a single action, as it requires the file path as its paramter.

This returns a CodeClass instance and can be added to by its methods like:

AddAttribute
AddFunction
...

This is quite restricting if you are looking for very strict code formatting (or in my case inserting macros that don't fit normal code syntax.

The simple way around this is to just build a string on your own for the parts that you need full control over using the EditPoint interface.

An EditPoint is a location inside a code file to which you can call methods like:

EditPoint.Insert(string)
Editpoint.InsertFromFile(path)

To get an EditPoint in a location where you would want to insert code, simply use the location of one of the existing items in the code gen file (like class or constructor) and get a TextPoint using .StartPointOf or .EndPointOf and manipulating the parameters.

Once you have a TextPoint you can create an EditPoint like so:

newclass.EndPointOf(vsCMPartBody).CreateEditPoint().Insert("\nprivate:\n  REGISTER_TYPE_MEMBER("+strClassName+");\n");

To get a TextPoint inside the .cpp file instead:

oConstructor.StartPointOf(vsCMPartWhole,vsCMWhereDefinition).CreateEditPoint().Insert("REGISTER_TYPE_BODY_ID("+strClassName+",REPLACE_ID);\n\n\n");

This gives you the power to do anything you want via JScript string manipulation as long as you can find the input data you need via the wizard (which I have not yet delved into)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!