|
|
Using ActiveSolutionProjects and ProjectItem.FileCodeModel to determine if a Window is a Designer or CodeWindow. | | How do I determine if the Active Code Window is associated with a WinForm or just simply a class without examining the code or using the CodeModel in an add-in? This is not rocket science, and may seem like a kludge, but it works. Make the following call to the method shown in Figure 1.
If IsProjectItemAForm(s) Then
' code window is code behind a form
Else
' code is not a forms code
End If
|
There are several ways to determine the type of window that is currently active and the type language that was used to create that window. The following code will return True if the passed Window Caption is code behind a WinForm. The following code is the easiest way to determine whether the ActiveWindow is a Form Designer or a CodeWindow, if in fact, the ActiveWindow is either. In all of the code examples, oVB is the application object pointing to the IDE. If you use the code in a macro instead of an add-in, change oVB to DTE.
''' <summary>
''' Returns True if IDE ActiveWindow is a Form Designer
'''
''' <returns>Boolean
Public Function IsProjectItemAForm() As Boolean
Dim oWin As Window = Connect.oVB.ActiveWindow
Return TypeOf oWin.Object Is System.ComponentModel.Design.IDesignerHost
If TypeOf oWin.Object Is System.ComponentModel.Design.IDesignerHost Then
Return True
ElseIf TypeOf oWin.Object Is TextWindow Then
If Not oVB.ActiveDocument.ProjectItem Is Nothing Then
If Not oVB.ActiveDocument.ProjectItem.FileCodeModel Is Nothing Then
MsgBox("Code Window")
End If
End If
End If
End Function
|
''' <summary>
''' Returns True if IDE ActiveWindow is a Code Window.
'''
''' <returns>Boolean
Public Function IsProjectItemACodeWindow() As Boolean
Dim oWin As Window = Connect.oVB.ActiveWindow
If TypeOf oWin.Object Is TextWindow AndAlso _
Not Connect.oVB.ActiveDocument.ProjectItem Is Nothing AndAlso _
Not Connect.oVB.ActiveDocument.ProjectItem.FileCodeModel Is Nothing Then
Return True
Else
Return False
End If
End Function
|
Alternate methods are shown below. Every WinForm, whether it be for C# (.cs) or VB.NET (.vb), has an associated .RESX file. The .RESX file is analogous in its use to the .FRX file in VB6. It is an XML representation of the form. Without examining the code of the code window, or possibly using the CodeModel, you can check for the existence of the associated .RESX file. The IsProjectItemAForm method is used to perform this functionality. It calls a helper method, GetActiveSolutionProject, to get the path to the form file and its .RESX file, if extant. This method will work for both VB.NET and C# projects.
Friend Function IsProjectItemAForm(ByVal sName As String) _
As Boolean
' This method returns True if the passed name
' represents a form, otherwise false.
Dim prj As Project
Dim s3 As String
Try
prj = GetActiveSolutionProject()
Dim sln As String = prj.FullName
Dim slnPath As String = IO.Path.GetDirectoryName(sln) & "\"
If sName.ToUpper.EndsWith(".VB") Then
s3 = slnPath & Replace(sName, ".vb", ".resx", _
Compare:=CompareMethod.Text)
ElseIf sName.ToUpper.EndsWith(".CS") Then
s3 = slnPath & Replace(sName, ".cs", ".resx", _
Compare:=CompareMethod.Text)
Else
Return False
End If
Dim fi As New System.IO.FileInfo(s3)
If fi.Exists Then
Return True
Else
Return False
End If
Catch ex As System.Exception
StructuredErrorHandler(ex.ToString)
End Try
End Function
|
This method returns the active project in the current Solution.
Public Function GetActiveSolutionProject() As Project
' Sets global miPrj = currently selected project and
' return the project to the caller.
Dim projs As System.Array
Dim proj As Project
Dim projects As Projects
Try
projs = Connect.oVB.ActiveSolutionProjects()
If projs.Length > 0 Then
proj = CType(projs.GetValue(0), EnvDTE.Project)
mPrj = proj
Return proj
End If
Catch ex As System.Exception
StructuredErrorHandler(ex.ToString)
End Try
End Function
| Determining the language, by which the active window was created can also be accomplished a couple of ways, as shown below.
Public Function GetProjectItemLanguage() As Short
Dim oWin As Window = Connect.oVB.ActiveWindow
If IsProjectItemACodeWindow() OrElse _
IsProjectItemAForm() Then
Select Case oWin.ProjectItem.FileCodeModel.Language
Case "{B5E9BD33-6D3E-4B5D-925E-8A43B79820B4}"
Return 8 ' VB
Case "{B5E9BD34-6D3E-4B5D-925E-8A43B79820B4}" 'C#
Return 9 ' C#
Case "{B5E9BD32-6D3E-4B5D-925E-8A43B79820B4}"
Return 1 ' c related VC++
Case "{B5E9BD36-6D3E-4B5D-925E-8A43B79820B4}"
Return 1 ' c related (managed VC++
Case Else
Return 0
End Select
End If
End Function
| The only problem with function shown above is that there are not as many strings defined as there are languages in .NET. Secondly, the use of a GUID type string is a little strange to me. An alternate method of getting the language type of a file is shown below. Also this method does not require that you have an active document; it works with a passed Document object.
Public Function GetFileType(ByRef doc As Document) As Integer
' Pass this function the document that you wish to get information for.
' Return value:
' 0 Unknown file type
' 1 C-related file, this includes .c, .cpp, .cxx, .h, hpp, .hxx
' 2 Java-related file, this includes .jav, .java
' 3 ODL-style file, .odl, .idl
' 4 Resource file, .rc, .rc2
' 7 Def-style file, .def
' 8 VB, .vb
' 9 C#, .cs
' 10 Batch, .bat
Dim pos As Integer
Dim ext As String
Try
ext = doc.Name.ToUpper
If ext.EndsWith(".RC") Or ext.EndsWith(".RC2") Then
Return 4
ElseIf ext.EndsWith(".CPP") Or _
ext.EndsWith(".C") Or _
ext.EndsWith(".H") Or _
ext.EndsWith(".HPP") Then
Return 1
ElseIf ext.EndsWith(".JAV") Or ext.EndsWith(".JAVA") Then
Return 2
ElseIf ext = ".DEF" Then
Return 7
ElseIf ext.EndsWith(".VB") Or ext.EndsWith(".BAS") Then
Return 8
ElseIf ext.EndsWith(".CS") Then
Return 9
ElseIf ext.EndsWith(".BAT") Then
Return 10
Else
Return 0
End If
Catch ex As System.Exception
Return 0
End Try
End Function
| |
|