//#define OV_DEBUG #include "OVIME.h" static bool isPrivateEightExecuting = false; LRESULT NotifyHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT lRet = 0L; //Unused codes //LPINPUTCONTEXT lpIMC; //LOGFONT* lfptr; //LOGFONT lf2; // if(!hUICurIMC) return lRet; dsvr->setHIMC(hUICurIMC); AVLoader* loader = AVLoader::open(); loader->connectDisplayServer(dsvr); switch (wParam) { case IMN_OPENSTATUSWINDOW: murmur("IMN_OPENSTATUSWINDOW"); murmur("\thwnd=%x", hWnd); dsvr->SetStatusEnabled(true); UICreateStatusWindow(hWnd); dsvr->showStatus(true); break; case IMN_SETOPENSTATUS: // the same as IMN_OPENSTATUSWINDOW murmur("IMN_SETOPENSTATUS"); UICreateStatusWindow(hWnd); dsvr->showStatus(true); break; case IMN_CLOSESTATUSWINDOW: murmur("IMN_CLOSESTATUSWINDOW"); dsvr->showStatus(false); // // When attached app lost focus, only this message occurred, // so it must also hide following windows. //dsvr->showBuf(false); //dsvr->showCandi(false); // break; case IMN_OPENCANDIDATE: murmur("IMN_OPENCANDIDATE"); dsvr->SetCandiEnabled(true); dsvr->showCandi(true); break; case IMN_CLOSECANDIDATE: murmur("IMN_CLOSECANDIDATE"); dsvr->showCandi(false); break; case IMN_CHANGECANDIDATE: dsvr->SetCandiEnabled(true); murmur("IMN_CHANGECANDIDATE"); break; case IMN_SETCONVERSIONMODE: murmur("IMN_SETCONVERSIONMODE"); DWORD conv, sentence; ImmGetConversionStatus( ImmGetContext(hWnd), &conv, &sentence); isChinese = (conv & IME_CMODE_NATIVE) == 0 ? false : true; isFullShape = (conv & IME_CMODE_FULLSHAPE) == 0 ? false : true; break; case IMN_SETSENTENCEMODE: murmur("IMN_SETSENTENCEMODE"); break; case IMN_SETCANDIDATEPOS: // For the Search Text Field of Firefox { murmur("IMN_SETCANDIDATEPOS"); dsvr->SetCandiEnabled(true); RefreshUI(hWnd); /*POINT ptSrc; SIZE szOffset; HDC hDC; ptSrc = lpIMC->cfCandForm[0].ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptSrc); hDC = GetDC(lpIMC->hWnd); GetTextExtentPoint(hDC, _T("A"), 1, &szOffset); ReleaseDC(lpIMC->hWnd,hDC); LPMYPRIVATE lpMyPrivate = (LPMYPRIVATE)ImmLockIMCC(lpIMC->hPrivate); CompX=ptSrc.x ;//+szOffset.cx; CompY=ptSrc.y + szOffset.cy; RefreshUI(hWnd);*/ //dsvr->moveCandi(CandX,CandY); //not finished!! break; } case IMN_SETCOMPOSITIONFONT: murmur("IMN_SETCOMPOSITIONFONT"); dsvr->SetCompEnabled(true); dsvr->SetCandiEnabled(true); // // It is weird but... when the attached app got focus back, // this message occurred. // RefreshUI(hWnd); break; case IMN_SETCOMPOSITIONWINDOW: { /* Sent immediately before the IME generates the composition string as a result of a keystroke. This message is a notification to an IME window to open its composition window. An application should process this message if it displays composition characters itself. */ murmur("IMN_SETCOMPOSITIONWINDOW"); dsvr->SetCompEnabled(true); dsvr->SetCandiEnabled(true); /*POINT ptSrc; SIZE szOffset; HDC hDC; TEXTMETRIC tm; int localDPIY; //for device dpiY ptSrc = lpIMC->cfCompForm.ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptSrc); hDC = GetDC(lpIMC->hWnd); murmur("\thWnd->%x", lpIMC->hWnd); GetTextExtentPoint(hDC, _T("A"), 1, &szOffset); GetTextMetrics(hDC, &tm); localDPIY = GetDeviceCaps(hDC, LOGPIXELSY); ReleaseDC(lpIMC->hWnd,hDC); lfptr = (LOGFONT*)(&lpIMC->lfFont); memcpy( &lf2, lfptr, sizeof( lf2) ); CompX = ptSrc.x ; CompY = ptSrc.y + abs(lf2.lfHeight)*localDPIY/tm.tmDigitizedAspectY;*/ RefreshUI(hWnd); break; } case IMN_GUIDELINE: murmur("IMN_GUIDELINE"); break; case IMN_SETSTATUSWINDOWPOS: murmur("IMN_SETSTATUSWINDOWPOS"); // MoveStatusWindow(hWnd, ); break; case IMN_PRIVATE: { murmur("IMN_PRIVATE"); murmur("\thwnd=%x", hWnd); murmur("lParam=%i", lParam); switch(lParam) { case 0: break; case 1: //Change UI Half/Full UIChangeHalfFull(hWnd); break; case 2: //Change UI CHI/ENG { murmur("\tChange UI CHI/ENG."); UIChangeChiEng(hWnd); //通知 windows API 輸入法狀態改變 HIMC imc = ImmGetContext( hWnd ); if( imc ) { isChinese=!isChinese; DWORD conv, sentence; ImmGetConversionStatus( imc, &conv, &sentence); if( isChinese ) conv |= IME_CMODE_NATIVE; else conv &= ~IME_CMODE_NATIVE; ImmSetConversionStatus( imc, conv, sentence); } break; } case 3: //Change Modules by Mouse { murmur("\tChange Modules by Mouse"); /* close module and set new IC */ loader->unloadCurrentModule(); int moduleId = UIModuleChange(); loader->initContext(moduleId); break; } case 4: // Change UI Traditional/Simplified Chinese murmur("\tChange UI Traditional/Simplified Chinese"); UIChangeSimpifiedOrTraditional(hWnd); break; case 5: //Change BoPoMoFo keyboard layout by ctrl +'=' /* close module and set new IC */ UIChangeBoPoMoFoLayout( loader->getSwitchedBoPoMoFoLayoutModIndex()); break; case 6: // Toggle Small/Large Candidate window. (ctrl+alt+g) murmur("\tToggle Small/Large Candidate window."); UIExpandCandi(); break; case 7: // Test Notify window. (ctrl+alt+L) { murmur("\tTest Notify window"); char *str="GG notify message"; //UICreateNotifyWindow(hWnd); //new IMENotifyWindow -> fake form dsvr->showNotify(str); //會 new 一個 NotifyWindow ->real form //UIShowNotifyWindow(); //show our IMENotifyWindow ->fake form break; } case 8: //Change Modules by ctrl +'\' { /* close module and poll current IC */ // // A stupid but necessary check to prevent infinite loop. if(!isPrivateEightExecuting) { isPrivateEightExecuting = true; loader->unloadCurrentModule(); int moduleId = UIModuleRotate(); loader->initContext(moduleId); isPrivateEightExecuting = false; } // break; } case 9: //Set all module names { int modAmount = loader->getInputMethodCount(); const char** modNameList = new const char* [modAmount]; loader->getAllModuleNames(modNameList); UISetStatusModStrMenuAll(modAmount, modNameList); break; } case 10: //send first word to app and refresh comp window { break; } default: murmur("\tUknown IMN_PRIVATE"); break; } break; } default: murmur("WM_IME_NOTIFY: no this wParam"); break; } return lRet; }