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

A Visual Studio add-in to move Windows Forms Designer generated code from a .vb file to a .Designer.vb file

Rate me:
Please Sign up or sign in to vote.
4.04/5 (11 votes)
19 Jan 2013CPOL7 min read 47.2K   808   12  
Convert VB.NET 2003 Windows Forms Designer section of Windows Form Public Class files to Partial Class files.
Option Strict On

Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
'Imports EnvDTE90
'Imports EnvDTE100

Imports System.Diagnostics
Public Class ConvertVBFiles
    Implements IDTExtensibility2
    Implements IDTCommandTarget
    Private _applicationObject As DTE2
    Private _addInInstance As AddIn
    '======================================================================================================================================
    '======================================================================================================================================
    '
    ' ConvertVBFiles
    ' 
    ' For use by friendly programmers according to the terms of The Code Project Open License (CPOL) (see http://www.codeproject.com/info/cpol10.aspx)
    '
    '
    ' Originally a Visual Studio Macro found at http://www.nathanpjones.com/wp/2010/02/converting-vb-net-2003-winforms-to-20052008-partial-classes
    ' Heavily modified and simplified
    '
    ' Tested with *.vb Public Class files in Visual Studio 2012
    ' Handles forms inherited from other forms
    ' Handles Sub New, Sub Dispose, Sub Finalize and Sub InitializeComponent
    '
    ' Moves Windows Forms declarations that are located in the source code below Sub New or Sub Dispose and above Sub InitializeComponent.
    '
    ' If no Sub New and no Sub Dispose, then moves declarations that come before InitializeComponent. 
    ' This may cause a problem if the *.vb file contains any programmer created declarations for items that are part of 
    ' System.Windows.Forms namespace before the Windows Forms generated code region. 
    ' PLEASE REVIEW THAT AREA of the *.vb FILE AFTER CONVERTING A FILE.
    '
    ' Anything not moved is left in the original Windows Forms generated code region of the *.vb file. 
    ' PLEASE REVIEW THAT AREA of the *.vb FILE AFTER CONVERTING A FILE.
    '
    ' January, 2013
    ' Mike Meinz
    '======================================================================================================================================
    '
    '
#If False Then
Code Project Open License (CPOL) 
Preamble

This License governs Your use of the Work. This License is intended to allow developers to use the Source Code and Executable Files provided as part of the Work in any application in any form. 

The main points subject to the terms of the License are:
•Source Code and Executable Files can be used in commercial applications;
•Source Code and Executable Files can be redistributed; and
•Source Code can be modified to create derivative works.
•No claim of suitability, guarantee, or any warranty whatsoever is provided. The software is provided "as-is".
•The Article(s) accompanying the Work may not be distributed or republished without the Author's consent

This License is entered between You, the individual or other entity reading or otherwise making use of the Work licensed pursuant to this License and the individual or other entity which offers the Work under the terms of this License ("Author").

License

THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT OPEN LICENSE ("LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HEREIN, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE AUTHOR GRANTS YOU THE RIGHTS CONTAINED HEREIN IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. IF YOU DO NOT AGREE TO ACCEPT AND BE BOUND BY THE TERMS OF THIS LICENSE, YOU CANNOT MAKE ANY USE OF THE WORK.
1.Definitions. a."Articles" means, collectively, all articles written by Author which describes how the Source Code and Executable Files for the Work may be used by a user.
b."Author" means the individual or entity that offers the Work under the terms of this License.
c."Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works.
d."Executable Files" refer to the executables, binary files, configuration and any required data files included in the Work.
e."Publisher" means the provider of the website, magazine, CD-ROM, DVD or other medium from or by which the Work is obtained by You.
f."Source Code" refers to the collection of source code and configuration files used to create the Executable Files.
g."Standard Version" refers to such a Work if it has not been modified, or has been modified in accordance with the consent of the Author, such consent being in the full discretion of the Author. 
h."Work" refers to the collection of files distributed by the Publisher, including the Source Code, Executable Files, binaries, data files, documentation, whitepapers and the Articles. 
i."You" is you, an individual or entity wishing to use the Work and exercise your rights under this License. 

2.Fair Use/Fair Use Rights. Nothing in this License is intended to reduce, limit, or restrict any rights arising from fair use, fair dealing, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. 
3.License Grant. Subject to the terms and conditions of this License, the Author hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: a.You may use the standard version of the Source Code or Executable Files in Your own applications. 
b.You may apply bug fixes, portability fixes and other modifications obtained from the Public Domain or from the Author. A Work modified in such a way shall still be considered the standard version and will be subject to this License.
c.You may otherwise modify Your copy of this Work (excluding the Articles) in any way to create a Derivative Work, provided that You insert a prominent notice in each changed file stating how, when and where You changed that file.
d.You may distribute the standard version of the Executable Files and Source Code or Derivative Work in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution. 
e.The Articles discussing the Work published in any form by the author may not be distributed or republished without the Author's consent. The author retains copyright to any such Articles. You may use the Executable Files and Source Code pursuant to this License but you may not repost or republish or otherwise distribute or make available the Articles, without the prior written consent of the Author.
Any subroutines or modules supplied by You and linked into the Source Code or Executable Files of this Work shall not be considered part of this Work and will not be subject to the terms of this License. 
4.Patent License. Subject to the terms and conditions of this License, each Author hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, import, and otherwise transfer the Work.
5.Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: a.You agree not to remove any of the original copyright, patent, trademark, and attribution notices and associated disclaimers that may appear in the Source Code or Executable Files. 
b.You agree not to advertise or in any way imply that this Work is a product of Your own. 
c.The name of the Author may not be used to endorse or promote products derived from the Work without the prior written consent of the Author.
d.You agree not to sell, lease, or rent any part of the Work. This does not restrict you from including the Work or any part of the Work inside a larger software distribution that itself is being sold. The Work by itself, though, cannot be sold, leased or rented.
e.You may distribute the Executable Files and Source Code only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy of the Executable Files or Source Code You distribute and ensure that anyone receiving such Executable Files and Source Code agrees that the terms of this License apply to such Executable Files and/or Source Code. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute the Executable Files or Source Code with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License. 
f.You agree not to use the Work for illegal, immoral or improper purposes, or on pages containing illegal, immoral or improper material. The Work is subject to applicable export laws. You agree to comply with all such laws and regulations that may apply to the Work after Your receipt of the Work. 

6.Representations, Warranties and Disclaimer. THIS WORK IS PROVIDED "AS IS", "WHERE IS" AND "AS AVAILABLE", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OR CONDITIONS OR GUARANTEES. YOU, THE USER, ASSUME ALL RISK IN ITS USE, INCLUDING COPYRIGHT INFRINGEMENT, PATENT INFRINGEMENT, SUITABILITY, ETC. AUTHOR EXPRESSLY DISCLAIMS ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS, INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT, OR THAT THE WORK (OR ANY PORTION THEREOF) IS CORRECT, USEFUL, BUG-FREE OR FREE OF VIRUSES. YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE WORK OR DERIVATIVE WORKS. 
7.Indemnity. You agree to defend, indemnify and hold harmless the Author and the Publisher from and against any claims, suits, losses, damages, liabilities, costs, and expenses (including reasonable legal or attorneys’ fees) resulting from or relating to any use of the Work by You. 
8.Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL THE AUTHOR OR THE PUBLISHER BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK OR OTHERWISE, EVEN IF THE AUTHOR OR THE PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
9.Termination. a.This License and the rights granted hereunder will terminate automatically upon any breach by You of any term of this License. Individuals or entities who have received Derivative Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 6, 7, 8, 9, 10 and 11 will survive any termination of this License. 
b.If You bring a copyright, trademark, patent or any other infringement claim against any contributor over infringements You claim are made by the Work, your License from such contributor to the Work ends automatically.
c.Subject to the above terms and conditions, this License is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, the Author reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 

10.Publisher. The parties hereby confirm that the Publisher shall not, under any circumstances, be responsible for and shall not have any liability in respect of the subject matter of this License. The Publisher makes no warranty whatsoever in connection with the Work and shall not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. The Publisher reserves the right to cease making the Work available to You at any time without notice
11.Miscellaneous a.This License shall be governed by the laws of the location of the head office of the Author or if the Author is an individual, the laws of location of the principal place of residence of the Author.
b.If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this License, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 
c.No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. 
d.This License constitutes the entire agreement between the parties with respect to the Work licensed herein. There are no understandings, agreements or representations with respect to the Work not specified herein. The Author shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Author and You. 

#End If
    '======================================================================================================================================
    '
    '
    '
    '
    '
    'Original comments below
    '======================================================================================================================================
    ' ————————————————————————-
    ' Extract WinForms Designer File Visual Studio 2005/2008 Macro
    ' ————————————————————————-
    ' Extracts the InitializeComponent() and Dispose() methods and control
    ' field declarations from a .NET 1.x VS 2003 project into a VS 2005/8
    ' style .NET 2.0 partial class in a *.Designer.cs file.
    '
    ' To use:
    ' * Copy the methods below into a Visual Studio Macro Module (use ALT+F11 to show the Macro editor)
    ' * Select a Windows Form in the Solution Explorer
    ' * Run the macro by showing the Macro Explorer (ALT+F8) and double-clicking the ‘ExtractWinFormsDesignerFile’ macro.
    '
    ' Duncan Smart, InfoBasis, 2007
    ' Adam Best, 2009
    ' Jeff Shelby, 2010
    ' ————————————————————————-
    '======================================================================================================================================
    '
    '
    ' 
    ' When true processes all forms in the selected Project. 
    ' When false, processes only the selected form
#Const CONVERT_ALL_FILES_IN_SELECTED_PROJECT = True
    '
    '
    '
    '
    Private intOffset_Dispose As Integer = 0
    Private intOffset_New As Integer = 0
    Private intOffset_InitializeComponent As Integer = 0
    Private Const MSGBOXTITLE As String = "Convert VB 'Windows Form Designer generated code' Region"
    Private intItemsConvertedCount As Integer = 0
    Private strPartialClassInheritsClause As String = ""

    Public Sub ExtractWinFormsDesignerFile()
        Dim objItem As ProjectItem
        Dim strFullFileName As String
        Dim strFileName As String
        Dim strEndingMessage As String = ""

#If CONVERT_ALL_FILES_IN_SELECTED_PROJECT Then
        Dim objProject As EnvDTE.Project
        Try
            objProject = _applicationObject.SelectedItems.Item(1).Project
        Catch
            MsgBox("Select a project", MsgBoxStyle.Exclamation, MSGBOXTITLE)
            Exit Sub
        End Try
        If IsNothing(objProject) OrElse IsNothing(objProject.ProjectItems) OrElse objProject.ProjectItems.Count = 0 Then
            MsgBox("Select a project", MsgBoxStyle.Exclamation, MSGBOXTITLE)
            Exit Sub
        Else
            For x As Integer = 1 To objProject.ProjectItems.Count
                If System.IO.Path.GetExtension(objProject.ProjectItems.Item(x).Name).ToLower = ".vb" Then
                    objItem = objProject.ProjectItems.Item(x)
                    strFullFileName = objItem.FileNames(1)
#Else
       Try
            objItem = _applicationObject.SelectedItems.Item(1).ProjectItem
            strFullFileName = objItem.FileNames(1)
        Catch
            MsgBox("Selected item is not a *.vb file", MsgBoxStyle.Exclamation, MSGBOXTITLE)
            Exit Sub
        End Try
        If System.IO.Path.GetExtension(strFullFileName).ToLower <> ".vb" Then
             MsgBox("Selected item is not a *.vb file", MsgBoxStyle.Exclamation, MSGBOXTITLE)
             Exit Sub
        End If
#End If

                    Dim strDirectory As String = System.IO.Path.GetDirectoryName(strFullFileName)
                    Dim strItemName As String = System.IO.Path.GetFileNameWithoutExtension(strFullFileName)
                    Dim strNewItemFullPathName As String = System.IO.Path.Combine(strDirectory, strItemName & ".Designer.vb")
                    strFileName = System.IO.Path.GetFileName(strFullFileName)
                    'If the designer file already exists, don’t create another one.
                    For Each objChildItem As ProjectItem In objItem.ProjectItems
                        If (objChildItem.FileNames(1) = strNewItemFullPathName) Then
#If CONVERT_ALL_FILES_IN_SELECTED_PROJECT Then
                            strEndingMessage += strFileName & " skipped: Form already has a Designer file." & vbNewLine
                            Continue For
#Else
                            MsgBox("This form already has a Designer file. It will not be converted.", MsgBoxStyle.Exclamation, MSGBOXTITLE)
                            Exit Sub
#End If
                        End If
                    Next

                    intItemsConvertedCount = 0
                    intOffset_Dispose = 0
                    intOffset_New = 0
                    intOffset_InitializeComponent = 0

                    Dim objCodeClass As CodeClass = LocateCodeClass(objItem.FileCodeModel.CodeElements)
                    'If we didn’t find a non-partial code class, there’s nothing to do.
                    If IsNothing(objCodeClass) Then
#If CONVERT_ALL_FILES_IN_SELECTED_PROJECT Then
                        strEndingMessage += strFileName & " skipped: Not a Public Class with the Inherits clause" & vbNewLine
                        Continue For
#Else
                        MsgBox("The item selected is not a Public Class with the Inherits clause", _
                            MsgBoxStyle.Exclamation, MSGBOXTITLE)
                        Exit Sub
#End If
                    End If

                    '
                    ' To hold contents of SUBs found in the Windows Forms generated code area
                    '
                    Dim strSUB_New As String
                    Dim strSUB_InitializeComponent As String
                    Dim strSUB_Dispose As String
                    Dim strSUB_Finalize As String

                    Try
                        strSUB_InitializeComponent = extractMember(objCodeClass.Members.Item("InitializeComponent"), intOffset_InitializeComponent)
                    Catch
                        strSUB_InitializeComponent = ""
                        intOffset_InitializeComponent = 0
                    End Try
                    ' InitializeComponent must be present to proceed
                    If intOffset_InitializeComponent = 0 Then
#If CONVERT_ALL_FILES_IN_SELECTED_PROJECT Then
                        strEndingMessage += strFileName & " skipped: Does not have a 'Sub InitializeComponent'" & vbNewLine
                        Continue For
#Else
                        MsgBox("The item selected does not have a 'Sub InitializeComponent'. Because of that, it probably does not contain Windows Form Designer generated code.", MsgBoxStyle.Exclamation, MSGBOXTITLE)
                        Exit Sub
#End If
                    End If

                    Try
                        strSUB_New = extractMember(objCodeClass.Members.Item("New"), intOffset_New)
                    Catch
                        ' If there is no Sub New, 0 is used as the stored offset value so that extractWinFormsFields will work correctly
                        strSUB_New = ""
                        intOffset_New = 0
                    End Try

                    Try
                        strSUB_Dispose = extractMember(objCodeClass.Members.Item("Dispose"), intOffset_Dispose)
                    Catch
                        ' If there is no Sub Dispose, 0 is used as the stored offset value so that extractWinFormsFields will work correctly
                        strSUB_Dispose = ""
                        intOffset_InitializeComponent = 0
                    End Try

                    Try
                        strSUB_Finalize = extractMember(objCodeClass.Members.Item("Finalize"))
                    Catch
                        strSUB_Finalize = ""
                    End Try

                    Dim strFormsDeclarations As String = extractWinFormsFields(objCodeClass)
                    Dim PartialClassFileContents As New System.Text.StringBuilder

                    With PartialClassFileContents
                        '
                        ' Build the *.Designer.vb file
                        '   using text extracted (and removed) from the *.vb file
                        '

                        If (Not IsNothing(objCodeClass.Namespace)) Then
                            .Append("Namespace " & objCodeClass.Namespace.FullName())
                        End If

                        .Append("<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _" & vbCrLf)
                        .Append(strPartialClassInheritsClause & vbCrLf & vbCrLf)


                        If strSUB_New.Length > 0 Then
                            ' If it is present, include 'Sub New' because it might contain some custom initialization code
                            .Append(strSUB_New & vbCrLf & vbCrLf)
                        End If

                        If strSUB_Dispose.Length > 0 Then
                            .Append("<System.Diagnostics.DebuggerNonUserCode()> _" & vbCrLf)
                            .Append(strSUB_Dispose & vbCrLf & vbCrLf)
                        End If

                        .Append("'NOTE: The following procedure is required by the Windows Form Designer" & vbCrLf)
                        .Append("'It can be modified using the Windows Form Designer." & vbCrLf)
                        .Append("'Do not modify it using the code editor." & vbCrLf & vbCrLf)
                        .Append(strFormsDeclarations & vbCrLf & vbCrLf)

                        If strSUB_InitializeComponent.Length > 0 Then ' Should always be > 0
                            .Append(strSUB_InitializeComponent & vbCrLf & vbCrLf)
                        End If

                        If strSUB_Finalize.Length > 0 Then ' Sometimes there is no Sub Finalize
                            .Append(strSUB_Finalize & vbCrLf & vbCrLf)
                        End If

                        .Append("End Class" & vbCrLf)

                        If (Not IsNothing(objCodeClass.Namespace)) Then
                            .Append("End Namespace")
                        End If

                    End With

                    System.IO.File.WriteAllText(strNewItemFullPathName, PartialClassFileContents.ToString)
                    Dim objNewProjectItem As ProjectItem = objItem.ProjectItems.AddFromFile(strNewItemFullPathName)
                    ' Open the new Partial Class file
                    objNewProjectItem.Open(Constants.vsViewKindCode)
                    objNewProjectItem.Document.Activate()
                    ' Reformat the new Partial Class file
                    _applicationObject.ExecuteCommand("Edit.FormatDocument") ' Reformat

#If CONVERT_ALL_FILES_IN_SELECTED_PROJECT Then
                    strEndingMessage += strFileName & " converted: " & intItemsConvertedCount.ToString & " declarations moved into the new file " & vbNewLine
                End If
            Next
        End If
#Else
        strendingmessage=intItemsConvertedCount.ToString & " declarations moved into the new file " & System.IO.Path.GetFileName(strNewItemFullPathName)
#End If
        MsgBox(strEndingMessage, MsgBoxStyle.Information, MSGBOXTITLE)
    End Sub

    Private Function LocateCodeClass(ByVal items As System.Collections.IEnumerable) As CodeClass
        For Each codeEl As CodeElement In items
            If (codeEl.Kind = vsCMElement.vsCMElementClass) Then
                Dim objStartPoint As EditPoint = codeEl.GetStartPoint().CreateEditPoint()
                Dim objEndPoint As TextPoint = codeEl.GetStartPoint(vsCMPart.vsCMPartBody)
                Dim strText As String = objStartPoint.GetText(objEndPoint)
                Dim strTextLC As String = strText.ToLower ' Same as text but all in lower case
                '
                ' Alert if it is already a Partial Class file
                '
                If strTextLC.Contains("partial class") Then
                    Return Nothing
                End If
                '
                ' Ensure that this is the correct type of project item file
                '
                If strTextLC.Contains("public class") AndAlso _
                    strTextLC.Contains("inherits") Then
                    '
                    ' Prepare Partial Class statement for the new file
                    '
                    strPartialClassInheritsClause = strText.ToLower.Replace("public class", "Partial Class")
                    Return DirectCast(codeEl, CodeClass)
                Else
                    Return Nothing
                End If
            ElseIf (codeEl.Children.Count > 0) Then
                Dim cls As CodeClass = LocateCodeClass(codeEl.Children)
                If Not IsNothing(cls) Then
                    Return cls
                End If
            End If
        Next
        Return Nothing
    End Function

    Private Function extractWinFormsFields(ByVal codeClass As CodeClass) As String
        Dim strWindowsFormsControlsDeclarations As New System.Text.StringBuilder
        Dim intWindowsFormsControlsCount As Integer = codeClass.Members.Count
        For iMember As Integer = intWindowsFormsControlsCount To 1 Step -1 ' In reverse because the items start to disappear from the collection
            Dim member As CodeElement = codeClass.Members.Item(iMember)
            Debug.WriteLine("member=" & member.FullName & " (" & member.Kind.ToString & ")")
            If (member.Kind = vsCMElement.vsCMElementVariable) Then
                Dim objDeclaration As CodeVariable = DirectCast(member, CodeVariable)
                Dim objFieldType As CodeType = objDeclaration.Type.CodeType
                If Not IsNothing(objFieldType) Then
                    If Not IsNothing(objFieldType.Namespace) Then
                        Dim isControl As Boolean = (objFieldType.Namespace.FullName.StartsWith("System.Windows.Forms") OrElse objFieldType.Namespace.FullName.StartsWith("System.Drawing.Printing")) AndAlso _
                            CBool(objDeclaration.Access And (vsCMAccess.vsCMAccessWithEvents + vsCMAccess.vsCMAccessProject))
                        Dim intOffset As Integer = objDeclaration.StartPoint.AbsoluteCharOffset ' Character offset of this variable's declaration
                        Debug.WriteLine("Namespace=" & objFieldType.Namespace.FullName)
                        '--------------------------------------------------------------------------------------------------------------------------
                        '
                        ' Declarations that are in the System.Windows.Forms Namespace or System.ComponentModel.IContainer
                        '
                        If isControl OrElse objFieldType.IsDerivedFrom("System.ComponentModel.IContainer") Then
                            '
                            ' A declarations that occur in the source code above "Sub InitializeComponent" and below "Sub New" and "Sub Dispose" are moved
                            '
                            ' Note: (intOffset_Dispose < intOffset OrElse intOffset_New < intOffset) clause handles the case where a SUB Dispose or a
                            '       SUB New may be missing from the *.vb file.
                            '       It is assumed that there will always be a SUB InitializeComponent 
                            '
                            If intOffset_InitializeComponent > intOffset AndAlso (intOffset_Dispose < intOffset OrElse intOffset_New < intOffset) Then
                                Debug.WriteLine("Added " & objFieldType.Namespace.FullName)
                                strWindowsFormsControlsDeclarations.AppendLine(extractMember(member))
                                intItemsConvertedCount += 1
                            End If
                        End If
                    End If
                End If
            End If
        Next
        Return strWindowsFormsControlsDeclarations.ToString()
    End Function

    Private Function extractMember(ByVal memberElement As CodeElement, ByRef intStartPointofThisCodeElement As Integer) As String
        If IsNothing(memberElement) Then
            intStartPointofThisCodeElement = 0
            Return ""
        End If
        intStartPointofThisCodeElement = memberElement.GetStartPoint.AbsoluteCharOffset
        Dim memberStart As EditPoint = memberElement.GetStartPoint().CreateEditPoint()
        Dim memberText As String = memberStart.GetText(memberElement.GetEndPoint())
        memberStart.Delete(memberElement.GetEndPoint())
        Debug.WriteLine("MemberText=" & memberText)
        Return memberText
    End Function

    Private Function extractMember(ByVal memberElement As CodeElement) As String
        If IsNothing(memberElement) Then
            Return ""
        End If
        Dim memberStart As EditPoint = memberElement.GetStartPoint().CreateEditPoint()
        Dim memberText As String = memberStart.GetText(memberElement.GetEndPoint())
        memberStart.Delete(memberElement.GetEndPoint())
        Debug.WriteLine("MemberText=" & memberText)
        Return memberText
    End Function




    '''<summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
    Public Sub New()

    End Sub

    '''<summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary>
    '''<param name='application'>Root object of the host application.</param>
    '''<param name='connectMode'>Describes how the Add-in is being loaded.</param>
    '''<param name='addInInst'>Object representing this Add-in.</param>
    '''<remarks></remarks>
    Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection
        Debug.WriteLine("OnConnection Begin")
        _applicationObject = CType(application, DTE2)
        _addInInstance = CType(addInInst, AddIn)
        '
        ' 1/14/2013:
        ' In the following line, I added "OrElse connectMode = ext_ConnectMode.ext_cm_AfterStartup" because the 
        ' menu item was not always appearing. This change corrected that.
        '
        '
        If connectMode = ext_ConnectMode.ext_cm_UISetup OrElse connectMode = ext_ConnectMode.ext_cm_AfterStartup Then
            Debug.WriteLine("OnConnection UISetup OR ext_cm_AfterStartup")

            Dim commands As Commands2 = CType(_applicationObject.Commands, Commands2)
            Dim toolsMenuName As String = "Tools"

            'Place the command on the tools menu.
            'Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
            Dim commandBars As CommandBars = CType(_applicationObject.CommandBars, CommandBars)
            Dim menuBarCommandBar As CommandBar = commandBars.Item("MenuBar")

            'Find the Tools command bar on the MenuBar command bar:
            Dim toolsControl As CommandBarControl = menuBarCommandBar.Controls.Item(toolsMenuName)
            Dim toolsPopup As CommandBarPopup = CType(toolsControl, CommandBarPopup)

            Try
                'Add a command to the Commands collection:
                Dim command As Command = commands.AddNamedCommand2(_addInInstance, "ConvertVBFiles", "Convert to Designer Partial Class", "Convert .vb files to Partial Class Designer files", True, 59, Nothing, CType(vsCommandStatus.vsCommandStatusSupported, Integer) + CType(vsCommandStatus.vsCommandStatusEnabled, Integer), vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton)

                'Find the appropriate command bar on the MenuBar command bar:
                command.AddControl(toolsPopup.CommandBar, 1)
            Catch argumentException As System.ArgumentException
                'If we are here, then the exception is probably because a command with that name
                '  already exists. If so there is no need to recreate the command and we can 
                '  safely ignore the exception.
                Debug.WriteLine("OnConnection Error: " & argumentException.Message)
            End Try

        End If
        Debug.WriteLine("OnConnection End")
    End Sub

    '''<summary>Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being unloaded.</summary>
    '''<param name='disconnectMode'>Describes how the Add-in is being unloaded.</param>
    '''<param name='custom'>Array of parameters that are host application specific.</param>
    '''<remarks></remarks>
    Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) Implements IDTExtensibility2.OnDisconnection
        Debug.WriteLine("OnDisconnect")
    End Sub

    '''<summary>Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification that the collection of Add-ins has changed.</summary>
    '''<param name='custom'>Array of parameters that are host application specific.</param>
    '''<remarks></remarks>
    Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
        Debug.WriteLine("OnAddInsUpdate")
    End Sub

    '''<summary>Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the host application has completed loading.</summary>
    '''<param name='custom'>Array of parameters that are host application specific.</param>
    '''<remarks></remarks>
    Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
        Debug.WriteLine("OnStartupComplete")
    End Sub

    '''<summary>Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host application is being unloaded.</summary>
    '''<param name='custom'>Array of parameters that are host application specific.</param>
    '''<remarks></remarks>
    Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
        Debug.WriteLine("OnBeginShutdown")
    End Sub

    '''<summary>Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's availability is updated</summary>
    '''<param name='commandName'>The name of the command to determine state for.</param>
    '''<param name='neededText'>Text that is needed for the command.</param>
    '''<param name='status'>The state of the command in the user interface.</param>
    '''<param name='commandText'>Text requested by the neededText parameter.</param>
    '''<remarks></remarks>
    Public Sub QueryStatus(ByVal commandName As String, ByVal neededText As vsCommandStatusTextWanted, ByRef status As vsCommandStatus, ByRef commandText As Object) Implements IDTCommandTarget.QueryStatus
        Debug.WriteLine("QueryStatus " & commandName)
        If neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then
            If commandName = "ConvertVBFiles.ConvertVBFiles.ConvertVBFiles" Then
                status = CType(vsCommandStatus.vsCommandStatusEnabled + vsCommandStatus.vsCommandStatusSupported, vsCommandStatus)
            Else
                status = vsCommandStatus.vsCommandStatusUnsupported
            End If
        End If
    End Sub

    '''<summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
    '''<param name='commandName'>The name of the command to execute.</param>
    '''<param name='executeOption'>Describes how the command should be run.</param>
    '''<param name='varIn'>Parameters passed from the caller to the command handler.</param>
    '''<param name='varOut'>Parameters passed from the command handler to the caller.</param>
    '''<param name='handled'>Informs the caller if the command was handled or not.</param>
    '''<remarks></remarks>
    Public Sub Exec(ByVal commandName As String, ByVal executeOption As vsCommandExecOption, ByRef varIn As Object, ByRef varOut As Object, ByRef handled As Boolean) Implements IDTCommandTarget.Exec
        Debug.WriteLine("Exec Begin")
        handled = False
        If executeOption = vsCommandExecOption.vsCommandExecOptionDoDefault Then
            Debug.WriteLine("Command: " & commandName)
            If commandName = "ConvertVBFiles.ConvertVBFiles.ConvertVBFiles" Then
                Debug.WriteLine("Call ExtractWinFormsDesignerFile")
                Call ExtractWinFormsDesignerFile()
                handled = True
                Debug.WriteLine("Exec End (handled=true)")
                Exit Sub
            End If
        End If
        Debug.WriteLine("Exec End")
    End Sub


End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Retired
United States United States
I’m retired. When I started my career, programming projects consisted of plugging wires into plug boards to create punch card processing applications to be run on electrical accounting machine like the IBM 402, 407, 085, 088, 514, 519, etc. From there, I moved to writing SPS and Autocoder applications on an IBM 1401 with 4K of memory eventually upgraded to 16K of memory. After many years of migrating my skills to various languages on various hardware platforms, I became an Information Technology Director where I didn’t need to program anymore. So, starting in 1996, I volunteered my time with a local community cable television organization and built some applications to help them run their operations. Originally in Clipper Summer 1987 and later Clipper 5.2, I migrated and enhanced those applications to VB .NET 2003 in 2003. I retired from my full-time job in 2010. Since then, I have continued to support the local community cable tv organization's applications. In 2013, I migrated the VB .NET 2003 Solution to VB .NET 2012 so that it can run on 64-bit computers and interact with Microsoft Office 2010. The upgrade went smoothly. In mid 2013, I developed a VB .NET 2012 application for them to download election results data from the Secretary of State's web site, format the results and send them to a VizRT character generator for on-air display.

Comments and Discussions