📄 text.java
字号:
/** * Sets the zero-relative index of the line which is currently * at the top of the receiver. This index can change when lines * are scrolled or new lines are added and removed. * * @param index the index of the top item * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */public void setTopIndex (int index) { checkWidget (); if ((style & SWT.SINGLE) != 0) return; int count = OS.SendMessage (handle, OS.EM_GETLINECOUNT, 0, 0); index = Math.min (Math.max (index, 0), count - 1); int topIndex = OS.SendMessage (handle, OS.EM_GETFIRSTVISIBLELINE, 0, 0); OS.SendMessage (handle, OS.EM_LINESCROLL, 0, index - topIndex);}/** * Shows the selection. * <p> * If the selection is already showing * in the receiver, this method simply returns. Otherwise, * lines are scrolled until the selection is visible. * </p> * * @exception SWTException <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * </ul> */public void showSelection () { checkWidget (); OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);}String verifyText (String string, int start, int end, Event keyEvent) { if (ignoreVerify) return string; Event event = new Event (); event.text = string; event.start = start; event.end = end; if (keyEvent != null) { event.character = keyEvent.character; event.keyCode = keyEvent.keyCode; event.stateMask = keyEvent.stateMask; } if (OS.IsDBLocale) { event.start = mbcsToWcsPos (start); event.end = mbcsToWcsPos (end); } /* * It is possible (but unlikely), that application * code could have disposed the widget in the verify * event. If this happens, answer null to cancel * the operation. */ sendEvent (SWT.Verify, event); if (!event.doit || isDisposed ()) return null; return event.text;}int wcsToMbcsPos (int wcsPos) { if (wcsPos == 0) return 0; if (OS.IsUnicode) return wcsPos; int cp = getCodePage (); int wcsTotal = 0, mbcsTotal = 0; byte [] buffer = new byte [128]; String delimiter = getLineDelimiter (); int delimiterSize = delimiter.length (); int count = OS.SendMessageA (handle, OS.EM_GETLINECOUNT, 0, 0); for (int line=0; line<count; line++) { int wcsSize = 0; int linePos = OS.SendMessageA (handle, OS.EM_LINEINDEX, line, 0); int mbcsSize = OS.SendMessageA (handle, OS.EM_LINELENGTH, linePos, 0); if (mbcsSize != 0) { if (mbcsSize + delimiterSize > buffer.length) { buffer = new byte [mbcsSize + delimiterSize]; } //ENDIAN buffer [0] = (byte) (mbcsSize & 0xFF); buffer [1] = (byte) (mbcsSize >> 8); mbcsSize = OS.SendMessageA (handle, OS.EM_GETLINE, line, buffer); wcsSize = OS.MultiByteToWideChar (cp, OS.MB_PRECOMPOSED, buffer, mbcsSize, null, 0); } if (line - 1 != count) { for (int i=0; i<delimiterSize; i++) { buffer [mbcsSize++] = (byte) delimiter.charAt (i); } wcsSize += delimiterSize; } if ((wcsTotal + wcsSize) >= wcsPos) { wcsSize = 0; int index = 0; while (index < mbcsSize) { if ((wcsTotal + wcsSize) == wcsPos) { return mbcsTotal + index; } if (OS.IsDBCSLeadByte (buffer [index++])) index++; wcsSize++; } return mbcsTotal + mbcsSize; } wcsTotal += wcsSize; mbcsTotal += mbcsSize; } return mbcsTotal;}int widgetStyle () { int bits = super.widgetStyle () | OS.ES_AUTOHSCROLL; if ((style & SWT.PASSWORD) != 0) bits |= OS.ES_PASSWORD; if ((style & SWT.CENTER) != 0) bits |= OS.ES_CENTER; if ((style & SWT.RIGHT) != 0) bits |= OS.ES_RIGHT; if ((style & SWT.READ_ONLY) != 0) bits |= OS.ES_READONLY; if ((style & SWT.SINGLE) != 0) return bits; bits |= OS.ES_MULTILINE | OS.ES_NOHIDESEL | OS.ES_AUTOVSCROLL; if ((style & SWT.WRAP) != 0) bits &= ~(OS.WS_HSCROLL | OS.ES_AUTOHSCROLL); return bits;}TCHAR windowClass () { return EditClass;}int windowProc () { return EditProc;}LRESULT WM_CHAR (int wParam, int lParam) { if (ignoreCharacter) return null; LRESULT result = super.WM_CHAR (wParam, lParam); if (result != null) return result; /* * Feature in Windows. For some reason, when the * widget is a single line text widget, when the * user presses tab, return or escape, Windows beeps. * The fix is to look for these keys and not call * the window proc. */ if ((style & SWT.SINGLE) != 0) { switch (wParam) { case OS.VK_RETURN: postEvent (SWT.DefaultSelection); // FALL THROUGH case OS.VK_TAB: case OS.VK_ESCAPE: return LRESULT.ZERO; } } return result;}LRESULT WM_CLEAR (int wParam, int lParam) { LRESULT result = super.WM_CLEAR (wParam, lParam); if (result != null) return result; if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return result; if ((style & SWT.READ_ONLY) != 0) return result; int [] start = new int [1], end = new int [1]; OS.SendMessage (handle, OS.EM_GETSEL, start, end); if (start [0] == end [0]) return result; String newText = verifyText ("", start [0], end [0], null); if (newText == null) return LRESULT.ZERO; if (newText.length () != 0) { result = new LRESULT (callWindowProc (OS.WM_CLEAR, 0, 0)); newText = Display.withCrLf (newText); TCHAR buffer = new TCHAR (getCodePage (), newText, true); /* * Feature in Windows. When an edit control with ES_MULTILINE * style that does not have the WS_VSCROLL style is full (i.e. * there is no space at the end to draw any more characters), * EM_REPLACESEL sends a WM_CHAR with a backspace character * to remove any further text that is added. This is an * implementation detail of the edit control that is unexpected * and can cause endless recursion when EM_REPLACESEL is sent * from a WM_CHAR handler. The fix is to ignore calling the * handler from WM_CHAR. */ ignoreCharacter = true; OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer); ignoreCharacter = false; } return result;}LRESULT WM_CUT (int wParam, int lParam) { LRESULT result = super.WM_CUT (wParam, lParam); if (result != null) return result; if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return result; if ((style & SWT.READ_ONLY) != 0) return result; int [] start = new int [1], end = new int [1]; OS.SendMessage (handle, OS.EM_GETSEL, start, end); if (start [0] == end [0]) return result; String newText = verifyText ("", start [0], end [0], null); if (newText == null) return LRESULT.ZERO; if (newText.length () != 0) { result = new LRESULT (callWindowProc (OS.WM_CUT, 0, 0)); newText = Display.withCrLf (newText); TCHAR buffer = new TCHAR (getCodePage (), newText, true); /* * Feature in Windows. When an edit control with ES_MULTILINE * style that does not have the WS_VSCROLL style is full (i.e. * there is no space at the end to draw any more characters), * EM_REPLACESEL sends a WM_CHAR with a backspace character * to remove any further text that is added. This is an * implementation detail of the edit control that is unexpected * and can cause endless recursion when EM_REPLACESEL is sent * from a WM_CHAR handler. The fix is to ignore calling the * handler from WM_CHAR. */ ignoreCharacter = true; OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer); ignoreCharacter = false; } return result;}LRESULT WM_GETDLGCODE (int wParam, int lParam) { LRESULT result = super.WM_GETDLGCODE (wParam, lParam); if (result != null) return result; /* * Bug in WinCE PPC. For some reason, sending WM_GETDLGCODE * to a multi-line edit control causes it to ignore return and * tab keys. The fix is to return the value which is normally * returned by the text window proc on other versions of Windows. */ if (OS.IsPPC) { if ((style & SWT.MULTI) != 0 && (style & SWT.READ_ONLY) == 0 && lParam == 0) { return new LRESULT (OS.DLGC_HASSETSEL | OS.DLGC_WANTALLKEYS | OS.DLGC_WANTCHARS); } } /* * Feature in Windows. Despite the fact that the * edit control is read only, it still returns a * dialog code indicating that it wants keys. The * fix is to detect this case and clear the bits. */ if ((style & SWT.READ_ONLY) != 0) { int code = callWindowProc (OS.WM_GETDLGCODE, wParam, lParam); code &= ~(OS.DLGC_WANTALLKEYS | OS.DLGC_WANTTAB | OS.DLGC_WANTARROWS); return new LRESULT (code); } return null;}LRESULT WM_IME_CHAR (int wParam, int lParam) { /* Process a DBCS character */ Display display = this.display; display.lastKey = 0; display.lastAscii = wParam; display.lastVirtual = display.lastNull = display.lastDead = false; if (!sendKeyEvent (SWT.KeyDown, OS.WM_IME_CHAR, wParam, lParam)) { return LRESULT.ZERO; } /* * Feature in Windows. The Windows text widget uses * two 2 WM_CHAR's to process a DBCS key instead of * using WM_IME_CHAR. The fix is to allow the text * widget to get the WM_CHAR's but ignore sending * them to the application. */ ignoreCharacter = true; int result = callWindowProc (OS.WM_IME_CHAR, wParam, lParam); MSG msg = new MSG (); int flags = OS.PM_REMOVE | OS.PM_NOYIELD | OS.PM_QS_INPUT | OS.PM_QS_POSTMESSAGE; while (OS.PeekMessage (msg, handle, OS.WM_CHAR, OS.WM_CHAR, flags)) { OS.TranslateMessage (msg); OS.DispatchMessage (msg); } ignoreCharacter = false; sendKeyEvent (SWT.KeyUp, OS.WM_IME_CHAR, wParam, lParam); // widget could be disposed at this point display.lastKey = display.lastAscii = 0; return new LRESULT (result);}LRESULT WM_LBUTTONDBLCLK (int wParam, int lParam) { /* * Prevent Windows from processing WM_LBUTTONDBLCLK * when double clicking behavior is disabled by not * calling the window proc. */ sendMouseEvent (SWT.MouseDown, 1, OS.WM_LBUTTONDOWN, wParam, lParam); sendMouseEvent (SWT.MouseDoubleClick, 1, OS.WM_LBUTTONDBLCLK, wParam, lParam); if (OS.GetCapture () != handle) OS.SetCapture (handle); if (!doubleClick) return LRESULT.ZERO; /* * Bug in Windows. When the last line of text in the * widget is double clicked and the line is empty, Windows * hides the i-beam then moves it to the first line in * the widget but does not scroll to show the user. * If the user types without clicking the mouse, invalid * characters are displayed at the end of each line of * text in the widget. The fix is to detect this case * and avoid calling the window proc. */ int [] start = new int [1], end = new int [1]; OS.SendMessage (handle, OS.EM_GETSEL, start, end); if (start [0] == end [0]) { int length = OS.GetWindowTextLength (handle); if (length == start [0]) { int result = OS.SendMessage (handle, OS.EM_LINELENGTH, length, 0); if (result == 0) return LRESULT.ZERO; } } return null;}LRESULT WM_PASTE (int wParam, int lParam) { LRESULT result = super.WM_PASTE (wParam, lParam); if (result != null) return result; if (!hooks (SWT.Verify) && !filters (SWT.Verify)) return result; if ((style & SWT.READ_ONLY) != 0) return result; String oldText = getClipboardText (); if (oldText == null) return result; int [] start = new int [1], end = new int [1]; OS.SendMessage (handle, OS.EM_GETSEL, start, end); String newText = verifyText (oldText, start [0], end [0], null); if (newText == null) return LRESULT.ZERO; if (newText != oldText) { newText = Display.withCrLf (newText); TCHAR buffer = new TCHAR (getCodePage (), newText, true); /* * Feature in Windows. When an edit control with ES_MULTILINE * style that does not have the WS_VSCROLL style is full (i.e. * there is no space at the end to draw any more characters), * EM_REPLACESEL sends a WM_CHAR with a backspace character * to remove any further text that is added. This is an * implementation detail of the edit control that is unexpected * and can cause endless recursion when EM_REPLACESEL is sent * from a WM_CHAR handler. The fix is to ignore calling the * handler from WM_CHAR. */ ignoreCharacter = true; OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer); ignoreCharacter = false; return LRESULT.ZERO; } return result;}LRESULT WM_UNDO (int wParam, int lParam) { LRESULT result = super.WM_UNDO (wParam, lParam); if (result != null) return result; if (!hooks (SWT.Verify) && !filters (SWT.Verify)) { return result; } /* Undo and then Redo to get the Undo text */ if (OS.SendMessage (handle, OS.EM_CANUNDO, 0, 0) == 0) { return result; } ignoreVerify = true; callWindowProc (OS.WM_UNDO, wParam, lParam); String oldText = getSelectionText (); callWindowProc (OS.WM_UNDO, wParam, lParam); ignoreVerify = false; /* Verify the Undo operation */ int [] start = new int [1], end = new int [1]; OS.SendMessage (handle, OS.EM_GETSEL, start, end); String newText = verifyText (oldText, start [0], end [0], null); if (newText == null) return LRESULT.ZERO; if (newText != oldText) { newText = Display.withCrLf (newText); TCHAR buffer = new TCHAR (getCodePage (), newText, true); /* * Feature in Windows. When an edit control with ES_MULTILINE * style that does not have the WS_VSCROLL style is full (i.e. * there is no space at the end to draw any more characters), * EM_REPLACESEL sends a WM_CHAR with a backspace character * to remove any further text that is added. This is an * implementation detail of the edit control that is unexpected * and can cause endless recursion when EM_REPLACESEL is sent * from a WM_CHAR handler. The fix is to ignore calling the * handler from WM_CHAR. */ ignoreCharacter = true; OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer); ignoreCharacter = false; return LRESULT.ZERO; } /* Do the original Undo */ ignoreVerify = true; callWindowProc (OS.WM_UNDO, wParam, lParam); ignoreVerify = false; return LRESULT.ONE;}LRESULT wmCommandChild (int wParam, int lParam) { int code = wParam >> 16; switch (code) { case OS.EN_CHANG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -