|
 |
|
|
 |
|
|
Adjusted the macro so it can be used for Visual Studio 2005
New Improved Search order: 1. Look in open documents (Inspired by Switch between Header and CPP file) 2. Look in the same directory as the opponent file 3. Look through all projects in the entire solution using DTE.Solution.FindProjectItem (Inspired by robertwrose.com) 4. Look through all include paths in the attached projects (Inspired by BorisJ's Blog)
The search of include paths, requires that one adds a reference to Microsoft.VisualStudio.VCProjectEngine
To install the macro do the following:
1. Start Visual Studio 2005 2. In the menu select Tools -> Macros -> Macro Explorer. 3. In the Macro Explorer right-click "MyMacros" and choose "New Module..." 4. Create a new Module with the name "Opac" 5. In the Macro Explorer double-click the newly created module "Opac". 6. In the Macro IDE overwrite the contents with the big chunk of code below 7. In the Macro IDE Project Explorer right-click References and choose Add Reference... to add:
Microsoft.VisualStudio.VCProjectEngine To assign a keyboard shortcut-key to the macro do the following: 1. Start Visual Studio 2005 2. In the menu select Tools -> Customize 3. Press the "Keyboard..." button 4. In the "Search Commands Containing" search for the name "Opac". 5. Change focus to "Press Shortcut keys" and assign a shortcut like CTRL+F6 (Or whatever) 6. Press "Assign" and THEN "Ok".
Enjoy
-Snakefoot
Option Strict Off Option Explicit Off
Imports EnvDTE Imports System.Diagnostics ' add reference to Microsoft.VisualStudio.VCProjectEngine Imports Microsoft.VisualStudio.VCProjectEngine
Public Module Opac
Function OpenLocalFile(ByVal sFile As String) As Boolean If My.Computer.FileSystem.FileExists(sFile) Then On Error Resume Next DTE.ItemOperations.OpenFile(sFile, Constants.vsViewKindCode) OpenLocalFile = (Err.Number = 0) Err.Clear() On Error GoTo 0 Else OpenLocalFile = False End If End Function
Function FilePath(ByVal file) 'DESCRIPTION: Returns file path (without the trailing backslash "\"). Dim iPos, iBS, strPath
strPath = file iBS = Nothing Do While True iPos = InStr(1, file, "\", 1) If iPos = 0 Or iPos = Nothing Then Exit Do Else file = Right(file, Len(file) - iPos) iBS = iPos End If Loop
If iBS = Nothing Then FilePath = "" Else FilePath = Left(strPath, Len(strPath) - Len(file) - 1) End If End Function
Sub Swap_H_CPP() Dim name As String
If ReferenceEquals(DTE.ActiveDocument, Nothing) Then DTE.StatusBar.Text = "Error no active document" Exit Sub End If
If DTE.ActiveDocument.Language <> EnvDTE.Constants.dsCPP Then DTE.StatusBar.Text = "Error not a C++ document" Exit Sub End If
name = DTE.ActiveDocument.Name.ToLower
' Try to switch from '.h' to '.cpp' then vice versa If name.EndsWith(".h") Then name = name.Replace(".h", ".cpp") ElseIf name.EndsWith(".hpp") Then name = name.Replace(".hpp", ".cpp") ElseIf name.EndsWith(".cpp") Then name = name.Replace(".cpp", ".h") ElseIf name.EndsWith(".c") Then name = name.Replace(".c", ".h") Else DTE.StatusBar.Text = "Error " + name + " has an unknown file-extension" Exit Sub End If
DTE.StatusBar.Text = "Searching for " + name + " ..."
' Search open documents Dim iDoc As Integer For iDoc = 1 To DTE.Documents.Count If DTE.Documents.Item(iDoc).Name.ToLower = name Then OpenLocalFile(DTE.Documents.Item(iDoc).FullName) DTE.StatusBar.Text = "Ready" Exit Sub End If Next iDoc
' Search current directory If OpenLocalFile(DTE.ActiveDocument.Path & name) Then DTE.StatusBar.Text = "Ready" Exit Sub End If
' Attempt to find document in solution Dim item As EnvDTE.ProjectItem item = DTE.Solution.FindProjectItem(name) If Not ReferenceEquals(item, Nothing) Then If OpenLocalFile(item.FileNames(0)) Then DTE.StatusBar.Text = "Ready" Exit Sub End If End If
' Attempt to find document in include paths (Requires Microsoft.VisualStudio.VCProjectEngine reference) For Each proj As Project In DTE.Solution.Projects Dim vcProj As VCProject = proj.Object If Not ReferenceEquals(vcProj, Nothing) Then Dim configs As IVCCollection = vcProj.Configurations Dim index As Integer For index = 1 To configs.Count Dim cfg As VCConfiguration = configs.Item(index) Dim tools As IVCCollection = cfg.Tools Dim compilerTool As VCCLCompilerTool = tools.Item("VCCLCompilerTool")
Dim path As String For Each path In compilerTool.FullIncludePath.Split(";") ' if relative path then adjust filepath accordingly If InStr(path, "..") <> 0 Then sFilePath = FilePath(proj.FullName) Do While InStr(path, "..") <> 0 sFilePath = Left(sFilePath, InStrRev(sFilePath, "\") - 1) path = Right(path, Len(path) - InStr(path, "..") - 1) Loop path = sFilePath + path End If
If OpenLocalFile(path + "\" + name) Then DTE.StatusBar.Text = "Ready" Exit Sub End If Next Next End If Next
DTE.StatusBar.Text = "Error File " + name + " could not be found in solution" Beep()
End Sub
End Module
-- modified at 5:45 Thursday 30th November, 2006 (Now using DTE.Solution.FindProjectItem)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Option Strict Off Option Explicit Off
Imports System Imports System.Collections Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics
Public Module Opac
Function OpenLocalFile(ByVal sFile As String) As Boolean On Error Resume Next Dim op As ItemOperations op = DTE.ItemOperations op.OpenFile(sFile, Constants.vsViewKindTextView) OpenLocalFile = (Err.Number = 0) Err.Clear() On Error GoTo 0 End Function
Function WalkProjectItemsAndOpen(ByRef items As ProjectItems, ByRef name As String) As Boolean Dim item As ProjectItem Dim item_name As String
'MsgBox("Looking for " + name + " in project " + items.ContainingProject.UniqueName) If ReferenceEquals(items, Nothing) Then Return False End If
For Each item In items If Not ReferenceEquals(item.ProjectItems, Nothing) Then If item.ProjectItems.Count > 0 Then If WalkProjectItemsAndOpen(item.ProjectItems, name) Then Return True End If End If End If
'MsgBox("Testing for " + name + " matching " + item.Name.ToLower) If name = item.Name.ToLower Then ' MsgBox("Found " + name + " in project " + items.ContainingProject.UniqueName) If Not OpenLocalFile(item.FileNames(0)) Then MsgBox("Cannot open " + item.FileNames(0) + " found in " + items.ContainingProject.UniqueName) End If Return True End If Next
Return False End Function
Sub Swap_H_CPP() Dim proj As Project Dim doc As Document
If ReferenceEquals(DTE.ActiveDocument, Nothing) Then DTE.StatusBar.Text = "Error no active document" Exit Sub End If
Dim name As String
name = DTE.ActiveDocument.Name.ToLower()
Dim cppExts As New ArrayList()
'all ext should be lower string - see above -> name = name.ToLower(), below If name.EndsWith(objLoop) Then cppExts.Add(".cpp") cppExts.Add(".cxx") cppExts.Add(".cc") cppExts.Add(".c")
Dim hppExts As New ArrayList()
'all ext should be lower string - see above -> name = name.ToLower(), below If name.EndsWith(objLoop) Then hppExts.Add(".hpp") hppExts.Add(".hxx") hppExts.Add(".hh") hppExts.Add(".h") hppExts.Add(".inl") 'hppExts.Add(".l") 'hppExts.Add(".h")
' array of array : if exts[0] is ".cpp" then aSubs[0] holds { ".hpp" ".hxx" ".hh" ".h" ".inl" ".cxx" ".cc" ".c" } ' ... ' array of array : if exts[4] is ".hpp" then aSubs[0] holds { ".cpp" ".cxx" ".cc" ".c" ".hxx" ".hh" ".h" ".inl" } ' ... Dim exts As New ArrayList() ' one extension of cppExts And hppExts Dim aSubs As New ArrayList()
Dim objLoop As Object Dim objTemp As Object Dim ALTemp
For Each objLoop In cppExts exts.Add(objLoop) ALTemp = New ArrayList() aSubs.Add(ALTemp) For Each objTemp In hppExts ALTemp.Add(objTemp) Next objTemp For Each objTemp In cppExts If objLoop <> objTemp Then ALTemp.Add(objTemp) End If Next objTemp Next objLoop
For Each objLoop In hppExts exts.Add(objLoop) ALTemp = New ArrayList() aSubs.Add(ALTemp) For Each objTemp In cppExts ALTemp.Add(objTemp) Next objTemp For Each objTemp In hppExts If objLoop <> objTemp Then ALTemp.Add(objTemp) End If Next objTemp Next objLoop
Dim count As Integer
count = 0
Dim nameTemp As String
For Each objLoop In exts If name.EndsWith(objLoop) Then For Each objTemp In aSubs.Item(count) nameTemp = name nameTemp = nameTemp.Replace(objLoop, objTemp)
DTE.StatusBar.Text = "Searching for " + nameTemp + " ..."
'not necessary??? '' Search open documents 'For Each doc In DTE.Documents 'If doc.Name.ToLower = nameTemp Then 'OpenLocalFile(doc.FullName) 'DTE.StatusBar.Text = "Ready" 'Exit Sub 'End If 'Next
' Search current directory If OpenLocalFile(DTE.ActiveDocument.Path & nameTemp) Then DTE.StatusBar.Text = "Ready" Exit Sub End If
'too slow to search... uncomment this block if you want '' Attempt to find document i solution 'Dim item As EnvDTE.ProjectItem 'item = DTE.Solution.FindProjectItem(nameTemp) 'If Not ReferenceEquals(item, Nothing) Then 'If OpenLocalFile(item.FileNames(0)) Then 'DTE.StatusBar.Text = "Ready" 'Exit Sub 'End If 'End If
'too slow to search... uncomment this block if you want 'DTE.StatusBar.Text = "Searching sequential for " + nameTemp + " ..." '' Search all projects in the solution (slow) 'For Each proj In DTE.Solution.Projects 'If WalkProjectItemsAndOpen(proj.ProjectItems, nameTemp) Then 'DTE.StatusBar.Text = "Ready" 'Exit Sub 'End If 'Next
DTE.StatusBar.Text = "Error File " + nameTemp + " could not be found in solution" Next objTemp Exit For End If count = count + 1 Next objLoop
DTE.StatusBar.Text = "Error " + name + " has an unknown file-extension" Beep()
Exit Sub End Sub
End Module
The meaning of life is to give life a meaning.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Hello and special thanks to all contributors to this macro.
Here is my adaptation.
Highlights: The filename match is now done in a case-insensitive way. This saves us the full conversion of both operands to lowercase prior to the comparison. The whole macro now feels snappier.
The way the "swap" was implemented did not completely suit my needs. I documented my changes with an ASCII diagram (I was bored...) so that you can see right away if it makes sense to you or not.
Tested in VS 2005 only.
Antoine
Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics
Public Module Utilities
#Region "ToggleDeclarationAndImplementation" #Region "Helper function: WalkProjectItemsAndOpen" Function WalkProjectItemsAndOpen(ByRef items As ProjectItems, ByRef name As String) As Boolean Dim item As ProjectItem Dim item_name As String
If ReferenceEquals(items, Nothing) Then Return False End If
For Each item In items Dim sub_items As ProjectItems sub_items = item.ProjectItems If Not sub_items Is Nothing Then If WalkProjectItemsAndOpen(sub_items, name) Then Return True End If End If
item_name = item.FileNames(1).ToLower If String.Compare(item_name, name, True) = 0 Then Dim op As ItemOperations op = DTE.ItemOperations op.OpenFile(item.FileNames(1), Constants.vsViewKindTextView) Return True End If Next Return False End Function #End Region
Sub ToggleDeclarationAndImplementation() Dim proj As Project Dim doc As Document Dim name As String Dim ext As String Dim toggledName As String
' Get the active document's name and extension doc = DTE.ActiveDocument name = doc.Path & doc.Name Dim pos = name.LastIndexOf(".") If pos <> -1 Then ext = name.Substring(pos).ToLower() name = name.Substring(0, pos) Else ext = String.Empty End If
' Graph: ' ' ,---<----<----<----<----<---, ,--<----<----<----<----<----<-, ' | ____ ____ | | ____ ____ | ' '--> / \ / \---' '--> / \ / \ | ' | .cpp |---> | .hpp | | .h |----> | .c | --' ' ,--> \____/ \____/---->----> \____/ \____/ ' | | | | ' | '---->---->---->---->---->---' | ' | | ' '---<----<----<----<----<----<----<----<-' ' ' Possible transitions: ' ' .cpp --> .hpp ' .cpp --> .h ' .c --> .h ' .hpp --> .h ' .hpp --> .cpp ' .h --> .c ' .h --> .cpp ' ' For any given file type, there are at most two outgoing transitions. ' We will try each transition until one is found or none can be made. ' ' Note: The order in which we try the transitions is important if we ' want to be able to cycle through the following sequence : cpp-hpp-h-cpp-...
' First possible transition for each of the four supported file types: If ext = ".cpp" Then toggledName = name & ".hpp" ElseIf ext = ".hpp" Then toggledName = name & ".h" ElseIf ext = ".h" Then toggledName = name & ".cpp" ElseIf ext = ".c" Then toggledName = name & ".h" Else ' Unsupported file type Beep() Exit Sub End If
' Try the first possible transition For Each proj In DTE.Solution.Projects If WalkProjectItemsAndOpen(proj.ProjectItems, toggledName) Then Exit Sub End If Next
' Second possible transition for the file types having two transitions If ext = ".cpp" Then toggledName = name & ".h" ElseIf ext = ".hpp" Then toggledName = name & ".cpp" ElseIf ext = ".h" Then toggledName = name & ".cpp" Else Beep() Exit Sub End If
' Try the second possible transition For Each proj In DTE.Solution.Projects If WalkProjectItemsAndOpen(proj.ProjectItems, toggledName) Then Exit Sub End If Next
Beep()
End Sub
#End Region
End Module
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Option Strict Off Option Explicit Off
Imports EnvDTE Imports System.Diagnostics
Public Module Opac
Function WalkProjectItemsAndOpen(ByRef items As ProjectItems, ByRef name As String) As Boolean Dim item As ProjectItem Dim item_name As String
If ReferenceEquals(items, Nothing) Then Return False End If
For Each item In items Dim sub_items As ProjectItems sub_items = item.ProjectItems If Not sub_items Is Nothing Then If WalkProjectItemsAndOpen(sub_items, name) Then Return True End If End If item_name = item.FileNames(1).ToLower If item_name = name Then ' MsgBox("Found " + name + " in project " + items.ContainingProject.UniqueName) Dim op As ItemOperations op = DTE.ItemOperations op.OpenFile(item.FileNames(0), Constants.vsViewKindTextView) Return True End If Next Return False End Function
Sub Swap_H_CPP() Dim proj As Project Dim doc As Document Dim name As String
doc = DTE.ActiveDocument name = doc.Path & doc.Name name = name.ToLower
' First try to switch from '.h' to '.cpp' then vice versa If name.EndsWith(".h") Then name = name.Replace(".h", ".cpp") ElseIf name.EndsWith(".hpp") Then name = name.Replace(".hpp", ".cpp") ElseIf name.EndsWith(".cpp") Then name = name.Replace(".cpp", ".h") ElseIf name.EndsWith(".c") Then name = name.Replace(".c", ".h")
ElseIf name.EndsWith(".h") Then name = name.Replace(".h", ".c") ElseIf name.EndsWith(".hpp") Then name = name.Replace(".hpp", ".c") ElseIf name.EndsWith(".cpp") Then name = name.Replace(".cpp", ".hpp") ElseIf name.EndsWith(".c") Then name = name.Replace(".c", ".hpp") End If
For Each proj In DTE.Solution.Projects If WalkProjectItemsAndOpen(proj.ProjectItems, name) Then Exit Sub End If Next
Beep()
End Sub
End Module
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thank you for the updates. I have switched to VS.NET 2005 and almost exclusively use C# now, so I won't try this new polished version of the macro in the coming months.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
yea, how do you load this in visual studio .net. I know how in 6.0 but not in .net
Does the .vb need to be somewhere? or else how is it loaded in IDE? How about assigning keyboard short cuts? how? not much details to this.
Tools - Customize - Command only displays macros
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Inside i have organised my sources in Sub Folders. The macro then doesn't work. It doesn't check the sub folder names. I've added the Bold stuff following to solve the problem
... sub_items = item.SubProject If Not sub_items Is Nothing Then If WalkProjectItemsAndOpen(sub_items, name) Then Return True End If End If
sub_items = item.ProjectItems If sub_items.Count > 0 Then If WalkProjectItemsAndOpen(sub_items, name) Then Return True End If End If
If item.Name = name Then 'MsgBox("Found " + name + " in project " + items.ContainingProject.UniqueName) ...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
It's amazing that such a simple macro can be so useful  Just a pity that VS.NET macros run so much slower than in VS6 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sorry if this seems to be a stupid question, but what is the correct way to install these macros? I tried just opening the macros IDE and simply pasting the code into the samples project, but then when I try to assign a key it does not appear in the listbox.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sorry if this seems to be a stupid question, but what is the correct way to install these macros? I tried just opening the macros IDE and simply pasting the code into the samples project, but then when I try to assign a key it does no appear in the listbox.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I doesn't able to assign the keyboard shortcut, because the macro doesn't appear in Options/Environment/Keyboard page. I can see only Macros.Samples.* items in the listbox. Anyone can help?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
All of you having problem installing the macro!
Make sure the Module name is the same as specified in the macro above Opac. If you create a new macro it is named as Module1, just rename it to Opac. Also dont forget to compile the project in which u created the module.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Here's a simple fix for files that have a mix of .H, .CPP, .Cpp or any other styles for which Pierre's code won't work off the bat.
Simply change these two lines:
In Swap_H_CPP() change name = doc.Name to name = doc.Name.ToLower
and also in Function WalkProjectItemsAndOpen() change If item.Name = name Then to If item.Name.ToLower = name Then
Now it should work in more cases.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This macro no longer works in VS. NET 2003. It's easy to fix though - replace this line:
sub_items = item.SubProject
with this one:
sub_items = item.ProjectItems
It should work fine now.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
There's also a simple typo:
If Not sub_items Is Nothing Then If WalkProjectItemsAndOpen(sub_itemsm, name) Then "sub_itemsm" should be "sub_items"
After doing this and the above-listed fix, the code works as in the article. It's too bad it's a little slow--it would be faster if it knew to check the project containing the current file first. (I'm not sure if multiple projects might contain the same files--they don't in our company--but it could still fall back to checking the other projects in the solution)
--Todd C. Gleason www.cool-man.org
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
|
Whenever I try to use Swap_H_CPP I get the following error:
QI for IEnumVARIANT failed on the unmanaged server.
Any help would be appreciated.
Thanks, Jason
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
No idea what this message is all about . Perhaps you might want to run the macro step-by-step and locate when exactly this problem happens. I suppose there might be an installation problem of your VS.NET.
Good luck.
Pierre
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|