Skip to content

Commit

Permalink
Cleanup HWND related interop
Browse files Browse the repository at this point in the history
  • Loading branch information
hughbe committed Aug 30, 2019
1 parent 966e928 commit 4973b41
Show file tree
Hide file tree
Showing 172 changed files with 2,677 additions and 1,565 deletions.
30 changes: 13 additions & 17 deletions src/Common/src/DpiHelper.DpiAwarenessContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using static Interop;

namespace System.Windows.Forms
{
/// <summary>
Expand All @@ -16,7 +18,7 @@ internal static partial class DpiHelper
/// <param name="awareness">The new DPI awareness for the current thread</param>
/// <returns>An object that, when disposed, will reset the current thread's
/// DPI awareness to the value it had when the object was created.</returns>
public static IDisposable EnterDpiAwarenessScope(DpiAwarenessContext awareness)
public static IDisposable EnterDpiAwarenessScope(User32.DpiAwarenessContext awareness)
{
return new DpiAwarenessScope(awareness);
}
Expand All @@ -30,38 +32,36 @@ public static IDisposable EnterDpiAwarenessScope(DpiAwarenessContext awareness)
/// <returns> returns object created in system aware mode</returns>
public static T CreateInstanceInSystemAwareContext<T>(Func<T> createInstance)
{
using (EnterDpiAwarenessScope(DpiAwarenessContext.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
using (EnterDpiAwarenessScope(User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
{
return createInstance();
}
}

#region Scoping DpiAwareness context helper class

/// <summary>
/// Class that help setting Dpi awareness context scope
/// </summary>
private class DpiAwarenessScope : IDisposable
{
private bool dpiAwarenessScopeIsSet = false;
private readonly DpiAwarenessContext originalAwareness = DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNSPECIFIED;
private readonly User32.DpiAwarenessContext originalAwareness = User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNSPECIFIED;

/// <summary>
/// Enters given Dpi awareness scope
/// </summary>
public DpiAwarenessScope(DpiAwarenessContext awareness)
public DpiAwarenessScope(User32.DpiAwarenessContext awareness)
{
try
{
if (!CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(awareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNSPECIFIED))
if (!User32.DpiAwarenessContextsEquals(awareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNSPECIFIED))
{
originalAwareness = CommonUnsafeNativeMethods.GetThreadDpiAwarenessContext();
originalAwareness = User32.GetCurrentThreadDpiAwarenessContext();

// If current process dpiawareness is SYSTEM_UNAWARE or SYSTEM_AWARE (must be equal to awareness), calling this method will be a no-op.
if (!CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(originalAwareness, awareness) &&
!CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(originalAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE))
if (!User32.DpiAwarenessContextsEquals(originalAwareness, awareness) &&
!User32.DpiAwarenessContextsEquals(originalAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE))
{
originalAwareness = CommonUnsafeNativeMethods.SetThreadDpiAwarenessContext(awareness);
originalAwareness = User32.SetCurrentThreadDpiAwarenessContext(awareness);
dpiAwarenessScopeIsSet = true;
}
}
Expand All @@ -75,10 +75,7 @@ public DpiAwarenessScope(DpiAwarenessContext awareness)
/// <summary>
/// Dispose object and resources
/// </summary>
public void Dispose()
{
ResetDpiAwarenessContextChanges();
}
public void Dispose() => ResetDpiAwarenessContextChanges();

/// <summary>
/// resetting dpiawareness of the thread.
Expand All @@ -87,11 +84,10 @@ private void ResetDpiAwarenessContextChanges()
{
if (dpiAwarenessScopeIsSet)
{
CommonUnsafeNativeMethods.TrySetThreadDpiAwarenessContext(originalAwareness);
User32.SetCurrentThreadDpiAwarenessContext(originalAwareness);
dpiAwarenessScopeIsSet = false;
}
}
}
#endregion
}
}
29 changes: 10 additions & 19 deletions src/Common/src/DpiHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Runtime.InteropServices;

using CAPS = System.Windows.Forms.NativeMethods;
using static Interop;

namespace System.Windows.Forms
{
Expand Down Expand Up @@ -55,7 +56,7 @@ internal static void InitializeDpiHelperForWinforms()
if (OsVersion.IsWindows10_1607OrGreater)
{
// We are on Windows 10/1603 or greater, but we could still be DpiUnaware or SystemAware, so let's find that out...
var currentProcessId = SafeNativeMethods.GetCurrentProcessId();
int currentProcessId = Kernel32.GetCurrentProcessId();
IntPtr hProcess = SafeNativeMethods.OpenProcess(SafeNativeMethods.PROCESS_QUERY_INFORMATION, false, currentProcessId);
SafeNativeMethods.GetProcessDpiAwareness(hProcess, out CAPS.PROCESS_DPI_AWARENESS processDpiAwareness);

Expand Down Expand Up @@ -90,8 +91,8 @@ internal static bool IsPerMonitorV2Awareness
{
// We can't cache this value because different top level windows can have different DPI awareness context
// for mixed mode applications.
DpiAwarenessContext dpiAwareness = CommonUnsafeNativeMethods.GetThreadDpiAwarenessContext();
return CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
User32.DpiAwarenessContext dpiAwareness = User32.GetCurrentThreadDpiAwarenessContext();
return User32.DpiAwarenessContextsEquals(dpiAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
else
{
Expand Down Expand Up @@ -319,29 +320,29 @@ internal static HighDpiMode GetWinformsApplicationDpiAwareness()
// For Windows 10 RS2 and above
if (OsVersion.IsWindows10_1607OrGreater)
{
DpiAwarenessContext dpiAwareness = CommonUnsafeNativeMethods.GetThreadDpiAwarenessContext();
User32.DpiAwarenessContext dpiAwareness = User32.GetCurrentThreadDpiAwarenessContext();

if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
if (User32.DpiAwarenessContextsEquals(dpiAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
{
return HighDpiMode.SystemAware;
}

if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE))
if (User32.DpiAwarenessContextsEquals(dpiAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE))
{
return HighDpiMode.DpiUnaware;
}

if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
if (User32.DpiAwarenessContextsEquals(dpiAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
{
return HighDpiMode.PerMonitorV2;
}

if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
if (User32.DpiAwarenessContextsEquals(dpiAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
{
return HighDpiMode.PerMonitor;
}

if (CommonUnsafeNativeMethods.TryFindDpiAwarenessContextsEqual(dpiAwareness, DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
if (User32.DpiAwarenessContextsEquals(dpiAwareness, User32.DpiAwarenessContext.DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
{
return HighDpiMode.DpiUnawareGdiScaled;
}
Expand Down Expand Up @@ -459,14 +460,4 @@ internal static bool SetWinformsApplicationDpiAwareness(HighDpiMode highDpiMode)
return false;
}
}

internal enum DpiAwarenessContext
{
DPI_AWARENESS_CONTEXT_UNSPECIFIED = 0,
DPI_AWARENESS_CONTEXT_UNAWARE = -1,
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2,
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = -3,
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4,
DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = -5
}
}
22 changes: 22 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.CloseHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern bool CloseHandle(IntPtr handle);

public static bool CloseHandle(HandleRef handle)
{
bool result = CloseHandle(handle.Handle);
GC.KeepAlive(handle.Wrapper);
return result;
}
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetCurrentProcess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern IntPtr GetCurrentProcess();
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetCurrentProcessId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern int GetCurrentProcessId();
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetCurrentThread.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern IntPtr GetCurrentThread();
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetCurrentThreadId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern int GetCurrentThreadId();
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetExitCodeThread.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern bool GetExitCodeThread(IntPtr hWnd, out uint lpdwExitCode);
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetThreadLocale.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern int GetThreadLocale();
}
}
14 changes: 14 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.GetTickCount.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public static extern int GetTickCount();
}
}
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Kernel32/Interop.SetThreadLocale.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, ExactSpelling = true)]
public extern static bool SetThreadLocale(int Locale);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

internal static partial class Interop
{
public static partial class Shell32
internal static partial class Shell32
{
[DllImport(Libraries.Shell32, ExactSpelling = true)]
public static extern CoTaskMemSafeHandle SHBrowseForFolderW(ref BROWSEINFO lpbi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

internal static partial class Interop
{
public static partial class Shell32
internal static partial class Shell32
{
[DllImport(Libraries.Shell32, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
public static extern int SHGetKnownFolderPath(ref Guid rfid, uint dwFlags, IntPtr hToken, out string pszPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

internal static partial class Interop
{
public static partial class Shell32
internal static partial class Shell32
{
[DllImport(ExternDll.Shell32, EntryPoint = "SHGetPathFromIDListEx", ExactSpelling = true)]
[DllImport(Libraries.Shell32, ExactSpelling = true)]
private static extern bool SHGetPathFromIDListEx(IntPtr pidl, IntPtr pszPath, int cchPath, int flags);

public static bool SHGetPathFromIDListLongPath(IntPtr pidl, out string path)
{
IntPtr pszPath = Marshal.AllocHGlobal((Interop.Kernel32.MAX_PATH + 1) * sizeof(char));
int length = Interop.Kernel32.MAX_PATH;
IntPtr pszPath = Marshal.AllocHGlobal((Kernel32.MAX_PATH + 1) * sizeof(char));
int length = Kernel32.MAX_PATH;
try
{
if (!SHGetPathFromIDListLongPath(pidl, ref pszPath, length))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

internal static partial class Interop
{
public static partial class Shell32
internal static partial class Shell32
{
[DllImport(Libraries.Shell32, ExactSpelling = true)]
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, out CoTaskMemSafeHandle ppidl);
Expand Down
15 changes: 15 additions & 0 deletions src/Common/src/Interop/Shell32/Interop.ShellExecute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Shell32
{
[DllImport(Libraries.Shell32, ExactSpelling = true, CharSet = CharSet.Ansi, BestFitMapping = false)]
public static extern IntPtr ShellExecuteA(HandleRef hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, User32.ShowWindowCommand nShowCmd);
}
}
Loading

0 comments on commit 4973b41

Please sign in to comment.