locked
Visual Studio .NET flickers when add-in opens projectitem in the code window RRS feed

  • Question

  • I have an Extension to Visual Studio 2015 to print source code in color of one or more project items in a project or projects. While the extension is processing project items a progress form is displayed to give the user some feedback. If any projectItem is not Open (using ProjectItem.IsOpen() )then the extension opens it using:

    ProjectItem.Open(EnvDTE.Constants.vsViewKindCode)

    The extension opens the  projectItem to obtain the FileCodeModel so that it can iterate Names, Classes, methods etc.

    On the call to ProjectItem.Open causes the progress Form to disappear behind the Visual Studio IDE. Bringing the Progress form to the fron causes very annoying flicker.

    Is there any way to achieve this without the flicker? Making the progress form a TopMost windows does the trick but is not ideal as processing all projects items make take while and also VS sometime displays a message that goes behind the progress form causing a lockout.

    Here is the test source code:

     Private Sub MenuItemCallback(sender As Object, e As EventArgs)
        Dim objProjectItem As ProjectItem
        Dim iCounter As Integer
        Dim objWindow As Window
        Dim activeDocument As Document = g_DTE.ActiveDocument
    
        If activeDocument Is Nothing Then
          MessageBox.Show("Please open a projectitem in the editor window and try again.")
        Else
          objProjectItem = activeDocument.ProjectItem
    
          ' Create and initialise a form to show progress
          Dim frmProgress As New ProgressForm
          With frmProgress.ProgressBar
            .Minimum = 1
            .Maximum = 500
          End With
    
          frmProgress.Show()
    
          ' Open the same projectitem in a loop to show thw flicker
          For iCounter = 1 To 500
            frmProgress.ShowProgress(iCounter)
    
            objWindow = objProjectItem.Open(EnvDTE.Constants.vsViewKindCode)
    
            objWindow.Close()
          Next
    
          frmProgress.Close()
        End If
    
      End Sub

    Sunday, February 7, 2016 11:35 AM

Answers

  • Hi Joginder,

    If I understand correctly, your problem is not the flickering but the fact that the progress form disappears behind the main window. If the form didn't disappear, there would be no need to bring it to front and therefore there wouldn't be any flicker. Is that correct?

    You can try using the Form.Show(IWin32Window owner) method that receives as parameter the owner form:

    https://msdn.microsoft.com/en-us/library/szcefbbd.aspx

    The owner form would be the main IDE window, whose handle you can obtain using DTE.MainWindow.hWnd, that you would have to encapsulate in a class implementing the IWin32Window interface (to return the Handle property).


    My portal and blog about VSX: http://www.visualstudioextensibility.com
    Twitter: https://twitter.com/VSExtensibility
    MZ-Tools productivity extension for Visual Studio: http://www.mztools.com

    • Marked as answer by J S Nahil Sunday, February 7, 2016 8:08 PM
    Sunday, February 7, 2016 12:22 PM

All replies

  • Hi Joginder,

    If I understand correctly, your problem is not the flickering but the fact that the progress form disappears behind the main window. If the form didn't disappear, there would be no need to bring it to front and therefore there wouldn't be any flicker. Is that correct?

    You can try using the Form.Show(IWin32Window owner) method that receives as parameter the owner form:

    https://msdn.microsoft.com/en-us/library/szcefbbd.aspx

    The owner form would be the main IDE window, whose handle you can obtain using DTE.MainWindow.hWnd, that you would have to encapsulate in a class implementing the IWin32Window interface (to return the Handle property).


    My portal and blog about VSX: http://www.visualstudioextensibility.com
    Twitter: https://twitter.com/VSExtensibility
    MZ-Tools productivity extension for Visual Studio: http://www.mztools.com

    • Marked as answer by J S Nahil Sunday, February 7, 2016 8:08 PM
    Sunday, February 7, 2016 12:22 PM
  • Hi Carlos,

    You are correct that the flicker is due to bringing the progress window to front of Visual Studio IDE each time a ProjectItem is opened and VS steals focus.  

    Based on your advice, I implemented the following that ensures that the progress window stays in front of Visual Studio IDE.

    This solutions works very well. 

    Thanks a million.

          m_winProgress = New winProgress   ' This is a WPF window
    
          ' Get the handle to Visual Studio's main window
          Dim hwnd = g_objDTE.MainWindow.HWnd
    
          ' WindowInteropHelper converts betwen WPF and Win32 
          Dim helper = New WindowInteropHelper(m_winProgress)
    
          ' Now we can use the IDE's main window's handle as the owner of our window
          helper.Owner = New IntPtr(hwnd)


    • Edited by J S Nahil Monday, February 8, 2016 8:52 AM Corrections
    Sunday, February 7, 2016 8:08 PM