/// <summary> return true if currently editing composition string in IME /// </summary> /// <param name="control"> /// </param> /// <returns> bool /// </returns> public bool IsEditingCompStr(Control control) { bool ret = false; if (control is TextBoxBase) { IntPtr hWnd = control.Handle; if (hWnd == IntPtr.Zero) { return(ret); } int hIMC = NativeWindowCommon.ImmGetContext(hWnd); if (hIMC == 0) { return(ret); } if (NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_COMPSTR, null, 0) > 0) { ret = true; } NativeWindowCommon.ImmReleaseContext(hWnd, hIMC); } return(ret); }
protected override void WndProc(ref Message m) { if (m.Msg == NativeWindowCommon.WM_IME_COMPOSITION) { switch (CultureInfo.CurrentCulture.LCID) { case 1041: // Japanese (JPN: ZIMERead function) if (((int)m.LParam & NativeWindowCommon.GCS_RESULTREADSTR) > 0) { int hIMC = NativeWindowCommon.ImmGetContext(this.Handle); try { int size = NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_RESULTREADSTR, null, 0); StringBuilder buffer = new StringBuilder(size); NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_RESULTREADSTR, buffer, (uint)size); string str = buffer.ToString().Substring(0, size / 2); ImeReadStrBuilder.Append(str); } finally { NativeWindowCommon.ImmReleaseContext(this.Handle, hIMC); } } break; case 1042: // Korean if (KoreanInterimSel < 0) { KoreanInterimSel = NativeWindowCommon.SendMessage(this.Handle, NativeWindowCommon.EM_GETSEL, 0, 0); } break; } } else if (m.Msg == NativeWindowCommon.WM_IME_ENDCOMPOSITION) { if (CultureInfo.CurrentCulture.LCID == 1042) { KoreanInterimSel = -1; } } else if (m.Msg == NativeWindowCommon.WM_PAINT) { if (isTransparent) { NativeWindowCommon.SendMessage(this.Handle, NativeWindowCommon.WM_NCPAINT, 0, 0); } if (ControlStyle == ControlStyle.ThreeD) { base.WndProc(ref m); using (Graphics g = Graphics.FromHwnd(this.Handle)) { BorderRenderer.PaintBorder(g, ClientRectangle, ForeColor, ControlStyle.ThreeD, false); return; } } } else if (m.Msg == NativeWindowCommon.WM_NCCALCSIZE) { if (BorderStyle == BorderStyle.FixedSingle) { RecalcNonClientArea(ref m); } } else if (m.Msg == NativeWindowCommon.WM_NCPAINT) { if (BorderStyle == BorderStyle.FixedSingle) { WMNCPaint(ref m); } } base.WndProc(ref m); }
private int WindowProc(IntPtr hwnd, uint msg, uint wParam, int lParam) { int ret = 0; // keydown of '\f' - barcode prefix. start accumulating key strokes if (msg == NativeWindowCommon.WM_KEYDOWN && wParam == '\f' && !(isJapanese() && usePasswordChar)) { accumulationMode = true; accumulatedBuffer = new StringBuilder(); } // If we are accumulating key strokes we don't want to pass on the keys messages if (accumulationMode && (msg == NativeWindowCommon.WM_KEYDOWN || msg == NativeWindowCommon.WM_CHAR || msg == NativeWindowCommon.WM_KEYUP)) { if (msg == NativeWindowCommon.WM_CHAR) { // Add the chars to our accumulation string if (wParam != '\f') { accumulatedBuffer.Append((char)wParam); } } if (msg == NativeWindowCommon.WM_KEYDOWN) { // tab signs the end of scanner input. set the text to the control and stop accumulating if ((char)wParam == '\t') { accumulationMode = false; KeyEventArgs e = new KeyEventArgs((Keys)KEY_ACCUMULATED); this.OnKeyDown(e); } } } else { // Call original proc // 1. We may get sometime (from Hebrew keyboard on a PC, from a barcode scanner...)a keydown event // with wParam 0, which translates to nothing and causes a crash // 2. The KeyDown event for the enter key is not raised for textbox on Mobile. // On Windows Mobile 6 standard, the up and down are used by the system to change focus, // and we don't get the events in the text box, so we skip the native window proc and raise // the event. if (msg != NativeWindowCommon.WM_KEYDOWN || (wParam != (int)Keys.Enter && wParam != (int)Keys.Down && wParam != (int)Keys.Up && wParam != 0)) { if (isJapanese()) // JPN: ZIMERead function { if (msg == NativeWindowCommon.WM_IME_COMPOSITION) { if ((lParam & NativeWindowCommon.GCS_RESULTREADSTR) > 0) { int hIMC = NativeWindowCommon.ImmGetContext(this.Handle); try { int size = NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_RESULTREADSTR, null, 0); StringBuilder buffer = new StringBuilder(size); NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_RESULTREADSTR, buffer, (uint)size); string str = buffer.ToString().Substring(0, size / 2); ImeReadStrBuilder.Append(str); } finally { NativeWindowCommon.ImmReleaseContext(this.Handle, hIMC); } } } } ret = NativeWindowCommon.CallWindowProc(OrigWndProc, hwnd, msg, wParam, lParam); } else if (msg != NativeWindowCommon.WM_KEYDOWN || wParam != 0) { KeyEventArgs e = new KeyEventArgs((Keys)wParam); this.OnKeyDown(e); } // else WM_KEYDOWN with wParam == 0 - do nothing } // Raise the events we don't get on Mobile if (msg == NativeWindowCommon.WM_LBUTTONDOWN) { MouseEventArgs mouseEvents = new MouseEventArgs(MouseButtons.Left, 0, NativeWindowCommon.LoWord(lParam), NativeWindowCommon.HiWord(lParam), 0); this.OnMouseDown(mouseEvents); } else if (msg == NativeWindowCommon.WM_LBUTTONUP) { MouseEventArgs mouseEvents = new MouseEventArgs(MouseButtons.Left, 0, NativeWindowCommon.LoWord(lParam), NativeWindowCommon.HiWord(lParam), 0); this.OnMouseUp(mouseEvents); } return(ret); }
protected override void WndProc(ref Message m) { if (m.Msg == NativeWindowCommon.WM_LBUTTONDOWN) { SaveSelectionStart = SelectionStart; SaveSelectionLength = SelectionLength; } else if (m.Msg == NativeWindowCommon.WM_PAINT) { if (!Focused) { //Allow framework to draw the borders, we will draw text & other things. //So called base.WndProc & removed ValidateRect() from PaintNotFocusedControl() method. base.WndProc(ref m); PaintNotFocusedControl(); return; } } if (isJapanese()) // JPN: ZIMERead function { if (m.Msg == NativeWindowCommon.WM_IME_COMPOSITION) { if (((int)m.LParam & NativeWindowCommon.GCS_RESULTREADSTR) > 0) { int hIMC = NativeWindowCommon.ImmGetContext(this.Handle); try { int size = NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_RESULTREADSTR, null, 0); StringBuilder buffer = new StringBuilder(size); NativeWindowCommon.ImmGetCompositionString(hIMC, NativeWindowCommon.GCS_RESULTREADSTR, buffer, (uint)size); string str = buffer.ToString().Substring(0, size / 2); ImeReadStrBuilder.Append(str); } finally { NativeWindowCommon.ImmReleaseContext(this.Handle, hIMC); } } } } // handling of cut/copy/paste event raised from default(system) conext menu invoked on text box switch (m.Msg) { case NativeWindowCommon.WM_CUT: if (CutEvent != null) { CutEvent(this, new EventArgs()); return; } else { break; } case NativeWindowCommon.WM_COPY: if (CopyEvent != null) { CopyEvent(this, new EventArgs()); return; } else { break; } case NativeWindowCommon.WM_PASTE: if (PasteEvent != null) { PasteEvent(this, new EventArgs()); return; } else { break; } case NativeWindowCommon.WM_CLEAR: if (ClearEvent != null) { ClearEvent(this, new EventArgs()); return; } else { break; } case NativeWindowCommon.WM_UNDO: if (UndoEvent != null) { UndoEvent(this, new EventArgs()); return; } else { break; } } if (isKorean() && !Multiline) { if (CheckClickSequence(m)) { return; } ImeParam im = KoreanImeMessageParam(m); if (im != null) { // (Korean) Some IME messages must be postponed until processing in // TextMaskEditor.action() is finished. So it is routed to RT Event loop. ImeEventArgs iea = new ImeEventArgs(im); ImeEvent(this, iea); if (iea.Handled) { return; } } else { // RT Event handler send back those IME messagesas MG_IME_XX // to avoid confusion, so it is translated to WM_IME_XX KoreanMessageTranslation(ref m); } } base.WndProc(ref m); }
/// <summary> turn on/off the input method editor /// </summary> /// <param name="control"> /// </param> public void controlIme(Control control, int imeMode) { if (control is TextBox || control is ComboBox || control is ListBox) { int hIMC = NativeWindowCommon.ImmGetContext(control.Handle); if (hIMC == 0) { return; } if (!isValid(imeMode)) { return; } if (control is TextBox) { if (imeMode == IME_DISABLE) { ((TextBox)control).ReadOnly = true; return; } } else { imeMode = 0; } int imeConvMode = imeMode2imeConvMode(imeMode); // get current open status bool isImeOpen = NativeWindowCommon.ImmGetOpenStatus(hIMC); if (!isImeOpen) { NativeWindowCommon.ImmSetOpenStatus(hIMC, true); } #if !PocketPC if (_prevImeState.IsContinue) #else if (_prevImeState.IsContinue || _prevImeMode.ConvMode == IME_NOT_INITIALIZED) #endif { _prevImeState.IsOpen = isImeOpen; // save the current open status as the previous state } _prevImeState.IsContinue = false; // get current conversion mode uint currImeConvMode; uint saveImeSentence; NativeWindowCommon.ImmGetConversionStatus(hIMC, out currImeConvMode, out saveImeSentence); if (_prevImeMode.IsContinue || _prevImeMode.ConvMode == IME_NOT_INITIALIZED) { _prevImeMode.ConvMode = (int)currImeConvMode; // save the current conversion mode as the previous state } _prevImeMode.IsContinue = false; if (imeConvMode == IME_CMODE_NOCONVERSION) { imeConvMode = _prevImeMode.ConvMode; if (imeMode == IME_FORCE_OFF || ImeAutoOff) { isImeOpen = false; #if !PocketPC _prevImeMode.IsContinue = true; // to save the conversion mode when the forcus is moved to other edit control #endif } else { isImeOpen = _prevImeState.IsOpen; _prevImeState.IsContinue = true; // to save the open status when the forcus is moved to other edit control _prevImeMode.IsContinue = true; // to save the conversion mode when the forcus is moved to other edit control } } else { isImeOpen = true; } #if PocketPC if (isImeOpen && (imeConvMode != currImeConvMode)) #else if (imeConvMode != currImeConvMode) #endif { NativeWindowCommon.ImmSetConversionStatus(hIMC, (uint)imeConvMode, saveImeSentence); } if (!isImeOpen) { #if PocketPC NativeWindowCommon.ImmSetConversionStatus(hIMC, (uint)IME_CMODE_NOCONVERSION, saveImeSentence); #endif NativeWindowCommon.ImmSetOpenStatus(hIMC, false); } NativeWindowCommon.ImmReleaseContext(control.Handle, hIMC); } }