//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.IO;
using System.ComponentModel;

namespace CommonHelpers {

//**************************************************************************************************
public static partial class HSystemWin {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="Win32Exception" />
public static unsafe IntPtr EnableVisualStyles()
{
   if ( Win32_SysUtils.LoadLibrary( "ComCtl32.dll" ) == IntPtr.Zero )
      throw new Win32Exception();

   var systemDir = Environment.SystemDirectory;
   char* pSystemDir = stackalloc char[ systemDir.Length + 1 ];
   UnsafeInternal.CopyStringToSZBuffer( systemDir, pSystemDir );

   string strSource = Path.Combine( systemDir, "shell32.dll" );
   char* pSource = stackalloc char[ strSource.Length+1 ];
   UnsafeInternal.CopyStringToSZBuffer( strSource, pSource );

   var actCtx = new Win32_SysUtils.ACTCTX()
   {
      cbSize = (uint)HMarshal.SizeOf( typeof(Win32_SysUtils.ACTCTX) ),
      dwFlags =
         Win32_SysUtils.ACTCTX_FLAG_RESOURCE_NAME_VALID |
         Win32_SysUtils.ACTCTX_FLAG_SET_PROCESS_DEFAULT |
         Win32_SysUtils.ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID,
      ipSource = (IntPtr)pSource,
      ipAssemblyDirectory = (IntPtr)pSystemDir,
      ipResourceName = (IntPtr)124
   };

   IntPtr hActCtx = Win32_SysUtils.CreateActCtx( ref actCtx );
   if ( hActCtx == Win32_SysUtils.INVALID_HANDLE_VALUE )
   {
      var e = HWin32Error.CreateExceptionFromLastError();
      if ( e.NativeErrorCode == Win32_SysUtils.ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET )
         e.Data[ _EnableVStylesErrorMarker_AllreadyInitialized_ ] = true;
      throw e;
   }
   var ipActivationCookie = IntPtr.Zero;
   if ( !Win32_SysUtils.ActivateActCtx( hActCtx, out ipActivationCookie ) )
      try
         { throw new Win32Exception(); }
      finally
         { Win32_SysUtils.ReleaseActCtx( hActCtx ); }

   return ipActivationCookie;
}

public static IntPtr TryEnableVisualStyles()
{
   bool areAllreadyInitialized;
   return TryEnableVisualStyles( out areAllreadyInitialized );
}
public static IntPtr TryEnableVisualStyles(out bool areAllreadyInitialized)
{
   Exception e;
   return TryEnableVisualStyles( out areAllreadyInitialized, out e );
}
public static IntPtr TryEnableVisualStyles(out bool areAllreadyInitialized,out Exception e)
{
   areAllreadyInitialized = false;
   e = null;
   try { return EnableVisualStyles(); }
   catch (Exception x) {
      areAllreadyInitialized = object.Equals(
         x.Data[ _EnableVStylesErrorMarker_AllreadyInitialized_ ],
         true );
      e = x;
      return IntPtr.Zero; }
}

//==================================================================================================

static readonly object
   _EnableVStylesErrorMarker_AllreadyInitialized_ = new object();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HSystemWin
//**************************************************************************************************

} // CommonHelpers
