private void DestroyImeWindow(IntPtr hwnd) { if (_systemCaret) { NativeIME.DestroyCaret(); _systemCaret = false; } }
private void OnIMESetContext(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam) { // We handle the IME Composition Window ourselves (but let the IME Candidates // Window be handled by IME through DefWindowProc()), so clear the // ISC_SHOWUICOMPOSITIONWINDOW flag: lParam = (IntPtr)(lParam.ToInt64() & ~NativeIME.ISC_SHOWUICOMPOSITIONWINDOW); NativeIME.DefWindowProc(hwnd, msg, wParam, lParam); // TODO: should we call ImmNotifyIME? CreateImeWindow(hwnd); MoveImeWindow(hwnd); }
private void Init(HwndSource source) { _source = source; sourceHook = SourceHook; source.AddHook(SourceHook); _owner.GotFocus += Owner_GotFocus; _owner.LostFocus += Owner_LostFocus; _defaultContext = NativeIME.ImmGetContext(_source.Handle); _browserContext = NativeIME.ImmCreateContext(); NativeIME.ImmAssociateContext(_source.Handle, _browserContext); // TODO: need to find a better way to trigger setting context on the window _owner.Focus(); }
private void CreateImeWindow(IntPtr hwnd) { // Chinese/Japanese IMEs somehow ignore function calls to // ::ImmSetCandidateWindow(), and use the position of the current system // caret instead -::GetCaretPos(). // Therefore, we create a temporary system caret for Chinese IMEs and use // it during this input context. // Since some third-party Japanese IME also uses ::GetCaretPos() to determine // their window position, we also create a caret for Japanese IMEs. _languageCodeId = PrimaryLangId(InputLanguageManager.Current.CurrentInputLanguage.KeyboardLayoutId); if (_languageCodeId == NativeIME.LANG_JAPANESE || _languageCodeId == NativeIME.LANG_CHINESE) { if (!_systemCaret) { if (NativeIME.CreateCaret(hwnd, IntPtr.Zero, 1, 1)) { _systemCaret = true; } } } }
private void MoveImeWindow(IntPtr hwnd) { if (!_owner.IsFocused) { return; } CefSharp.Structs.Rect rc = _imeRect; int location = _cursorIndex; // If location is not specified fall back to the composition range start. if (location == -1) { location = _compositionRange.From; } // Offset location by the composition range start if required. if (location >= _compositionRange.From) { location -= _compositionRange.From; } if (location < _compositionBounds.Count) { rc = _compositionBounds[location]; } else { return; } int caretMargin = 1; if (_languageCodeId == NativeIME.LANG_CHINESE) { var formPoint = new NativeIME.TagCompositionForm { DwStyle = NativeIME.CFS_POINT, PtCurrentPos = new NativeIME.TagPoint { X = rc.X, Y = rc.Y }, RcArea = new NativeIME.TagRect { Left = rc.X, Top = rc.Y, Right = rc.X + rc.Width, Bottom = rc.Y + rc.Height } }; // TODO :: candidate window for Chinese using (var handler = IMEHandler.Create(hwnd)) { //NativeIME.ImmSetCompositionWindow(handler._hIMC, ref formPoint); } } if (_systemCaret) { if (_languageCodeId == NativeIME.LANG_JAPANESE) { var firstRc = _compositionBounds[0]; NativeIME.SetCaretPos(firstRc.X, firstRc.Y + firstRc.Height); } else { NativeIME.SetCaretPos(rc.X, rc.Y); } } if (_languageCodeId == NativeIME.LANG_KOREAN) { rc = new CefSharp.Structs.Rect(rc.X, rc.Y + caretMargin, rc.Width, rc.Height); } // Japanese IMEs and Korean IMEs also use the rectangle given to // ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE // Therefore, we also set this parameter here. //Referred from : https://bitbucket.org/chromiumembedded/cef/src/af349ade330c33b669c9ad61cd5000c140968fd7/tests/cefclient/browser/osr_ime_handler_win.cc?at=master&fileviewer=file-view-default#osr_ime_handler_win.cc-206 /* * CANDIDATEFORM exclude_rectangle = { * 0, * CFS_EXCLUDE, * {rc.x, rc.y}, * {rc.x, rc.y, rc.x + rc.width, rc.y + rc.height}}; * ::ImmSetCandidateWindow(imc, &exclude_rectangle); * * ::ImmReleaseContext(hwnd_, imc); */ var candidateForm = new NativeIME.TagCandidateForm { DwStyle = NativeIME.CFS_EXCLUDE, PtCurrentPos = new NativeIME.TagPoint { X = rc.X, Y = rc.Y }, RcArea = new NativeIME.TagRect { Left = rc.X, Top = rc.Y, Right = rc.X + rc.Width, Bottom = rc.Y + rc.Height } }; using (var handler = IMEHandler.Create(hwnd)) { NativeIME.ImmSetCandidateWindow(handler._hIMC, ref candidateForm); } }