Visual Studio Macro to switch between CPP and H files

I’ve been doing a lot of managed C++ programming lately and I had forgotten what a pain it is switching back and forth between the header file and source file.  Back in the days of Visual Studio 6 I had a macro that switched between the CPP and H file, so I went googling, but the macro I found didn’t work very well in VS2008.  Like any good coder, I decided to write it myself instead.

If you haven’t written a macro before, here are the steps.

  1. In Visual Studio, go to Tools | Macros | Macros IDE. A new window should open and in the Project Explorer, the MyMacros project should be open.
  2. Right click on the MyMacros project and select Add | Add Module. Name it CppUtilities.  The CppUtilities should open in the editor window.
  3. Add the code from below into the module and save the project.
‘=====================================================================
‘ If the currently open document is a CPP or an H file, attempts to
‘ switch between the CPP and the H file.
‘=====================================================================
Public Sub SwitchBetweenSourceAndHeader()
  Dim currentDocument As String
  Dim targetDocument As String

  currentDocument = ActiveDocument.FullName

  If currentDocument.EndsWith(“.cpp”, StringComparison.InvariantCultureIgnoreCase) Then
    targetDocument = Left(currentDocument, Len(currentDocument) - 3) + “h”
    OpenDocument(targetDocument)
  ElseIf currentDocument.EndsWith(“.h”, StringComparison.InvariantCultureIgnoreCase) Then
    targetDocument = Left(currentDocument, Len(currentDocument) - 1) + “cpp”
    OpenDocument(targetDocument)
  End If

End Sub

‘=====================================================================
‘ Given a document name, attempts to activate it if it is already open,
‘ otherwise attempts to open it.
‘=====================================================================
Private Sub OpenDocument(ByRef documentName As String)
  Dim document As EnvDTE.Document
  Dim activatedTarget As Boolean
  activatedTarget = False

  For Each document In Application.Documents
    If document.FullName = documentName And document.Windows.Count > 0 Then
      document.Activate()
      activatedTarget = True
      Exit For
    End If
  Next
  If Not activatedTarget Then
    Application.Documents.Open(documentName, “Text”)
  End If
End Sub

If you switch back to Visual Studio and open the Macro Explorer, you should see the new module CppUtilities and the new macro SwitchBetweenSourceAndHeader in the tree.  You could run the macro from here, but it is much easier to bind it to a keystroke.

  1. Click on Tools | Options then go to the Environment | Keyboard tab.
  2. In the Show commands containing: box, type CppUtilities. This should filter the list down to one entry, Macros.MyMacros.CppUtilitities.SwitchBetweenSourceAndHeader.
  3. Click on the Press shortcut keys: text box and then press the keystroke you would like to use to run the macro. If the keystroke is already used, it will show you below in the Shortcut currently used by: dropdown.  When you find one that is unused, click the Assign button to use it.  I use Ctrl+Shift+Alt+Bkspce.
  4. Click OK then open a CPP or H file and give it a try.

25 thoughts on “Visual Studio Macro to switch between CPP and H files

  1. Thanks for this. I also modified it to support cpp and h in different directories and to open the document by finding it in the project:

    ‘=====================================================================
    ‘ If the currently open document is a CPP or an H file, attempts to
    ‘ switch between the CPP and the H file.
    ‘=====================================================================
    Public Sub SwitchBetweenSourceAndHeader()
    Dim currentDocument As String
    Dim targetDocument As String

    currentDocument = ActiveDocument.FullName

    If currentDocument.EndsWith(“.cpp”, StringComparison.InvariantCultureIgnoreCase) Then
    targetDocument = Left(currentDocument, Len(currentDocument) – 3) + “h”
    OpenDocument(targetDocument)
    ElseIf currentDocument.EndsWith(“.h”, StringComparison.InvariantCultureIgnoreCase) Then
    targetDocument = Left(currentDocument, Len(currentDocument) – 1) + “cpp”
    OpenDocument(targetDocument)
    End If

    End Sub

    ‘=====================================================================
    ‘ Given a document name, attempts to activate it if it is already open,
    ‘ otherwise attempts to open it.
    ‘=====================================================================
    Private Sub OpenDocument(ByRef documentName As String)
    Dim document As EnvDTE.Document

    For Each document In Application.Documents
    If document.FullName = documentName And document.Windows.Count > 0 Then
    document.Activate()
    Return
    Exit For
    End If
    Next

    Dim documentShortName As String = Right(documentName, Len(documentName) – documentName.LastIndexOf(“\”) – 1)

    For Each document In Application.Documents
    If document.Name = documentShortName And document.Windows.Count > 0 Then
    document.Activate()
    Return
    Exit For
    End If
    Next

    Dim item As EnvDTE.ProjectItem = DTE.Solution.FindProjectItem(documentShortName)
    If item Is Nothing Then
    Return
    End If
    item.Open()
    item.Document.Activate()

    End Sub

  2. Modified to handle c and h in different directories

    ‘=====================================================================
    ‘ If the currently open document is a CPP or an H file, attempts to
    ‘ switch between the CPP and the H file.
    ‘=====================================================================
    Public Sub SwitchBetweenSourceAndHeader()
    Dim currentDocument As String
    Dim targetDocument As String

    currentDocument = ActiveDocument.FullName

    If currentDocument.EndsWith(“.cpp”, StringComparison.InvariantCultureIgnoreCase) Then
    targetDocument = Left(currentDocument, Len(currentDocument) – 3) + “h”
    targetDocument = targetDocument.Substring(targetDocument.LastIndexOf(“\”) + 1)
    OpenDocument(targetDocument)
    ElseIf currentDocument.EndsWith(“.h”, StringComparison.InvariantCultureIgnoreCase) Then
    targetDocument = Left(currentDocument, Len(currentDocument) – 1) + “cpp”
    targetDocument = targetDocument.Substring(targetDocument.LastIndexOf(“\”) + 1)
    OpenDocument(targetDocument)
    End If

    End Sub

    ‘=====================================================================
    ‘ Given a document name, attempts to activate it if it is already open,
    ‘ otherwise attempts to open it.
    ‘=====================================================================
    Private Sub OpenDocument(ByRef documentName As String)
    Dim document As EnvDTE.Document
    Dim activatedTarget As Boolean
    activatedTarget = False

    For Each document In Application.Documents
    If document.Name = documentName Then
    documentName = document.FullName
    If document.Windows.Count > 0 Then
    document.Activate()
    activatedTarget = True
    Exit For
    End If
    End If
    Next
    If Not activatedTarget Then
    Application.Documents.Open(documentName, “Text”)
    End If
    End Sub

  3. This macro works only if cpp and h files are in same directory. What if they are in different directories. ex: h file in “inc” dir and cpp file in “src”?

  4. I got it why it was slow for me. I always keep a lot of files open in Visual Studio, and since the macro goes through all of the open files and activates it if it’s found, (opens otherwise) it becomes slow. I think there’s no need for doing this. If you try to ‘open’ the file when it’s already open, Visual Studio anyway just activates that. Result, the switching becomes very fast.

  5. Thanks very much! I was looking for this for long. Many times though, you store header files in a folder called ‘blah/blah/include/file.h’ and source file in ‘blah/blah/source/file.cpp’. So If the file to be opened doesn’t exist, I try by replacing documentName.replace(“source”,”include”) and vice versa if that file exists to open. As someone already pointed out, we could directly do a File.Exists() to test for it.

    The only thing remaining now is that it is a ‘bit’ slow (not much, but not negligible also) for me in VS 2005. Does anyone know how to make it instantaneous.

  6. Thanks, great macro. I started working at home recently and I don’t have Visual Assist, which adds Alt+O as this option, I’ve been missing it.

    Alt+O is back =)
    -Eli

  7. This is perfect. Thanks!

    Slight mod to avoid error message when the matching file doesn’t exist:

    instead of:
    Application.Documents.Open(documentName, “Text”)

    change to:
    If FileIO.FileSystem.FileExists(documentName) Then
    Application.Documents.Open(documentName, “Text”)
    End If

  8. I have been looking for something to do this for months. I had been using WndTabs for VS6, but there is no equal for VS2008.

    If you want to make a button you can click to do this, follow these steps:
    1) R-click on toolbar, select Customize
    2) In the Commands tab, under Categories, select Macros then the macro you just made (mine was at the top)
    3) Drag the name of the macro onto the toolbar you want to use (you can make a new one, or add it somewhere)
    4) R-click on the button you just added (the Customize Window needs to be open) and change the name to something shorter (“CPPH”)

Comments are closed.