{"record":{"id":"016f7789f7973b1a","repo":"dotnet/wpf","slug":"sr-penservice-windownotregistered","errorCode":null,"errorMessage":"SR.PenService_WindowNotRegistered","messagePattern":"SR\\.PenService_WindowNotRegistered","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs","lineNumber":3226,"sourceCode":"                if (__penContextsMap.TryGetValue(hwndSource, out penContexts))\n                {\n                    __penContextsMap.Remove(hwndSource);\n\n                    // \n                    // If the application dispatcher is being shut down, we should destroy our pen thread as well.\n                    penContexts.Disable(shutdownWorkThread);\n\n                    // Make sure we remember the last location of this window for mapping stylus input later.\n                    if (UnsafeNativeMethods.IsWindow(new HandleRef(hwndSource, hwndSource.Handle)))\n                    {\n                        penContexts.DestroyedLocation = PointUtil.ClientToScreen(new Point(0, 0), hwndSource);\n                    }\n                }\n\n                // If we failed to find penContexts for this window above then throw an error now.\n                if (penContexts == null)\n                {\n                    throw new InvalidOperationException(SR.PenService_WindowNotRegistered);\n                }\n            }\n        }\n\n\n        /////////////////////////////////////////////////////////////////////\n\n        internal PenContexts GetPenContextsFromHwnd(PresentationSource presentationSource)\n        {\n            // Only safe to call from UI thread since only it will change Map.\n            Debug.Assert(Dispatcher.CheckAccess());\n\n            PenContexts penContexts = null;\n\n            if (presentationSource != null)\n            {\n                __penContextsMap.TryGetValue(presentationSource, out penContexts);\n            }","sourceCodeStart":3208,"sourceCodeEnd":3244,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs#L3208-L3244","documentation":"WispLogic (WispLogic.cs:3226) throws InvalidOperationException(SR.PenService_WindowNotRegistered) when a lookup for the PenContexts of a given PresentationSource returns null — i.e. the window was never registered with the pen service (or was already unregistered). The stylus stack cannot route tablet input for an unregistered window.","triggerScenarios":"Calling WispLogic APIs that resolve PenContexts for an input source (e.g. enabling/disabling stylus for a window, toggling RealTimeStylus paths) before RegisterStylusPointProcessor/source registration, or after the source was unregistered on close.","commonSituations":"Calling stylus enable/disable APIs in a window constructor before the HwndSource exists; operating on a closed window; mismatched ordering between plugin registration and use across app lifetime events.","solutions":["Register the window's PresentationSource with the stylus service before any PenContexts-dependent call.","Check the window/source is still open and registered before issuing stylus commands.","Ensure unregistration on close does not run earlier than subsequent stylus calls in your shutdown sequence."],"exampleFix":"// before\nvoid OnClose(object s, EventArgs e) { DisableStylus(window); window.Close(); Unregister(window); }\n// after\nvoid OnClose(object s, EventArgs e) { window.Close(); Unregister(window); } // unregister last","handlingStrategy":"validation","validationCode":"if (window == null || !window.IsLoaded) return; // window must be open and registered before stylus calls","typeGuard":null,"tryCatchPattern":"try { EnableStylusForWindow(window); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"not registered\")) { /* register the source first, then retry once */ }","preventionTips":["Register the window's PresentationSource before any stylus/PenContexts API","Perform stylus teardown after window close, never before dependent calls","Check window lifetime (IsLoaded) before stylus operations"],"tags":["wpf","stylus","pen","registration"],"backgroundTag":"resource-not-found","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"}