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
- Do not call GetFormattedText on WPF text stores; use GetText instead.
- In the text service, treat E_NOTIMPL as 'capability absent' and fall back to GetText/plain text.
- 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
- Treat GetFormattedText as unimplemented in WPF TSF
- Always provide a GetText fallback path
- Probe optional ITextStoreACP members defensively
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)