Skip to content

Commit

Permalink
Migrate DPI awareness initialization to managed (#5765)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasGoulet73 authored Jan 3, 2022
1 parent c52adfb commit d21ce7a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 71 deletions.
65 changes: 0 additions & 65 deletions src/Microsoft.DotNet.Wpf/src/DirectWriteForwarder/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,6 @@ using namespace System::Diagnostics;
// code in this Assembly when the assembly is loaded into any AppDomain.
//

//
// We want to call SetProcessDPIAware from user32.dll only on machines
// running Vista or later OSs. We provide our own declaration (the
// original is in winuser.h) here so we can specify the DllImport attribute
// which allows delayed loading of the function - thereby allowing us to
// run on pre-Vista OSs.
//

[DllImport("user32.dll", EntryPoint="SetProcessDPIAware")]
WINUSERAPI
BOOL
WINAPI
SetProcessDPIAware_Internal(
VOID);


#define WINNT_VISTA_VERSION 0x06

namespace MS { namespace Internal {
private ref class NativeWPFDLLLoader sealed
{
Expand Down Expand Up @@ -121,7 +103,6 @@ private class CModuleInitialize
// Constructor of class CModuleInitialize
__declspec(noinline) CModuleInitialize(void (*cleaningUpFunc)())
{
IsProcessDpiAware();
MS::Internal::NativeWPFDLLLoader::LoadDwrite();

// Initialize some global arrays.
Expand Down Expand Up @@ -159,52 +140,6 @@ private class CModuleInitialize
{
return MS::Internal::NativeWPFDLLLoader::GetDWriteCreateFactoryFunctionPointer();
}

private :

//
// A private helper method to handle the DpiAwareness issue for current application.
// This method is set as noinline since the MC++ compiler may otherwise inline it in a
// Security Transparent method which will lead to a security violation where the transparent
// method will be calling security critical code in this method.
//
__declspec(noinline) void IsProcessDpiAware( )
{
Version ^osVersion = (Environment::OSVersion)->Version;

if (osVersion->Major < WINNT_VISTA_VERSION)
{
// DPIAware feature is available only in Vista and after.
return;
}

//
// Below code is only for Vista and newer platform.
//
Assembly ^ assemblyApp;
Type ^ disableDpiAwareType = System::Windows::Media::DisableDpiAwarenessAttribute::typeid;
bool bDisableDpiAware = false;

// By default, Application is DPIAware.
assemblyApp = Assembly::GetEntryAssembly();

// Check if the Application has explicitly set DisableDpiAwareness attribute.
if (assemblyApp != nullptr && Attribute::IsDefined(assemblyApp, disableDpiAwareType))
{
bDisableDpiAware = true;
}


if (!bDisableDpiAware)
{
// DpiAware composition is enabled for this application.
SetProcessDPIAware_Internal( );
}

// Only when DisableDpiAwareness attribute is set in Application assembly,
// It will ignore the SetProcessDPIAware API call.
}

};

void CleanUp();
Expand Down
31 changes: 25 additions & 6 deletions src/Microsoft.DotNet.Wpf/src/PresentationCore/ModuleInitializer.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

internal static class ModuleInitializer
{
Expand All @@ -15,11 +13,32 @@ internal static class ModuleInitializer
/// operations are carried out. To do this, we simply call LoadDwrite
/// as the module constructor for DirectWriteForwarder would do this anyway.
/// </summary>
#pragma warning disable CA2255
#pragma warning disable CA2255
[ModuleInitializer]
public static void Initialize()
{
IsProcessDpiAware();

MS.Internal.NativeWPFDLLLoader.LoadDwrite();
}
#pragma warning restore CA2255
#pragma warning restore CA2255

private static void IsProcessDpiAware()
{
// By default, Application is DPIAware.
Assembly assemblyApp = Assembly.GetEntryAssembly();

// Check if the Application has explicitly set DisableDpiAwareness attribute.
if (assemblyApp != null && Attribute.IsDefined(assemblyApp, typeof(System.Windows.Media.DisableDpiAwarenessAttribute)))
{
// DpiAware composition is enabled for this application.
SetProcessDPIAware_Internal();
}

// Only when DisableDpiAwareness attribute is set in Application assembly,
// It will ignore the SetProcessDPIAware API call.
}

[DllImport("user32.dll", EntryPoint = "SetProcessDPIAware")]
private static extern void SetProcessDPIAware_Internal();
}

0 comments on commit d21ce7a

Please sign in to comment.