/*
 *  ActiveIMMApp Interface
 *
 *  Copyright 2008  CodeWeavers, Aric Stewart
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winreg.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "dimm.h"
#include "imm.h"

#include "wine/unicode.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msimtf);

typedef struct tagActiveIMMApp {
    IActiveIMMApp IActiveIMMApp_iface;
    IActiveIMMMessagePumpOwner IActiveIMMMessagePumpOwner_iface;
    LONG refCount;
} ActiveIMMApp;

static inline ActiveIMMApp *impl_from_IActiveIMMApp(IActiveIMMApp *iface)
{
    return CONTAINING_RECORD(iface, ActiveIMMApp, IActiveIMMApp_iface);
}

static void ActiveIMMApp_Destructor(ActiveIMMApp* This)
{
    TRACE("\n");
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI ActiveIMMApp_QueryInterface (IActiveIMMApp* iface,
        REFIID iid, LPVOID *ppvOut)
{
    ActiveIMMApp *This = impl_from_IActiveIMMApp(iface);
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IActiveIMMApp))
    {
        *ppvOut = This;
    }
    else if (IsEqualIID(iid, &IID_IActiveIMMMessagePumpOwner))
    {
        *ppvOut = &This->IActiveIMMMessagePumpOwner_iface;
    }

    if (*ppvOut)
    {
        IUnknown_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ActiveIMMApp_AddRef(IActiveIMMApp* iface)
{
    ActiveIMMApp *This = impl_from_IActiveIMMApp(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI ActiveIMMApp_Release(IActiveIMMApp* iface)
{
    ActiveIMMApp *This = impl_from_IActiveIMMApp(iface);
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        ActiveIMMApp_Destructor(This);
    return ret;
}

static HRESULT WINAPI ActiveIMMApp_AssociateContext(IActiveIMMApp* iface,
        HWND hWnd, HIMC hIME, HIMC *phPrev)
{
    *phPrev = ImmAssociateContext(hWnd,hIME);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_ConfigureIMEA(IActiveIMMApp* This,
        HKL hKL, HWND hwnd, DWORD dwMode, REGISTERWORDA *pData)
{
    BOOL rc;

    rc = ImmConfigureIMEA(hKL, hwnd, dwMode, pData);
    if (rc)
        return E_FAIL;
    else
        return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_ConfigureIMEW(IActiveIMMApp* This,
        HKL hKL, HWND hWnd, DWORD dwMode, REGISTERWORDW *pData)
{
    BOOL rc;

    rc = ImmConfigureIMEW(hKL, hWnd, dwMode, pData);
    if (rc)
        return E_FAIL;
    else
        return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_CreateContext(IActiveIMMApp* This,
        HIMC *phIMC)
{
    *phIMC = ImmCreateContext();
    if (*phIMC)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_DestroyContext(IActiveIMMApp* This,
        HIMC hIME)
{
    BOOL rc;

    rc = ImmDestroyContext(hIME);
    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_EnumRegisterWordA(IActiveIMMApp* This,
        HKL hKL, LPSTR szReading, DWORD dwStyle, LPSTR szRegister,
        LPVOID pData, IEnumRegisterWordA **pEnum)
{
    FIXME("Stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMApp_EnumRegisterWordW(IActiveIMMApp* This,
        HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister,
        LPVOID pData, IEnumRegisterWordW **pEnum)
{
    FIXME("Stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMApp_EscapeA(IActiveIMMApp* This,
        HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT *plResult)
{
    *plResult = ImmEscapeA(hKL, hIMC, uEscape, pData);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_EscapeW(IActiveIMMApp* This,
        HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT *plResult)
{
    *plResult = ImmEscapeW(hKL, hIMC, uEscape, pData);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCandidateListA(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST *pCandList,
        UINT *puCopied)
{
    *puCopied = ImmGetCandidateListA(hIMC, dwIndex, pCandList, uBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCandidateListW(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST *pCandList,
        UINT *puCopied)
{
    *puCopied = ImmGetCandidateListW(hIMC, dwIndex, pCandList, uBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCandidateListCountA(IActiveIMMApp* This,
        HIMC hIMC, DWORD *pdwListSize, DWORD *pdwBufLen)
{
   *pdwBufLen = ImmGetCandidateListCountA(hIMC, pdwListSize);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCandidateListCountW(IActiveIMMApp* This,
        HIMC hIMC, DWORD *pdwListSize, DWORD *pdwBufLen)
{
   *pdwBufLen = ImmGetCandidateListCountA(hIMC, pdwListSize);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCandidateWindow(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, CANDIDATEFORM *pCandidate)
{
    BOOL rc;
    rc = ImmGetCandidateWindow(hIMC,dwIndex,pCandidate);
    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetCompositionFontA(IActiveIMMApp* This,
        HIMC hIMC, LOGFONTA *plf)
{
    BOOL rc;
    rc = ImmGetCompositionFontA(hIMC,plf);
    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetCompositionFontW(IActiveIMMApp* This,
        HIMC hIMC, LOGFONTW *plf)
{
    BOOL rc;
    rc = ImmGetCompositionFontW(hIMC,plf);
    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetCompositionStringA(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG *plCopied, LPVOID pBuf)
{
    *plCopied = ImmGetCompositionStringA(hIMC, dwIndex, pBuf, dwBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCompositionStringW(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG *plCopied, LPVOID pBuf)
{
    *plCopied = ImmGetCompositionStringW(hIMC, dwIndex, pBuf, dwBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCompositionWindow(IActiveIMMApp* This,
        HIMC hIMC, COMPOSITIONFORM *pCompForm)
{
    BOOL rc;

    rc = ImmGetCompositionWindow(hIMC,pCompForm);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetContext(IActiveIMMApp* This,
        HWND hwnd, HIMC *phIMC)
{
    *phIMC = ImmGetContext(hwnd);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetConversionListA(IActiveIMMApp* This,
        HKL hKL, HIMC hIMC, LPSTR pSrc, UINT uBufLen, UINT uFlag,
        CANDIDATELIST *pDst, UINT *puCopied)
{
    *puCopied = ImmGetConversionListA(hKL, hIMC, pSrc, pDst, uBufLen, uFlag);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetConversionListW(IActiveIMMApp* This,
        HKL hKL, HIMC hIMC, LPWSTR pSrc, UINT uBufLen, UINT uFlag,
        CANDIDATELIST *pDst, UINT *puCopied)
{
    *puCopied = ImmGetConversionListW(hKL, hIMC, pSrc, pDst, uBufLen, uFlag);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetConversionStatus(IActiveIMMApp* This,
        HIMC hIMC, DWORD *pfdwConversion, DWORD *pfdwSentence)
{
    BOOL rc;

    rc = ImmGetConversionStatus(hIMC, pfdwConversion, pfdwSentence);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetDefaultIMEWnd(IActiveIMMApp* This,
        HWND hWnd, HWND *phDefWnd)
{
    *phDefWnd = ImmGetDefaultIMEWnd(hWnd);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetDescriptionA(IActiveIMMApp* This,
        HKL hKL, UINT uBufLen, LPSTR szDescription, UINT *puCopied)
{
    *puCopied = ImmGetDescriptionA(hKL, szDescription, uBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetDescriptionW(IActiveIMMApp* This,
        HKL hKL, UINT uBufLen, LPWSTR szDescription, UINT *puCopied)
{
    *puCopied = ImmGetDescriptionW(hKL, szDescription, uBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetGuideLineA(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPSTR pBuf,
        DWORD *pdwResult)
{
    *pdwResult = ImmGetGuideLineA(hIMC, dwIndex, pBuf, dwBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetGuideLineW(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPWSTR pBuf,
        DWORD *pdwResult)
{
    *pdwResult = ImmGetGuideLineW(hIMC, dwIndex, pBuf, dwBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetIMEFileNameA(IActiveIMMApp* This,
        HKL hKL, UINT uBufLen, LPSTR szFileName, UINT *puCopied)
{
    *puCopied = ImmGetIMEFileNameA(hKL, szFileName, uBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetIMEFileNameW(IActiveIMMApp* This,
        HKL hKL, UINT uBufLen, LPWSTR szFileName, UINT *puCopied)
{
    *puCopied = ImmGetIMEFileNameW(hKL, szFileName, uBufLen);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetOpenStatus(IActiveIMMApp* This,
        HIMC hIMC)
{
    return ImmGetOpenStatus(hIMC);
}

static HRESULT WINAPI ActiveIMMApp_GetProperty(IActiveIMMApp* This,
        HKL hKL, DWORD fdwIndex, DWORD *pdwProperty)
{
    *pdwProperty = ImmGetProperty(hKL, fdwIndex);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetRegisterWordStyleA(IActiveIMMApp* This,
        HKL hKL, UINT nItem, STYLEBUFA *pStyleBuf, UINT *puCopied)
{
    *puCopied = ImmGetRegisterWordStyleA(hKL, nItem, pStyleBuf);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetRegisterWordStyleW(IActiveIMMApp* This,
        HKL hKL, UINT nItem, STYLEBUFW *pStyleBuf, UINT *puCopied)
{
    *puCopied = ImmGetRegisterWordStyleW(hKL, nItem, pStyleBuf);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetStatusWindowPos(IActiveIMMApp* This,
        HIMC hIMC, POINT *pptPos)
{
    BOOL rc;
    rc = ImmGetStatusWindowPos(hIMC, pptPos);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetVirtualKey(IActiveIMMApp* This,
        HWND hWnd, UINT *puVirtualKey)
{
    *puVirtualKey = ImmGetVirtualKey(hWnd);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_InstallIMEA(IActiveIMMApp* This,
        LPSTR szIMEFileName, LPSTR szLayoutText, HKL *phKL)
{
    *phKL = ImmInstallIMEA(szIMEFileName,szLayoutText);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_InstallIMEW(IActiveIMMApp* This,
        LPWSTR szIMEFileName, LPWSTR szLayoutText, HKL *phKL)
{
    *phKL = ImmInstallIMEW(szIMEFileName,szLayoutText);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_IsIME(IActiveIMMApp* This,
        HKL hKL)
{
    return ImmIsIME(hKL);
}

static HRESULT WINAPI ActiveIMMApp_IsUIMessageA(IActiveIMMApp* This,
        HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return ImmIsUIMessageA(hWndIME,msg,wParam,lParam);
}

static HRESULT WINAPI ActiveIMMApp_IsUIMessageW(IActiveIMMApp* This,
        HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return ImmIsUIMessageW(hWndIME,msg,wParam,lParam);
}

static HRESULT WINAPI ActiveIMMApp_NotifyIME(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
{
    BOOL rc;

    rc = ImmNotifyIME(hIMC,dwAction,dwIndex,dwValue);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_RegisterWordA(IActiveIMMApp* This,
        HKL hKL, LPSTR szReading, DWORD dwStyle, LPSTR szRegister)
{
    BOOL rc;

    rc = ImmRegisterWordA(hKL,szReading,dwStyle,szRegister);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_RegisterWordW(IActiveIMMApp* This,
        HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister)
{
    BOOL rc;

    rc = ImmRegisterWordW(hKL,szReading,dwStyle,szRegister);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_ReleaseContext(IActiveIMMApp* This,
        HWND hWnd, HIMC hIMC)
{
    BOOL rc;

    rc = ImmReleaseContext(hWnd,hIMC);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetCandidateWindow(IActiveIMMApp* This,
        HIMC hIMC, CANDIDATEFORM *pCandidate)
{
    BOOL rc;

    rc = ImmSetCandidateWindow(hIMC,pCandidate);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetCompositionFontA(IActiveIMMApp* This,
        HIMC hIMC, LOGFONTA *plf)
{
    BOOL rc;

    rc = ImmSetCompositionFontA(hIMC,plf);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetCompositionFontW(IActiveIMMApp* This,
        HIMC hIMC, LOGFONTW *plf)
{
    BOOL rc;

    rc = ImmSetCompositionFontW(hIMC,plf);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetCompositionStringA(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen,
        LPVOID pRead, DWORD dwReadLen)
{
    BOOL rc;

    rc = ImmSetCompositionStringA(hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetCompositionStringW(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen,
        LPVOID pRead, DWORD dwReadLen)
{
    BOOL rc;

    rc = ImmSetCompositionStringW(hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetCompositionWindow(IActiveIMMApp* This,
        HIMC hIMC, COMPOSITIONFORM *pCompForm)
{
    BOOL rc;

    rc = ImmSetCompositionWindow(hIMC,pCompForm);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetConversionStatus(IActiveIMMApp* This,
        HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
{
    BOOL rc;

    rc = ImmSetConversionStatus(hIMC,fdwConversion,fdwSentence);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetOpenStatus(IActiveIMMApp* This,
        HIMC hIMC, BOOL fOpen)
{
    BOOL rc;

    rc = ImmSetOpenStatus(hIMC,fOpen);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SetStatusWindowPos(IActiveIMMApp* This,
        HIMC hIMC, POINT *pptPos)
{
    BOOL rc;

    rc = ImmSetStatusWindowPos(hIMC,pptPos);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_SimulateHotKey(IActiveIMMApp* This,
        HWND hwnd, DWORD dwHotKeyID)
{
    BOOL rc;

    rc = ImmSimulateHotKey(hwnd,dwHotKeyID);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_UnregisterWordA(IActiveIMMApp* This,
        HKL hKL, LPSTR szReading, DWORD dwStyle, LPSTR szUnregister)
{
    BOOL rc;

    rc = ImmUnregisterWordA(hKL,szReading,dwStyle,szUnregister);

    if (rc)
        return S_OK;
    else
        return E_FAIL;

}

static HRESULT WINAPI ActiveIMMApp_UnregisterWordW(IActiveIMMApp* This,
        HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szUnregister)
{
    BOOL rc;

    rc = ImmUnregisterWordW(hKL,szReading,dwStyle,szUnregister);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_Activate(IActiveIMMApp* This,
        BOOL fRestoreLayout)
{
    FIXME("Stub\n");
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_Deactivate(IActiveIMMApp* This)
{
    FIXME("Stub\n");
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_OnDefWindowProc(IActiveIMMApp* This,
        HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
{
    FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam);
    return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_FilterClientWindows(IActiveIMMApp* This,
        ATOM *aaClassList, UINT uSize)
{
    FIXME("Stub\n");
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetCodePageA(IActiveIMMApp* This,
        HKL hKL, UINT *uCodePage)
{
    FIXME("Stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMApp_GetLangId(IActiveIMMApp* This,
        HKL hKL, LANGID *plid)
{
    FIXME("Stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMApp_AssociateContextEx(IActiveIMMApp* This,
        HWND hWnd, HIMC hIMC, DWORD dwFlags)
{
    BOOL rc;

    rc = ImmAssociateContextEx(hWnd,hIMC,dwFlags);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_DisableIME(IActiveIMMApp* This,
        DWORD idThread)
{
    BOOL rc;

    rc = ImmDisableIME(idThread);

    if (rc)
        return S_OK;
    else
        return E_FAIL;
}

static HRESULT WINAPI ActiveIMMApp_GetImeMenuItemsA(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwFlags, DWORD dwType,
        IMEMENUITEMINFOA *pImeParentMenu, IMEMENUITEMINFOA *pImeMenu,
        DWORD dwSize, DWORD *pdwResult)
{
    *pdwResult = ImmGetImeMenuItemsA(hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_GetImeMenuItemsW(IActiveIMMApp* This,
        HIMC hIMC, DWORD dwFlags, DWORD dwType,
        IMEMENUITEMINFOW *pImeParentMenu, IMEMENUITEMINFOW *pImeMenu,
        DWORD dwSize, DWORD *pdwResult)
{
    *pdwResult = ImmGetImeMenuItemsW(hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize);
    return S_OK;
}

static HRESULT WINAPI ActiveIMMApp_EnumInputContext(IActiveIMMApp* This,
        DWORD idThread, IEnumInputContext **ppEnum)
{
    FIXME("Stub\n");
    return E_NOTIMPL;
}

static const IActiveIMMAppVtbl ActiveIMMAppVtbl =
{
    ActiveIMMApp_QueryInterface,
    ActiveIMMApp_AddRef,
    ActiveIMMApp_Release,

    ActiveIMMApp_AssociateContext,
    ActiveIMMApp_ConfigureIMEA,
    ActiveIMMApp_ConfigureIMEW,
    ActiveIMMApp_CreateContext,
    ActiveIMMApp_DestroyContext,
    ActiveIMMApp_EnumRegisterWordA,
    ActiveIMMApp_EnumRegisterWordW,
    ActiveIMMApp_EscapeA,
    ActiveIMMApp_EscapeW,
    ActiveIMMApp_GetCandidateListA,
    ActiveIMMApp_GetCandidateListW,
    ActiveIMMApp_GetCandidateListCountA,
    ActiveIMMApp_GetCandidateListCountW,
    ActiveIMMApp_GetCandidateWindow,
    ActiveIMMApp_GetCompositionFontA,
    ActiveIMMApp_GetCompositionFontW,
    ActiveIMMApp_GetCompositionStringA,
    ActiveIMMApp_GetCompositionStringW,
    ActiveIMMApp_GetCompositionWindow,
    ActiveIMMApp_GetContext,
    ActiveIMMApp_GetConversionListA,
    ActiveIMMApp_GetConversionListW,
    ActiveIMMApp_GetConversionStatus,
    ActiveIMMApp_GetDefaultIMEWnd,
    ActiveIMMApp_GetDescriptionA,
    ActiveIMMApp_GetDescriptionW,
    ActiveIMMApp_GetGuideLineA,
    ActiveIMMApp_GetGuideLineW,
    ActiveIMMApp_GetIMEFileNameA,
    ActiveIMMApp_GetIMEFileNameW,
    ActiveIMMApp_GetOpenStatus,
    ActiveIMMApp_GetProperty,
    ActiveIMMApp_GetRegisterWordStyleA,
    ActiveIMMApp_GetRegisterWordStyleW,
    ActiveIMMApp_GetStatusWindowPos,
    ActiveIMMApp_GetVirtualKey,
    ActiveIMMApp_InstallIMEA,
    ActiveIMMApp_InstallIMEW,
    ActiveIMMApp_IsIME,
    ActiveIMMApp_IsUIMessageA,
    ActiveIMMApp_IsUIMessageW,
    ActiveIMMApp_NotifyIME,
    ActiveIMMApp_RegisterWordA,
    ActiveIMMApp_RegisterWordW,
    ActiveIMMApp_ReleaseContext,
    ActiveIMMApp_SetCandidateWindow,
    ActiveIMMApp_SetCompositionFontA,
    ActiveIMMApp_SetCompositionFontW,
    ActiveIMMApp_SetCompositionStringA,
    ActiveIMMApp_SetCompositionStringW,
    ActiveIMMApp_SetCompositionWindow,
    ActiveIMMApp_SetConversionStatus,
    ActiveIMMApp_SetOpenStatus,
    ActiveIMMApp_SetStatusWindowPos,
    ActiveIMMApp_SimulateHotKey,
    ActiveIMMApp_UnregisterWordA,
    ActiveIMMApp_UnregisterWordW,

    ActiveIMMApp_Activate,
    ActiveIMMApp_Deactivate,
    ActiveIMMApp_OnDefWindowProc,
    ActiveIMMApp_FilterClientWindows,
    ActiveIMMApp_GetCodePageA,
    ActiveIMMApp_GetLangId,
    ActiveIMMApp_AssociateContextEx,
    ActiveIMMApp_DisableIME,
    ActiveIMMApp_GetImeMenuItemsA,
    ActiveIMMApp_GetImeMenuItemsW,
    ActiveIMMApp_EnumInputContext
};

static inline ActiveIMMApp *impl_from_IActiveIMMMessagePumpOwner(IActiveIMMMessagePumpOwner *iface)
{
    return CONTAINING_RECORD(iface, ActiveIMMApp, IActiveIMMMessagePumpOwner_iface);
}

static HRESULT WINAPI ActiveIMMMessagePumpOwner_QueryInterface(IActiveIMMMessagePumpOwner* iface,
        REFIID iid, LPVOID *ppvOut)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    return IActiveIMMApp_QueryInterface(&This->IActiveIMMApp_iface, iid, ppvOut);
}

static ULONG WINAPI ActiveIMMMessagePumpOwner_AddRef(IActiveIMMMessagePumpOwner* iface)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    return IActiveIMMApp_AddRef(&This->IActiveIMMApp_iface);
}

static ULONG WINAPI ActiveIMMMessagePumpOwner_Release(IActiveIMMMessagePumpOwner* iface)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    return IActiveIMMApp_Release(&This->IActiveIMMApp_iface);
}

static HRESULT WINAPI ActiveIMMMessagePumpOwner_Start(IActiveIMMMessagePumpOwner* iface)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    FIXME("(%p)->(): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMMessagePumpOwner_End(IActiveIMMMessagePumpOwner* iface)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    FIXME("(%p)->(): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMMessagePumpOwner_OnTranslateMessage(IActiveIMMMessagePumpOwner* iface,
        const MSG *msg)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    FIXME("(%p)->(%p): stub\n", This, msg);
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMMessagePumpOwner_Pause(IActiveIMMMessagePumpOwner* iface,
        DWORD *cookie)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    FIXME("(%p)->(%p): stub\n", This, cookie);
    return E_NOTIMPL;
}

static HRESULT WINAPI ActiveIMMMessagePumpOwner_Resume(IActiveIMMMessagePumpOwner* iface,
        DWORD cookie)
{
    ActiveIMMApp *This = impl_from_IActiveIMMMessagePumpOwner(iface);
    FIXME("(%p)->(%u): stub\n", This, cookie);
    return E_NOTIMPL;
}

static const IActiveIMMMessagePumpOwnerVtbl ActiveIMMMessagePumpOwnerVtbl =
{
    ActiveIMMMessagePumpOwner_QueryInterface,
    ActiveIMMMessagePumpOwner_AddRef,
    ActiveIMMMessagePumpOwner_Release,
    ActiveIMMMessagePumpOwner_Start,
    ActiveIMMMessagePumpOwner_End,
    ActiveIMMMessagePumpOwner_OnTranslateMessage,
    ActiveIMMMessagePumpOwner_Pause,
    ActiveIMMMessagePumpOwner_Resume,
};

DECLSPEC_HIDDEN HRESULT ActiveIMMApp_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
    ActiveIMMApp *This;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ActiveIMMApp));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->IActiveIMMApp_iface.lpVtbl = &ActiveIMMAppVtbl;
    This->IActiveIMMMessagePumpOwner_iface.lpVtbl = &ActiveIMMMessagePumpOwnerVtbl;
    This->refCount = 1;

    TRACE("returning %p\n",This);
    *ppOut = (IUnknown *)This;
    return S_OK;
}
