bool QWindowsInputContext::endComposition(HWND hwnd)
{
    if (QWindowsContext::verboseInputMethods)
        qDebug() << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
    // Googles Pinyin Input Method likes to call endComposition again
    // when we call notifyIME with CPS_CANCEL, so protect ourselves
    // against that.
    if (m_endCompositionRecursionGuard || m_compositionContext.hwnd != hwnd)
        return false;
    QObject *fo = qApp->focusObject();
    if (!fo)
        return false;

    m_endCompositionRecursionGuard = true;

    imeNotifyCancelComposition(m_compositionContext.hwnd);
    if (m_compositionContext.isComposing) {
        QInputMethodEvent event;
        QCoreApplication::sendEvent(fo, &event);
    }
    doneContext();

    m_endCompositionRecursionGuard = false;
    return true;
}
void QWindowsInputContext::initContext(HWND hwnd)
{
    if (m_compositionContext.hwnd)
        doneContext();
    m_compositionContext.hwnd = hwnd;
    // Create a hidden caret which is kept at the microfocus
    // position in update(). This is important for some
    // Chinese input methods.
    m_compositionContext.haveCaret = CreateCaret(hwnd, 0, 1, 1);
    HideCaret(hwnd);
    update(Qt::ImQueryAll);
    m_compositionContext.isComposing = false;
    m_compositionContext.position = 0;
}
void QWindowsInputContext::reset()
{
    QPlatformInputContext::reset();
    if (!m_compositionContext.hwnd)
        return;
    qCDebug(lcQpaInputMethods) << __FUNCTION__;
    if (m_compositionContext.isComposing && !m_compositionContext.focusObject.isNull()) {
        QInputMethodEvent event;
        if (!m_compositionContext.composition.isEmpty())
            event.setCommitString(m_compositionContext.composition);
        QCoreApplication::sendEvent(m_compositionContext.focusObject, &event);
        endContextComposition();
    }
    imeNotifyCancelComposition(m_compositionContext.hwnd);
    doneContext();
}
void QWindowsInputContext::reset()
{
    QPlatformInputContext::reset();
    if (!m_compositionContext.hwnd)
        return;
    QObject *fo = qApp->focusObject();
    if (QWindowsContext::verboseInputMethods)
        qDebug() << __FUNCTION__<< fo;
    if (!fo)
        return;
    if (m_compositionContext.isComposing) {
        QInputMethodEvent event;
        if (!m_compositionContext.composition.isEmpty())
            event.setCommitString(m_compositionContext.composition);
        QCoreApplication::sendEvent(fo, &event);
        endContextComposition();
    }
    imeNotifyCancelComposition(m_compositionContext.hwnd);
    doneContext();
}