/**********************************************************************/
/*                                                                    */
/*      IMM.C - Windows 95 FAKEIME                                    */
/*                                                                    */
/*      Copyright (c) 1994-1995  Microsoft Corporation                */
/*                                                                    */
/**********************************************************************/
#include "windows.h"
#include "imm.h"
#include "fakeime.h"

#ifdef FAKEIMEM
int GetCandidateStringsFromDictionary(LPWSTR lpString, LPWSTR lpBuf, DWORD dwBufLen, LPSTR szDicFileName);
#endif

/**********************************************************************/
/*      ImeInquire()                                                  */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPSTR lpszClassName,LPCSTR lpszOption)
{
    ImeLog(LOGF_ENTRY | LOGF_API, "ImeInquire");

    // Init IMEINFO Structure.
    lpIMEInfo->dwPrivateDataSize = sizeof(UIEXTRA);
    lpIMEInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |
#ifdef FAKEIMEM
                             IME_PROP_UNICODE |
#endif
                             IME_PROP_AT_CARET;
    lpIMEInfo->fdwConversionCaps = IME_CMODE_LANGUAGE |
                                IME_CMODE_FULLSHAPE |
                                IME_CMODE_ROMAN |
                                IME_CMODE_CHARCODE;
    lpIMEInfo->fdwSentenceCaps = 0L;
    lpIMEInfo->fdwUICaps = UI_CAP_2700;

    lpIMEInfo->fdwSCSCaps = SCS_CAP_COMPSTR | 
                            SCS_CAP_MAKEREAD | 
                            SCS_CAP_SETRECONVERTSTRING;

    lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;

#ifdef FAKEIMEM
    memcpy((LPWSTR)lpszClassName,(LPWSTR)wszUIClassName,
                   (lstrlenW((LPWSTR)wszUIClassName) + 1) * sizeof(WCHAR));
#else
    lstrcpy(lpszClassName,(LPSTR)szUIClassName);
#endif


    return TRUE;
}

/**********************************************************************/
/*      ImeConversionList()                                           */
/*                                                                    */
/**********************************************************************/
DWORD WINAPI ImeConversionList(HIMC hIMC,LPCTSTR lpSource,LPCANDIDATELIST lpCandList,DWORD dwBufLen,UINT uFlags)
{
    ImeLog(LOGF_API, "ImeConversionList");


    return 0;
}

/**********************************************************************/
/*      ImeDestroy()                                                  */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI ImeDestroy(UINT uForce)
{
    ImeLog(LOGF_ENTRY | LOGF_API, "ImeDestroy");

    return TRUE;
}

/**********************************************************************/
/*      ImeEscape()                                                   */
/*                                                                    */
/**********************************************************************/
LRESULT WINAPI ImeEscape(HIMC hIMC,UINT uSubFunc,LPVOID lpData)
{
    LRESULT lRet = FALSE;

    ImeLog(LOGF_API, "ImeEscape");

    switch (uSubFunc)
    {
        case IME_ESC_QUERY_SUPPORT:
            switch (*(LPUINT)lpData)
            {
                case IME_ESC_QUERY_SUPPORT:
                case IME_ESC_PRI_GETDWORDTEST:
                case IME_ESC_GETHELPFILENAME:
                    lRet = TRUE;
                    break;

                default:
                    lRet = FALSE;
                    break;
            }
            break;

        case IME_ESC_PRI_GETDWORDTEST:
            lRet = 0x12345678;
            break;

        case IME_ESC_GETHELPFILENAME:
            Mylstrcpy((LPMYSTR)lpData, MYTEXT("fakeime.hlp"));
            lRet = TRUE;
            break;

        default:
            lRet = FALSE;
            break;
    }

    return lRet;
}

/**********************************************************************/
/*      ImeSetActiveContext()                                         */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI ImeSetActiveContext(HIMC hIMC,BOOL fFlag)
{
    ImeLog(LOGF_API, "ImeSetActiveContext");

    UpdateIndicIcon(hIMC);

    return TRUE;
}

/**********************************************************************/
/*      ImeProcessKey()                                               */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI ImeProcessKey(HIMC hIMC,UINT vKey,LPARAM lKeyData,CONST LPBYTE lpbKeyState)
{
    BOOL fRet = FALSE;
    BOOL fOpen;
    BOOL fCompStr = FALSE;
    LPINPUTCONTEXT lpIMC;
    LPCOMPOSITIONSTRING lpCompStr;

    ImeLog(LOGF_KEY | LOGF_API, "ImeProcessKey");


    if (lKeyData & 0x80000000)
        return FALSE;

    if (!(lpIMC = ImmLockIMC(hIMC)))
        return FALSE;

    fOpen = lpIMC->fOpen;

    if (fOpen)
    {
        if (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr))
        {
            if ((lpCompStr->dwSize > sizeof(COMPOSITIONSTRING)) && 
                (lpCompStr->dwCompStrLen))
                fCompStr = TRUE;
        }

        if (lpbKeyState[VK_MENU] & 0x80)
        {
            fRet = FALSE;
        }
        else if (lpbKeyState[VK_CONTROL] & 0x80)
        {
            if (fCompStr)
                fRet = (BOOL)bCompCtl[vKey];
            else
                fRet = (BOOL)bNoCompCtl[vKey];
        }
        else if (lpbKeyState[VK_SHIFT] & 0x80)
        {
            if (fCompStr)
                fRet = (BOOL)bCompSht[vKey];
            else
                fRet = (BOOL)bNoCompSht[vKey];
        }
        else 
        {
            if (fCompStr)
                fRet = (BOOL)bComp[vKey];
            else
                fRet = (BOOL)bNoComp[vKey];
        }

        if (lpCompStr)
            ImmUnlockIMCC(lpIMC->hCompStr);
    }

    ImmUnlockIMC(hIMC);
    return fRet;
}

/**********************************************************************/
/*      NotifyIME()                                                   */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI NotifyIME(HIMC hIMC,DWORD dwAction,DWORD dwIndex,DWORD dwValue)
{
    LPINPUTCONTEXT      lpIMC;
    BOOL                bRet = FALSE;
    LPCOMPOSITIONSTRING lpCompStr;
    LPCANDIDATEINFO     lpCandInfo;
    LPCANDIDATELIST     lpCandList;
    MYCHAR              szBuf[256];
    int                 nBufLen;
    LPMYSTR             lpstr;
    GENEMSG             GnMsg;
    int                 i = 0;
    LPDWORD             lpdw;

    ImeLog(LOGF_API, "NotifyIME");

    switch(dwAction)
    {

        case NI_CONTEXTUPDATED:
             switch (dwValue)
             {
                 case IMC_SETOPENSTATUS:
                     lpIMC = ImmLockIMC(hIMC);
                     if (lpIMC)
                     {
                         if (!lpIMC->fOpen && IsCompStr(hIMC))
                             FlushText(hIMC);
                         ImmUnlockIMC(hIMC);
                     }
                     UpdateIndicIcon(hIMC);
                     bRet = TRUE;
                     break;

                 case IMC_SETCONVERSIONMODE:
                     break;

                 case IMC_SETCOMPOSITIONWINDOW:
                     break;

                 default:
                     break;
             }
             break;

        case NI_COMPOSITIONSTR:
             switch (dwIndex)
             {
                 case CPS_COMPLETE:
                     MakeResultString(hIMC,TRUE);
                     bRet = TRUE;
                     break;

                 case CPS_CONVERT:
                     ConvKanji(hIMC);
                     bRet = TRUE;
                     break;

                 case CPS_REVERT:
                     RevertText(hIMC);
                     bRet = TRUE;
                     break;

                 case CPS_CANCEL:
                     FlushText(hIMC);
                     bRet = TRUE;
                     break;

                 default:
                     break;
             }
             break;

        case  NI_OPENCANDIDATE:
             if (IsConvertedCompStr(hIMC))
             {

                 if (!(lpIMC = ImmLockIMC(hIMC)))
                     return FALSE;

                 if (!(lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr)))
                 {
                     ImmUnlockIMC(hIMC);
                     return FALSE;
                 }

                 if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo))
                 {

                     // 
                     // Get the candidate strings from dic file.
                     //
#ifdef FAKEIMEM
                     nBufLen = GetCandidateStringsFromDictionary(GETLPCOMPREADSTR(lpCompStr),
                                                                 (LPMYSTR)szBuf,256,
                                                                 (LPSTR)szDicFileName );
#else
                     nBufLen = GetPrivateProfileString(GETLPCOMPREADSTR(lpCompStr),
                            NULL,(LPSTR)"",
                            (LPMYSTR)szBuf,256,(LPSTR)szDicFileName );
#endif

                     //
                     // generate WM_IME_NOTFIY IMN_OPENCANDIDATE message.
                     //
                     GnMsg.msg = WM_IME_NOTIFY;
                     GnMsg.wParam = IMN_OPENCANDIDATE;
                     GnMsg.lParam = 1L;
                     GenerateMessage(hIMC, lpIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg);

                     //
                     // Make candidate structures.
                     //
                     lpCandInfo->dwSize = sizeof(MYCAND);
                     lpCandInfo->dwCount = 1;
                     lpCandInfo->dwOffset[0] = 
                           (DWORD)((LPSTR)&((LPMYCAND)lpCandInfo)->cl - (LPSTR)lpCandInfo);
                     lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo  + lpCandInfo->dwOffset[0]);
                     lpdw = (LPDWORD)&(lpCandList->dwOffset);

                     lpstr = &szBuf[0];
                     while (*lpstr && (i < MAXCANDSTRNUM))
                     {
                         lpCandList->dwOffset[i] = 
                                (DWORD)((LPSTR)((LPMYCAND)lpCandInfo)->szCand[i] - (LPSTR)lpCandList);
                         Mylstrcpy((LPMYSTR)((LPMYSTR)lpCandList+lpCandList->dwOffset[i]),lpstr);
                         lpstr += (Mylstrlen(lpstr) + 1);
                         i++;
                     }

                     lpCandList->dwSize = sizeof(CANDIDATELIST) + 
                          (MAXCANDSTRNUM * (sizeof(DWORD) + MAXCANDSTRSIZE));
                     lpCandList->dwStyle = IME_CAND_READ;
                     lpCandList->dwCount = i;
                     lpCandList->dwPageStart = 0;
                     if (i < MAXCANDPAGESIZE)
                         lpCandList->dwPageSize  = i;
                     else
                         lpCandList->dwPageSize  = MAXCANDPAGESIZE;

                     lpCandList->dwSelection++;
                     if (lpCandList->dwSelection == (DWORD)i)
                         lpCandList->dwSelection = 0;

                     //
                     // Generate messages.
                     //
                     GnMsg.msg = WM_IME_NOTIFY;
                     GnMsg.wParam = IMN_CHANGECANDIDATE;
                     GnMsg.lParam = 1L;
                     GenerateMessage(hIMC, lpIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg);

                     ImmUnlockIMCC(lpIMC->hCandInfo);
                     ImmUnlockIMC(hIMC);

                     bRet = TRUE;
                 }
             }
             break;

        case  NI_CLOSECANDIDATE:
             if (!(lpIMC = ImmLockIMC(hIMC)))
                 return FALSE;
             if (IsCandidate(lpIMC))
             {
                 GnMsg.msg = WM_IME_NOTIFY;
                 GnMsg.wParam = IMN_CLOSECANDIDATE;
                 GnMsg.lParam = 1L;
                 GenerateMessage(hIMC, lpIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg);
                 bRet = TRUE;
             }
             ImmUnlockIMC(hIMC);
             break;

        case  NI_SELECTCANDIDATESTR:
             if (!(lpIMC = ImmLockIMC(hIMC)))
                 return FALSE;

             if (dwIndex == 1 && IsCandidate(lpIMC))
             {

                 if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo))
                 {

                     lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo  + lpCandInfo->dwOffset[0]);
                     if (lpCandList->dwCount > dwValue)
                     {
                         lpCandList->dwSelection = dwValue;
                         bRet = TRUE;

                         //
                         // Generate messages.
                         //
                         GnMsg.msg = WM_IME_NOTIFY;
                         GnMsg.wParam = IMN_CHANGECANDIDATE;
                         GnMsg.lParam = 1L;
                         GenerateMessage(hIMC, lpIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg);
                     }
                     ImmUnlockIMCC(lpIMC->hCandInfo);

                 }
             }
             ImmUnlockIMC(hIMC);
             break;

        case  NI_CHANGECANDIDATELIST:
             if (!(lpIMC = ImmLockIMC(hIMC)))
                return FALSE;

             if (dwIndex == 1 && IsCandidate(lpIMC))
                 bRet = TRUE;

             ImmUnlockIMC(hIMC);
             break;

        case NI_SETCANDIDATE_PAGESIZE:
             if (!(lpIMC = ImmLockIMC(hIMC)))
                return FALSE;

             if (dwIndex == 1 && IsCandidate(lpIMC))
             {
                 if (dwValue > MAXCANDPAGESIZE)
                     return FALSE;


                 if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo))
                 {
                     lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo  + lpCandInfo->dwOffset[0]);
                     if (lpCandList->dwCount > dwValue)
                     {
                         lpCandList->dwPageSize = dwValue;
                         bRet = TRUE;

                         //
                         // Generate messages.
                         //
                         GnMsg.msg = WM_IME_NOTIFY;
                         GnMsg.wParam = IMN_CHANGECANDIDATE;
                         GnMsg.lParam = 1L;
                         GenerateMessage(hIMC, lpIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg);
                     }
                     ImmUnlockIMCC(lpIMC->hCandInfo);
                 }
             }
             ImmUnlockIMC(hIMC);
             break;

        case NI_SETCANDIDATE_PAGESTART:
             if (!(lpIMC = ImmLockIMC(hIMC)))
                 return FALSE;

             if (dwIndex == 1 && IsCandidate(lpIMC))
             {
                 if (dwValue > MAXCANDPAGESIZE)
                     return FALSE;


                 if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo))
                 {
                     lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo  + lpCandInfo->dwOffset[0]);
                     if (lpCandList->dwCount > dwValue)
                     {
                         lpCandList->dwPageStart = dwValue;
                         bRet = TRUE;

                         //
                         // Generate messages.
                         //
                         GnMsg.msg = WM_IME_NOTIFY;
                         GnMsg.wParam = IMN_CHANGECANDIDATE;
                         GnMsg.lParam = 1L;
                         GenerateMessage(hIMC, lpIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg);
                     }
                     ImmUnlockIMCC(lpIMC->hCandInfo);

                 }
             }
             ImmUnlockIMC(hIMC);
             break;

        case NI_IMEMENUSELECTED:
#ifdef DEBUG
             {
             char szDev[80];
             OutputDebugString((LPSTR)"NotifyIME IMEMENUSELECTED\r\n");
             wsprintf((LPSTR)szDev,"\thIMC is 0x%x\r\n",hIMC);
             OutputDebugString((LPSTR)szDev);
             wsprintf((LPSTR)szDev,"\tdwIndex is 0x%x\r\n",dwIndex);
             OutputDebugString((LPSTR)szDev);
             wsprintf((LPSTR)szDev,"\tdwValue is 0x%x\r\n",dwValue);
             OutputDebugString((LPSTR)szDev);
             }
#endif
             break;

        default:
             break;
    }
    return bRet;
}

/**********************************************************************/
/*      ImeSelect()                                                   */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect)
{
    LPINPUTCONTEXT lpIMC;

    ImeLog(LOGF_ENTRY | LOGF_API, "ImeSelect");

    if (fSelect)
        UpdateIndicIcon(hIMC);

    // it's NULL context.
    if (!hIMC)
        return TRUE;

    if (lpIMC = ImmLockIMC(hIMC))
    {
        if (fSelect)
        {
            LPCOMPOSITIONSTRING lpCompStr;
            LPCANDIDATEINFO lpCandInfo;

            // Init the general member of IMC.
            if (!(lpIMC->fdwInit & INIT_LOGFONT))
            {
                lpIMC->lfFont.A.lfCharSet = SHIFTJIS_CHARSET;
                lpIMC->fdwInit |= INIT_LOGFONT;
            }

        
            if (!(lpIMC->fdwInit & INIT_CONVERSION))
            {
                lpIMC->fdwConversion = IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
                lpIMC->fdwInit |= INIT_CONVERSION;
            }

            lpIMC->hCompStr = ImmReSizeIMCC(lpIMC->hCompStr,sizeof(MYCOMPSTR));
            if (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr)) 
            {
                lpCompStr->dwSize = sizeof(MYCOMPSTR);
                ImmUnlockIMCC(lpIMC->hCompStr);
            }
            lpIMC->hCandInfo = ImmReSizeIMCC(lpIMC->hCandInfo,sizeof(MYCAND));
            if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo)) 
            {
                lpCandInfo->dwSize = sizeof(MYCAND);
                ImmUnlockIMCC(lpIMC->hCandInfo);
            }
        }
    }

    ImmUnlockIMC(hIMC);
    return TRUE;
}

#ifdef DEBUG
void DumpRS(LPRECONVERTSTRING lpRS)
{
    char szDev[80];
    LPMYSTR lpDump= (LPMYSTR)((LPSTR)lpRS + lpRS->dwStrOffset);
    *(lpDump + lpRS->dwStrLen) = MYTEXT('\0');

    OutputDebugString("DumpRS\r\n");
    wsprintf(szDev, "dwSize            %x\r\n", lpRS->dwSize);
    OutputDebugString(szDev);
    wsprintf(szDev, "dwStrLen          %x\r\n", lpRS->dwStrLen);
    OutputDebugString(szDev);
    wsprintf(szDev, "dwStrOffset       %x\r\n", lpRS->dwStrOffset);
    OutputDebugString(szDev);
    wsprintf(szDev, "dwCompStrLen      %x\r\n", lpRS->dwCompStrLen);
    OutputDebugString(szDev);
    wsprintf(szDev, "dwCompStrOffset   %x\r\n", lpRS->dwCompStrOffset);
    OutputDebugString(szDev);
    wsprintf(szDev, "dwTargetStrLen    %x\r\n", lpRS->dwTargetStrLen);
    OutputDebugString(szDev);
    wsprintf(szDev, "dwTargetStrOffset %x\r\n", lpRS->dwTargetStrOffset);
    OutputDebugString(szDev);
    MyOutputDebugString(lpDump);
    OutputDebugString("\r\n");
}
#endif

/**********************************************************************/
/*      ImeSetCompositionString()                                     */
/*                                                                    */
/**********************************************************************/
BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD dwComp, LPVOID lpRead, DWORD dwRead)
{
    ImeLog(LOGF_API, "ImeSetCompositionString");

    switch (dwIndex)
    {
        case SCS_QUERYRECONVERTSTRING:
#ifdef DEBUG
            OutputDebugString("SCS_QUERYRECONVERTSTRING\r\n");
            if (lpComp)
                DumpRS((LPRECONVERTSTRING)lpComp);
            if (lpRead)
                DumpRS((LPRECONVERTSTRING)lpRead);
#endif
            break;

        case SCS_SETRECONVERTSTRING:
#ifdef DEBUG
            OutputDebugString("SCS_SETRECONVERTSTRING\r\n");
            if (lpComp)
                DumpRS((LPRECONVERTSTRING)lpComp);
            if (lpRead)
                DumpRS((LPRECONVERTSTRING)lpRead);
#endif
            break;
    }

    return FALSE;
}

/**********************************************************************/
/*      ImeGetImeMenuItemInfo()                                       */
/*                                                                    */
/**********************************************************************/
DWORD WINAPI ImeGetImeMenuItems(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPMYIMEMENUITEMINFO lpImeParentMenu, LPMYIMEMENUITEMINFO lpImeMenu, DWORD dwSize)
{
    ImeLog(LOGF_API, "ImeGetImeMenuItems");


    if (!lpImeMenu)
    {
        if (!lpImeParentMenu)
        {
            if (dwFlags & IGIMIF_RIGHTMENU)
                return NUM_ROOT_MENU_R;
            else
                return NUM_ROOT_MENU_L;
        }
        else
        {
            if (dwFlags & IGIMIF_RIGHTMENU)
                return NUM_SUB_MENU_R;
            else
                return NUM_SUB_MENU_L;
        }

        return 0;
    }

    if (!lpImeParentMenu)
    {
        if (dwFlags & IGIMIF_RIGHTMENU)
        {
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_ROOT_MR_1;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("RootRightMenu1"));
            lpImeMenu->hbmpItem = 0;

            lpImeMenu++;
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = IMFT_SUBMENU;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_ROOT_MR_2;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("RootRightMenu2"));
            lpImeMenu->hbmpItem = 0;

            lpImeMenu++;
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_ROOT_MR_3;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("RootRightMenu3"));
            lpImeMenu->hbmpItem = 0;

            return NUM_ROOT_MENU_R;
        }
        else
        {
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_ROOT_ML_1;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("RootLeftMenu1"));
            lpImeMenu->hbmpItem = 0;

            lpImeMenu++;
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = IMFT_SUBMENU;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_ROOT_ML_2;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("RootLeftMenu2"));
            lpImeMenu->hbmpItem = 0;

            lpImeMenu++;
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_ROOT_ML_3;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("RootLeftMenu3"));
            lpImeMenu->hbmpItem = LoadBitmap(hInst,"FACEBMP");

            return NUM_ROOT_MENU_L;
        }
    }
    else
    {
        if (dwFlags & IGIMIF_RIGHTMENU)
        {
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_SUB_MR_1;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("SubRightMenu1"));
            lpImeMenu->hbmpItem = 0;

            lpImeMenu++;
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = 0;
            lpImeMenu->wID = IDIM_SUB_MR_2;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("SubRightMenu2"));
            lpImeMenu->hbmpItem = 0;

            return NUM_SUB_MENU_R;
        }
        else
        {
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = IMFS_CHECKED;
            lpImeMenu->wID = IDIM_SUB_ML_1;
            lpImeMenu->hbmpChecked = 0;
            lpImeMenu->hbmpUnchecked = 0;
            Mylstrcpy(lpImeMenu->szString, MYTEXT("SubLeftMenu1"));
            lpImeMenu->hbmpItem = 0;

            lpImeMenu++;
            lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO);
            lpImeMenu->fType = 0;
            lpImeMenu->fState = IMFS_CHECKED;
            lpImeMenu->wID = IDIM_SUB_ML_2;
            lpImeMenu->hbmpChecked = LoadBitmap(hInst,"CHECKBMP");
            lpImeMenu->hbmpUnchecked = LoadBitmap(hInst,"UNCHECKBMP");
            Mylstrcpy(lpImeMenu->szString, MYTEXT("SubLeftMenu2"));
            lpImeMenu->hbmpItem = 0;

            return NUM_SUB_MENU_L;
        }
    }

    return 0;
}
