{"record":{"id":"bd5d2218f9d87fe9","repo":"dotnet/wpf","slug":"sr-stylus-pencontextfailure","errorCode":null,"errorMessage":"SR.Stylus_PenContextFailure","messagePattern":"SR\\.Stylus_PenContextFailure","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs","lineNumber":18,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nusing System.Windows.Input.StylusWisp;\nusing System.Windows.Media;\nusing System.Windows.Input.StylusPlugIns;\nusing System.Windows.Interop;\n\nnamespace System.Windows.Input\n{\n    internal sealed class PenContexts\n    {\n        internal PenContexts(WispLogic stylusLogic, PresentationSource inputSource)\n        {\n            HwndSource hwndSource = inputSource as HwndSource;\n            if(hwndSource == null || IntPtr.Zero == (hwndSource).Handle)\n            {\n                throw new InvalidOperationException(SR.Stylus_PenContextFailure);\n            }\n\n            _stylusLogic = stylusLogic;\n            _inputSource = hwndSource;\n        }\n\n        /////////////////////////////////////////////////////////////////////////\n\n        internal void Enable()\n        {\n            if (_contexts == null)\n            {\n                // create contexts\n                _contexts = _stylusLogic.WispTabletDevices.CreateContexts(_inputSource.Handle, this);\n\n                foreach(PenContext context in _contexts)\n                {\n                    context.Enable();","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/PenContexts.cs#L1-L36","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nvar ctx = new PenContexts(logic, PresentationSource.FromVisual(myVisual));\n// after\nvar src = PresentationSource.FromVisual(myVisual) as HwndSource;\nif (src == null || src.Handle == IntPtr.Zero) return;\nvar ctx = new PenContexts(logic, src);","handlingStrategy":"validation","validationCode":"var src = PresentationSource.FromVisual(visual) as HwndSource;\nif (src == null || src.Handle == IntPtr.Zero)\n    return; // cannot initialize pen contexts","typeGuard":"bool IsValidHwndSource(PresentationSource s) => s is HwndSource hs && hs.Handle != IntPtr.Zero;","tryCatchPattern":"try { new PenContexts(logic, src); }\ncatch (InvalidOperationException ex) { Log.Error(\"PenContexts requires live HwndSource\", ex); }","preventionTips":["Only initialize stylus after the window handle exists","Do not use fake PresentationSource subclasses in tests","Disable stylus support before closing the HwndSource"],"tags":["wpf","stylus","wisp","hwnd","invalid-operation"],"backgroundTag":"incompatible-source-type","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}