Walkthrough: Using the Gradient Service in a Tool Window

This walkthrough demonstrates how to use the Visual Studio Integration Package Wizard to create a VSPackage that includes a tool window. The walkthrough then demonstrates how to obtain an interface from a service and how to use the service to fill the background of a tool window with a color gradient.

A VSPackage can request a specific interface from a service to access a particular feature. For example, the gradient service lets you fill a region of a window with a particular gradient type. Typically, a VSPackage requests a primary interface from a service and then uses that interface to obtain other interfaces that are associated with that service. With the gradient service, the VSPackage must ask the SVsUIShell service for an IVsUIShell interface, obtain the IVsUIShell2 interface from the IVsUIShell interface, and finally call the CreateGradient method in the IVsUIShell2 interface to obtain the gradient service.

For more information, see Services.

Prerequisites

To complete this walkthrough, you must have the Visual Studio SDK.

Creating a VSPackage to Provide a Tool Window

This section of the walkthrough demonstrates how to use the Visual Studio Integration Package Wizard to create a VSPackage that includes a tool window.

To create a managed VSPackage to provide a tool window

  1. Create a VSPackage. For more information, see How to: Create VSPackages (C# and Visual Basic). Name the package MyTWGradientPackage.

  2. In the Visual Studio Integration Package Wizard, do the following things:

    • Set the programming language to Visual Basic or Visual C#.

    • Use the default values on the Basic Package Information page.

    • Add a tool window that is named Gradient Tool Window.

Using the Gradient Service

To use the gradient service, you must obtain an instance of the IVsGradient interface. You use the IVsGradient interface to paint the background of the tool window.

To use the gradient service

  1. Open the MyControl class in the code editor.

  2. At the top of the file, add the following lines after the last namespace statement if they are not already present:

    Imports Microsoft.VisualStudio 
    Imports Microsoft.VisualStudio.Shell.Interop 
    Imports Microsoft.VisualStudio.OLE.Interop 
    Imports System
    Imports System.Drawing
    
    using Microsoft.VisualStudio; 
    using Microsoft.VisualStudio.Shell.Interop; 
    using Microsoft.VisualStudio.OLE.Interop; 
    using System;
    using System.Drawing;
    
  3. Before the MyControl class constructor, add a private variable named backgroundGradient that has the type, IVsGradient.

    Private backgroundGradient As IVsGradient
    
    private IVsGradient backgroundGradient;
    
  4. At the bottom of the MyControl class, add the GetGradient method.

    This method obtains the IVsUIShell2 interface and uses the CreateGradient method to access the gradient service. Notice how the SVsUIShell service obtains the IVsUIShell2 interface.

    Private Function GetGradient(ByVal gradientType As __GRADIENTTYPE) _
        As IVsGradient
    
        Dim uiShell2 As IVsShell2 = TryCast( _
            GetService(GetType(SVsShell)), IVsShell2)
        If uiShell2 IsNot Nothing Then
            Dim gradient As IVsGradient
            ErrorHandler.ThrowOnFailure(uiShell2.CreateGradient( _
                CUInt(gradientType), gradient))
            Return gradient
        End If
    
        Return Nothing
    End Function
    
    private IVsGradient GetGradient(__GRADIENTTYPE gradientType)
    {
        IVsUIShell2 uiShell2 =
            this.GetService(typeof(SVsUIShell)) as IVsUIShell2;
        if (uiShell2 != null)
        {
            IVsGradient gradient;
            ErrorHandler.ThrowOnFailure(uiShell2.CreateGradient(
                (uint)gradientType, out gradient));
            return gradient;
        }
        return null;
    }
    
  5. After the GetGradient method that you just added, add the SetBackgroundGradient method.

    This method sets the background gradient of the control.

    Private Sub SetBackgroundGradient()
        Me.backgroundGradient = GetGradient( _
            __GRADIENTTYPE.VSGRADIENT_TOOLWIN_ACTIVE_TITLE_BAR)
    End Sub
    
    private void SetBackgroundGradient()
    {
        this.backgroundGradient = 
            GetGradient(__GRADIENTTYPE.VSGRADIENT_TOOLWIN_ACTIVE_TITLE_BAR);
    }
    
  6. After the SetBackgroundGradient method that you just added, add the DoPaintBackground method.

    This method uses the gradient to fill the background of a control, which in this case is the tool window.

    Private Sub DoPainBackground( _
        ByVal hdc As IntPtr, ByVal clipRectangle As Rectangle)
    
        If Me.backgroundGradient Is Nothing Then
            ' Make sure there is a gradient to work with.
            SetBackgroundGradient()
        End If
    
        Dim rect1 As New RECT
        With rect1
            .left = clipRectangle.Left
            .right = clipRectangle.Right
            .top = clipRectangle.Top
            .bottom = clipRectangle.Bottom
        End With
        Dim gradientRect() As RECT = New RECT() {rect1}
        ErrorHandler.ThrowOnFailure(Me.backgroundGradient.DrawGradient( _
            Me.Handle, hdc, gradientRect, gradientRect))
    End Sub
    
    private void DoPaintBackground(IntPtr hdc, Rectangle clipRectangle)
    {
        if (null == this.backgroundGradient)
        {
            // Make sure ther is a gradient to work with!
            SetBackgroundGradient();
        }
    
        RECT[] gradientRect = new RECT[1];
        gradientRect[0].left   = clipRectangle.Left;
        gradientRect[0].top    = clipRectangle.Top;
        gradientRect[0].right  = clipRectangle.Right;
        gradientRect[0].bottom = clipRectangle.Bottom;
    
        ErrorHandler.ThrowOnFailure(this.backgroundGradient.DrawGradient(
            this.Handle, hdc, gradientRect, gradientRect);
    }
    
  7. Override the OnPaintBackground method and replace the contents with the following lines. Put this new method after the DoPaintBackground method that you added earlier.

    Note

    In Visual C#, you can type override, or in Visual Basic, Overrides, to see a list of methods that can be overridden. When you select OnPaintBackground from the list, the method is automatically created.

    Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs)
        Try
            DoPaintBackground(e.Graphics.GetHdc(), e.ClipRectangle)
        Finally
            e.Graphics.ReleaseHdc()
        End Try
    End Sub
    
    protected override void OnPaintBackground(PaintEventArgs e)
    {
        try
        {
            DoPaintBackground(e.Graphics.GetHdc(), e.ClipRectangle);
        }
        finally
        {
            e.Graphics.ReleaseHdc();
        }
    }
    
  8. On the Build menu, click Build Solution to compile the code.

    Make sure there are no errors. This step registers the VSPackage and its tool window with Visual Studio.

  9. Press F5 to start an instance of the experimental build of Visual Studio in debug mode.

  10. In the experimental build of Visual Studio, on the View menu, point to Other Windows, and then click Gradient Tool Window.

    Doing this displays the tool window.

    Notice that the background of your tool window has a blue gradient that moves from dark to light, top to bottom. You can try other __GRADIENTTYPE values, but you must exit the experimental build of Visual Studio, recompile the VSPackage, and then open the experimental build of Visual Studio to see the changes.

See Also

Other Resources

Tool Window Walkthroughs

Services

VSPackages

Tool Windows