dotnet/wpf · error · InvalidOperationException
SR.Stylus_PenContextFailure
Error message
SR.Stylus_PenContextFailure
What it means
PenContexts binds wisp (legacy) stylus input to a specific HWND. Its constructor throws InvalidOperationException (SR.Stylus_PenContextFailure) when the PresentationSource is not an HwndSource or the HwndSource handle is IntPtr.Zero, because pen contexts can only be created for a live HWND-backed window.
Solutions
- Ensure the window (HwndSource) is fully created — handle non-zero — before stylus contexts initialize
- Check PresentationSource.FromVisual(elem) is an HwndSource with a valid handle before touching PenContexts
- Do not dispose the HwndSource while stylus input is active
- Verify the code path is on a standard Window/Page hosting (HWND-based) environment
Example fix
// before var ctx = new PenContexts(logic, PresentationSource.FromVisual(myVisual)); // after var src = PresentationSource.FromVisual(myVisual) as HwndSource; if (src == null || src.Handle == IntPtr.Zero) return; var ctx = new PenContexts(logic, src);
Defensive patterns
Strategy: validation
Validate before calling
var src = PresentationSource.FromVisual(visual) as HwndSource;
if (src == null || src.Handle == IntPtr.Zero)
return; // cannot initialize pen contexts Type guard
bool IsValidHwndSource(PresentationSource s) => s is HwndSource hs && hs.Handle != IntPtr.Zero;
Try / catch
try { new PenContexts(logic, src); }
catch (InvalidOperationException ex) { Log.Error("PenContexts requires live HwndSource", ex); } Prevention
- Only initialize stylus after the window handle exists
- Do not use fake PresentationSource subclasses in tests
- Disable stylus support before closing the HwndSource
When it happens
Trigger: Constructing PenContexts directly with a PresentationSource that is not HwndSource (e.g. a custom PopupSource/test double), or with an HwndSource whose window handle is zero (window not yet created or already disposed).
Common situations: Creating stylus input before the window is shown/initialized; accessing PenContexts after window close; running in environments without HWND-backed presentation (custom presentation sources); unit tests substituting a fake PresentationSource.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- SR.Format(SR.Invalid_IInputElement, oldCapture.GetType())
- SR.Format(SR.Invalid_IInputElement, oldOver.GetType())
- SR.Format(SR.Invalid_IInputElement…
- SR.Format(SR.Invalid_IInputElement…
- SR.Format(SR.Invalid_IInputElement, oldCapture.GetType())
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/bd5d2218f9d87fe9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs:18
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Windows.Input.StylusWisp;
using System.Windows.Media;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Interop;
namespace System.Windows.Input
{
internal sealed class PenContexts
{
internal PenContexts(WispLogic stylusLogic, PresentationSource inputSource)
{
HwndSource hwndSource = inputSource as HwndSource;
if(hwndSource == null || IntPtr.Zero == (hwndSource).Handle)
{
throw new InvalidOperationException(SR.Stylus_PenContextFailure);
}
_stylusLogic = stylusLogic;
_inputSource = hwndSource;
}
/////////////////////////////////////////////////////////////////////////
internal void Enable()
{
if (_contexts == null)
{
// create contexts
_contexts = _stylusLogic.WispTabletDevices.CreateContexts(_inputSource.Handle, this);
foreach(PenContext context in _contexts)
{
context.Enable();View on GitHub (pinned to 81131a70a4)