KnowDotNet Visual Organizer

Handling Multiple Languages in an Add-in

Determining Project Type When Windows Change

by Les Smith
Print this Article Discuss in Forums

I need to turn menus on and off, based on the language of the current window, in a solution with multiple language types.  How can I determine the type of project language that I am in when a window is activated?  

The problem is a bit tricky.  Assuming that you have registered an event to fire when the user activates a new or different window in the IDE, you cannot check the project type of the window as soon as the WindowActivated event fires.  The reason for this is that the event fires before the focus has switched to the new window.  If you are using the methodology of testing the file extension of the ActiveWindow Caption, you will pick up the name of the window from which the developer is switching, not the one to which they are moving.  It will not do any good to try DoEvents, as the Add-in does not relinquish control back to the IDE until it does an exit from the WindowActivated event.

My solution to this problem was to create a wrapper class for a System.Timers object and start a new thread in that class.  At that point, control can be passed back to the IDE by exiting the WindowActivated event.  The timer will fire in 100ms and by that time the IDE will have completed the switching to the newly selected window.  It can then safely check the type of file that is in the new window.  The code shown below is the code that handles the WindowActivated event and starts the timer class.

   Private Sub eventWindows_WindowActivated(ByVal GotFocus As EnvDTE.Window, _
      
ByVal LostFocus As EnvDTE.Window) Handles eventWindows.WindowActivated
      
Dim t As System.Threading.Thread


         ' set up file type so we can toggle windows
         Try
            t = New System.Threading.Thread(AddressOf CkForTogglingMenus)
            t.Start()
        
Catch

         End Try
   End Sub

The code shown below is the code for the timer wrapper class,  The constructor starts the 100 ms timer.  When the 100 ms has expired,the event handler calls a utility method that simply looks at the caption of the active window and determines the file type, returning an Integer denoting the type.  It then calls a method that toggles my menus based on the file type.


' Created when a window is activated or opened
' to ck the file type after the window has had
' time to change.
Imports System.Timers

Public Class CWindowTimer
  
Private oVB As EnvDTE.DTE
  
Private oUtil As CUtilities

  
WithEvents WindowTimer As New System.Timers.Timer()
  
Public Sub New(ByRef roVB As EnvDTE.DTE)
      oVB = roVB
      
Me.WindowTimer.Interval = 100
      WindowTimer.Enabled =
True
      oUtil = New CUtilities(oVB)
  
End Sub

   Private Sub WindowTimer_Elapsed(ByVal sender As Object, _
      
ByVal e As System.Timers.ElapsedEventArgs) _
      
Handles WindowTimer.Elapsed
      
Try
         Dim i As Integer = oUtil.GetFileType(oVB.ActiveDocument)
        
If i <> 0 Then
            modMain.FileType = i
            modMain.ToggleMenus(i)
        
End If
         Me.WindowTimer.Enabled = False
         Me.WindowTimer.Interval = 0
      
Catch
      End Try
   End Sub

   Protected Overrides Sub Finalize()
      
MyBase.Finalize()
      
On Error Resume Next
      WindowTimer.Enabled = False
      WindowTimer.Interval = 0
      WindowTimer =
Nothing
   End Sub
End
Class

Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing