Skip to content

Use ReadOnlySpan<HwndWrapperHook> instead of a temporary heap array #10008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -721,13 +721,7 @@ internal struct BitmapTransformCaps
// TRUE if the effect supports multi-resolution

[MarshalAs(UnmanagedType.Bool)] bool fSupportMultiResolution;
};

[StructLayout(LayoutKind.Sequential)]
internal struct HWND
{
public int hwnd;
}
};

[StructLayout(LayoutKind.Sequential)]
internal struct MILAVInstruction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,23 @@ private void Initialize(HwndSourceParameters parameters)
// list. If this is done the other way around, first HwndTarget resize will
// force re-render, then layout will be updated according to the new size,
// scheduling another render.
HwndWrapperHook[] wrapperHooks = { _hwndTargetHook, _layoutHook, _inputHook, null };

if (null != parameters.HwndSourceHook)
ReadOnlySpan<HwndWrapperHook> wrapperHooks = [_hwndTargetHook, _layoutHook, _inputHook, _publicHook];

if (parameters.HwndSourceHook is not null)
{
// In case there's more than one delegate, add these to the event storage backwards
// so they'll get invoked in the expected order.
Delegate[] handlers = parameters.HwndSourceHook.GetInvocationList();
for (int i = handlers.Length -1; i >= 0; --i)
for (int i = handlers.Length - 1; i >= 0; --i)
{
EventHelper.AddHandler(ref _hooks, (HwndSourceHook)handlers[i]);
}
wrapperHooks[3] = _publicHook;
}
else
{
// In this case, we do not need the _publicHook
wrapperHooks = wrapperHooks.Slice(0, 3);
}

_restoreFocusMode = parameters.RestoreFocusMode;
Expand All @@ -260,27 +265,19 @@ private void Initialize(HwndSourceParameters parameters)
parameters.ExtendedWindowStyle &= (~NativeMethods.WS_EX_LAYERED);
}


_constructionParameters = parameters;
_hwndWrapper = new HwndWrapper(parameters.WindowClassStyle,
parameters.WindowStyle,
parameters.ExtendedWindowStyle,
parameters.PositionX,
parameters.PositionY,
parameters.Width,
parameters.Height,
parameters.WindowName,
parameters.ParentWindow,
wrapperHooks);

_hwndTarget = new HwndTarget(_hwndWrapper.Handle);
_hwndTarget.UsesPerPixelOpacity = parameters.EffectivePerPixelOpacity;
if(_hwndTarget.UsesPerPixelOpacity)

_hwndWrapper = new HwndWrapper(parameters.WindowClassStyle, parameters.WindowStyle, parameters.ExtendedWindowStyle,
parameters.PositionX, parameters.PositionY, parameters.Width, parameters.Height,
parameters.WindowName, parameters.ParentWindow, wrapperHooks);

_hwndTarget = new HwndTarget(_hwndWrapper.Handle) { UsesPerPixelOpacity = parameters.EffectivePerPixelOpacity };
if (_hwndTarget.UsesPerPixelOpacity)
{
_hwndTarget.BackgroundColor = Colors.Transparent;

// Prevent this window from being themed.
UnsafeNativeMethods.CriticalSetWindowTheme(new HandleRef(this, _hwndWrapper.Handle), "", "");
UnsafeNativeMethods.CriticalSetWindowTheme(new HandleRef(this, _hwndWrapper.Handle), string.Empty, string.Empty);
}
_constructionParameters = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2567,19 +2567,7 @@ public NotificationWindowHelper()
// (HwndWrapper keeps a WeakReference to the hook)

_notificationHook = new HwndWrapperHook(NotificationFilterMessage);
HwndWrapperHook[] wrapperHooks = { _notificationHook };

_notificationHwnd = new HwndWrapper(
0,
0,
0,
0,
0,
0,
0,
"",
IntPtr.Zero,
wrapperHooks);
_notificationHwnd = new HwndWrapper(0, 0, 0, 0, 0, 0, 0, string.Empty, IntPtr.Zero, _notificationHook);

Guid monitorGuid = new Guid(NativeMethods.GUID_MONITOR_POWER_ON.ToByteArray());
unsafe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,9 @@ internal MediaContextNotificationWindow(MediaContext ownerMediaContext)

// Create a top-level, invisible window so we can get the WM_DWMCOMPOSITIONCHANGED
// and other DWM notifications that are broadcasted to top-level windows only.
HwndWrapper hwndNotification;
hwndNotification = new HwndWrapper(0, NativeMethods.WS_POPUP, 0, 0, 0, 0, 0, "MediaContextNotificationWindow", IntPtr.Zero, null);

_hwndNotificationHook = new HwndWrapperHook(MessageFilter);

_hwndNotification = hwndNotification;
_hwndNotification = new HwndWrapper(0, NativeMethods.WS_POPUP, 0, 0, 0, 0, 0, "MediaContextNotificationWindow", parent: IntPtr.Zero);
_hwndNotification.AddHook(_hwndNotificationHook);

_isDisposed = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public virtual Nullable<bool> ShowDialog()
// prevent breaking UIAutomation.
if (hwndOwner == IntPtr.Zero)
{
tempParentHwnd = new HwndWrapper(0, 0, 0, 0, 0, 0, 0, "", IntPtr.Zero, null);
tempParentHwnd = new HwndWrapper(0, 0, 0, 0, 0, 0, 0, string.Empty, IntPtr.Zero);
hwndOwner = tempParentHwnd.Handle;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2143,19 +2143,7 @@ private void EnsureHwndSource()
// (HwndWrapper keeps a WeakReference to the hook)

_appFilterHook = new HwndWrapperHook(AppFilterMessage);
HwndWrapperHook[] wrapperHooks = {_appFilterHook};

_parkingHwnd = new HwndWrapper(
0,
0,
0,
0,
0,
0,
0,
"",
IntPtr.Zero,
wrapperHooks);
_parkingHwnd = new HwndWrapper(0, 0, 0, 0, 0, 0, 0, string.Empty, IntPtr.Zero, _appFilterHook);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1115,18 +1115,15 @@ private static DpiUtil.HwndDpiInfo CreateResourceChangeListenerWindow(DpiAwarene
{
// Create a top-level, invisible window so we can get the WM_THEMECHANGE notification
// and for HwndHost to park non-visible HwndHosts.
var hwndNotify =
new HwndWrapper(
classStyle: 0,
style: NativeMethods.WS_POPUP | NativeMethods.WS_DISABLED,
exStyle: 0,
x: x,
y: y,
width: 0,
height: 0,
name: "SystemResourceNotifyWindow",
parent: IntPtr.Zero,
hooks: null);
HwndWrapper hwndNotify = new(classStyle: 0,
style: NativeMethods.WS_POPUP | NativeMethods.WS_DISABLED,
exStyle: 0,
x: x,
y: y,
width: 0,
height: 0,
name: "SystemResourceNotifyWindow",
parent: IntPtr.Zero);

// Do not call into DpiUtil.GetExtendedDpiInfoForWindow()
// unless IsPerMonitorDpiscalingActive == true. DpiUtil.GetExtendedDpiInfoForWindow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6377,21 +6377,15 @@ private static void _OnClipToBoundsChanged(DependencyObject d, DependencyPropert
/// </summary>
private HwndWrapper EnsureHiddenWindow()
{
if (_hiddenWindow == null)
{
_hiddenWindow = new HwndWrapper(
0, // classStyle
NativeMethods.WS_OVERLAPPEDWINDOW, // style
0, // exStyle
NativeMethods.CW_USEDEFAULT, // x
NativeMethods.CW_USEDEFAULT, // y
NativeMethods.CW_USEDEFAULT, // width
NativeMethods.CW_USEDEFAULT, // height
"Hidden Window", // name
IntPtr.Zero,
null
);
}
_hiddenWindow ??= new HwndWrapper(classStyle: 0,
NativeMethods.WS_OVERLAPPEDWINDOW, // style
exStyle: 0,
NativeMethods.CW_USEDEFAULT, // x
NativeMethods.CW_USEDEFAULT, // y
NativeMethods.CW_USEDEFAULT, // width
NativeMethods.CW_USEDEFAULT, // height
"Hidden Window", // name
IntPtr.Zero);

return _hiddenWindow;
}
Expand Down
27 changes: 5 additions & 22 deletions src/Microsoft.DotNet.Wpf/src/Shared/MS/Win32/HwndSubclass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,13 @@
// 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;
using MS.Internal;
using MS.Internal.Interop;
using MS.Utility;
using System.Windows;
using System.Windows.Threading;
using System.Security; // CAS
using System.Threading; // Thread

// The SecurityHelper class differs between assemblies and could not actually be
// shared, so it is duplicated across namespaces to prevent name collision.
#if WINDOWS_BASE
using MS.Internal.WindowsBase;
#elif PRESENTATION_CORE
using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
using MS.Internal.PresentationFramework;
#elif DRT
using MS.Internal.Drt;
#else
#error Attempt to use a class (duplicated across multiple namespaces) from an unknown assembly.
#endif
using MS.Internal.Interop;
using System.Threading;
using System;

using SR = MS.Internal.WindowsBase.SR;

namespace MS.Win32
{
Expand All @@ -49,7 +33,6 @@ namespace MS.Win32
/// is not thread safe and will be operated on by the thread that owns
/// the window.
/// </summary>
/// <remarks> Not available to partial trust callers</remarks>
internal class HwndSubclass : IDisposable
{
static HwndSubclass()
Expand Down
Loading