BOOL GenerateMessage(HIMC hIMC, LPDWORD lpdwTransKey,LPGENEMSG lpGeneMsg) { LPINPUTCONTEXT lpIMC; if( (lpIMC = ImmLockIMC(hIMC)) == NULL ) return FALSE; if (lpdwTransKey){ ImmUnlockIMC(hIMC); return GenerateMessageToTransKey(lpdwTransKey,lpGeneMsg); } if (IsWindow(lpIMC->hWnd)) { LPDWORD lpdw; if (!(lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD) * (lpIMC->dwNumMsgBuf +1) * 3))) return FALSE; if (!(lpdw = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf))) return FALSE; lpdw += (lpIMC->dwNumMsgBuf) * 3; *((LPGENEMSG)lpdw) = *lpGeneMsg; ImmUnlockIMCC(lpIMC->hMsgBuf); lpIMC->dwNumMsgBuf++; ImmGenerateMessage(hIMC); } ImmUnlockIMC(hIMC); return TRUE; }
HRESULT WeaselIME::_EndComposition(LPCWSTR composition) { if (composition) { LPINPUTCONTEXT lpIMC; LPCOMPOSITIONSTRING lpCompStr; lpIMC = ImmLockIMC(m_hIMC); if (!lpIMC) return E_FAIL; lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if (!lpCompStr) { ImmUnlockIMC(m_hIMC); return E_FAIL; } CompositionInfo* pInfo = (CompositionInfo*)lpCompStr; wcscpy_s(pInfo->szResultStr, composition); lpCompStr->dwResultStrLen = wcslen(pInfo->szResultStr); ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMC(m_hIMC); _AddIMEMessage(WM_IME_COMPOSITION, 0, GCS_COMP|GCS_RESULTSTR); } _AddIMEMessage(WM_IME_ENDCOMPOSITION, 0, 0); _AddIMEMessage(WM_IME_NOTIFY, IMN_CLOSECANDIDATE, 0); m_composing = false; return S_OK; }
void SetCandPosition(HWND hCandWnd) { LPUIPRIV lpUIPriv; HIMC hIMC; LPINPUTCONTEXT lpIMC; POINT ptNew; lpUIPriv = (LPUIPRIV)GetWindowLong(hCandWnd, IMMGWL_PRIVATE); if (!lpUIPriv) { return; } if (!lpUIPriv->lpCandList) { return; } hIMC = (HIMC)GetWindowLong(hCandWnd, IMMGWL_IMC); if (!hIMC) { return; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { ImmUnlockIMC(hIMC); return; } GetWorkArea(&g_sImeUIG.rcWorkArea); ImmUnlockIMC(hIMC); AdjustCandWnd(hCandWnd, ptNew); return; }
HRESULT WeaselIME::_Initialize() { LPINPUTCONTEXT lpIMC = ImmLockIMC(m_hIMC); if(!lpIMC) return E_FAIL; lpIMC->fOpen = TRUE; HIMCC& hIMCC = lpIMC->hCompStr; if (!hIMCC) hIMCC = ImmCreateIMCC(sizeof(CompositionInfo)); else hIMCC = ImmReSizeIMCC(hIMCC, sizeof(CompositionInfo)); if(!hIMCC) { ImmUnlockIMC(m_hIMC); return E_FAIL; } CompositionInfo* pInfo = (CompositionInfo*)ImmLockIMCC(hIMCC); if (!pInfo) { ImmUnlockIMC(m_hIMC); return E_FAIL; } pInfo->Reset(); ImmUnlockIMCC(hIMCC); ImmUnlockIMC(m_hIMC); return S_OK; }
void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) { HIMC imc; LPINPUTCONTEXT lpIMC; HIMCC newCompStr; LPIMEPRIVATE myPrivate; imc = RealIMC(FROM_X11); lpIMC = ImmLockIMC(imc); if (lpIMC == NULL) return; newCompStr = updateResultStr(lpIMC->hCompStr, lpResult, dwResultLen); ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = newCompStr; myPrivate = ImmLockIMCC(lpIMC->hPrivate); if (!myPrivate->bInComposition) GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_RESULTSTR); if (!myPrivate->bInComposition) GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMC(imc); }
static void test_ImmDestroyContext(void) { HIMC imc; DWORD ret, count; INPUTCONTEXT *ic; imc = ImmCreateContext(); count = ImmGetIMCLockCount(imc); ok(count == 0, "expect 0, returned %d\n", count); ic = ImmLockIMC(imc); ok(ic != NULL, "ImmLockIMC failed!\n"); count = ImmGetIMCLockCount(imc); ok(count == 1, "expect 1, returned %d\n", count); ret = ImmDestroyContext(imc); ok(ret == TRUE, "Destroy a locked IMC should success!\n"); ic = ImmLockIMC(imc); todo_wine ok(ic == NULL, "Lock a destroyed IMC should fail!\n"); ret = ImmUnlockIMC(imc); todo_wine ok(ret == FALSE, "Unlock a destroyed IMC should fail!\n"); count = ImmGetIMCLockCount(imc); todo_wine ok(count == 0, "Get lock count of a destroyed IMC should return 0!\n"); SetLastError(0xdeadbeef); ret = ImmDestroyContext(imc); todo_wine ok(ret == FALSE, "Destroy a destroyed IMC should fail!\n"); ret = GetLastError(); todo_wine ok(ret == ERROR_INVALID_HANDLE, "wrong last error %08x!\n", ret); }
LRESULT WeaselIME::OnIMEFocus(BOOL fFocus) { EZDBGONLYLOGGERPRINT("On IME focus: %d, HIMC = 0x%x", fFocus, m_hIMC); LPINPUTCONTEXT lpIMC = ImmLockIMC(m_hIMC); if(!lpIMC) { return 0; } if (fFocus) { if(!(lpIMC->fdwInit & INIT_COMPFORM)) { lpIMC->cfCompForm.dwStyle = CFS_DEFAULT; GetCursorPos(&lpIMC->cfCompForm.ptCurrentPos); ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos); lpIMC->fdwInit |= INIT_COMPFORM; } m_client.FocusIn(); } else { m_client.FocusOut(); } ImmUnlockIMC(m_hIMC); return 0; }
void IME_SetCompositionStatus(BOOL fOpen) { HIMC imc; LPINPUTCONTEXT lpIMC; LPIMEPRIVATE myPrivate; imc = RealIMC(FROM_X11); lpIMC = ImmLockIMC(imc); if (lpIMC == NULL) return; myPrivate = ImmLockIMCC(lpIMC->hPrivate); if (fOpen && !myPrivate->bInComposition) { GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); } else if (!fOpen && myPrivate->bInComposition) { ShowWindow(myPrivate->hwndDefault, SW_HIDE); ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = ImeCreateBlankCompStr(); GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); } myPrivate->bInComposition = fOpen; ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMC(imc); }
void SelectCandFromCandlist( HIMC hIMC, WORD wParam) { if( wParam >= _T('0') && wParam <= _T('9') ){ DWORD dwIdx; LPTSTR lpConvStr; LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; LPCOMPOSITIONSTRING lpCompStr; lpIMC = ImmLockIMC(hIMC); lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]); lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if( wParam == (WORD)_T('0') ) dwIdx=9; else dwIdx = wParam - _T('1'); if(dwIdx < lpCandList->dwPageSize ) { dwIdx += lpCandList->dwPageStart; if( dwIdx < (lpCandList->dwCount + 2) && lpCandList->dwCount){ lpConvStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szConvCompStr; _tcscpy(lpConvStr,GETLPCANDSTR(lpCandList,dwIdx)); MakeResultString(hIMC,TRUE); } } ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); } return; }
static BOOL UnlockRealIMC(HIMC hIMC) { HIMC real_imc = RealIMC(hIMC); if (real_imc) return ImmUnlockIMC(real_imc); else return FALSE; }
BOOL MakeResultString( HIMC hIMC,BOOL fFlag) { GENEMSG GnMsg; LPCOMPOSITIONSTRING lpCompStr; LPINPUTCONTEXT lpIMC; LPTSTR lpConvStr,lpPreResultStr; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; /* if (!IsCompStr(hIMC)) return FALSE; */ wConversionMode = 0; dwCurPhraseAttrib=0; lpIMC = ImmLockIMC(hIMC); lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]); if(fFlag) { lpConvStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szConvCompStr; lpPreResultStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szPreResultStr; _tcscpy(lpPreResultStr,lpConvStr); if(wConversionSet & CONVERSION_SET_BIG5) gb2big(lpConvStr); _tcscpy(GETLPRESULTSTR(lpCompStr),lpConvStr); lpCompStr->dwResultStrLen = _tcslen(lpConvStr); } else{ *GETLPRESULTSTR(lpCompStr) = _T('\0'); lpCompStr->dwResultStrLen = 0; } lpCandList->dwCount = 0; lpCompStr->dwCompStrLen = 0; _tcscpy(GETLPCANDSTR(lpCandList,0),_T("")); _tcscpy(GETLPCANDSTR(lpCandList,1),_T("")); ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMCC(lpIMC->hCandInfo); GnMsg.msg = WM_IME_COMPOSITION; GnMsg.wParam = 0; GnMsg.lParam = GCS_RESULTSTR; GenerateMessage(hIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg); GnMsg.msg = WM_IME_ENDCOMPOSITION; GnMsg.wParam = 0; GnMsg.lParam = 0; GenerateMessage(hIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg); ImmUnlockIMC(hIMC); return TRUE; }
BOOL IsIMEOpen(HIMC hIMC) { BOOL fOpen; LPINPUTCONTEXT lpIMC; if (!(lpIMC = ImmLockIMC(hIMC))) return FALSE; fOpen = lpIMC->fOpen; ImmUnlockIMC(hIMC); return fOpen; }
LRESULT WeaselIME::OnUIMessage(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp) { LPINPUTCONTEXT lpIMC = (LPINPUTCONTEXT)ImmLockIMC(m_hIMC); switch (uMsg) { case WM_IME_NOTIFY: { EZDBGONLYLOGGERPRINT("WM_IME_NOTIFY: wp = 0x%x, lp = 0x%x, HIMC = 0x%x", wp, lp, m_hIMC); _OnIMENotify(lpIMC, wp, lp); } break; case WM_IME_SELECT: { EZDBGONLYLOGGERPRINT("WM_IME_SELECT: wp = 0x%x, lp = 0x%x, HIMC = 0x%x", wp, lp, m_hIMC); if (m_preferCandidatePos) _SetCandidatePos(lpIMC); else _SetCompositionWindow(lpIMC); } break; case WM_IME_STARTCOMPOSITION: { EZDBGONLYLOGGERPRINT("WM_IME_STARTCOMPOSITION: wp = 0x%x, lp = 0x%x, HIMC = 0x%x", wp, lp, m_hIMC); if (m_preferCandidatePos) _SetCandidatePos(lpIMC); else _SetCompositionWindow(lpIMC); } break; default: if (!IsIMEMessage(uMsg)) { ImmUnlockIMC(m_hIMC); return DefWindowProcW(hWnd, uMsg, wp, lp); } EZDBGONLYLOGGERPRINT("WM_IME_(0x%x): wp = 0x%x, lp = 0x%x, HIMC = 0x%x", uMsg, wp, lp, m_hIMC); } ImmUnlockIMC(m_hIMC); return 0; }
HRESULT WeaselIME::_AddIMEMessage(UINT msg, WPARAM wp, LPARAM lp) { if(!m_hIMC) return S_FALSE; LPINPUTCONTEXT lpIMC = (LPINPUTCONTEXT)ImmLockIMC(m_hIMC); if(!lpIMC) return E_FAIL; HIMCC hBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(TRANSMSG) * (lpIMC->dwNumMsgBuf + 1)); if(!hBuf) { ImmUnlockIMC(m_hIMC); return E_FAIL; } lpIMC->hMsgBuf = hBuf; LPTRANSMSG pBuf = (LPTRANSMSG)ImmLockIMCC(hBuf); if(!pBuf) { ImmUnlockIMC(m_hIMC); return E_FAIL; } DWORD last = lpIMC->dwNumMsgBuf; pBuf[last].message = msg; pBuf[last].wParam = wp; pBuf[last].lParam = lp; lpIMC->dwNumMsgBuf++; ImmUnlockIMCC(hBuf); ImmUnlockIMC(m_hIMC); if (!ImmGenerateMessage(m_hIMC)) { return E_FAIL; } return S_OK; }
static void test_ImmGetIMCLockCount(void) { HIMC imc; DWORD count, ret, i; INPUTCONTEXT *ic; imc = ImmCreateContext(); count = ImmGetIMCLockCount(imc); ok(count == 0, "expect 0, returned %d\n", count); ic = ImmLockIMC(imc); ok(ic != NULL, "ImmLockIMC failed\n!"); count = ImmGetIMCLockCount(imc); ok(count == 1, "expect 1, returned %d\n", count); ret = ImmUnlockIMC(imc); ok(ret == TRUE, "expect TRUE, ret %d\n", ret); count = ImmGetIMCLockCount(imc); ok(count == 0, "expect 0, returned %d\n", count); ret = ImmUnlockIMC(imc); ok(ret == TRUE, "expect TRUE, ret %d\n", ret); count = ImmGetIMCLockCount(imc); ok(count == 0, "expect 0, returned %d\n", count); for (i = 0; i < GMEM_LOCKCOUNT * 2; i++) { ic = ImmLockIMC(imc); ok(ic != NULL, "ImmLockIMC failed!\n"); } count = ImmGetIMCLockCount(imc); todo_wine ok(count == GMEM_LOCKCOUNT, "expect GMEM_LOCKCOUNT, returned %d\n", count); for (i = 0; i < GMEM_LOCKCOUNT - 1; i++) ImmUnlockIMC(imc); count = ImmGetIMCLockCount(imc); todo_wine ok(count == 1, "expect 1, returned %d\n", count); ImmUnlockIMC(imc); count = ImmGetIMCLockCount(imc); todo_wine ok(count == 0, "expect 0, returned %d\n", count); ImmDestroyContext(imc); }
BOOL IsCompStr(HIMC hIMC) { LPINPUTCONTEXT lpIMC; LPCOMPOSITIONSTRING lpCompStr; BOOL fRet = FALSE; if (!(lpIMC = ImmLockIMC(hIMC))) return FALSE; if (ImmGetIMCCSize(lpIMC->hCompStr) < sizeof (COMPOSITIONSTRING)) { ImmUnlockIMC(hIMC); return FALSE; } lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); fRet = (lpCompStr->dwCompStrLen > 0); ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMC(hIMC); return fRet; }
BOOL IsCandidate(HIMC hIMC) { LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; BOOL fRet = FALSE; if (!(lpIMC = ImmLockIMC(hIMC))) return FALSE; if (ImmGetIMCCSize(lpIMC->hCandInfo) < sizeof (CANDIDATEINFO)){ ImmUnlockIMC(hIMC); return FALSE; } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); fRet = (lpCandList->dwCount > 0); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return fRet; }
HRESULT WeaselIME::_Finalize() { LPINPUTCONTEXT lpIMC = ImmLockIMC(m_hIMC); if (lpIMC) { lpIMC->fOpen = FALSE; if (lpIMC->hCompStr) { ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = NULL; } } ImmUnlockIMC(m_hIMC); return S_OK; }
//***************************************************************** // 向HIMC发送消息 // 利用此函数直接向输入法所属窗口发送消息 //***************************************************************** BOOL MyGenerateMessage(HIMC hIMC, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL bRet=FALSE; LPINPUTCONTEXT lpIMC= ImmLockIMC(hIMC); if(lpIMC == NULL) return FALSE; if (IsWindow(lpIMC->hWnd)) { PostMessage(lpIMC->hWnd,msg,wParam,lParam); bRet=TRUE; } ImmUnlockIMC(hIMC); return bRet; }
void DeleteCharBackward(HIMC hIMC,WORD wParam) { if(wConversionMode & CONVERSION_MODE_PHRASETOCHAR){ MakeResultString(hIMC,FALSE); } else if( wConversionMode & CONVERSION_MODE_I || wConversionMode & CONVERSION_MODE_U || wConversionMode & CONVERSION_MODE_V ) { LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; LPCOMPOSITIONSTRING lpCompStr; GENEMSG GnMsg; LPTSTR lpStr; lpIMC = ImmLockIMC(hIMC); lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]); lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if( !lpCandList->dwCount ) MakeResultString(hIMC,FALSE); else{ lpCandList->dwCount = 0; lpStr = GETLPCOMPSTR(lpCompStr); lpStr = CharPrev(lpStr,lpStr + _tcslen(lpStr)); *lpStr= _T('\0'); lpStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szPaintCompStr; lpStr = CharPrev(lpStr,lpStr + _tcslen(lpStr)); *lpStr= _T('\0'); GnMsg.msg = WM_IME_COMPOSITION; GnMsg.wParam = 0; GnMsg.lParam = GCS_COMPSTR; GenerateMessage(hIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg); } ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); } else AddChar(hIMC,wParam,EDIT_BACK); return; }
void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) { HIMC imc; LPINPUTCONTEXT lpIMC; HIMCC newCompStr; LPIMEPRIVATE myPrivate; BOOL inComp; imc = RealIMC(FROM_X11); lpIMC = ImmLockIMC(imc); if (lpIMC == NULL) return; newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0); ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = newCompStr; newCompStr = updateResultStr(lpIMC->hCompStr, lpResult, dwResultLen); ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = newCompStr; myPrivate = ImmLockIMCC(lpIMC->hPrivate); inComp = myPrivate->bInComposition; ImmUnlockIMCC(lpIMC->hPrivate); if (!inComp) { ImmSetOpenStatus(imc, TRUE); GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); } GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR); GenerateIMEMessage(imc, WM_IME_COMPOSITION, lpResult[0], GCS_RESULTSTR|GCS_RESULTCLAUSE); GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); if (!inComp) ImmSetOpenStatus(imc, FALSE); ImmUnlockIMC(imc); }
/***************************************************************************** * * * UpdateIndicIcon( hIMC ) * * * *****************************************************************************/ void UpdateIndicIcon(HIMC hIMC) { HWND hwndIndicate; BOOL fOpen = FALSE; LPINPUTCONTEXT lpIMC; if (!hFreePYKL) { hFreePYKL = GetMyHKL(); if (!hFreePYKL) return; } hwndIndicate = FindWindow(INDICATOR_CLASS, NULL); if (hIMC) { lpIMC = ImmLockIMC(hIMC); if (lpIMC) { fOpen = lpIMC->fOpen; ImmUnlockIMC(hIMC); } } if (IsWindow(hwndIndicate)) { ATOM atomTip; atomTip = GlobalAddAtom(ATOMTIP); PostMessage(hwndIndicate, INDICM_SETIMEICON, fOpen ? 1 : (-1), (LPARAM)hFreePYKL); PostMessage(hwndIndicate, INDICM_SETIMETOOLTIPS, fOpen ? atomTip : (-1), (LPARAM)hFreePYKL); PostMessage(hwndIndicate, INDICM_REMOVEDEFAULTMENUITEMS, // fOpen ? (RDMI_LEFT | RDMI_RIGHT) : 0, (LPARAM)hMyKL); fOpen ? (RDMI_LEFT) : 0, (LPARAM)hFreePYKL); } }
UINT WINNLSTranslateMessage( INT iNum, // number of messages in the source buffer PTRANSMSG pTransMsg, // source buffer that contains 4.0 style messages HIMC hImc, // input context handle BOOL fAnsi, // TRUE if pdwt contains ANSI messages DWORD dwLangId ) // language ID ( KOREAN or JAPANESE ) { LPINPUTCONTEXT pInputContext; LPCOMPOSITIONSTRING pCompStr; UINT uiRet = 0; pInputContext = ImmLockIMC(hImc); if (pInputContext == NULL) { return uiRet; } pCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC( pInputContext->hCompStr ); if (dwLangId == LANG_KOREAN) { uiRet = WINNLSTranslateMessageK((UINT)iNum, pTransMsg, pInputContext, pCompStr, fAnsi ); } else if ( dwLangId == LANG_JAPANESE ) { uiRet = WINNLSTranslateMessageJ((UINT)iNum, pTransMsg, pInputContext, pCompStr, fAnsi ); } if (pCompStr != NULL) { ImmUnlockIMCC(pInputContext->hCompStr); } ImmUnlockIMC(hImc); return uiRet; }
void ChangeCand(HWND hUIWnd) { LPUIPRIV lpUIPriv; HIMC hIMC; CONST INPUTCONTEXT * lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; int nCandWi, nCandHi; lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE); if (!lpUIPriv) { return; } if (!(lpUIPriv->fdwUIFlags & UI_CAND_ALREADY_OPEN)) { return; } hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC); if (!hIMC) { return; } lpIMC = (CONST INPUTCONTEXT *)ImmLockIMC(hIMC); if (!lpIMC) { return; } if (!lpIMC->hCandInfo) { ImmUnlockIMC(hIMC); return; } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { goto ChangeCandUnlockIMCC; } lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); lpUIPriv->lpCandList = lpCandList; nCandWi = lpUIPriv->nCandWi; nCandHi = lpUIPriv->nCandHi; CalcCandSize(lpUIPriv->hCandWnd); if (nCandWi != lpUIPriv->nCandWi || nCandHi != lpUIPriv->nCandHi) { SetWindowPos(lpUIPriv->hCandWnd, NULL, 0, 0, lpUIPriv->nCandWi, lpUIPriv->nCandHi, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); SetWindowPos(lpUIPriv->hScrBar, NULL, lpUIPriv->rcCandText.right, lpUIPriv->rcCandText.top, g_sImeUIG.cxVScroll, (lpUIPriv->rcCandText.bottom - lpUIPriv->rcCandText.top), SWP_NOACTIVATE|SWP_NOZORDER); } InvalidateRect(lpUIPriv->hCandWnd, NULL, TRUE); ShowCand(hUIWnd, SW_SHOWNOACTIVATE); ChangeCandUnlockIMCC: ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; }
DWORD WINAPI ImmProcessKey( HWND hWnd, HKL hkl, UINT uVKey, LPARAM lParam, DWORD dwHotKeyID) { HIMC hIMC = ImmGetContext(hWnd); PIMEDPI pImeDpi = ImmLockImeDpi(hkl); DWORD dwReturn = 0; #if DBG if (dwHotKeyID >= IME_KHOTKEY_FIRST && dwHotKeyID <= IME_KHOTKEY_LAST) { TAGMSG2(DBGTAG_IMM, "ImmProcessKey: Kor IME Hotkeys should not come here: dwHotKeyID=%x, uVKey=%x", dwHotKeyID, uVKey); } #endif ImmAssert(dwHotKeyID != IME_KHOTKEY_ENGLISH && dwHotKeyID != IME_KHOTKEY_SHAPE_TOGGLE && dwHotKeyID != IME_KHOTKEY_HANJACONVERT); // // call ImeProcessKey // if (pImeDpi != NULL) { PINPUTCONTEXT pInputContext = ImmLockIMC(hIMC); if (pInputContext != NULL) { BOOLEAN fTruncateWideVK = FALSE; BOOLEAN fCallIme = TRUE; BOOLEAN fSkipThisKey = FALSE; #ifdef LATER // // if the current imc is not open and IME doesn't need // keys when being closed, we don't pass any keyboard // input to ime except hotkey and keys that change // the keyboard status. // if ((pImeDpi->fdwProperty & IME_PROP_NO_KEYS_ON_CLOSE) && !pInputContext->fOpen && uVKey != VK_SHIFT && uVKey != VK_CONTROL && uVKey != VK_CAPITAL && uVKey != VK_KANA && uVKey != VK_NUMLOCK && uVKey != VK_SCROLL) { // Check if Korea Hanja conversion mode if(!(pimc->fdwConvMode & IME_CMODE_HANJACONVERT)) { fCallIme = FALSE; } } else #endif // // Protect IMEs which are unaware of wide virtual keys. // if ((BYTE)uVKey == VK_PACKET && (pImeDpi->ImeInfo.fdwProperty & IME_PROP_ACCEPT_WIDE_VKEY) == 0) { if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) { // // Since this IME is not ready to accept wide VKey, we should // truncate it. // fTruncateWideVK = TRUE; } else { // // Hmm, this guy is ANSI IME, and does not declare Wide Vkey awareness. // Let's guess this one is not ready to accept Wide Vkey, so let's not // pass it to this guy. // And if it is opened, we'd better skip this key for safety. // fCallIme = FALSE; if (pInputContext->fOpen) { fSkipThisKey = TRUE; } } } if (fCallIme) { PBYTE pbKeyState = (PBYTE)ImmLocalAlloc(0, 256); ImmAssert(fSkipThisKey == FALSE); if (pbKeyState != NULL) { if (GetKeyboardState(pbKeyState)) { UINT uVKeyIme = uVKey; if (fTruncateWideVK) { uVKeyIme &= 0xffff; } if ( (*pImeDpi->pfn.ImeProcessKey)(hIMC, uVKeyIme, lParam, pbKeyState) ) { // // if the return value of ImeProcessKey is TRUE, // it means the key is the one that the ime is // waiting for. // pInputContext->fChgMsg = TRUE; pInputContext->uSavedVKey = uVKey; dwReturn |= IPHK_PROCESSBYIME; } } ImmLocalFree(pbKeyState); } } else if (fSkipThisKey) { dwReturn |= IPHK_SKIPTHISKEY; ImmAssert((dwReturn & (IPHK_PROCESSBYIME | IPHK_HOTKEY)) == 0); } ImmUnlockIMC(hIMC); } ImmUnlockImeDpi(pImeDpi); } // // call hotkey handler // if (dwHotKeyID != IME_INVALID_HOTKEY && HotKeyIDDispatcher(hWnd, hIMC, hkl, dwHotKeyID)) { // Backward compat: // On Japanese system, some applications may want VK_KANJI. if ((uVKey != VK_KANJI) || (dwHotKeyID != IME_JHOTKEY_CLOSE_OPEN)) { dwReturn |= IPHK_HOTKEY; } } // // some 3.x application doesn't like to see // VK_PROCESSKEY. // if (dwReturn & IPHK_PROCESSBYIME) { DWORD dwImeCompat = ImmGetAppCompatFlags(hIMC); if (dwImeCompat & IMECOMPAT_NOVKPROCESSKEY) { // Korea 3.x application doesn't like to see dummy finalize VK_PROCESSKEY // and IME hot key. if ( PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) == LANG_KOREAN && ( (uVKey == VK_PROCESSKEY) || (dwReturn & IPHK_HOTKEY) ) ) { ImmReleaseContext(hWnd, hIMC); return dwReturn; } ImmTranslateMessage(hWnd, WM_KEYDOWN, VK_PROCESSKEY, lParam); dwReturn &= ~IPHK_PROCESSBYIME; dwReturn |= IPHK_SKIPTHISKEY; } } ImmReleaseContext(hWnd, hIMC); return dwReturn; }
BOOL CharHandleU( HIMC hIMC,WORD wParam,LONG lParam) { LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; LPCOMPOSITIONSTRING lpCompStr; WORD wHead; lpIMC = ImmLockIMC(hIMC); lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]); lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if( !lpCandList->dwCount ){ int i; wHead = wParam - _T('!'); for( i=0;_tcslen(aPunct[wHead][i]);i++){ _tcscpy(GETLPCANDSTR(lpCandList,i+2),aPunct[wHead][i]); } if( i == 0) MessageBeep(0xFFFFFFFF ); else if( i == 1 ){ LPTSTR lpConvStr; lpConvStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szConvCompStr; _tcscpy(lpConvStr,aPunct[wHead][0]); MakeResultString(hIMC,TRUE); } else { LPTSTR lpStr; WORD wStrLen; lpStr = GETLPCOMPSTR(lpCompStr); wStrLen = _tcslen(lpStr); *(lpStr + wStrLen) = (TCHAR)wParam; *(lpStr + wStrLen +1) = _T('\0'); lpStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szPaintCompStr; wStrLen = _tcslen(lpStr); *(lpStr + wStrLen) = (TCHAR)wParam; *(lpStr + wStrLen +1) = _T('\0'); lpCandList->dwSelection = 0; lpCandList->dwCount = i; lpCandList->dwPageStart = 2; lpCandList->dwPageSize = 0; SelectForwardFromCand(hIMC,lpCandList); } } else{ if( wParam == _T('=') || wParam == _T('.') || wParam == _T('>')) { SelectForwardFromCand(hIMC,lpCandList); } else if( wParam == _T('-') || wParam == _T(',') || wParam == _T('<')) { SelectBackwardFromCand(hIMC,lpCandList); } else if( wParam >= _T('0') && wParam <= _T('9') ){ SelectCandFromCandlist(hIMC, wParam); } } ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return TRUE; }
LRESULT WINAPI UIWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HIMC hUICurIMC; LPINPUTCONTEXT lpIMC; LPUIEXTRA lpUIExtra; HGLOBAL hUIExtra; LONG lRet = 0L; DebugLog(1,(DebugLogFile,"UIWnd\n")); hUICurIMC = (HIMC)GetWindowLong(hWnd,IMMGWL_IMC); // // Even if there is no current UI. these messages should not be pass to // DefWindowProc(). // if (!hUICurIMC) { switch (message) { case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: case WM_IME_NOTIFY: case WM_IME_CONTROL: case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: case WM_IME_CHAR: return 0L; default: break; } } switch (message) { case WM_CREATE: DebugLog(1,(DebugLogFile,"UIWnd:WM_CREATE\n")); // // Allocate UI's extra memory block. // hUIExtra = GlobalAlloc(GHND,sizeof(UIEXTRA)); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); lpUIExtra->uiComp.pt.x = -1; lpUIExtra->uiComp.pt.y = -1; CreateCompWindow(hWnd,lpUIExtra); CreateCandWindow(hWnd,lpUIExtra); GlobalUnlock(hUIExtra); SetWindowLong(hWnd,IMMGWL_PRIVATE,(DWORD)hUIExtra); break; case WM_IME_SETCONTEXT: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SETCONTEXT\n")); if (wParam) { hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); if (hUICurIMC) { // // input context was chenged. // if there are the child windows, the diplay have to be // updated. // lpIMC = ImmLockIMC(hUICurIMC); if (lpIMC) { MoveCandWindow(hWnd,lpUIExtra,lpIMC); MoveCompWindow(hWnd,lpUIExtra,lpIMC); } else { HideCandWindow(lpUIExtra); HideCompWindow(lpUIExtra); } ImmUnlockIMC(hUICurIMC); } else // it is NULL input context. { HideCandWindow(lpUIExtra); HideCompWindow(lpUIExtra); } GlobalUnlock(hUIExtra); } break; case WM_IME_STARTCOMPOSITION: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_STARTCOMPOSITION\n")); // // Start composition! Ready to display the composition string. // break; case WM_IME_COMPOSITION: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITION\n")); // // Update to display the composition string. // lpIMC = ImmLockIMC(hUICurIMC); hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); MoveCompWindow(hWnd,lpUIExtra,lpIMC); MoveCandWindow(hWnd,lpUIExtra,lpIMC); GlobalUnlock(hUIExtra); ImmUnlockIMC(hUICurIMC); break; case WM_IME_ENDCOMPOSITION: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_ENDCOMPOSITION\n")); // // Finish to display the composition string. // hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); HideCompWindow(lpUIExtra); HideCandWindow(lpUIExtra); GlobalUnlock(hUIExtra); break; case WM_IME_COMPOSITIONFULL: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITIONFULL\n")); break; case WM_IME_SELECT: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SELECT\n")); break; case WM_IME_CONTROL: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_CONTROL\n")); lRet = ControlHandle(hUICurIMC, hWnd,message,wParam,lParam); break; case WM_IME_NOTIFY: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY\n")); lRet = NotifyHandle(hUICurIMC, hWnd,message,wParam,lParam); break; case WM_DESTROY: DebugLog(1,(DebugLogFile,"UIWnd:WM_DESTROY\n")); hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); if (IsWindow(lpUIExtra->uiStatus.hWnd)) DestroyWindow(lpUIExtra->uiStatus.hWnd); if (IsWindow(lpUIExtra->uiCand.hWnd)) DestroyWindow(lpUIExtra->uiCand.hWnd); if (IsWindow(lpUIExtra->uiComp.hWnd)) DestroyWindow(lpUIExtra->uiComp.hWnd); GlobalUnlock(hUIExtra); GlobalFree(hUIExtra); break; case WM_UI_COMPMOVE: hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); lpUIExtra->uiComp.pt.x = (long)LOWORD(lParam); lpUIExtra->uiComp.pt.y = (long)HIWORD(lParam); GlobalUnlock(hUIExtra); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } return lRet; }
LONG NotifyHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LONG lRet = 0L; LPINPUTCONTEXT lpIMC; HGLOBAL hUIExtra; LPUIEXTRA lpUIExtra; if (!(lpIMC = ImmLockIMC(hUICurIMC))) return 0L; hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE); lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra); switch (wParam) { case IMN_CLOSESTATUSWINDOW: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOW\n")); if (IsWindow(lpUIExtra->uiStatus.hWnd)) { ShowWindow(lpUIExtra->uiStatus.hWnd,SW_HIDE); } break; case IMN_OPENSTATUSWINDOW: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENSTATUSWINDOW\n")); CreateStatusWindow( hWnd, lpUIExtra); break; case IMN_OPENCANDIDATE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENCANDIDATE\n")); break; case IMN_CHANGECANDIDATE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CHANGECANDIDATE\n")); break; case IMN_CLOSECANDIDATE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSECANDIDATE\n")); break; case IMN_SETCONVERSIONMODE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCONVERSIONMODE\n")); UpdateStatusWindow(lpUIExtra); break; case IMN_SETSENTENCEMODE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSENTENCEMODE\n")); break; case IMN_SETOPENSTATUS: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETOPENSTATUS\n")); if(!IsIMEOpen(hUICurIMC)) { MakeResultString(hUICurIMC,FALSE); } UpdateStatusWindow(lpUIExtra); break; case IMN_SETCANDIDATEPOS: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCANDIDATEPOS\n")); break; case IMN_SETCOMPOSITIONFONT: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONT\n")); break; case IMN_SETCOMPOSITIONWINDOW: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOW\n")); if(wConversionSet & CONVERSION_SET_FOLLOW) { POINT ptSrc; SIZE szOffset; HDC hDC; HFONT oldFont; ptSrc = lpIMC->cfCompForm.ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptSrc); hDC = GetDC(lpIMC->hWnd); oldFont = SelectObject(hDC, hUIFont); GetTextExtentPoint(hDC,"A",1,&szOffset); SelectObject(hDC, oldFont); ReleaseDC(lpIMC->hWnd,hDC); lpUIExtra->uiComp.pt.x = ptSrc.x + szOffset.cx; lpUIExtra->uiComp.pt.y = ptSrc.y + szOffset.cy; } if (IsWindow(lpUIExtra->uiComp.hWnd)) InvalidateRect(lpUIExtra->uiComp.hWnd,NULL,FALSE); break; case IMN_GUIDELINE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_GUIDELINE\n")); break; case IMN_SETSTATUSWINDOWPOS: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOS\n")); break; case IMN_PRIVATE: DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_PRIVATE\n")); break; default: break; } GlobalUnlock(hUIExtra); ImmUnlockIMC(hUICurIMC); return lRet; }
void OpenCand(HWND hUIWnd) { LPUIPRIV lpUIPriv; HIMC hIMC; LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; int nCandWi, nCandHi; POINT ptNew; lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE); if (!lpUIPriv) { return; } lpUIPriv->lpCandList = NULL; hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC); if (!hIMC) { return; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } if (!lpIMC->hCandInfo) { ImmUnlockIMC(hIMC); return; } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { ImmUnlockIMC(hIMC); return; } lpUIPriv->lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); if (lpUIPriv->lpCandList->dwPageSize > MAX_PAGESIZE) { lpUIPriv->lpCandList->dwPageSize = MAX_PAGESIZE; } lpUIPriv->dwPageSize = lpUIPriv->lpCandList->dwCount > lpUIPriv->lpCandList->dwPageSize ? lpUIPriv->lpCandList->dwPageSize : lpUIPriv->lpCandList->dwCount; lpUIPriv->lpCandList->dwPageSize = lpUIPriv->dwPageSize; if (!lpUIPriv->hCandWnd) { lpUIPriv->hCandWnd = CreateWindowEx( WS_EX_NOACTIVATE|WS_EX_TOPMOST, v_szCandClassName, NULL, WS_POPUP|WS_BORDER|WS_NOTIFY|CLS_FRACTION, 0, 0, 50, 50, hUIWnd, (HMENU)NULL, lpUIPriv->hInst, NULL); if (!lpUIPriv->hCandWnd) { lpUIPriv->lpCandList = NULL; ImmUnlockIMCC(lpIMC->hCandInfo); goto OpenCandUnlockIMCC; } } lpUIPriv->fdwUIFlags |= UI_CAND_ALREADY_OPEN; nCandWi = lpUIPriv->nCandWi; nCandHi = lpUIPriv->nCandHi; CalcCandSize(lpUIPriv->hCandWnd); if (nCandWi != lpUIPriv->nCandWi || nCandHi != lpUIPriv->nCandHi) { SetWindowPos(lpUIPriv->hCandWnd, HWND_TOPMOST, 0, 0, lpUIPriv->nCandWi, lpUIPriv->nCandHi, SWP_NOACTIVATE|SWP_NOMOVE); //|SWP_NOZORDER); SetWindowPos(lpUIPriv->hScrBar, NULL, lpUIPriv->rcCandText.right, lpUIPriv->rcCandText.top, g_sImeUIG.cxVScroll, (lpUIPriv->rcCandText.bottom - lpUIPriv->rcCandText.top), SWP_NOACTIVATE|SWP_NOZORDER); } if (IsWindowVisible(lpUIPriv->hCompWnd)) { ptNew.x = lpUIPriv->ptComp.x; ptNew.y = lpUIPriv->ptComp.y + lpUIPriv->nCompHi - g_sImeUIG.cyBorder; } else { ptNew = lpIMC->cfCandForm[0].ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptNew); } //AdjustCandWnd(lpUIPriv->hCandWnd, ptNew); SetCandPosition(lpUIPriv->hCandWnd); ShowCand(hUIWnd, SW_SHOWNOACTIVATE); OpenCandUnlockIMCC: ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; }
/***************************************************************************\ * ImmTranslateMessage (Called from user\client\ntstubs.c\TranslateMessage()) * * Call ImeToAsciiEx() * * History: * 01-Mar-1996 TakaoK Created \***************************************************************************/ BOOL ImmTranslateMessage( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HIMC hImc; PINPUTCONTEXT pInputContext; BOOL fReturn = FALSE; HKL hkl; PIMEDPI pImeDpi = NULL; PBYTE pbKeyState; PTRANSMSG pTransMsg; PTRANSMSGLIST pTransMsgList; DWORD dwSize; UINT uVKey; INT iNum; UNREFERENCED_PARAMETER(wParam); // // we're interested in only those keyboard messages. // switch (message) { case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: break; default: return FALSE; } // // input context is necessary for further handling // hImc = ImmGetContext(hwnd); pInputContext = ImmLockIMC(hImc); if (pInputContext == NULL) { ImmReleaseContext(hwnd, hImc); return FALSE; } // // At first, handle VK_PROCESSKEY generated by IME. // if (!pInputContext->fChgMsg) { if ((iNum=pInputContext->dwNumMsgBuf) != 0) { pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf); if (pTransMsg != NULL) { ImmPostMessages(hwnd, hImc, iNum, pTransMsg); ImmUnlockIMCC(pInputContext->hMsgBuf); fReturn = TRUE; } pInputContext->dwNumMsgBuf = 0; } goto ExitITM; } pInputContext->fChgMsg = FALSE; // // retrieve the keyboard layout and IME entry points // hkl = GetKeyboardLayout( GetWindowThreadProcessId(hwnd, NULL) ); pImeDpi = ImmLockImeDpi(hkl); if (pImeDpi == NULL) { RIPMSG1(RIP_WARNING, "ImmTranslateMessage pImeDpi is NULL(hkl=%x)", hkl); goto ExitITM; } pbKeyState = ImmLocalAlloc(0, 256); if ( pbKeyState == NULL ) { RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" ); goto ExitITM; } if (!GetKeyboardState(pbKeyState)) { RIPMSG0(RIP_WARNING, "ImmTranslateMessage GetKeyboardState() failed" ); ImmLocalFree( pbKeyState ); goto ExitITM; } // // Translate the saved vkey into character code if needed // uVKey = pInputContext->uSavedVKey; if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST) { if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) { WCHAR wcTemp; iNum = ToUnicode(pInputContext->uSavedVKey, // virtual-key code HIWORD(lParam), // scan code pbKeyState, // key-state array &wcTemp, // buffer for translated key 1, // size of buffer 0); if (iNum == 1) { // // hi word : unicode character code // hi byte of lo word : zero // lo byte of lo word : virtual key // uVKey = (uVKey & 0x00ff) | ((UINT)wcTemp << 16); } } else { WORD wTemp = 0; iNum = ToAsciiEx(pInputContext->uSavedVKey, // virtual-key code HIWORD(lParam), // scan code pbKeyState, // key-state array &wTemp, // buffer for translated key 0, // active-menu flag hkl); ImmAssert(iNum <= 2); if (iNum > 0) { // // hi word : should be zero // hi byte of lo word : character code // lo byte of lo word : virtual key // uVKey = (uVKey & 0x00FF) | ((UINT)wTemp << 8); if ((BYTE)uVKey == VK_PACKET) { // // If ANSI IME is wide vkey aware, its ImeToAsciiEx will receive the uVKey // as follows: // // 31 24 23 16 15 8 7 0 // +----------------+-----------------------------+-------------------+---------------+ // | 24~31:reserved | 16~23:trailing byte(if any) | 8~15:leading byte | 0~7:VK_PACKET | // +----------------+-----------------------------+-------------------+---------------+ // ImmAssert(pImeDpi->ImeInfo.fdwProperty & IME_PROP_ACCEPT_WIDE_VKEY); } else { uVKey &= 0xffff; } } } } dwSize = FIELD_OFFSET(TRANSMSGLIST, TransMsg) + TRANSMSGCOUNT * sizeof(TRANSMSG); pTransMsgList = (PTRANSMSGLIST)ImmLocalAlloc(0, dwSize); if (pTransMsgList == NULL) { RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" ); ImmLocalFree(pbKeyState); goto ExitITM; } pTransMsgList->uMsgCount = TRANSMSGCOUNT; iNum = (*pImeDpi->pfn.ImeToAsciiEx)(uVKey, HIWORD(lParam), pbKeyState, pTransMsgList, 0, hImc); if (iNum > TRANSMSGCOUNT) { // // The message buffer is not big enough. IME put messages // into hMsgBuf in the input context. // pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf); if (pTransMsg != NULL) { ImmPostMessages(hwnd, hImc, iNum, pTransMsg); ImmUnlockIMCC(pInputContext->hMsgBuf); } #ifdef LATER // Shouldn't we need this ? fReturn = TRUE; #endif } else if (iNum > 0) { ImmPostMessages(hwnd, hImc, iNum, &pTransMsgList->TransMsg[0]); fReturn = TRUE; } ImmLocalFree(pbKeyState); ImmLocalFree(pTransMsgList); ExitITM: ImmUnlockImeDpi(pImeDpi); ImmUnlockIMC(hImc); ImmReleaseContext(hwnd, hImc); return fReturn; }