{"record":{"id":"b5fbac82364c9100","repo":"dotnet/wpf","slug":"sr-noitextdocumentfromrichedit","errorCode":null,"errorMessage":"SR.NoITextDocumentFromRichEdit","messagePattern":"SR\\.NoITextDocumentFromRichEdit","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsRichEdit.cs","lineNumber":485,"sourceCode":"        //  Private Methods\n        //\n        //------------------------------------------------------\n\n        #region Private Methods\n\n        // call this method before allowing access to any TextPattern properties or methods.\n        // it ensures that we have an ITextDocument pointer to the richedit control.\n        private void EnsureTextDocument()\n        {\n            // if we don't have a document pointer yet then get one by sending richedit a WM_GETOBJECT message\n            // with object id asking for the native OM.\n            if (_document == null)\n            {\n                object obj = null;\n\n                if (UnsafeNativeMethods.AccessibleObjectFromWindow(WindowHandle, NativeMethods.OBJID_NATIVEOM, ref UnsafeNativeMethods.IID_IDispatch, ref obj) != NativeMethods.S_OK)\n                {\n                    throw new System.NotImplementedException(SR.NoITextDocumentFromRichEdit);\n                }\n\n                // This is temp solution which will prevent exception in the case\n                // when we cannot obtain the ITextDocument from a RichEdit control\n                // The direct cast does not work for RichEdit20w controls used in MS Office\n                _document = obj as ITextDocument;\n                if (_document == null)\n                {\n                    throw new System.NotImplementedException(SR.NoITextDocumentFromRichEdit);\n                }\n            }\n        }\n\n        private string GetValue()\n        {\n            if (_type == WindowsEditBox.EditboxType.Password)\n            {\n                // Trying to retrieve the text (through WM_GETTEXT) from an edit box that has","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsRichEdit.cs#L467-L503","documentation":"EnsureTextDocument lazily obtains the RichEdit control's native ITextDocument via AccessibleObjectFromWindow(OBJID_NATIVEOM). If that call does not return S_OK, the text pattern cannot function, and the code throws NotImplementedException(SR.NoITextDocumentFromRichEdit) — the RichEdit build does not expose its native object model (e.g. plain rich edit versions lack the TOM interface).","triggerScenarios":"GetPatternProvider or RaiseTextSelectionEvent calls EnsureTextDocument on a rich edit whose AccessibleObjectFromWindow(OBJID_NATIVEOM, IID_IDispatch) fails (non-S_OK) — typically a RichEdit version without TOM/native-OM support.","commonSituations":"RichEdit controls from older Windows versions or certain class variants (RichEdit20W in some apps) that don't publish the native object model; embedding controls in apps that disable the native OM.","solutions":["Check the Text pattern's availability before use; handle the pattern being absent rather than calling it","Use a RichEdit version that supports the TOM interface (IRichEditOle / native OM), e.g. ensure MSFTEDIT_CLASS (msftedit.dll) where possible","Catch NotImplementedException around Text pattern access and fall back to ValuePattern for text retrieval","Verify the target application isn't deliberately restricting OBJID_NATIVEOM access"],"exampleFix":"// before\nvar text = element.GetCurrentPattern(TextPattern.Pattern) as TextPattern;\nvar doc = text.DocumentRange; // throws if no ITextDocument\n// after\ntry {\n    var text = element.GetCurrentPattern(TextPattern.Pattern) as TextPattern;\n    var doc = text.DocumentRange;\n} catch (NotImplementedException) {\n    var value = element.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;\n    var content = value.Value; // fallback\n}","handlingStrategy":"try-catch","validationCode":"bool HasTextPattern(AutomationElement e) { object p; return e.TryGetCurrentPattern(TextPattern.Pattern, out p) && IsRichEditWithTom(e); }","typeGuard":"bool TryGetTextPattern(AutomationElement e, out TextPattern tp) { tp = null; try { tp = (TextPattern)e.GetCurrentPattern(TextPattern.Pattern); return true; } catch (NotImplementedException) { return false; } }","tryCatchPattern":"try { var doc = textPattern.DocumentRange; } catch (NotImplementedException) { /* RichEdit lacks native OM/ITextDocument: fall back to ValuePattern */ }","preventionTips":["Only expect Text pattern support on RichEdit versions with TOM support (RICHEDIT50W/msftedit)","Wrap Text pattern acquisition in try/catch for NotImplementedException","Provide a ValuePattern-based fallback path for text retrieval in automation frameworks"],"tags":["uiautomation","richedit","text-pattern","not-implemented","itextdocument"],"backgroundTag":"method-not-implemented","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"}