Author: jimtabor Date: Tue Oct 23 08:19:29 2007 New Revision: 29811
URL: http://svn.reactos.org/svn/reactos?rev=29811&view=rev Log: Sync with Wine: Edit controls.
Modified: trunk/reactos/dll/win32/user32/controls/edit.c trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/user32/controls/edit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/controls/e... ============================================================================== --- trunk/reactos/dll/win32/user32/controls/edit.c (original) +++ trunk/reactos/dll/win32/user32/controls/edit.c Tue Oct 23 08:19:29 2007 @@ -68,7 +68,8 @@ #define EF_AFTER_WRAP 0x0080 /* the caret is displayed after the last character of a wrapped line, instead of in front of the next character */ #define EF_USE_SOFTBRK 0x0100 /* Enable soft breaks in text. */ - +#define EF_APP_HAS_HANDLE 0x0200 /* Set when an app sends EM_[G|S]ETHANDLE. We are in sole control of + the text buffer if this is clear. */ typedef enum { END_0 = 0, /* line ends with terminating '\0' character */ @@ -91,6 +92,7 @@ { BOOL is_unicode; /* how the control was created */ LPWSTR text; /* the actual contents of the control */ + UINT text_length; /* cached length of text buffer (in WCHARs) - use get_text_length() to retrieve */ UINT buffer_size; /* the size of the buffer in characters */ UINT buffer_limit; /* the maximum size to which the buffer may grow in characters */ HFONT font; /* NULL means standard system font */ @@ -240,7 +242,7 @@ #ifndef __REACTOS__ static void EDIT_EM_SetHandle16(EDITSTATE *es, HLOCAL16 hloc); #endif -static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit); +static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit); static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, WORD left, WORD right, BOOL repaint); static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c); static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap); @@ -402,6 +404,17 @@ return version; }
+static inline UINT get_text_length(EDITSTATE *es) +{ + if(es->text_length == (UINT)-1) + es->text_length = strlenW(es->text); + return es->text_length; +} + +static inline void text_buffer_changed(EDITSTATE *es) +{ + es->text_length = (UINT)-1; +}
static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc) { @@ -816,8 +829,7 @@ break;
case EM_POSFROMCHAR: - result = strlenW(es->text); - if ((INT)wParam >= result) result = -1; + if ((INT)wParam >= get_text_length(es)) result = -1; else result = EDIT_EM_PosFromChar(es, (INT)wParam, FALSE); break;
@@ -951,8 +963,8 @@ break;
case WM_GETTEXTLENGTH: - if (unicode) result = strlenW(es->text); - else result = WideCharToMultiByte( CP_ACP, 0, es->text, strlenW(es->text), + if (unicode) result = get_text_length(es); + else result = WideCharToMultiByte( CP_ACP, 0, es->text, get_text_length(es), NULL, 0, NULL, NULL ); break;
@@ -1077,6 +1089,8 @@ break;
case WM_IME_COMPOSITION: + { + int caret_pos = es->selection_end; if (es->composition_len == 0) { if (es->selection_start != es->selection_end) @@ -1088,7 +1102,9 @@ es->composition_start = es->selection_end; } EDIT_ImeComposition(hwnd,lParam,es); - break; + EDIT_SetCaretPos(es, caret_pos, es->flags & EF_AFTER_WRAP); + break; + }
case WM_IME_ENDCOMPOSITION: es->composition_len= 0; @@ -1631,7 +1647,7 @@ else { INT low = es->x_offset; - INT high = strlenW(es->text) + 1; + INT high = get_text_length(es) + 1; while (low < high - 1) { INT mid = (low + high) / 2; @@ -1707,7 +1723,7 @@ static LPWSTR EDIT_GetPasswordPointer_SL(EDITSTATE *es) { if (es->style & ES_PASSWORD) { - INT len = strlenW(es->text); + INT len = get_text_length(es); LPWSTR text = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); text[len] = '\0'; while(len) text[--len] = es->password_char; @@ -1803,6 +1819,7 @@ LocalUnlock(es->hloc32A); } } + if(es->flags & EF_APP_HAS_HANDLE) text_buffer_changed(es); es->lock_count++; }
@@ -1905,7 +1922,7 @@ return;
if (end == -1) - end = strlenW(es->text); + end = get_text_length(es);
if (end < start) { INT tmp = start; @@ -2053,7 +2070,7 @@ e = EDIT_CharFromPos(es, 0x3fffffff, HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), &after_wrap); else - e = strlenW(es->text); + e = get_text_length(es); EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap); EDIT_EM_ScrollCaret(es); } @@ -2463,7 +2480,7 @@ es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom);
if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) - EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); + EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL);
EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); } @@ -2543,7 +2560,7 @@ if (es->hloc32W) { CHAR *textA = NULL; UINT countA = 0; - UINT countW = strlenW(es->text) + 1; + UINT countW = get_text_length(es) + 1; #ifndef __REACTOS__ STACK16FRAME* stack16 = NULL; HANDLE16 oldDS = 0; @@ -2982,7 +2999,7 @@
if (!(es->style & ES_MULTILINE)) return 0; - if (index > (INT)strlenW(es->text)) + if (index > (INT)get_text_length(es)) return es->line_count - 1; if (index == -1) index = min(es->selection_start, es->selection_end); @@ -3044,7 +3061,7 @@ LINEDEF *line_def;
if (!(es->style & ES_MULTILINE)) - return strlenW(es->text); + return get_text_length(es);
if (index == -1) { /* get the number of remaining non-selected chars of selected lines */ @@ -3152,7 +3169,7 @@ */ static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap) { - INT len = strlenW(es->text); + INT len = get_text_length(es); INT l; INT li; INT x; @@ -3258,7 +3275,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit) { UINT strl = strlenW(lpsz_replace); - UINT tl = strlenW(es->text); + UINT tl = get_text_length(es); UINT utl; UINT s; UINT e; @@ -3288,7 +3305,11 @@ * such that buffer limit is honored. */ if ((honor_limit) && (es->buffer_limit > 0) && (size > es->buffer_limit)) { EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); - strl = es->buffer_limit - (tl - (e-s)); + /* Buffer limit can be smaller than the actual length of text in combobox */ + if (es->buffer_limit < (tl - (e-s))) + strl = 0; + else + strl = es->buffer_limit - (tl - (e-s)); }
if (!EDIT_MakeFit(es, tl - (e - s) + strl)) @@ -3304,10 +3325,11 @@ buf[bufl] = 0; /* ensure 0 termination */ /* now delete */ strcpyW(es->text + s, es->text + e); + text_buffer_changed(es); } if (strl) { /* there is an insertion */ - tl = strlenW(es->text); + tl = get_text_length(es); TRACE("inserting stuff (tl %d, strl %d, selstart %d ('%s'), text '%s')\n", tl, strl, s, debugstr_w(es->text + s), debugstr_w(es->text)); for (p = es->text + tl ; p >= es->text + s ; p--) p[strl] = p[0]; @@ -3317,6 +3339,7 @@ CharUpperBuffW(p, strl); else if(es->style & ES_LOWERCASE) CharLowerBuffW(p, strl); + text_buffer_changed(es); } if (es->style & ES_MULTILINE) { @@ -3333,6 +3356,7 @@ if (e != s) for (i = 0 , p = es->text ; i < e - s ; i++) p[i + s] = buf[i]; + text_buffer_changed(es); EDIT_BuildLineDefs_ML(es, s, e, abs(es->selection_end - es->selection_start) - strl, hrgn); strl = 0; @@ -3351,6 +3375,7 @@ strl--; EDIT_CalcLineWidth_SL(es); } + text_buffer_changed(es); EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); } } @@ -3555,7 +3580,7 @@ EDIT_UpdateText(es, NULL, TRUE); } else if (x > es->format_rect.right) { INT x_last; - INT len = strlenW(es->text); + INT len = get_text_length(es); goal = es->format_rect.right - format_width / HSCROLL_FRACTION; do { es->x_offset++; @@ -3637,6 +3662,7 @@
es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
+ es->flags |= EF_APP_HAS_HANDLE; EDIT_LockBuffer(es);
es->x_offset = es->y_offset = 0; @@ -3644,7 +3670,7 @@ EDIT_EM_EmptyUndoBuffer(es); es->flags &= ~EF_MODIFIED; es->flags &= ~EF_UPDATE; - EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); + EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); EDIT_UpdateText(es, NULL, TRUE); EDIT_EM_ScrollCaret(es); /* force scroll info update */ @@ -3712,7 +3738,7 @@ EDIT_EM_EmptyUndoBuffer(es); es->flags &= ~EF_MODIFIED; es->flags &= ~EF_UPDATE; - EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); + EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); EDIT_UpdateText(es, NULL, TRUE); EDIT_EM_ScrollCaret(es); /* force scroll info update */ @@ -3725,27 +3751,14 @@ * * EM_SETLIMITTEXT * - * FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF - * However, the windows version is not complied to yet in all of edit.c - * - * Additionally as the wrapper for RichEdit controls we need larger buffers - * at present -1 will represent nolimit - */ -static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit) -{ - if (limit == 0xFFFFFFFF) - es->buffer_limit = -1; - else if (es->style & ES_MULTILINE) { - if (limit) - es->buffer_limit = min(limit, BUFLIMIT_MULTI); - else - es->buffer_limit = BUFLIMIT_MULTI; - } else { - if (limit) - es->buffer_limit = min(limit, BUFLIMIT_SINGLE); - else - es->buffer_limit = BUFLIMIT_SINGLE; - } + * NOTE: this version currently implements WinNT limits + * + */ +static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit) +{ + if (!limit) limit = ~0u; + if (!(es->style & ES_MULTILINE)) limit = min(limit, 0x7ffffffe); + es->buffer_limit = limit; }
@@ -3875,7 +3888,7 @@ { UINT old_start = es->selection_start; UINT old_end = es->selection_end; - UINT len = strlenW(es->text); + UINT len = get_text_length(es);
if (start == (UINT)-1) { start = es->selection_end; @@ -3995,7 +4008,7 @@ #endif
if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) { - EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); + EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); EDIT_UpdateText(es, NULL, TRUE); } } @@ -4015,7 +4028,7 @@ es->word_break_proc = NULL; es->word_break_proc16 = wbp; if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) { - EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); + EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); EDIT_UpdateText(es, NULL, TRUE); } } @@ -4108,16 +4121,21 @@ } break; case 0x03: /* ^C */ - SendMessageW(es->hwndSelf, WM_COPY, 0, 0); + if (!(es->style & ES_PASSWORD)) + SendMessageW(es->hwndSelf, WM_COPY, 0, 0); break; case 0x16: /* ^V */ if (!(es->style & ES_READONLY)) SendMessageW(es->hwndSelf, WM_PASTE, 0, 0); break; case 0x18: /* ^X */ - if (!(es->style & ES_READONLY)) + if (!((es->style & ES_READONLY) || (es->style & ES_PASSWORD))) SendMessageW(es->hwndSelf, WM_CUT, 0, 0); break; + case 0x1A: /* ^Z */ + if (!(es->style & ES_READONLY)) + SendMessageW(es->hwndSelf, WM_UNDO, 0, 0); + break;
default: /*If Edit control style is ES_NUMBER allow users to key in only numeric values*/ @@ -4212,7 +4230,17 @@ /* delete */ EnableMenuItem(popup, 5, MF_BYPOSITION | ((end - start) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED)); /* select all */ - EnableMenuItem(popup, 7, MF_BYPOSITION | (start || (end != strlenW(es->text)) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(popup, 7, MF_BYPOSITION | (start || (end != get_text_length(es)) ? MF_ENABLED : MF_GRAYED)); + + if (x == -1 && y == -1) /* passed via VK_APPS press/release */ + { + RECT rc; + /* Windows places the menu at the edit's center in this case */ + GetClientRect(es->hwndSelf, &rc); + MapWindowPoints(es->hwndSelf, 0, (POINT *)&rc, 2); + x = rc.left + (rc.right - rc.left) / 2; + y = rc.top + (rc.bottom - rc.top) / 2; + }
TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, es->hwndSelf, NULL); DestroyMenu(menu); @@ -5040,6 +5068,11 @@ EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE); GlobalUnlock(hsrc); } + else if (es->style & ES_PASSWORD) { + /* clear selected text in password edit box even with empty clipboard */ + const WCHAR empty_strW[] = { 0 }; + EDIT_EM_ReplaceSel(es, TRUE, empty_strW, TRUE, TRUE); + } CloseClipboard(); }
@@ -5106,7 +5139,7 @@ EC_USEFONTINFO, EC_USEFONTINFO, FALSE);
if (es->style & ES_MULTILINE) - EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); + EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL); else EDIT_CalcLineWidth_SL(es);
@@ -5136,11 +5169,12 @@ */ static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text, BOOL unicode) { + LPWSTR textW = NULL; if (!unicode && text) { LPCSTR textA = (LPCSTR)text; INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); - LPWSTR textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)); + textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)); if (textW) MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); text = textW; @@ -5157,7 +5191,7 @@ TRACE("%s\n", debugstr_w(text)); EDIT_EM_ReplaceSel(es, FALSE, text, FALSE, FALSE); if(!unicode) - HeapFree(GetProcessHeap(), 0, (LPWSTR)text); + HeapFree(GetProcessHeap(), 0, textW); } else { @@ -5475,7 +5509,8 @@ return; }
- ImmGetCompositionStringW(hIMC, GCS_COMPSTR, lpCompStr, dwBufLen); + if (dwBufLen) + ImmGetCompositionStringW(hIMC, GCS_COMPSTR, lpCompStr, dwBufLen); lpCompStr[dwBufLen/sizeof(WCHAR)] = 0;
if (CompFlag & GCS_COMPATTR)
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=2... ============================================================================== --- trunk/reactos/media/doc/README.WINE (original) +++ trunk/reactos/media/doc/README.WINE Tue Oct 23 08:19:29 2007 @@ -123,7 +123,7 @@ User32 - reactos/dll/win32/user32/controls/button.c # Synced at 20060621 reactos/dll/win32/user32/controls/combo.c # Synced at 20060904 - reactos/dll/win32/user32/controls/edit.c # Synced at 20060710 + reactos/dll/win32/user32/controls/edit.c # Synced at 20071022 reactos/dll/win32/user32/controls/icontitle.c # Synced at 20060617 reactos/dll/win32/user32/controls/listbox.c # Synced at 20060616 reactos/dll/win32/user32/controls/scrollbar.c # Forked