locked
DTE.ExecuteCommand("EditorContextMenus.CodeWindow.GoToHeaderFile") failed RRS feed

  • Question

  • Visual Studio 2010 with SP1, when running a macro

    DTE.ExecuteCommand("EditorContextMenus.CodeWindow.GoToHeaderFile")

    error msg pop: "Error HRESULT E_FAIL has been returned from a call to a COM component"

    I am sure that the current active doc is a cpp file.

    and, If I paste the "EditorContextMenus.CodeWindow.GoToHeaderFile" in the Command Window, it worked.

    Why it failed in macro ?

    Thanks!

    the macro script

    Imports System
    Imports EnvDTE
    Imports System.Diagnostics
    
    Public Module swaphcpp
    
        Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane
            Dim window As Window
            Dim outputWindow As OutputWindow
            Dim outputWindowPane As OutputWindowPane
    
            window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
            If show Then window.Visible = True
            outputWindow = window.Object
            Try
                outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)
            Catch e As System.Exception
                outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)
            End Try
            outputWindowPane.Activate()
            Return outputWindowPane
        End Function
    
        Sub SwapHeaderSource()
            Dim proj As Project
            Dim doc As Document
            Dim name As String
            Dim window As Window
            Dim target As Object = Nothing
            Dim item As ProjectItem
    
            doc = DTE.ActiveDocument
    
            If doc Is Nothing Then
                Exit Sub
            End If
    
    
            If (DTE.ActiveWindow Is window) Then
                target = window.Object
            Else
                target = GetOutputWindowPane("List Project")
                target.Clear()
            End If
    
            name = doc.Name
            name = LCase(name)
    
            If name.EndsWith(".h") Then
                name = name.Replace(".h", ".cpp")
            ElseIf name.EndsWith(".cpp") Or name.EndsWith(".c") Then
                MsgBox("11111")
                DTE.ExecuteCommand("EditorContextMenus.CodeWindow.GoToHeaderFile")
            End If
        End Sub
    
    End Module
    
    

    Saturday, January 3, 2015 1:50 AM

Answers

  • Hi chenzero,

    The problem is that you set the focus to the output window, when the output window is activated, this command won't work. Try to comment out this code, you'll find that it works fine:

    'If (DTE.ActiveWindow Is window) Then
            '    target = window.Object
            'Else
            '    target = GetOutputWindowPane("List Project")
            '    target.Clear()
            'End If

    If you want to run this code snippet anyway, you can set the focus back to the cpp document window later.

    If (DTE.ActiveWindow Is window) Then
                target = window.Object
            Else
                target = GetOutputWindowPane("List Project")
                target.Clear()
            End If
    
            name = doc.Name
            name = LCase(name)
    
            doc.Activate()
    
            If name.EndsWith(".h") Then
                name = name.Replace(".h", ".cpp")
            ElseIf name.EndsWith(".cpp") Or name.EndsWith(".c") Then
                MsgBox("11111")
                DTE.ExecuteCommand("EditorContextMenus.CodeWindow.GoToHeaderFile")
            End If


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by chenzero Monday, January 5, 2015 2:55 PM
    Monday, January 5, 2015 8:03 AM

All replies

  • Hi chenzero,

    The problem is that you set the focus to the output window, when the output window is activated, this command won't work. Try to comment out this code, you'll find that it works fine:

    'If (DTE.ActiveWindow Is window) Then
            '    target = window.Object
            'Else
            '    target = GetOutputWindowPane("List Project")
            '    target.Clear()
            'End If

    If you want to run this code snippet anyway, you can set the focus back to the cpp document window later.

    If (DTE.ActiveWindow Is window) Then
                target = window.Object
            Else
                target = GetOutputWindowPane("List Project")
                target.Clear()
            End If
    
            name = doc.Name
            name = LCase(name)
    
            doc.Activate()
    
            If name.EndsWith(".h") Then
                name = name.Replace(".h", ".cpp")
            ElseIf name.EndsWith(".cpp") Or name.EndsWith(".c") Then
                MsgBox("11111")
                DTE.ExecuteCommand("EditorContextMenus.CodeWindow.GoToHeaderFile")
            End If


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Marked as answer by chenzero Monday, January 5, 2015 2:55 PM
    Monday, January 5, 2015 8:03 AM
  • Hi Cailen,

    It's really not easy to find the reason and Thank you very much !

    following is a macro to toggle header to cpp  file, hope it useful :)

    Imports System
    Imports EnvDTE
    Imports System.Diagnostics
    
    ' a macro to toggle header and cpp file for Visual Studio S2010
    Public Module swaphcpp3
        'a fixed size stack, recursively access project item is very slow
        Class Stack
            Const SIZE As Integer = 100
            Dim data(SIZE)
            Dim count As Integer = 0
    
            Sub push(ByVal a As Object)
                If (count + 1 > SIZE) Then
                    Err.Raise(1, Nothing, "stack full")
                End If
                data(count) = a
    
                count = count + 1
            End Sub
    
            Function isEmpty() As Boolean
                If (count = 0) Then
                    isEmpty = True
                Else
                    isEmpty = False
                End If
            End Function
    
            Function top() As Object
                If (isEmpty()) Then
                    Err.Raise(1, Nothing, "empty stack")
                End If
                top = data(count - 1)
            End Function
    
            Sub pop()
                If (isEmpty()) Then
                    Err.Raise(1, Nothing, "pop empty stack")
                End If
                count = count - 1
            End Sub
    
            Function toString() As String
                Dim ret = ""
                Dim i As Integer
                For i = 0 To count - 1
                    ret = ret & data(i) & " "
                Next
                toString = ret
            End Function
    
            Sub clear()
                count = 0
            End Sub
        End Class
    
        'recursively list project item
        Function ListProjAux0(ByVal projectItems As EnvDTE.ProjectItems, ByVal name As String, ByVal outputWinPane As Object) As Boolean
            Dim projectItem As EnvDTE.ProjectItem
    
            For Each projectItem In projectItems
                '' Ignore item if it is not rooted in this collection (check for VC project model).
                If projectItem.Collection Is projectItems Then
                    Dim projectItems2 As EnvDTE.ProjectItems
                    Dim notSubCollection As Boolean
    
                    If (OutputItem(projectItem, name, outputWinPane)) Then
                        ListProjAux0 = True
                        Exit Function
                    End If
                    '' Recurse if this item has subitems ...
                    projectItems2 = projectItem.ProjectItems
                    notSubCollection = projectItems2 Is Nothing
                    If Not notSubCollection Then
                        ListProjAux0(projectItems2, name, outputWinPane)
                    End If
                End If
            Next
            ListProjAux0 = False
        End Function
    
        Dim stk As Stack = New Stack()
    
        ' non-recursively list project item
        Function ListProjAux(ByVal projectItems As EnvDTE.ProjectItems, ByVal name As String, ByVal outputWinPane As Object) As Boolean
            Dim projectItem As EnvDTE.ProjectItem
            stk.clear()
            stk.push(projectItems)
    
            Dim items As ProjectItems
            Dim items2 As ProjectItems
    
            While (Not stk.isEmpty())
                items = stk.top
                stk.pop()
    
                For Each projectItem In items
                    items2 = projectItem.ProjectItems
    
                    If (items2 Is Nothing) Then
    
                        If (OutputItem(projectItem, name, outputWinPane)) Then
                            ListProjAux = True
                            Exit Function
                        End If
                    Else
                        If (items2.Count > 0) Then
                            stk.push(items2)
                        Else
                            If (OutputItem(projectItem, name, outputWinPane)) Then
                                ListProjAux = True
                                Exit Function
                            End If
    
                        End If
                    End If
                Next
            End While
    
            ListProjAux = False
        End Function
    
        Function OutputItem(ByVal projectItem As EnvDTE.ProjectItem, ByVal name As String, ByVal outputWinPane As Object) As Boolean
            Dim i As Integer = 0
    
            If LCase(projectItem.Name) = name Then
                Dim op As ItemOperations
                op = DTE.ItemOperations
                op.OpenFile(projectItem.FileNames(1), Constants.vsViewKindTextView)
    
                OutputItem = True
            Else
                OutputItem = False
            End If
        End Function
    
        Sub SwapHeaderSource()
            Dim proj As Project
            Dim doc As Document
            Dim name As String
            Dim window As Window
            Dim target As Object = Nothing
            Dim item As ProjectItem
    
            doc = DTE.ActiveDocument
    
            If doc Is Nothing Then
                Exit Sub
            End If
    
            Dim cmd As Command
    
            name = doc.Name
            name = LCase(name)
            Dim op = 0
    
            ' please refer: https://social.msdn.microsoft.com/Forums/vstudio/en-US/bf07f5b4-6517-4e73-aba5-1efabd2189e0/dteexecutecommandeditorcontextmenuscodewindowgotoheaderfile-failed?forum=vsx
            doc.Activate()
    
            If name.EndsWith(".h") Then
                name = name.Replace(".h", ".cpp")
                op = 1
            ElseIf name.EndsWith(".hpp") Then
                name = name.Replace(".hpp", ".cpp")
                op = 1
            ElseIf name.EndsWith(".cpp") Or name.EndsWith(".c") Then
                DTE.ExecuteCommand("EditorContextMenus.CodeWindow.GoToHeaderFile")
            End If
    
            Dim ret
            Dim s = Timer()
            If (op = 1) Then
                For Each proj In DTE.Solution.Projects
                    ret = ListProjAux(proj.ProjectItems(), name, target)
                    If (ret) Then
                        Dim e = Timer()
                        'MsgBox("t:" & (e - s))
                        Exit Sub
                    End If
                Next
            End If
            Dim e2 = Timer()
            'MsgBox("t2:" & (e2 - s))
        End Sub
    
    End Module
    

    Monday, January 5, 2015 10:45 AM