using System;
using System.Runtime.InteropServices;
using JetBrains.Interop.WinApi;
using JetBrains.Omea.OpenAPI;
using JetBrains.UI.Interop;
using JetBrains.Util.Interop;
namespace JetBrains.UI.Hooks
{
///
/// Enforses crisp fonts in avalon controls.
/// Call whenever you're about to use Avalon, before or after doing so.
/// All the calls but the first one will be ignored.
///
///
/// Hooks the MILCORE so that it obtained somehow improved information about the system settings.
///
public static unsafe class AvalonOperationCrisp
{
#region Data
private static readonly object myCookie = new object();
private static bool myExecuted;
#endregion
#region Operations
public static void Execute()
{
// On the second time the hook would not find the original function to play with, and will throw
lock(myCookie)
{
if(myExecuted)
return;
myExecuted = true;
}
// Do it
try
{
Execute_InstallHook();
myExecuted = true;
Execute_InvalidateMil();
}
catch(Exception ex)
{
Core.ReportException(ex, false);
}
}
#endregion
#region Implementation
///
/// Injects the hook.
///
private static void Execute_InstallHook()
{
ImportAddressTableHook.Install("USER32.DLL", "SystemParametersInfoW", "MILCORE.DLL", (SystemParametersInfoWDelegate)OnSystemParametersInfoW);
}
///
/// A kick for the MILCORE to query for the display settings again, this time with our improved data.
///
private static void Execute_InvalidateMil()
{
// Send an update to all the top-level windows on our thread
Win32Declarations.EnumWindows(delegate(IntPtr hWnd, IntPtr lParam)
{
int dwDummy;
if(Win32Declarations.GetWindowThreadProcessId(hWnd, out dwDummy) == Kernel32Dll.GetCurrentThreadId())
{
User32Dll.Helpers.SendMessageW(hWnd, WindowsMessages.WM_SETTINGCHANGE, (IntPtr)Win32Declarations.SPI_SETFONTSMOOTHING, IntPtr.Zero);
User32Dll.Helpers.SendMessageW(hWnd, WindowsMessages.WM_SETTINGCHANGE, (IntPtr)Win32Declarations.SPI_SETFONTSMOOTHINGTYPE, IntPtr.Zero);
}
return true; // Go on
}, 0);
}
///
/// Our replacement function which we hook into the MILCORE's IAT.
///
private static int OnSystemParametersInfoW(UInt32 uiAction, UInt32 uiParam, void* pvParam, UInt32 fWinIni)
{
switch(uiAction)
{
case Win32Declarations.SPI_GETCLEARTYPE:
*((int*)pvParam) = 1;
return 1;
case Win32Declarations.SPI_GETFONTSMOOTHING:
*((int*)pvParam) = 1;
return 1;
case Win32Declarations.SPI_GETFONTSMOOTHINGTYPE:
*((UInt32*)pvParam) = Win32Declarations.FE_FONTSMOOTHINGCLEARTYPE;
return 1;
default:
return SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni); // As we hook only MILCORE's view on the function, we're still calling the original version (or, maybe, hooked by someone else ;)
}
}
[DllImport("User32.dll", ExactSpelling = true)]
private static extern int SystemParametersInfoW(UInt32 uiAction, UInt32 uiParam, void* pvParam, UInt32 fWinIni);
#endregion
#region SystemParametersInfoWDelegate Type
public delegate int SystemParametersInfoWDelegate(UInt32 uiAction, UInt32 uiParam, void* pvParam, UInt32 fWinIni);
#endregion
}
}