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

你说的曾经没有我的故事 提交于 2019-12-04 12:09:53

问题


in order to make new C++ classes conform to some rather picky coding conventions (upfront: I am not in the position to discuss these...), I was thinking about a way of generating stubs for new C++ classes. Currently, everyone is doing copy-paste, regularly missing some detail. The IDE in use is MS Visual Studio 2005, but I think there has not been much of a change in 2008 and 2010 regarding these topics.

My first idea was to implement a command line script to do this, which would be fairly straight forward to do. Alternatively, I thought about using a default VS extension mechanism for better IDE integration. So, this would be hooking in some custom stuff when selecting Add->New Item... on a filter (Solution Explorer).

After some investigation, I found out there is an easy-to-use templating mechanism, which unfortunately does not work for C++ (http://msdn.microsoft.com/en-us/library/6db0hwky%28v=vs.80%29.aspx). For C++, it seems like you have to implement a custom wizard instead, incorporating html for the layout and javascript for the logic.

Regarding the custom wizard approach, I've come to the conclusion that this would require some effort (at least for me) to get this done. MSDN is not very detailed on this topic. I've found some walkthroughs in the web, which are dealing with custom wizards for projects only (Add->New Project... instead of Add->New Item...).

So, here's the qn: Anyone having done this or something similar? Is it (better IDE integration) worth the effort (coping with the details of custom wizard implementation), or would you suggest the go for the command line tool instead? More than two days of work would not pay off in the current project, I guess.

If you think custom wizards are great, maybe you can give some hints to get started. Also, maybe there are alternatives I did not come up with. VS Add-Ins seemed to be over the top for this, and adapting e.g. VC\vcprojectitems\newc++file.cpp will not do the job.

Thanks in advance and best regards... Jerb


回答1:


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)



来源:https://stackoverflow.com/questions/5132896/implementing-a-custom-wizard-for-visual-studio-for-custom-c-classes

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