dotnet/wpf · error · ArgumentNullException
throw new ArgumentNullException(nameof(hwnd));
Error message
throw new ArgumentNullException(nameof(hwnd));
What it means
HwndSubclass.RequestDetach sends a special message to the window to locate and detach the given subclass. It validates inputs: an IntPtr.Zero hwnd cannot receive a message, so it throws ArgumentNullException for hwnd.
Solutions
- Verify hwnd != IntPtr.Zero before calling RequestDetach
- Skip detach if the window handle is already destroyed/zero (detach is then moot)
- Store the HWND in a checked property rather than a raw field that can become Zero
Example fix
// before HwndSubclass.RequestDetach(_hwnd, _gcHandle, true); // after if (_hwnd != IntPtr.Zero) HwndSubclass.RequestDetach(_hwnd, _gcHandle, true);
Defensive patterns
Strategy: validation
Validate before calling
if (hwnd == IntPtr.Zero) return; // window already gone; nothing to detach HwndSubclass.RequestDetach(hwnd, subclass, force);
Type guard
bool IsValidWindowHandle(IntPtr hwnd) => hwnd != IntPtr.Zero;
Try / catch
try { HwndSubclass.RequestDetach(hwnd, subclass, force); } catch (ArgumentNullException ex) when (ex.ParamName == "hwnd") { /* handle already destroyed; skip */ } Prevention
- Check handle validity before any Win32 call
- Treat a destroyed window's Zero handle as a no-op for detach
- Do not cache raw IntPtrs across window teardown
When it happens
Trigger: Calling HwndSubclass.RequestDetach(IntPtr.Zero, subclass, force) — passing a zero handle as the target window.
Common situations: Caching an HWND after the window was destroyed (handle resets to Zero); using a default-initialized IntPtr; detaching during shutdown after handle teardown.
Related errors
- ArgumentNullException
- throw new ArgumentNullException(nameof(callback));
- throw new ArgumentNullException(nameof(prefix));
- throw new…
- annotation component
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/33641e86d99ef0a1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/Shared/MS/Win32/HwndSubclass.cs:223
/// </param>
/// <param name="subclass">
/// The identifier of the subclass to unsubclass.
/// </param>
/// <param name="force">
/// Whether or not the unsubclassing should be forced. Due to the
/// way that Win32 implements window subclassing, it is not always
/// possible to safely remove a window proc from the WNDPROC chain.
/// However, the delegate will not be called again after this
/// method returns.
/// </param>
/// <returns>
/// Nothing.
/// </returns>
internal static void RequestDetach(IntPtr hwnd, IntPtr subclass, bool force)
{
if(hwnd == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(hwnd));
}
if(subclass == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(subclass));
}
int iForce = force ? 1 : 0;
UnsafeNativeMethods.UnsafeSendMessage(hwnd, DetachMessage, subclass, (IntPtr) iForce);
}
/// <summary>
/// This is the WNDPROC that gets inserted into the window's
/// WNDPROC chain. It responds to various conditions that
/// would cause this HwndSubclass object to unsubclass the window,
/// and then calls the delegate specified to the HwndSubclass
/// constructor to process the message. If the delegate does not
/// handle the message, the message is then passed on down the
/// WNDPROC chain for further processing.View on GitHub (pinned to 81131a70a4)