Click here to Skip to main content
15,885,985 members
Articles / Programming Languages / Visual Basic

Open Related C++ .h/.cpp Files and Call Compiler in a .h File

Rate me:
Please Sign up or sign in to vote.
4.44/5 (3 votes)
24 Jul 2007CPOL2 min read 87.9K   213   16   13
Macro to find related .h/.cpp files and do some action.

Introduction

In Visual Studio .NET 2003/2005, if you want open the related .cpp file when you are editing a .h file, or if you want to open the related .h file when you are editing a .cpp file, or if you want to compile the related .cpp file when you are editing a .h file, is there a simple way?

Usually, programmer opens the related file in Solution Explorer, or use Ctrl+Tab to find the related file. The is not very simple. So I wrote a macro to find and open related files. After you import the macro into Macro Explorer, you can run it simply by double clicking it.

Of course, there is a more simple way. Follow the menu 'Tools->Option->Environment->Keyboard' to open the shortcut configuration dialog. Then find the OpenRelatedFile macro, give it a shortcut such as Ctrl+F6, and find the CompileImplFile macro, give it a shortcut, such as Ctrl+F7. OK, you can now use the shortcut to invoke the macro now.

Basic Opinion

To find the related file in a project, several steps are necessary:

  1. Get the file name of the currently opened source file and generate the related file names. For example, if the current file is bla.h, we should look for bla.cpp, bla.c, etc.
  2. Create a map which contains all files we are looking for.
  3. Look for the files in the project.
  4. If a target file is found, open it or compile it.

Source Code

It's necessary to traverse all folders in a project to look for a file by recursion. For that, we need a recursion function:

VB
' Find and open file in specified project item and it's children
Private Sub FindAndOpenFile(ByRef item As ProjectItem)
    ' The item maybe a file or a folder.
    If filenames.IndexOf(item.Name.ToLower()) >= 0 Then
        ' If the item's document is not nothing, it should be a file
        ' This condition cannot be merged outer one, becuase if the document
        ' is not nothing, the file should be activated by using Document property.
        ' However, VB calculates all condition in 'and' chain.
        If Not item.Document Is Nothing Then
            DTE.ItemOperations.OpenFile(item.FileNames(0))
            Exit Sub
        End If
    End If

    ' To process in childrens of current item.
    ' If current item has no children, the for each loop should be ignored by interpreter
    Dim i As ProjectItem
    For Each i In item.ProjectItems
        FindAndOpenFile(i)
    Next
End Sub

The global variable filenames contains some filenames which we want to look for. If the function finds one of the filenames, open it and try to find another one.

The function starts with a ProjectItems object. Every item in the object is perhaps a filename or a folder. If it's a folder, its ProjectItems property should not be empty. Thus the function invokes itself with the item's ProjectItems property as a parameter recursively.

VB
Private Sub FindAndOpenFileInProject()
    ' Get current project
    Dim projs As System.Array
    Dim proj As Project
    projs = DTE.ActiveSolutionProjects()

    If projs.Length = 0 Then
        Exit Sub
    End If

    proj = CType(projs.GetValue(0), EnvDTE.Project)

    ' To look for the related file and activate it.
    Dim item As ProjectItem
    For Each item In proj.ProjectItems
        FindAndOpenFile(item)
    Next
End Sub

In the OpenRelatedFile function, all related .cpp/.c/.h/.hpp files should be searched.

VB
' Create a set to contains the filename which would be looked for.
filenames.Clear()
filenames.Add(curName)
filenames.Add(curName & ".h")
filenames.Add(curName & ".cpp")
filenames.Add(curName & ".c")
filenames.Add(curName & ".hpp")
filenames.Remove(curFilename)

In the CompileImplFile function, only the related .cpp/.c files should be searched, so there is a little difference when we set the filenames list:

VB
' Create a set to contains filenames which would be looked for.
filenames.Clear()
filenames.Add(curName & ".cpp")
filenames.Add(curName & ".c")

If a .cpp/.c file is found and opened, the function executes the Build.Compile command to compile it.

VB
curFilename = DTE.ActiveDocument.Name
If (curFilename.EndsWith(".cpp") Or curFilename.EndsWith(".c")) Then
    DTE.ExecuteCommand("Build.Compile")
End If

Update Log

  • 2007-07-25: Optimized code.
  • 2007-07-12: Fixed the bug that sometimes we cannot open the related .h file.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
China China
James Fancy, is a software engineer from China. He enjoys and familiar with Java, C++ and some script languages.

If you can read Chinese word, here is one of James Fancy's BLOG:
http://hi.baidu.com/jamesfancy

Comments and Discussions

 
GeneralSolution.FindProjectItem is faster Pin
Rolf Kristensen2-Oct-08 1:23
Rolf Kristensen2-Oct-08 1:23 
GeneralRe: Solution.FindProjectItem is faster Pin
jamesfancy2-Oct-08 16:44
jamesfancy2-Oct-08 16:44 
Questioncannot open the related .h file Pin
connectpalm11-Jul-07 5:01
connectpalm11-Jul-07 5:01 
AnswerRe: cannot open the related .h file [modified] Pin
jamesfancy11-Jul-07 17:02
jamesfancy11-Jul-07 17:02 
AnswerRe: cannot open the related .h file Pin
jamesfancy11-Jul-07 17:12
jamesfancy11-Jul-07 17:12 
GeneralRe: cannot open the related .h file Pin
connectpalm11-Jul-07 22:50
connectpalm11-Jul-07 22:50 
GeneralRe: cannot open the related .h file Pin
connectpalm11-Jul-07 23:34
connectpalm11-Jul-07 23:34 
GeneralRe: cannot open the related .h file Pin
jamesfancy12-Jul-07 0:16
jamesfancy12-Jul-07 0:16 
GeneralRe: cannot open the related .h file Pin
connectpalm12-Jul-07 1:39
connectpalm12-Jul-07 1:39 
James, good that you have added some comments, now the code looks more friendly.
I still have few comments in the code:

in the procedure FindAndOpenFile you should avoid using the reserved word continue as a variable. It may create unknown runtime problems and as well mislead the reader.

and in the first place, I don't think you need that boolean variable. this below condition will work in every case if don't omit the Constants.vsViewKindTextView, else it may open the header file in the designer.

If findNames.ContainsKey(item.Name.ToLower()) Then
DTE.ItemOperations.OpenFile(item.FileNames(0), Constants.vsViewKindTextView)
Else
If item.ProjectItems.Count > 0 Then
FindAndOpenFile(findNames, item.ProjectItems)
End If
End If

lastly, i would suggest to replace Hashtable with an arraylist, because u anyhow don't add any value to the keys. For a simple macro like this, you are allocating more than the need by using a hashtable.

cheers

GeneralRe: cannot open the related .h file Pin
jamesfancy12-Jul-07 18:19
jamesfancy12-Jul-07 18:19 
GeneralRe: cannot open the related .h file Pin
jamesfancy24-Jul-07 22:02
jamesfancy24-Jul-07 22:02 
General嗯 如果是个插件 Pin
anycallmy7-Feb-07 3:55
anycallmy7-Feb-07 3:55 
GeneralRe: Pin
jamesfancy7-Feb-07 4:51
jamesfancy7-Feb-07 4:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.