dotnet/wpf · warning · COMException

0x80004001

0x80004001

Error message

SR.TextStore_E_NOTIMPL

What it means

TextStore.GetFormattedText (ITextStoreACP::GetFormattedText) is not implemented by WPF's TSF text store; it always throws a COMException with E_NOTIMPL (0x80004001) after setting the out parameter to null. The TSF interface member exists for embedded-format retrieval, which WPF does not support.

Solutions

  1. Do not call GetFormattedText on WPF text stores; use GetText instead.
  2. In the text service, treat E_NOTIMPL as 'capability absent' and fall back to GetText/plain text.
  3. Query supported functionality before invoking optional interface members.

Example fix

// before
store.GetFormattedText(start, end, out obj);
// after: use plain text
string text = null; store.GetText(start, end, 0, null, out text, out change);
Defensive patterns

Strategy: try-catch

Try / catch

try { store.GetFormattedText(start, end, out obj); } catch (COMException ex) when (ex.ErrorCode == unchecked((int)0x80004001)) { /* fall back to GetText */ }

Prevention

When it happens

Trigger: Any text service or TSF client calling ITextStoreACP::GetFormattedText on a WPF TextStore, regardless of arguments or state.

Common situations: Custom text services or TSF-based automation probing supported interface members; ported Win32 text-service code assuming full ITextStoreACP support.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextStore.cs:545

            }
            finally
            {
                // Closes compsotion undo unit with commit to add the composition undo unit into the undo stack.
                CloseTextParentUndoUnit(unit, undoCloseAction);
            }

            if (IsTracing)
            {
                IMECompositionTracer.Trace(this, IMECompositionTraceOp.ESetText,
                                            "change:", change.start, change.oldEnd, change.newEnd);
            }
        }

        // See msdn's ITextStoreACP documentation for a full description.
        public void GetFormattedText(int startIndex, int endIndex, out object obj)
        {
            obj = null;
            throw new COMException(SR.TextStore_E_NOTIMPL, unchecked((int)0x80004001));
        }

        // See msdn's ITextStoreACP documentation for a full description.
        public void GetEmbedded(int index, ref Guid guidService, ref Guid riid, out object obj)
        {
            obj = null;

#if ENABLE_INK_EMBEDDING
            ITextPointer textPosition;

            if (index < this.TextContainer.IMECharCount)
            {
                // Create a position just following the index and look backward.
                // CreatePointerAtCharOffset always returns a pointer adjacent
                // to the lowest symbol offset matching a given char offset.
                textPosition = CreatePointerAtCharOffset(index + 1, LogicalDirection.Forward);

                if (textPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.EmbeddedElement)

View on GitHub (pinned to 81131a70a4)