Supported external association between active IME composition and its rendering window

paopao 0 Reputation points
2026-10-31T09:46:13.0133333+00:00

Question

We are building an external window-sharing tool. Which supported API combination associates a selected application's current input/composition context with its separate Microsoft IME preedit rendering HWND (or equivalent capturable surface), including validity and invalidation? If cooperation is required, what must the application or input provider expose?

Context and constraints

A user explicitly selects a top-level application window. We need visible Japanese Microsoft IME preedit, underline and conversion updates to accompany it through commit/cancel and focus changes. Some applications draw these pixels in their body; others use a separate MSCTFIME Composition window. We need both paths; the candidate list is outside our intended scope.

Our normal-user process must work without reading/reconstructing input text, keys, clipboard or accessibility Name/Value, injecting into another process, installing a text service, changing the application's input mode, or capturing the desktop. A matching class name and root-owner chain alone cannot authorize adding another captured window. The scope does not add a defense against arbitrary code executing inside the selected application, or require one API or a signed token.

What we have checked

We found these relevant TSF interfaces:

  • ITfCompositionView::GetOwnerClsid identifies the service owning a logical composition, and can report termination.
  • ITfThreadMgr::GetFocus / ITfDocumentMgr::GetTop lead to a document context for TSF clients. TF_GetThreadMgr explicitly refers to the calling thread; the ITfThreadMgr creation example uses CLSCTX_INPROC_SERVER. That example alone does not prove that all cross-process access is impossible.
  • ITfContextView::GetWnd identifies the document window, and can return NULL.
  • ITfUIElementMgr / ITfUIElementSink expose UI-element lifetimes. The base ITfUIElement interface has a GUID and visibility control, but no rendering-HWND method.

We have not established the supported path from a foreign focused HWND into its live context, then from that context to the separate rendering surface. We are seeking that missing relationship, rather than assuming these interfaces cannot be combined.

We also considered out-of-context SetWinEventHook notifications for EVENT_OBJECT_IME_SHOW/HIDE/CHANGE and EVENT_OBJECT_CREATE/DESTROY. The callback defines an event window (or NULL), object and child identifiers, but we found no contract stating which preedit rendering HWND these IME events identify for MSCTFIME Composition, or how they tie it to the current composition/document. Do these signals supply that relationship, or only lifecycle hints? We have not run a new IME-event experiment or treated an event ID as provider authentication.

The lifetime matters: in one observed ordinary-input path the preedit HWND is destroyed on commit/cancel and recreated on the next composition. A one-time choice of that HWND therefore does not cover normal use. A retained HWND must also be associated with the current composition rather than being accepted merely because its attributes still match.

Capture observations (background)

Capture observations are background to this association question. Our CreateForWindow(selected HWND) / IncludeSecondaryWindows=true path omitted preedit in one observed real-IME application path. WGC-REPRO.txt separately describes a color-only topology comparison, its additional cross/hidden controls and its limits; an identical underlying mechanism with the real IME has not been established. The secondary API lists Windows 11 24H2/build 26100 as its introduction. The older topology runs' exact OS build/update revision was not preserved; a separate source-build host reported 26200.0 and does not fill that gap.

Reproduction materials

The six source-text and supporting materials are combined in the attached IME-WGC-reproduction-materials.txt. Each section has its original filename, byte length and SHA-256. WGC-REPRO.txt within that attachment contains the build/run instructions. The source bytes and reported observations are unchanged.

IME-WGC-reproduction-materials.txt

References

Windows development | Windows API - Win32
0 comments No comments

2 answers

Sort by: Oldest
  1. AI answer

    2026-10-31T09:47:27.1066667+00:00

    There is no documented public API combination that lets an ordinary external process authoritatively associate another application’s active TSF composition with a separate MSCTFIME rendering HWND, so this requires explicit application/input-provider cooperation or capture of a surface already covered by the selected Windows Graphics Capture item.

    Why the TSF interfaces do not provide the relationship

    • A TSF thread manager maintains documents, contexts, and input focus for its thread. TF_GetThreadMgr obtains a manager previously created within the calling thread, while ITfThreadMgr2 operations such as activation, enumeration, and focus are also defined in terms of the calling thread.^1^ ^2^
    • ITfThreadMgr::GetFocus returns the document manager that has TSF input focus; it does not accept a foreign HWND or provide a system-wide lookup from HWND to another thread’s document manager.^3^
    • ITfContextView::GetWnd, ITextStoreACP::GetWnd, and their equivalents return the window corresponding to the document or text-store view. They may legitimately return NULL; their contracts do not identify a TIP-owned preedit window.^4^ ^5^
    • ITfCompositionView represents a logical composition and exposes its range and owner CLSID, but no rendering HWND or capturable surface.^6^

    Consequently, those interfaces cannot be joined into:

    foreign HWND
      → foreign focused ITfContext
      → active ITfCompositionView
      → authoritative rendering HWND
    

    The missing arrows are not public TSF contracts.

    Composition lifetime is available only to participating context owners

    An application that owns the TSF context can implement ITfContextOwnerCompositionSink. TSF installs that sink while creating the context and calls it for composition start, update, and end.^7^ The application therefore has an authoritative logical lifetime boundary, including commit/cancel termination, but that notification is part of application-side TSF integration—not an external subscription to an arbitrary process.

    ITfThreadMgrEventSink similarly reports document-manager/context events such as focus changes and context pushes or pops for the associated thread manager; it does not provide a foreign-HWND association service.^8^

    WinEvents are lifecycle hints, not authorization or association

    The documented meanings are limited to:

    • EVENT_OBJECT_IME_SHOW: an IME window became visible.
    • EVENT_OBJECT_IME_HIDE: an IME window became hidden.
    • EVENT_OBJECT_IME_CHANGE: an IME window’s size or position changed.
    • EVENT_OBJECT_CREATE/DESTROY: an accessible object was created or destroyed.^9^

    WinEventProc says that hwnd is the window generating the event, or NULL, and that idObject/idChild identify its accessible object. It does not define a composition ID, document manager, selected top-level application, or trusted provider identity.^10^

    Therefore, these events can trigger rescanning or invalidate a previously observed HWND, but cannot establish that the HWND belongs to the selected application’s current composition. Class names, owner chains, process identity, timing, and matching event sequences remain heuristics.

    Supported cooperation models

    The selected application can provide a private integration contract that exposes:

    1. A stable application/document instance identifier.
    2. A per-composition generation or opaque token.
    3. The capturable HWND/surface associated with that generation, if separate.
    4. Start, update, end, focus-loss, surface-replacement, and process-exit notifications.
    5. An atomic validation operation so the capturer can reject stale HWND reuse.

    No particular IPC technology or token format is prescribed by TSF. The association is authoritative because the context-owning application vouches for it, not because the external process inferred it from window topology.

    Alternatively, the application can render composition display attributes directly in its captured document surface. Microsoft’s TSF composition model places composition monitoring and display-attribute rendering with the application/context owner.^11^

    For cooperating applications and TIPs, TSF UI-less mode offers structured BeginUIElement, UpdateUIElement, and EndUIElement notifications. The application may suppress the TIP’s original UI and render supported UI-element content itself; the TIP must support the UI-element model.^12^ This is in-process TSF participation and may expose candidate/reading content, not an external API for discovering an existing Microsoft IME HWND.

    Windows Graphics Capture fallback

    On Windows 11 24H2, IncludeSecondaryWindows includes qualifying intersecting WS_POPUP or WS_EX_TOOLWINDOW windows according to documented style and Z-order rules. It does not claim semantic inclusion of every IME window or provide a composition association.^13^

    If the IME surface does not qualify and the application/provider does not cooperate, the stated constraints leave no supported authoritative way to add it while excluding unrelated windows.


    References

    1. TF_GetThreadMgr function (msctf.h)
    2. ITfThreadMgr2 interface (msctf.h)
    3. ITfThreadMgr::GetFocus method (msctf.h)
    4. ITfContextView::GetWnd method (msctf.h)
    5. ITextStoreACP::GetWnd method (textstor.h)
    6. ITfCompositionView interface (msctf.h)
    7. ITfContextOwnerCompositionSink interface (msctf.h)
    8. ITfThreadMgrEventSink interface (msctf.h)
    9. Event Constants (Winuser.h)
    10. WINEVENTPROC callback function (winuser.h)
    11. Compositions
    12. UILess Mode Overview
    13. GraphicsCaptureSession.IncludeSecondaryWindows Property-Definition
    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

  2. Gatlin Le (WICLOUD CORPORATION) 1,385 Reputation points Microsoft External Staff Moderator
    2026-11-02T03:59:42.6233333+00:00

    Hi @paopao ,

    I could not verify a supported public API combination for this. The reviewed documentation leaves two relationships unspecified: from a foreign HWND to its live TSF context, and from that context's composition to a separate rendering window.

    The TSF accessors do not fill those gaps: TF_GetThreadMgr returns the calling thread's manager, and ITfThreadMgr::GetFocus has no foreign-HWND input. ITfContextView::GetWnd returns the document window, possibly NULL, while ITfCompositionView has no rendering-surface accessor. UI-less mode also does not define a general preedit-HWND accessor; its predefined interfaces cover candidate and reading information.

    The IME WinEvents provide lifecycle hints, not a documented composition-to-window binding. The event definitions cover visibility and geometry changes, and WinEventProc identifies the event-generating window/object. Neither specifies which MSCTFIME Composition window belongs to the selected application's current composition. These events may help invalidate an independently established association, but are not documented as complete composition-lifetime notifications.

    For cooperation, the first question is which participant knows the rendering relationship. An application can receive composition start, update and end through ITfContextOwnerCompositionSink, but those callbacks do not identify a window rendered by another component. The application would need to either own the rendering or obtain the surface binding through an integration with the participant that knows it. An application-side composition sink alone does not expose the existing Microsoft IME preedit HWND.

    If application changes are acceptable, the TSF composition guidance describes using display attributes to render composition within the application's own captured surface. For a cooperating IMM32 application that implements its own composition rendering, WM_IME_COMPOSITION supplies update notifications, and a message with no GCS_ values indicates cancellation; WM_IME_ENDCOMPOSITION signals termination. The WM_IME_SETCONTEXT documentation specifies clearing ISC_SHOWUICOMPOSITIONWINDOW from lParam before forwarding to DefWindowProc or ImmIsUIMessage when the application draws the composition itself. Clearing that flag alone does not implement the rendering. The application would handle its own composition data and lifecycle, and the sharing process would capture the resulting pixels. This is conditional application cooperation, not an external lookup for an unchanged application.

    Where the composition surface must stay separate, a proposed cooperation contract could expose the selected document/context identity, a composition generation, its surface, and notifications for termination, focus/context changes, surface replacement and process exit. It would also need to keep that surface valid during capture or coordinate revocation with the capturer, because validating once before asynchronous capture leaves a lifetime race. This is an application-defined design, not a TSF-defined IPC protocol, and it need not expose composition text to the sharing process.

    Your IncludeSecondaryWindows=true result remains a separate capture observation. Its documented rules cover window styles, intersection and Z-order, and clip secondary-window pixels outside the main top-level window. They do not supply the composition binding, and the color-window comparison does not identify the cause of the real-IME omission.

    Can the selected applications participate in rendering or exposing this association, or must their provider-owned Microsoft IME UI remain unchanged? That determines which cooperation route is available.

    If you have any further questions, feel free to ask or leave a comment, and if you found my explanation above was truly helpful or informative to you, I would greatly appreciate it if you could follow this guidance so others with the same issue could benefit as well.

    Thank you.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.