Example #1
0
 private void DestroyImeWindow(IntPtr hwnd)
 {
     if (_systemCaret)
     {
         NativeIME.DestroyCaret();
         _systemCaret = false;
     }
 }
Example #2
0
        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);
        }
Example #3
0
        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();
        }
Example #4
0
        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;
                    }
                }
            }
        }
Example #5
0
        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);
            }
        }