Logo
HOWTO: Theme scrollbars of controls on a Windows Forms modal window from a Visual Studio 2012 add-in.

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2012
Date: October 2012    
       
Introduction

Visual Studio 2012 automatically changes the style of scrollbars of controls in toolwindows of add-ins, but not in modal forms. This article shows how to do that.

More information

To force Visual Studio 2012 to "theme" scrollbars of controls in a modal form, you have to call the SetProp Win32 API function with the "VisualStudio.ScrollbarThemeMode" property name and the value 1 (this value indicates Visual Studio to theme the scrollbars of all the children windows of the given window).

The following add-in shows a modal form named Form1 with a RichTextBox and a themed scrollbar:

Language: VB.NET   Copy Code Copy Code (IE only)
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports System.Runtime.InteropServices

Public Class Connect
   Implements IDTExtensibility2
	
   Private _applicationObject As DTE2
   Private _addInInstance As AddIn

   <DllImport("User32", CharSet:=CharSet.Unicode)> _
   Private Shared Function SetProp(ByVal hwnd As IntPtr, ByVal propName As String, ByVal value As IntPtr) As IntPtr
   End Function

   <DllImport("User32", CharSet:=CharSet.Unicode)> _
   Private Shared Function RemoveProp(ByVal hwnd As IntPtr, ByVal propName As String) As IntPtr
   End Function

   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, _
      ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      _applicationObject = CType(application, DTE2)
      _addInInstance = CType(addInInst, AddIn)

      Select Case connectMode

         Case ext_ConnectMode.ext_cm_AfterStartup
      
            Initialize()
      
         Case ext_ConnectMode.ext_cm_Startup
      
            ' OnStartupComplete will be called
      
      End Select

   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete

      Initialize()

   End Sub

   Private Sub Initialize()

      Const NSTM_All As Integer = 1

      Const PROPERTY_NAME_SCROLLBAR_THEME_MODE As String = "VisualStudio.ScrollbarThemeMode"

      Const SUCCESS As Integer = 1

      Dim frm1 As New Form1()
      Dim result As IntPtr


      frm1.RichTextBox1.ScrollBars = RichTextBoxScrollBars.ForcedBoth
      For i As Integer = 1 To 1000
         frm1.RichTextBox1.Text &= "Line " & i.ToString & Microsoft.VisualBasic.ControlChars.CrLf
      Next

      result = SetProp(frm1.Handle, PROPERTY_NAME_SCROLLBAR_THEME_MODE, New IntPtr(NSTM_All))
      If result.ToInt32 <> SUCCESS Then
         MessageBox.Show("Failed to theme control")
      End If

      frm1.ShowDialog()

      RemoveProp(frm1.Handle, PROPERTY_NAME_SCROLLBAR_THEME_MODE)
     
      frm1.Dispose()

   End Sub

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) Implements IDTExtensibility2.OnDisconnection
   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

End Class
Language: C#   Copy Code Copy Code (IE only)
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CSThemedAddIn
{

   public class Connect : IDTExtensibility2
   {

      [DllImport("User32", CharSet = CharSet.Unicode)]
      private static extern IntPtr SetProp(IntPtr hwnd, string propName, IntPtr Value);

      [DllImport("User32", CharSet = CharSet.Unicode)]
      private static extern IntPtr RemoveProp(IntPtr hwnd, string propName);

      private DTE2 _applicationObject;
      private AddIn _addInInstance;

      public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
      {
         _applicationObject = (DTE2)application;
         _addInInstance = (AddIn)addInInst;

         switch (connectMode)
         {
            case ext_ConnectMode.ext_cm_AfterStartup:
      
               InitializeAddIn();
               break;

            case ext_ConnectMode.ext_cm_Startup:
      
               // OnStartupComplete will be called
               break;
         }
      }

      public void OnStartupComplete(ref Array custom)
      {
         InitializeAddIn();
      }

      private void InitializeAddIn()
      {
         const int NSTM_All = 1;

         const string PROPERTY_NAME_SCROLLBAR_THEME_MODE = "VisualStudio.ScrollbarThemeMode";

         const int SUCCESS = 1;

         Form1 frm1 = new Form1();
         IntPtr result;

         // Note: Change the richTextBox1 modifier from private to public
         frm1.richTextBox1.ScrollBars = RichTextBoxScrollBars.ForcedBoth;
         for (int i = 1; i <= 1000; i++)
         {
            frm1.richTextBox1.Text += "Line " + i.ToString() + "\n";
         }

         result = SetProp(frm1.Handle, PROPERTY_NAME_SCROLLBAR_THEME_MODE, new IntPtr(NSTM_All));
         if (result.ToInt32() != SUCCESS)
         {
            MessageBox.Show("Failed to theme control");
         }

         frm1.ShowDialog();

         RemoveProp(frm1.Handle, PROPERTY_NAME_SCROLLBAR_THEME_MODE);

         frm1.Dispose();
      }

      public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
      {
      }

      public void OnAddInsUpdate(ref Array custom)
      {
      }

      public void OnBeginShutdown(ref Array custom)
      {
      }

   }
}

Related articles



Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)


Top