English

How To: Programatically disable the Windows Aero theme for standalone ArcGIS applications

Summary

When running standalone applications for ArcGIS it is recommended to turn off the Windows Aero theme during the lifetime of the application. There are some cases where having the Aero theme enabled may cause display issues. These display issues become more apparent in dynamic display and 3D modes.

Procedure

The following code sample shows how to add logic to standalone .NET applications by using the Windows API to disable the Aero theme at runtime. When the application shuts down the Aero theme returns.

  • The following C# code demonstrates this:
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using ESRI.ArcGIS;
    
    namespace MyApp
    {
      static class Program
      {
        [DllImport("kernel32", SetLastError = true)]
        static extern IntPtr LoadLibrary(string lpFileName);
        [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
        internal delegate int DwmEnableComposition(int enable);
    
        [STAThread]
        static void Main()
        {
    	if (!RuntimeManager.Bind(ProductCode.Engine))
    	{
    	  if (!RuntimeManager.Bind(ProductCode.Desktop))
    	  {
    	    MessageBox.Show("Unable to bind to ArcGIS runtime. Application will be shut down.");
    	    return;
    	  }
    	}
    	DisableAeroDesktopWindowManager();
    	Application.EnableVisualStyles();
    	Application.SetCompatibleTextRenderingDefault(false);
    	Application.Run(new MainForm());
        }
    
        private static void DisableAeroDesktopWindowManager()
        {
    
    	IntPtr pDll = IntPtr.Zero;
    	try
    	{
    	  // Load the Desktop Windows Manger library, if the library does not exist
    	  // then bail out because we are on an OS older than Vista.
    	  pDll = LoadLibrary("dwmapi.dll");
    	  if (pDll == IntPtr.Zero)
    	    return;
    
    	  // Get the DwmEnableComposition Function
    	  IntPtr pFunc = GetProcAddress(pDll, "DwmEnableComposition");
    	  if (pFunc == IntPtr.Zero)
    	    return;
    
    	  DwmEnableComposition enableDwm = (DwmEnableComposition)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(pFunc, typeof(DwmEnableComposition));
    	  if (enableDwm == null) return;
    	  {
    	    // Disable Desktop Window Manager
    	    enableDwm(0);
    	  }
    	}
    	catch
    	{
    	  //Todo: log error
    	}
        }
      }
    }
  • Add the following VB.NET code to the Application events portion of the code:
    Imports System.Runtime.InteropServices
    
    Namespace My
    
        Partial Friend Class MyApplication
    
    	<DllImport("kernel32", SetLastError:=True)> _
    	Public Shared Function LoadLibrary(ByVal lpFileName As String) As IntPtr
    	End Function
    	<DllImport("kernel32", CharSet:=CharSet.Ansi, ExactSpelling:=True, SetLastError:=True)> _
    	Public Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal procName As String) As IntPtr
    	End Function
    	Friend Delegate Function DwmEnableComposition(ByVal enable As Integer) As Integer
    
    	Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
    	  If Not ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine) Then
    	    If Not ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop) Then
    		MessageBox.Show("Unable to bind to ArcGIS runtime. Application will be shut down.")
    		e.Cancel = True 'Abort application start up
    	    End If
    	  End If
    
    	  DisableAeroDesktopWindowManager()
    
    	End Sub
    
    	Private Sub DisableAeroDesktopWindowManager()
    	  Dim pDll As IntPtr = IntPtr.Zero
    	  Try
    	    pDll = LoadLibrary("dwmapi.dll")
    	    If (pDll = IntPtr.Zero) Then
    		Return
    	    End If
    
    	    ' Get the DwmEnabledComposition Function
    	    Dim pFunc As IntPtr = GetProcAddress(pDll, "DwmEnableComposition")
    	    If (pFunc = IntPtr.Zero) Then
    		Return
    	    End If
    	    Dim enableDwm As DwmEnableComposition
    	    enableDwm = DirectCast(System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(pFunc, GetType(DwmEnableComposition)), DwmEnableComposition)
    	    If (enableDwm Is Nothing) Then
    		Return
    	    End If
    	    ' Disable Desktop Window Manager
    	    enableDwm(0)
    	  Catch
    	    'Todo: log error
    	  End Try
    
    	End Sub
    
        End Class
    
    End Namespace