
/*++

Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved

Module Name:

    ui.c


++*/


#include <windows.h>
#include <immdev.h>
#include <imedefs.h>
#include <regstr.h>



/**********************************************************************/
/* CMenuDestryed()                                                    */
/**********************************************************************/
void PASCAL CMenuDestroyed(             // context menu window
                                        // already destroyed
    HWND hUIWnd)
{
    HGLOBAL  hUIPrivate;
    LPUIPRIV lpUIPrivate;

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {     
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {    
        return;
    }

    lpUIPrivate->hCMenuWnd = NULL;

    GlobalUnlock(hUIPrivate);
}
/**********************************************************************/
/* SoftkeyMenuDestroyed()                                                    */
/**********************************************************************/
void PASCAL SoftkeyMenuDestroyed(             // context menu window
                                        // already destroyed
    HWND hUIWnd)
{
    HGLOBAL  hUIPrivate;
    LPUIPRIV lpUIPrivate;

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {     
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {    
        return;
    }

    lpUIPrivate->hSoftkeyMenuWnd = NULL;

    GlobalUnlock(hUIPrivate);
}

/**********************************************************************/
/* CreateUIWindow()                                                   */
/**********************************************************************/
void PASCAL CreateUIWindow(             // create composition window
    HWND hUIWnd)
{
    HGLOBAL hUIPrivate;

    // create storage for UI setting
    hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV));
    if (!hUIPrivate) {     
        return;
    }

    SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)hUIPrivate);

    // set the default position for UI window, it is hide now
    SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER);

    ShowWindow(hUIWnd, SW_SHOWNOACTIVATE);

    return;
}

/**********************************************************************/
/* DestroyUIWindow()                                                  */
/**********************************************************************/
void PASCAL DestroyUIWindow(            // destroy composition window
    HWND hUIWnd)
{
    HGLOBAL  hUIPrivate;
    LPUIPRIV lpUIPrivate;

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {     
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {    
        return;
    }

    //destroy ContextMenuWnd
    if (lpUIPrivate->hCMenuWnd) {
        SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_HUIWND,(LONG_PTR)0);
        PostMessage(lpUIPrivate->hCMenuWnd, WM_USER_DESTROY, 0, 0);
    }
    //destroy SoftkeyMenuWnd
    if (lpUIPrivate->hSoftkeyMenuWnd) {
        SetWindowLongPtr(lpUIPrivate->hSoftkeyMenuWnd, SOFTKEYMENU_HUIWND,(LONG_PTR)0);
        PostMessage(lpUIPrivate->hSoftkeyMenuWnd, WM_USER_DESTROY, 0, 0);
    }

    // composition window need to be destroyed
    if (lpUIPrivate->hCompWnd) {
        DestroyWindow(lpUIPrivate->hCompWnd);
    }

    // candidate window need to be destroyed
    if (lpUIPrivate->hCandWnd) {
        DestroyWindow(lpUIPrivate->hCandWnd);
    }

    // status window need to be destroyed
    if (lpUIPrivate->hStatusWnd) {
        DestroyWindow(lpUIPrivate->hStatusWnd);
    }

    // soft keyboard window need to be destroyed
    if (lpUIPrivate->hSoftKbdWnd) {
        ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
    }

    GlobalUnlock(hUIPrivate);

    // free storage for UI settings
    GlobalFree(hUIPrivate);

    return;
}

/**********************************************************************/
/* ShowSoftKbd                                                        */
/**********************************************************************/
void PASCAL ShowSoftKbd(   // Show the soft keyboard window
    HWND          hUIWnd,
    int           nShowSoftKbdCmd,
    LPPRIVCONTEXT lpImcP)
{
    HGLOBAL  hUIPrivate;
    LPUIPRIV lpUIPrivate;

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {          // can not darw status window
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {         // can not draw status window
        return;
    }

    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL1, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL2, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL3, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL4, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL5, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL6, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL7, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL8, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL9, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL10, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL11, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL12, MF_UNCHECKED);
    CheckMenuItem(lpImeL->hSKMenu, IDM_SKL13, MF_UNCHECKED);

    if (!lpUIPrivate->hSoftKbdWnd) {
        // not in show status window mode
    } else if (lpUIPrivate->nShowSoftKbdCmd != nShowSoftKbdCmd) {
        ImmShowSoftKeyboard(lpUIPrivate->hSoftKbdWnd, nShowSoftKbdCmd);
        lpUIPrivate->nShowSoftKbdCmd = nShowSoftKbdCmd;
    }

    GlobalUnlock(hUIPrivate);
    return;
}

/**********************************************************************/
/* CheckSoftKbdPosition()                                             */
/**********************************************************************/
void PASCAL CheckSoftKbdPosition(
    LPUIPRIV       lpUIPrivate,
    LPINPUTCONTEXT lpIMC)
{

#ifndef MUL_MONITOR
    UINT fPortionBits = 0;
    UINT fPortionTest;
    int  xPortion, yPortion, nPortion;
    RECT rcWnd;

    // portion of dispaly
    // 0  1
    // 2  3

    if (lpUIPrivate->hCompWnd) {
        GetWindowRect(lpUIPrivate->hCompWnd, &rcWnd);

        if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
            xPortion = 1;
        } else {
            xPortion = 0;
        }

        if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
            yPortion = 1;
        } else {
            yPortion = 0;
        }

        fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
    }

    if (lpUIPrivate->hStatusWnd) {
        GetWindowRect(lpUIPrivate->hStatusWnd, &rcWnd);

        if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
            xPortion = 1;
        } else {
            xPortion = 0;
        }

        if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
            yPortion = 1;
        } else {
            yPortion = 0;
        }

        fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
    }

    GetWindowRect(lpUIPrivate->hSoftKbdWnd, &rcWnd);

    // start from portion 3
    for (nPortion = 3, fPortionTest = 0x0008; fPortionTest;
        nPortion--, fPortionTest >>= 1) {
        if (fPortionTest & fPortionBits) {
            // someone here!
            continue;
        }

        if (nPortion % 2) {
            lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.right -
                (rcWnd.right - rcWnd.left) - UI_MARGIN;
        } else {
            lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.left;
        }

        if (nPortion / 2) {
            lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.bottom -
                (rcWnd.bottom - rcWnd.top) - UI_MARGIN;
        } else {
            lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.top;
        }

        lpIMC->fdwInit |= INIT_SOFTKBDPOS;

        break;
    }
#else   //MUL_MONITOR
    RECT rcWorkArea, rcWnd;

    GetWindowRect(lpUIPrivate->hSoftKbdWnd, &rcWnd);

    rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);

    lpIMC->ptSoftKbdPos.x = rcWorkArea.right -
                            (rcWnd.right-rcWnd.left)-UI_MARGIN;

    lpIMC->ptSoftKbdPos.y = rcWorkArea.bottom -
                            (rcWnd.bottom-rcWnd.top)-UI_MARGIN;
#endif
    return;
}

/**********************************************************************/
/* SetSoftKbdData()                                                   */
/**********************************************************************/
void PASCAL SetSoftKbdData(
    HWND           hSoftKbdWnd,
    LPINPUTCONTEXT lpIMC)
{
    int         i;
    LPSOFTKBDDATA lpSoftKbdData;
    LPPRIVCONTEXT  lpImcP;

    HGLOBAL hsSoftKbdData;

       lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
    if (!lpImcP) {
        return;
    }
    
    hsSoftKbdData = GlobalAlloc(GHND, sizeof(SOFTKBDDATA) * 2);
    if (!hsSoftKbdData) {
        ImmUnlockIMCC(lpIMC->hPrivate);
        return;
    }

    lpSoftKbdData = (LPSOFTKBDDATA)GlobalLock(hsSoftKbdData);
    if (!lpSoftKbdData) {         // can not draw soft keyboard window
        ImmUnlockIMCC(lpIMC->hPrivate);
        return;
    }

    lpSoftKbdData->uCount = 2;

    for (i = 0; i < 48; i++) {
        BYTE bVirtKey;

        bVirtKey = VirtKey48Map[i];

        if (!bVirtKey) {
            continue;
        }

        {
            WORD CHIByte, CLOByte;

#ifdef UNICODE
            lpSoftKbdData->wCode[0][bVirtKey] = SKLayout[lpImeL->dwSKWant][i];
            lpSoftKbdData->wCode[1][bVirtKey] = SKLayoutS[lpImeL->dwSKWant][i];
#else
            CHIByte = SKLayout[lpImeL->dwSKWant][i*2] & 0x00ff;
            CLOByte = SKLayout[lpImeL->dwSKWant][i*2 + 1] & 0x00ff;
            lpSoftKbdData->wCode[0][bVirtKey] = (CHIByte << 8) | CLOByte;
            CHIByte = SKLayoutS[lpImeL->dwSKWant][i*2] & 0x00ff;
            CLOByte = SKLayoutS[lpImeL->dwSKWant][i*2 + 1] & 0x00ff;
            lpSoftKbdData->wCode[1][bVirtKey] = (CHIByte << 8) | CLOByte;
#endif
        }
    }

    SendMessage(hSoftKbdWnd, WM_IME_CONTROL, IMC_SETSOFTKBDDATA,
        (LPARAM)lpSoftKbdData);

    GlobalUnlock(hsSoftKbdData);

    // free storage for UI settings
    GlobalFree(hsSoftKbdData);
    ImmUnlockIMCC(lpIMC->hPrivate);
    return;
}

/**********************************************************************/
/* UpdateSoftKbd()                                                    */
/**********************************************************************/
void PASCAL UpdateSoftKbd(
    HWND   hUIWnd)
{
    HIMC           hIMC;
    LPINPUTCONTEXT lpIMC;
    LPPRIVCONTEXT  lpImcP;
    HGLOBAL        hUIPrivate;
    LPUIPRIV       lpUIPrivate;

    hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
    if (!hIMC) {
        return;
    }

    lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
    if (!lpIMC) {
        return;
    }

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {          // can not darw soft keyboard window
        ImmUnlockIMC(hIMC);
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {         // can not draw soft keyboard window
        ImmUnlockIMC(hIMC);
        return;
    }

    lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
    if (!lpImcP) {
        GlobalUnlock(hUIPrivate);
        ImmUnlockIMC(hIMC);
        return;
    }

    if (!(lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
        if (lpUIPrivate->hSoftKbdWnd) {

            ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
            lpUIPrivate->hSoftKbdWnd = NULL;
        }

        lpUIPrivate->nShowSoftKbdCmd = SW_HIDE;
    } else if (!lpIMC->fOpen) {
        if (lpUIPrivate->nShowSoftKbdCmd != SW_HIDE) {
            ShowSoftKbd(hUIWnd, SW_HIDE, NULL);
        }
    } else {
        if (!lpUIPrivate->hSoftKbdWnd) {
            // create soft keyboard
            lpUIPrivate->hSoftKbdWnd =
                ImmCreateSoftKeyboard(SOFTKEYBOARD_TYPE_C1, hUIWnd,
                0, 0);
        }

        if (!(lpIMC->fdwInit & INIT_SOFTKBDPOS)) {
            CheckSoftKbdPosition(lpUIPrivate, lpIMC);
        }

        SetSoftKbdData(lpUIPrivate->hSoftKbdWnd, lpIMC);

        lpUIPrivate->fdwSetContext |= ISC_SHOW_SOFTKBD;

        if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
            SetWindowPos(lpUIPrivate->hSoftKbdWnd, NULL,
                lpIMC->ptSoftKbdPos.x, lpIMC->ptSoftKbdPos.y,
                0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);

            // only show, if the application want to show it
            if (lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) {
                ShowSoftKbd(hUIWnd, SW_SHOWNOACTIVATE, lpImcP);
            }
        }
    }

    ImmUnlockIMCC(lpIMC->hPrivate);
    GlobalUnlock(hUIPrivate);
    ImmUnlockIMC(hIMC);

    return;
}

/**********************************************************************/
/* SoftKbdDestryed()                                                  */
/**********************************************************************/
void PASCAL SoftKbdDestroyed(           // soft keyboard window
                                        // already destroyed
    HWND hUIWnd)
{
    HGLOBAL  hUIPrivate;
    LPUIPRIV lpUIPrivate;

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {     
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {    
        return;
    }

    lpUIPrivate->hSoftKbdWnd = NULL;

    GlobalUnlock(hUIPrivate);
}

/**********************************************************************/
/* StatusWndMsg()                                                     */
/**********************************************************************/
void PASCAL StatusWndMsg(       // set the show hide state and
    HWND        hUIWnd,
    BOOL        fOn)
{
    HGLOBAL  hUIPrivate;
    HIMC     hIMC;
    HWND     hStatusWnd;

    register LPUIPRIV lpUIPrivate;

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {
        return;
    }

    hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
    if (!hIMC) {
        GlobalUnlock(hUIPrivate);
    return;
    }

    if (fOn) {
        lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;

        if (!lpUIPrivate->hStatusWnd) {
            OpenStatus(
                hUIWnd);
        }
    } else {
        lpUIPrivate->fdwSetContext &= ~(ISC_OPEN_STATUS_WINDOW);
    }

    hStatusWnd = lpUIPrivate->hStatusWnd;

    GlobalUnlock(hUIPrivate);

    if (!hStatusWnd) {
        return;
    }

    if (!fOn) {
        register DWORD fdwSetContext;

        fdwSetContext = lpUIPrivate->fdwSetContext &
            (ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);

        if (fdwSetContext == ISC_HIDE_COMP_WINDOW) {
            ShowComp(
                hUIWnd, SW_HIDE);
        }

        fdwSetContext = lpUIPrivate->fdwSetContext &
            (ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);

        if (fdwSetContext == ISC_HIDE_CAND_WINDOW) {
            ShowCand(
                hUIWnd, SW_HIDE);
        }

        fdwSetContext = lpUIPrivate->fdwSetContext &
            (ISC_SHOW_SOFTKBD|ISC_HIDE_SOFTKBD);

        if (fdwSetContext == ISC_HIDE_SOFTKBD) {
            lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
            ShowSoftKbd(hUIWnd, SW_HIDE, NULL);
        }

        ShowStatus(
            hUIWnd, SW_HIDE);
    } else if (hIMC) {
        ShowStatus(
            hUIWnd, SW_SHOWNOACTIVATE);
    } else {
        ShowStatus(
            hUIWnd, SW_HIDE);
    }

    return;
}

/**********************************************************************/
/* ShowUI()                                                           */
/**********************************************************************/
void PASCAL ShowUI(             // show the sub windows
    HWND   hUIWnd,
    int    nShowCmd)
{
    HIMC           hIMC;
    LPINPUTCONTEXT lpIMC;
    LPPRIVCONTEXT  lpImcP;
    HGLOBAL        hUIPrivate;
    LPUIPRIV       lpUIPrivate;

    if (nShowCmd == SW_HIDE) {
    } else if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))) {
        nShowCmd = SW_HIDE;
    } else if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
        nShowCmd = SW_HIDE;
    } else if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
        ImmUnlockIMC(hIMC);
        nShowCmd = SW_HIDE;
    } else {
    }

    if (nShowCmd == SW_HIDE) {
        ShowStatus(hUIWnd, nShowCmd);
        ShowComp(hUIWnd, nShowCmd);
        ShowCand(hUIWnd, nShowCmd);
        ShowSoftKbd(hUIWnd, nShowCmd, NULL);
        return;
    }

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {          // can not darw status window
        goto ShowUIUnlockIMCC;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {         // can not draw status window
        goto ShowUIUnlockIMCC;
    }

    lpUIPrivate->fdwSetContext |= ISC_SHOWUICOMPOSITIONWINDOW;

    if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW) &&
        (lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
        if (lpUIPrivate->hCompWnd) {

            if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
                // some time the WM_NCPAINT is eaten by the app
                RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL,
                    RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
            }

            if (sImeG.IC_Trace) {            // modify 95.7.17
                SendMessage(lpUIPrivate->hCompWnd, WM_IME_NOTIFY,
                    IMN_SETCOMPOSITIONWINDOW, 0);
            }

            if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
                ShowComp(hUIWnd, nShowCmd);
            }
        } else {
            StartComp(hUIWnd);
        }
    } else if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
    } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
        lpUIPrivate->fdwSetContext |= ISC_HIDE_COMP_WINDOW;
    } else {
        ShowComp(hUIWnd, SW_HIDE);
    }

    if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW) &&
        (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)) {
        if (lpUIPrivate->hCandWnd) {
            if (lpUIPrivate->nShowCandCmd != SW_HIDE) {
                // some time the WM_NCPAINT is eaten by the app
                RedrawWindow(lpUIPrivate->hCandWnd, NULL, NULL,
                    RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
            }

            if (sImeG.IC_Trace) {            
                SendMessage(lpUIPrivate->hCandWnd, WM_IME_NOTIFY,
                    IMN_SETCANDIDATEPOS, 0x0001);
            }

            if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
                ShowCand(hUIWnd, nShowCmd);
            }
        } else {
            OpenCand(hUIWnd);
        }
    } else if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
    } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
        lpUIPrivate->fdwSetContext |= ISC_HIDE_CAND_WINDOW;
    } else {
        ShowCand(hUIWnd, SW_HIDE);
    }

    if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
        if (!lpUIPrivate->hStatusWnd) {
            OpenStatus(hUIWnd);
        }
        if (lpUIPrivate->nShowStatusCmd != SW_HIDE) {
            // some time the WM_NCPAINT is eaten by the app
            RedrawWindow(lpUIPrivate->hStatusWnd, NULL, NULL,
                RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
        }

        SendMessage(lpUIPrivate->hStatusWnd, WM_IME_NOTIFY,
            IMN_SETSTATUSWINDOWPOS, 0);
        if (lpUIPrivate->nShowStatusCmd == SW_HIDE) {
            ShowStatus(hUIWnd, nShowCmd);
        }
        else{
            ShowStatus(hUIWnd, nShowCmd);
        }
    } else if (lpUIPrivate->hStatusWnd) {
        DestroyWindow(lpUIPrivate->hStatusWnd);
    } 

    if (!lpIMC->fOpen) {
        if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
            ShowSoftKbd(hUIWnd, SW_HIDE, NULL);
        }
    } else if ((lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) &&
        (lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
        if (!lpUIPrivate->hSoftKbdWnd) {
            UpdateSoftKbd(hUIWnd);
        } else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
            ShowSoftKbd(hUIWnd, nShowCmd, lpImcP);
        } else if (lpUIPrivate->hIMC != hIMC) {
            UpdateSoftKbd(hUIWnd);
        } else {
            RedrawWindow(lpUIPrivate->hSoftKbdWnd, NULL, NULL,
                RDW_FRAME|RDW_INVALIDATE);
        }
    } else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
    } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
        lpUIPrivate->fdwSetContext |= ISC_HIDE_SOFTKBD;
    } else {
        ShowSoftKbd(hUIWnd, SW_HIDE, NULL);
    }

    // we switch to this hIMC
    lpUIPrivate->hIMC = hIMC;

    GlobalUnlock(hUIPrivate);

ShowUIUnlockIMCC:
    ImmUnlockIMCC(lpIMC->hPrivate);
    ImmUnlockIMC(hIMC);

    return;
}

/**********************************************************************/
/* ShowGuideLine                                                      */
/**********************************************************************/
void PASCAL ShowGuideLine(
    HWND hUIWnd)
{
    HIMC           hIMC;
    LPINPUTCONTEXT lpIMC;
    LPGUIDELINE    lpGuideLine;

    hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
    if (!hIMC) {
        return;
    }

    lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
    if (!lpIMC) {
        return;
    }

    lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);

    if (!lpGuideLine) {
    } else if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
        MessageBeep((UINT)-1);
        MessageBeep((UINT)-1);
    } else if (lpGuideLine->dwLevel == GL_LEVEL_WARNING) {
        MessageBeep((UINT)-1);
    } else {
    }

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

    return;
}

/**********************************************************************/
/* UpdateStatusWindow()                                               */
/* Return Value:                                                      */
/*     none                                                             */
/**********************************************************************/
BOOL UpdateStatusWindow(
    HWND   hUIWnd)
{
    HWND           hStatusWnd;

    if (!(hStatusWnd = GetStatusWnd(hUIWnd))) {
        return (FALSE);
    }

    InvalidateRect(hStatusWnd, &(sImeG.rcStatusText), TRUE);
    UpdateWindow(hStatusWnd);

    return (TRUE);
}


/**********************************************************************/
/* NotifyUI()                                                         */
/**********************************************************************/
void PASCAL NotifyUI(
    HWND        hUIWnd,
    WPARAM      wParam,
    LPARAM      lParam)
{
    HWND hStatusWnd;

    switch (wParam) {
    case IMN_OPENSTATUSWINDOW:
        //PostStatus(hUIWnd, TRUE);
        StatusWndMsg(hUIWnd, TRUE);
        break;
    case IMN_CLOSESTATUSWINDOW:
        //PostStatus(hUIWnd, FALSE);
        StatusWndMsg(hUIWnd, FALSE);
        break;
    case IMN_OPENCANDIDATE:
        if (lParam & 0x00000001) {
            OpenCand(hUIWnd);
        }
        break;
    case IMN_CHANGECANDIDATE:
        if (lParam & 0x00000001) {
            HDC  hDC;
            HWND hCandWnd;

            hCandWnd = GetCandWnd(hUIWnd);
            if (!hCandWnd) {
                return;
            }

            hDC = GetDC(hCandWnd);
            PaintCandWindow(hCandWnd, hDC);
            ReleaseDC(hCandWnd, hDC);
        }
        break;
    case IMN_CLOSECANDIDATE:
        if (lParam & 0x00000001) {
            CloseCand(hUIWnd);
        }
        break;
    case IMN_SETSENTENCEMODE:
        break;
    case IMN_SETOPENSTATUS:
    case IMN_SETCONVERSIONMODE:
        hStatusWnd = GetStatusWnd(hUIWnd);
        if (!hStatusWnd) {
            return;
        }

        {
            RECT rcRect;

            rcRect = sImeG.rcStatusText;
            
            // off by 1
            rcRect.right += 1;
            rcRect.bottom += 1;

            RedrawWindow(hStatusWnd, &rcRect, NULL, RDW_INVALIDATE);
        }
        break;
    case IMN_SETCOMPOSITIONFONT:
        // we are not going to change font, but an IME can do this if it want
        break;
    case IMN_SETCOMPOSITIONWINDOW:
        {
            HWND hCompWnd;

            hCompWnd = GetCompWnd(hUIWnd);
            if (!hCompWnd) {
                return;
            }

            PostMessage(hCompWnd, WM_IME_NOTIFY, wParam, lParam);
        }
        break;
    case IMN_SETCANDIDATEPOS:
        {
            HWND hCandWnd;

            hCandWnd = GetCandWnd(hUIWnd);
            if (!hCandWnd) {
                return;
            }

            PostMessage(hCandWnd, WM_IME_NOTIFY, wParam, lParam);
        }
        break;
    case IMN_SETSTATUSWINDOWPOS:
        hStatusWnd = GetStatusWnd(hUIWnd);
        if (hStatusWnd) {
            PostMessage(hStatusWnd, WM_IME_NOTIFY, wParam, lParam);
        } else {
        }
        break;
    case IMN_GUIDELINE:
        ShowGuideLine(hUIWnd);

        break;
    case IMN_PRIVATE:
        switch (lParam) {
        case IMN_PRIVATE_UPDATE_SOFTKBD:
            UpdateSoftKbd(hUIWnd);
            break;
        case IMN_PRIVATE_UPDATE_STATUS:
            UpdateStatusWindow(hUIWnd);
            break;
        case IMN_PRIVATE_DESTROYCANDWIN:
            SendMessage(GetCandWnd(hUIWnd), WM_DESTROY, (WPARAM)0, (LPARAM)0);
            break;
        case IMN_PRIVATE_CMENUDESTROYED:
            CMenuDestroyed(hUIWnd);
            break;
        case IMN_PRIVATE_SOFTKEYMENUDESTROYED:
            SoftkeyMenuDestroyed(hUIWnd);
            break;
        }
        break;
    case IMN_SOFTKBDDESTROYED:
        SoftKbdDestroyed(hUIWnd);
        break;
    default:
        break;
    }

    return;
}

/**********************************************************************/
/* SetContext()                                                       */
/**********************************************************************/
void PASCAL SetContext(         // the context activated/deactivated
    HWND   hUIWnd,
    BOOL   fOn,
    LPARAM lShowUI)
{
    HIMC           hIMC;
    LPINPUTCONTEXT lpIMC;
    LPPRIVCONTEXT  lpImcP;
    HGLOBAL        hUIPrivate;
    register LPUIPRIV lpUIPrivate;
#if defined(COMBO_IME)
    DWORD    dwRegImeIndex;
#endif
    RECT            rcWorkArea;

#ifdef MUL_MONITOR
    rcWorkArea = ImeMonitorWorkAreaFromWindow(hUIWnd);
#else
    rcWorkArea = sImeG.rcWorkArea;
#endif


    hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);

    if (!hIMC) {          
        return ;
    }

    // get lpIMC
    lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
    if (!lpIMC) {
        return;
    }

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {
        ImmUnlockIMC(hIMC);
        return;
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {
        ImmUnlockIMC(hIMC);
        return;
    }

    if (fOn) {
        register DWORD fdwSetContext;

        lpUIPrivate->fdwSetContext = lpUIPrivate->fdwSetContext &
            ~(ISC_SHOWUIALL|ISC_HIDE_SOFTKBD);

        lpUIPrivate->fdwSetContext |= (lShowUI & ISC_SHOWUIALL) |
            ISC_SHOW_SOFTKBD;

        {
        HKEY hKey;
        DWORD bcData; 
        char buf[256];
        bcData=256;
        if(RegOpenKeyEx (HKEY_CURRENT_USER,
                         TEXT("Control Panel\\Input Method"),
                         0,
                         KEY_ENUMERATE_SUB_KEYS |
                         KEY_EXECUTE |
                         KEY_QUERY_VALUE,
                         &hKey)){
            goto SetShowStatus;
        }
        if(RegQueryValueEx (hKey, TEXT("show status"),
                     NULL,
                     NULL,             //null-terminate string
                     (LPBYTE)buf,              //&bData,
                     &bcData) != ERROR_SUCCESS){
                     // Set default as ON if no entry in registry
                     lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
                 goto SetShowStatus;
             }
        if(strcmp(buf, "1")==0)
            lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
        else
            lpUIPrivate->fdwSetContext &= ~ISC_OPEN_STATUS_WINDOW;
SetShowStatus:
        RegCloseKey(hKey);
        }

        fdwSetContext = lpUIPrivate->fdwSetContext &
            (ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);

        if (fdwSetContext == ISC_HIDE_COMP_WINDOW) {
            ShowComp(
                hUIWnd, SW_HIDE);
        } else if (fdwSetContext & ISC_HIDE_COMP_WINDOW) {
            lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_COMP_WINDOW);
        } else {
        }

        fdwSetContext = lpUIPrivate->fdwSetContext &
            (ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);

        if (fdwSetContext == ISC_HIDE_CAND_WINDOW) {
            ShowCand(
                hUIWnd, SW_HIDE);
        } else if (fdwSetContext & ISC_HIDE_CAND_WINDOW) {
            lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_CAND_WINDOW);
        } else {
        }

        if (lpIMC->cfCandForm[0].dwIndex != 0) {
            lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
        }


        lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
        if (!lpImcP) {
            GlobalUnlock(hUIPrivate);
            ImmUnlockIMC(hIMC);
            return;
        }

        // init ime properties & reset context
        {
            HKEY  hKeyCurrVersion;
            HKEY  hKeyGB;
            DWORD ValueType;
            DWORD ValueSize;
            LONG    retCode;

            retCode = OpenReg_PathSetup(&hKeyCurrVersion);
            if (retCode) {
            TCHAR    Buf[MAX_PATH];
                wsprintf (Buf, TEXT("Error: RegOpenKeyEx = %d"), retCode);
                MessageBox (lpIMC->hWnd, Buf, szWarnTitle, MB_OK | MB_ICONINFORMATION);
                return;
            }

#if defined(COMBO_IME)
            retCode = OpenReg_User (hKeyCurrVersion,
                               szImeRegName,
                               &hKeyGB);
#else
            retCode = OpenReg_User (hKeyCurrVersion,
                               szImeName,
                               &hKeyGB);
#endif //COMBO_IME
            // query ¹â±ê¸úËæ value
            ValueSize = sizeof(DWORD);
            RegQueryValueEx (hKeyGB,szTrace ,
                            (DWORD)0,
                               (LPDWORD)&ValueType,
                            (LPBYTE)&sImeG.IC_Trace,
                            (LPDWORD)&ValueSize);
#ifdef CROSSREF         
            if(RegQueryValueEx (hKeyGB, szRegRevKL,
                     NULL,
                     NULL,             //null-terminate string
                     (LPBYTE)&sImeG.hRevKL,              //&bData,
                     &ValueSize) != ERROR_SUCCESS)
            sImeG.hRevKL = NULL;
            if(RegQueryValueEx (hKeyGB, szRegRevMaxKey,
                     NULL,
                     NULL,             //null-terminate string
                     (LPBYTE)&sImeG.nRevMaxKey,              //&bData,
                     &ValueSize) != ERROR_SUCCESS)
            sImeG.hRevKL = NULL;
#endif
        

#if defined(COMBO_IME)
            // query ¹â±ê¸úËæ value
            ValueSize = sizeof(DWORD);
            RegQueryValueEx (hKeyGB, szRegImeIndex,
                            (DWORD)0,
                            (LPDWORD)&ValueType,
                            (LPBYTE)&dwRegImeIndex,
                            (LPDWORD)&ValueSize);
#endif

            RegCloseKey(hKeyGB);
            RegCloseKey(hKeyCurrVersion);

        }

#if defined(COMBO_IME)
        if(sImeL.dwRegImeIndex != dwRegImeIndex) {
        DWORD    dwConvMode;
        int        cxBorder, cyBorder;

            //change current IME index
            dwConvMode = lpIMC->fdwConversion ^ (IME_CMODE_INDEX_FIRST << sImeL.dwRegImeIndex);
            sImeL.dwRegImeIndex = dwRegImeIndex;
            szImeName = pszImeName[dwRegImeIndex];
            dwConvMode |= (IME_CMODE_INDEX_FIRST << dwRegImeIndex);
            // re-caculate statusuidata
            cxBorder = GetSystemMetrics(SM_CXBORDER);
            cyBorder = GetSystemMetrics(SM_CYBORDER);
            InitStatusUIData(cxBorder, cyBorder);

            ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
        }
#endif //COMBO_IME

        if(sImeG.IC_Trace != SaTC_Trace) {
            int UI_MODE;

            lpImcP->iImeState = CST_INIT;
            CompCancel(hIMC, lpIMC);
            
            // init fields of hPrivate
            lpImcP->fdwImeMsg = (DWORD)0;
            lpImcP->dwCompChar = (DWORD)0;
            lpImcP->fdwGcsFlag = (DWORD)0;
            lpImcP->uSYHFlg = 0x00000000;
            lpImcP->uDYHFlg = 0x00000000;

            // change compwnd size

            // init fields of hIMC
            lpIMC->fOpen = TRUE;

            SendMessage(GetCandWnd(hUIWnd), WM_DESTROY, (WPARAM)0, (LPARAM)0);
            
            // set cand window data
            if(sImeG.IC_Trace) {
                UI_MODE = BOX_UI;
            } else {
                POINT ptSTFixPos;
            
    
                UI_MODE = LIN_UI;
                ptSTFixPos.x = 0;
                ptSTFixPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
                ImmSetStatusWindowPos(hIMC, (LPPOINT)&ptSTFixPos);
            }
            
            InitCandUIData(
                GetSystemMetrics(SM_CXBORDER),
                GetSystemMetrics(SM_CYBORDER), UI_MODE);
        }
            
        SaTC_Trace = sImeG.IC_Trace;

        // init Caps
        {
            BYTE  lpbKeyState[256];
            DWORD fdwConversion;

            if (!GetKeyboardState(lpbKeyState))
                lpbKeyState[VK_CAPITAL] = 0;
                         
            if (lpbKeyState[VK_CAPITAL] & 0x01) {
                // 10.11 add
                uCaps = 1;
                // change to alphanumeric mode
                fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_CHARCODE |
                    IME_CMODE_NATIVE | IME_CMODE_EUDC);
            } else {
                // change to native mode
                if(uCaps == 1) {
                        fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
                        ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC);
                } else {
                    fdwConversion = lpIMC->fdwConversion;
                }
                uCaps = 0;
            }
            ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
        }

        if ((lpIMC->cfCompForm.dwStyle & CFS_FORCE_POSITION)
            && (sImeG.IC_Trace)) {
            POINT ptNew;            // new position of UI
            POINT ptSTWPos;

            ImmGetStatusWindowPos(hIMC, (LPPOINT)&ptSTWPos);

            ptNew.x = ptSTWPos.x + sImeG.xStatusWi + UI_MARGIN;
            if((ptSTWPos.x + sImeG.xStatusWi + sImeG.xCandWi + lpImeL->xCompWi + 2 * UI_MARGIN) >=
              rcWorkArea.right) { 
                ptNew.x = ptSTWPos.x - lpImeL->xCompWi - UI_MARGIN;
            }
            ptNew.x += lpImeL->cxCompBorder;
            ptNew.y = ptSTWPos.y + lpImeL->cyCompBorder;
            lpIMC->cfCompForm.ptCurrentPos = ptNew;

            ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
            lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
        }
    } else {
        lpUIPrivate->fdwSetContext &= ~ISC_SETCONTEXT_UI;
    }

    GlobalUnlock(hUIPrivate);

    UIPaint(hUIWnd);

    ImmUnlockIMC(hIMC);
    return;
}


/**********************************************************************/
/* GetCompWindow()                                                    */
/**********************************************************************/
LRESULT PASCAL GetCompWindow(
    HWND              hUIWnd,
    LPCOMPOSITIONFORM lpCompForm)
{
    HWND hCompWnd;
    RECT rcCompWnd;

    hCompWnd = GetCompWnd(hUIWnd);

    if (!hCompWnd) {
        return (1L);
    }

    if (!GetWindowRect(hCompWnd, &rcCompWnd)) {
        return (1L);
    }

    lpCompForm->dwStyle = CFS_POINT|CFS_RECT;
    lpCompForm->ptCurrentPos = *(LPPOINT)&rcCompWnd;
    lpCompForm->rcArea = rcCompWnd;

    return (0L);
}

/**********************************************************************/
/* SelectIME()                                                        */
/**********************************************************************/
void PASCAL SelectIME(          // switch IMEs
    HWND hUIWnd,
    BOOL fSelect)
{
    if (!fSelect) {
        ShowUI(hUIWnd, SW_HIDE);
    } else {

        ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
          
    }

    return;
}

/**********************************************************************/
/* UIPaint()                                                          */
/**********************************************************************/
LRESULT PASCAL UIPaint(
    HWND        hUIWnd)
{
    PAINTSTRUCT ps;
    MSG         sMsg;
    HGLOBAL     hUIPrivate;
    LPUIPRIV    lpUIPrivate;

    // for safety
    BeginPaint(hUIWnd, &ps);
    EndPaint(hUIWnd, &ps);

    // some application will not remove the WM_PAINT messages
    PeekMessage(&sMsg, hUIWnd, WM_PAINT, WM_PAINT, PM_REMOVE|PM_NOYIELD);

    hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
    if (!hUIPrivate) {
        return (0L);
    }

    lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
    if (!lpUIPrivate) {
        return (0L);
    }

    if (lpUIPrivate->fdwSetContext & ISC_SETCONTEXT_UI) {
        ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
    } else {
        ShowUI(hUIWnd, SW_HIDE);
    }

    GlobalUnlock(hUIPrivate);

    return (0L);
}

/**********************************************************************/
/* UIWndProc()                                                        */
/**********************************************************************/
LRESULT CALLBACK UIWndProc(
    HWND   hUIWnd,
    UINT   uMsg,
    WPARAM wParam,
    LPARAM lParam)
{

    switch (uMsg) {
    case WM_CREATE:
        CreateUIWindow(hUIWnd);
        break;
    case WM_DESTROY:
        DestroyUIWindow(hUIWnd);
        break;
    case WM_IME_STARTCOMPOSITION:
        // you can create a window as the composition window here
        StartComp(hUIWnd);
        break;
    case WM_IME_COMPOSITION:
        if (!sImeG.IC_Trace) {
        } else if (lParam & GCS_RESULTSTR) {
            MoveDefaultCompPosition(hUIWnd);
        } else {
        }

        {
            HWND hCompWnd;

            hCompWnd = GetCompWnd(hUIWnd);

            if (hCompWnd) {
                RECT rcRect;

                rcRect = lpImeL->rcCompText;
                // off by 1
                rcRect.right += 1;
                rcRect.bottom += 1;

                RedrawWindow(hCompWnd, &rcRect, NULL, RDW_INVALIDATE);
            }
        }
        break;
    case WM_IME_ENDCOMPOSITION:
        // you can destroy the composition window here
        EndComp(hUIWnd);
        break;
    case WM_IME_NOTIFY:
        NotifyUI(hUIWnd, wParam, lParam);
        break;
    case WM_IME_SETCONTEXT:
        SetContext(hUIWnd, (BOOL)wParam, lParam);
        
        if (wParam && GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))
            SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOMOVE);

        break;
    case WM_IME_CONTROL:
        switch (wParam) {
        case IMC_GETCANDIDATEPOS:
            return (1L);                    // not implemented yet
        case IMC_GETCOMPOSITIONFONT:
            return (1L);                    // not implemented yet
        case IMC_GETCOMPOSITIONWINDOW:
            return GetCompWindow(hUIWnd, (LPCOMPOSITIONFORM)lParam);
        case IMC_GETSTATUSWINDOWPOS:
            {
                HWND   hStatusWnd;
                RECT   rcStatusWnd;
                LPARAM lParam;

                hStatusWnd = GetStatusWnd(hUIWnd);
                if (!hStatusWnd) {
                    return (0L);    // fail, return (0, 0)?
                }

                if (!GetWindowRect(hStatusWnd, &rcStatusWnd)) {
                     return (0L);    // fail, return (0, 0)?
                }

                lParam = MAKELRESULT(rcStatusWnd.left, rcStatusWnd.top);

                return (lParam);
            }
            return (0L);
        case IMC_SETSTATUSWINDOWPOS:
            {
                HIMC            hIMC;
                LPINPUTCONTEXT  lpIMC;
                LPPRIVCONTEXT   lpImcP;
                //COMPOSITIONFORM CompForm;
                POINT           ptPos;
                RECT            rcWorkArea;

#ifdef MUL_MONITOR
                rcWorkArea = ImeMonitorWorkAreaFromWindow(hUIWnd);
#else
                rcWorkArea = sImeG.rcWorkArea;
#endif

                ptPos.x = ((LPPOINTS)&lParam)->x;
                ptPos.y = ((LPPOINTS)&lParam)->y;

                hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
                if (!hIMC) {
                    return (1L);
                }

                if(!ImmSetStatusWindowPos(hIMC, &ptPos)) {
                    return (1L);
                }

                // set comp window position when TraceCuer
                lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
                if (!lpIMC) {
                    return (1L);
                }

                lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
                if (!lpImcP) {
                    return (1L);
                }

                if(!sImeG.IC_Trace) {
                    lpIMC->cfCompForm.dwStyle = CFS_RECT;
                    lpIMC->cfCompForm.ptCurrentPos.x = ptPos.x + sImeG.xStatusWi + UI_MARGIN;
                    lpIMC->cfCompForm.ptCurrentPos.y = ptPos.y;
                    CopyRect(&lpIMC->cfCompForm.rcArea, &rcWorkArea);

                    ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
                    // set composition window to the new poosition
                    PostMessage(GetCompWnd(hUIWnd), WM_IME_NOTIFY, IMN_SETCOMPOSITIONWINDOW, 0);

                }

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

                return (0L);
            }
            return (1L);
        default:
            return (1L);
        }
        break;
    case WM_IME_COMPOSITIONFULL:
        return (0L);
    case WM_IME_SELECT:
//#if  defined(LATER)
        SetContext(hUIWnd, (BOOL)wParam, 0);
//#else
//        SelectIME(hUIWnd, (BOOL)wParam);
//#endif
        return (0L);
    case WM_MOUSEACTIVATE:
        return (MA_NOACTIVATE);
    case WM_PAINT:
        return UIPaint(hUIWnd);
    default:
        return DefWindowProc(hUIWnd, uMsg, wParam, lParam);
    }
    return (0L);
}

void DrawConvexRect(HDC hDC, int x1, int y1, int x2, int y2)
{
    HPEN hPen, hOldPen;
    
    SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
    SelectObject(hDC, GetStockObject(WHITE_PEN));
    MoveToEx(hDC, x1, y1,NULL);
    LineTo(hDC, x2, y1);
    MoveToEx(hDC, x1, y1,NULL);
    LineTo(hDC, x1, y2);
    hPen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));

    if ( hPen )
    {
        hOldPen = SelectObject (hDC, hPen);
        MoveToEx(hDC, x2-1, y2-1,NULL);
        LineTo(hDC, x2-1, y1);
        MoveToEx(hDC, x2-1, y2-1,NULL);
        LineTo(hDC, x1, y2-1);
        SelectObject(hDC, hOldPen);
        DeleteObject(hPen);          
    }
}

void DrawConvexRectP(HDC hDC, int x1, int y1, int x2, int y2)
{
    HPEN hPen, hOldPen;
    
    SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
    SelectObject(hDC, GetStockObject(WHITE_PEN));
    MoveToEx(hDC, x1, y1,NULL);
    LineTo(hDC, x2 - 1, y1);
    MoveToEx(hDC, x1, y1,NULL);
    LineTo(hDC, x1, y2 - 1);
    hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));

    if ( hPen )
    {
        hOldPen = SelectObject (hDC, hPen);
        MoveToEx(hDC, x2-1, y2-1,NULL);
        LineTo(hDC, x2-1, y1);
        MoveToEx(hDC, x2-1, y2-1,NULL);
        LineTo(hDC, x1, y2-1);
        SelectObject(hDC, hOldPen);
        DeleteObject(hPen);          
    }
}

void DrawConcaveRect(HDC hDC, int x1, int y1, int x2, int y2)
{
    HPEN hLtPen = CreatePen(PS_SOLID, 1, 0x00808080);

    if ( hLtPen != NULL )
    {
        HPEN OldPen = SelectObject(hDC, hLtPen);
        MoveToEx(hDC, x1, y1,NULL);
        LineTo(hDC, x2, y1);
        MoveToEx(hDC, x1, y1,NULL);
        LineTo(hDC, x1, y2);
        SelectObject(hDC, GetStockObject(WHITE_PEN));
        MoveToEx(hDC, x2  , y2,NULL);
        LineTo(hDC, x2  , y1-1);
        MoveToEx(hDC, x2  , y2,NULL);
        LineTo(hDC, x1-1, y2);
        SelectObject(hDC, OldPen);
        DeleteObject(hLtPen);     
    }
}

