dotnet/wpf · error · NotImplementedException

SR.NoITextDocumentFromRichEdit

Error message

SR.NoITextDocumentFromRichEdit

What it means

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).

Solutions

  1. Check the Text pattern's availability before use; handle the pattern being absent rather than calling it
  2. Use a RichEdit version that supports the TOM interface (IRichEditOle / native OM), e.g. ensure MSFTEDIT_CLASS (msftedit.dll) where possible
  3. Catch NotImplementedException around Text pattern access and fall back to ValuePattern for text retrieval
  4. Verify the target application isn't deliberately restricting OBJID_NATIVEOM access

Example fix

// before
var text = element.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
var doc = text.DocumentRange; // throws if no ITextDocument
// after
try {
    var text = element.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
    var doc = text.DocumentRange;
} catch (NotImplementedException) {
    var value = element.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
    var content = value.Value; // fallback
}
Defensive patterns

Strategy: try-catch

Validate before calling

bool HasTextPattern(AutomationElement e) { object p; return e.TryGetCurrentPattern(TextPattern.Pattern, out p) && IsRichEditWithTom(e); }

Type guard

bool TryGetTextPattern(AutomationElement e, out TextPattern tp) { tp = null; try { tp = (TextPattern)e.GetCurrentPattern(TextPattern.Pattern); return true; } catch (NotImplementedException) { return false; } }

Try / catch

try { var doc = textPattern.DocumentRange; } catch (NotImplementedException) { /* RichEdit lacks native OM/ITextDocument: fall back to ValuePattern */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/b5fbac82364c9100. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsRichEdit.cs:485

        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        // call this method before allowing access to any TextPattern properties or methods.
        // it ensures that we have an ITextDocument pointer to the richedit control.
        private void EnsureTextDocument()
        {
            // if we don't have a document pointer yet then get one by sending richedit a WM_GETOBJECT message
            // with object id asking for the native OM.
            if (_document == null)
            {
                object obj = null;

                if (UnsafeNativeMethods.AccessibleObjectFromWindow(WindowHandle, NativeMethods.OBJID_NATIVEOM, ref UnsafeNativeMethods.IID_IDispatch, ref obj) != NativeMethods.S_OK)
                {
                    throw new System.NotImplementedException(SR.NoITextDocumentFromRichEdit);
                }

                // This is temp solution which will prevent exception in the case
                // when we cannot obtain the ITextDocument from a RichEdit control
                // The direct cast does not work for RichEdit20w controls used in MS Office
                _document = obj as ITextDocument;
                if (_document == null)
                {
                    throw new System.NotImplementedException(SR.NoITextDocumentFromRichEdit);
                }
            }
        }

        private string GetValue()
        {
            if (_type == WindowsEditBox.EditboxType.Password)
            {
                // Trying to retrieve the text (through WM_GETTEXT) from an edit box that has

View on GitHub (pinned to 81131a70a4)