private static void GetCompositionUnderlines(IntPtr hIMC, int targetStart, int targetEnd, List <CompositionUnderline> underlines) { var clauseSize = ImeNative.ImmGetCompositionString(hIMC, ImeNative.GCS_COMPCLAUSE, null, 0); if (clauseSize <= 0) { return; } int clauseLength = (int)clauseSize / sizeof(Int32); // buffer contains 32 bytes (4 bytes) array var clauseData = new byte[(int)clauseSize]; ImeNative.ImmGetCompositionString(hIMC, ImeNative.GCS_COMPCLAUSE, clauseData, clauseSize); var clauseLength_1 = clauseLength - 1; for (int i = 0; i < clauseLength_1; i++) { int from = BitConverter.ToInt32(clauseData, i * sizeof(Int32)); int to = BitConverter.ToInt32(clauseData, (i + 1) * sizeof(Int32)); var range = new Range(from, to); bool thick = (range.From >= targetStart && range.To <= targetEnd); underlines.Add(new CompositionUnderline(range, ColorUNDERLINE, ColorBKCOLOR, thick)); } }
//销毁输入法窗口 private void DestroyImeWindow(IntPtr hwnd) { if (systemCaret) { //清除位置信息 ImeNative.DestroyCaret(); systemCaret = false; } }
private void CloseImeComposition() { if (hasImeComposition) { // Set focus to 0, which destroys IME suggestions window. ImeNative.SetFocus(IntPtr.Zero); // Restore focus. ImeNative.SetFocus(source.Handle); } }
public static bool GetResult(IntPtr hwnd, uint lParam, out string text) { var hIMC = ImeNative.ImmGetContext(hwnd); var ret = GetString(hIMC, lParam, ImeNative.GCS_RESULTSTR, out text); ImeNative.ImmReleaseContext(hwnd, hIMC); return(ret); }
private void CreateImeWindow(IntPtr hwnd) { languageCodeId = PrimaryLangId(InputLanguageManager.Current.CurrentInputLanguage.KeyboardLayoutId); if (languageCodeId == ImeNative.LANG_JAPANESE || languageCodeId == ImeNative.LANG_CHINESE) { if (!systemCaret) { if (ImeNative.CreateCaret(hwnd, IntPtr.Zero, 1, 1)) { systemCaret = true; } } } }
public static bool GetComposition(IntPtr hwnd, uint lParam, List <CompositionUnderline> underlines, ref int compositionStart, out string text) { var hIMC = ImeNative.ImmGetContext(hwnd); bool ret = GetString(hIMC, lParam, ImeNative.GCS_COMPSTR, out text); if (ret) { GetCompositionInfo(hwnd, lParam, text, underlines, ref compositionStart); } ImeNative.ImmReleaseContext(hwnd, hIMC); return(ret); }
private void MoveImeWindow(IntPtr hwnd) { var hIMC = ImeNative.ImmGetContext(hwnd); var rc = MBApi.wkeGetCaretRect(owner.MiniblinkHandle); var x = rc.x + rc.w; var y = rc.y + rc.h; const int kCaretMargin = 1; var candidatePosition = new ImeNative.CANDIDATEFORM { dwIndex = 0, dwStyle = (int)ImeNative.CFS_CANDIDATEPOS, ptCurrentPos = new ImeNative.POINT(x, y), rcArea = new ImeNative.RECT(0, 0, 0, 0) }; ImeNative.ImmSetCandidateWindow(hIMC, ref candidatePosition); if (systemCaret) { ImeNative.SetCaretPos(x, y); } if (languageCodeId == ImeNative.LANG_KOREAN) { y += kCaretMargin; } var excludeRectangle = new ImeNative.CANDIDATEFORM { dwIndex = 0, dwStyle = (int)ImeNative.CFS_EXCLUDE, ptCurrentPos = new ImeNative.POINT(x, y), rcArea = new ImeNative.RECT(rc.x, rc.y, x, y + kCaretMargin) }; ImeNative.ImmSetCandidateWindow(hIMC, ref excludeRectangle); ImeNative.ImmReleaseContext(hwnd, hIMC); }
private static bool GetString(IntPtr hIMC, uint lParam, uint type, out string text) { text = string.Empty; if (!IsParam(lParam, type)) { return(false); } var strLen = ImeNative.ImmGetCompositionString(hIMC, type, null, 0); if (strLen <= 0) { return(false); } // buffer contains char (2 bytes) byte[] buffer = new byte[strLen]; ImeNative.ImmGetCompositionString(hIMC, type, buffer, strLen); text = Encoding.Unicode.GetString(buffer); return(true); }
private static void GetCompositionSelectionRange(IntPtr hIMC, ref int targetStart, ref int targetEnd) { var attributeSize = ImeNative.ImmGetCompositionString(hIMC, ImeNative.GCS_COMPATTR, null, 0); if (attributeSize <= 0) { return; } int start = 0; int end = 0; // Buffer contains 8bit array var attributeData = new byte[attributeSize]; ImeNative.ImmGetCompositionString(hIMC, ImeNative.GCS_COMPATTR, attributeData, attributeSize); for (start = 0; start < attributeSize; ++start) { if (IsSelectionAttribute(attributeData[start])) { break; } } for (end = start; end < attributeSize; ++end) { if (!IsSelectionAttribute(attributeData[end])) { break; } } targetStart = start; targetEnd = end; }
private static void GetCompositionInfo(IntPtr hwnd, uint lParam, string text, List <CompositionUnderline> underlines, ref int compositionStart) { var hIMC = ImeNative.ImmGetContext(hwnd); underlines.Clear(); int targetStart = text.Length; int targetEnd = text.Length; if (IsParam(lParam, ImeNative.GCS_COMPATTR)) { GetCompositionSelectionRange(hIMC, ref targetStart, ref targetEnd); } // Retrieve the selection range information. If CS_NOMOVECARET is specified // it means the cursor should not be moved and we therefore place the caret at // the beginning of the composition string. Otherwise we should honour the // GCS_CURSORPOS value if it's available. if (!IsParam(lParam, ImeNative.CS_NOMOVECARET) && IsParam(lParam, ImeNative.GCS_CURSORPOS)) { // IMM32 does not support non-zero-width selection in a composition. So // always use the caret position as selection range. int cursor = (int)ImeNative.ImmGetCompositionString(hIMC, ImeNative.GCS_CURSORPOS, null, 0); compositionStart = cursor; } else { compositionStart = 0; } if (IsParam(lParam, ImeNative.GCS_COMPCLAUSE)) { GetCompositionUnderlines(hIMC, targetStart, targetEnd, underlines); } if (underlines.Count == 0) { var range = new Range(); bool thick = false; if (targetStart > 0) { range = new Range(0, targetStart); } if (targetEnd > targetStart) { range = new Range(targetStart, targetEnd); thick = true; } if (targetEnd < text.Length) { range = new Range(targetEnd, text.Length); } underlines.Add(new CompositionUnderline(range, ColorUNDERLINE, ColorBKCOLOR, thick)); } ImeNative.ImmReleaseContext(hwnd, hIMC); }