0X80040010

OLE_E_NOT_INPLACEACTIVE (0x80040010) fix: object context mismatch

Windows Errors Intermediate 👁 1 views 📅 May 28, 2026

You get this when COM tries to in-place activate an object that's already closed or not ready. It's a timing or reference issue, not a corrupt file.

Quick answer (for advanced users)

Call IOleObject::DoVerb(OLEIVERB_INPLACEACTIVATE, ...) before any in-place editing, or fix the container's IOleInPlaceSite implementation so it correctly reports the object's activation state via GetWindowContext. The object isn't corrupt — your code's activation state machine is off.

Context: what's actually happening here

OLE_E_NOT_INPLACEACTIVE (0x80040010) shows up when a COM object's container tries to perform an in-place operation — like resizing, moving, or toolbar negotiation — but the object hasn't been properly transitioned into the in-place active state. This usually happens in Office automation, custom OLE containers (think old MFC apps), or any ActiveX document host.

The OLE spec defines a strict state machine: loaded → running → in-place active → UI active. Your code jumped the gun and tried to act on the object while it was still in 'running' or worse, 'loaded'. I've seen this most often when someone keeps a reference to an embedded Excel worksheet or Word document, closes the parent document, and then tries to edit the object again — the COM server's still there but it's been told to deactivate.

Another common trigger: calling TranslateAccelerator or OnDocWindowActivate on an object that was never in-place activated. The object doesn't know where to draw itself or handle keyboard input.

Fix steps

  1. Verify the object's current state
    In your container code, check the object's state before calling any in-place method. Call IOleObject::GetMiscStatus and read the OLEMISC flags. If the object isn't in OLEMISC_INPLACEABLE, it can't go in-place at all — you'll need a different UI (modal editing). Most objects that throw this error are marked inplaceable but just haven't been activated yet.
  2. Forced in-place activation before any edit
    Call IOleObject::DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, lpOleClientSite, 0, hwndParent, &rcBounds) explicitly. Don't assume the object will activate itself. The OLEIVERB_INPLACEACTIVATE verb (value 5, or -5 in some headers) forces the transition. Do this before TranslateAccelerator or ResizeBorder. Sequence matters: always activate, then do UI work.
  3. Check your IOleInPlaceSite implementation
    The container's IOleInPlaceSite::GetWindowContext must return a valid IOleInPlaceFrame and IOleInPlaceUIWindow pointer. If you return NULL for either, the object can't activate in-place and silently stays in 'running' state. Common bug: returning E_NOTIMPL or skipping the frame pointer. Implement it properly — even if you don't have toolbars, return a valid frame.
  4. Release and re-acquire references after deactivation
    If the container deactivates the object (for example, user clicks outside), the object's in-place site is invalidated. Any cached pointer to the object from before deactivation is stale. Re-query the object with QueryInterface for IOleObject again after a deactivation. Don't reuse the same pointer.

Alternative fixes if the main steps don't work

  • Use OLEIVERB_OPEN instead of in-place activation
    If the object consistently fails to activate in-place, switch to OLEIVERB_OPEN — this opens the object in its own window (e.g., a separate Excel window). It's less elegant but skips the entire in-place state machine. Call DoVerb(OLEIVERB_OPEN, ...) when the user double-clicks or hits Enter.
  • Rebuild the OLE container's site object
    If you're writing the container from scratch, check that your IOleClientSite and IAdviseSink implementations aren't returning E_NOINTERFACE for critical interfaces. A missing IOleInPlaceSite advise sink can cause the server to never transition to in-place active.
  • Disable in-place activation entirely
    For older apps that don't need in-place editing (like a report generator), set the container's OLEDRAGDROP and OLEMISC flags to suppress in-place. The object stays in 'running' state — you get less interactivity but no 0x80040010.

Prevention tip

Always treat OLE activation like a state machine, not a fire-and-forget. After any deactivation event (e.g., OnDeactivateUI), invalidate all cached object pointers. When the user re-clicks the object, force a fresh activation via DoVerb(OLEIVERB_INPLACEACTIVATE). This pattern prevents 99% of in-place state errors. Test with both Office 2016 and Office 365 — their activation timing can differ slightly.

Was this solution helpful?