diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index ff6ff008c8a..bdab1791871 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -383,6 +383,9 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, { const WCHAR *pos; ME_Cursor *p = NULL; + /* FIXME: is this too slow? */ + /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */ + int freeSpace = editor->nTextLimit - ME_GetTextLength(editor); assert(style); @@ -393,6 +396,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, assert(nCursor>=0 && nCursornCursors); if (len == -1) len = lstrlenW(str); + len = min(len, freeSpace); while (len) { pos = str; diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 28f371aa73b..109861877eb 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -32,7 +32,7 @@ - EM_DISPLAYBAND + EM_EMPTYUNDOBUFFER + EM_EXGETSEL - - EM_EXLIMITTEXT + + EM_EXLIMITTEXT + EM_EXLINEFROMCHAR + EM_EXSETSEL + EM_FINDTEXT (only FR_DOWN flag implemented) @@ -51,7 +51,7 @@ - EM_GETIMEOPTIONS 1.0asian - EM_GETIMESTATUS - EM_GETLANGOPTIONS 2.0 - - EM_GETLIMITTEXT + + EM_GETLIMITTEXT + EM_GETLINE + EM_GETLINECOUNT returns number of rows, not of paragraphs + EM_GETMODIFY @@ -232,6 +232,8 @@ #define STACK_SIZE_DEFAULT 100 #define STACK_SIZE_MAX 1000 + +#define TEXT_LIMIT_DEFAULT 32767 WINE_DEFAULT_DEBUG_CHANNEL(richedit); @@ -1124,6 +1126,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { ed->bCaretAtEnd = FALSE; ed->nEventMask = 0; ed->nModifyStep = 0; + ed->nTextLimit = TEXT_LIMIT_DEFAULT; ed->pUndoStack = ed->pRedoStack = ed->pUndoStackBottom = NULL; ed->nUndoStackSize = 0; ed->nUndoLimit = STACK_SIZE_DEFAULT; @@ -1420,7 +1423,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP switch(msg) { UNSUPPORTED_MSG(EM_DISPLAYBAND) - UNSUPPORTED_MSG(EM_EXLIMITTEXT) UNSUPPORTED_MSG(EM_FINDWORDBREAK) UNSUPPORTED_MSG(EM_FMTLINES) UNSUPPORTED_MSG(EM_FORMATRANGE) @@ -1429,7 +1431,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP UNSUPPORTED_MSG(EM_GETIMECOMPMODE) /* UNSUPPORTED_MSG(EM_GETIMESTATUS) missing in Wine headers */ UNSUPPORTED_MSG(EM_GETLANGOPTIONS) - UNSUPPORTED_MSG(EM_GETLIMITTEXT) /* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */ UNSUPPORTED_MSG(EM_GETREDONAME) UNSUPPORTED_MSG(EM_GETTEXTMODE) @@ -2194,6 +2195,20 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP TRACE("EM_LINELENGTH(%d)==%d\n",wParam, nChars); return nChars; } + case EM_EXLIMITTEXT: + { + if (wParam != 0 || lParam < 0) + return 0; + if (lParam == 0) + editor->nTextLimit = 65536; + else + editor->nTextLimit = (int) lParam; + return 0; + } + case EM_GETLIMITTEXT: + { + return editor->nTextLimit; + } case EM_FINDTEXT: { FINDTEXTA *ft = (FINDTEXTA *)lParam; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 1109175832f..f22717f60e8 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -312,6 +312,7 @@ typedef struct tagME_TextEditor RECT rcFormat; BOOL bRedraw; int nInvalidOfs; + int nTextLimit; EDITWORDBREAKPROCW pfnWordBreak; LPRICHEDITOLECALLBACK lpOleCallback; /*TEXTMODE variable; contains only one of each of the following options: diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 5c1f7c1988b..7812f7d9037 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -972,6 +972,96 @@ static void test_EM_SETTEXTEX() } +static void test_EM_EXLIMITTEXT(void) +{ + int i, selBegin, selEnd, len1, len2; + int BUFSIZE = 1024; + char text[BUFSIZE+1]; + int textlimit = 0; /* multiple of 100 */ + HWND hwndRichEdit = new_richedit(NULL); + + i = SendMessage(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); + ok(32767 == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", 32767, i); /* default */ + + textlimit = 256000; + SendMessage(hwndRichEdit, EM_EXLIMITTEXT, 0, textlimit); + i = SendMessage(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); + /* set higher */ + ok(textlimit == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", textlimit, i); + + textlimit = 1000; + SendMessage(hwndRichEdit, EM_EXLIMITTEXT, 0, textlimit); + i = SendMessage(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); + /* set lower */ + ok(textlimit == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", textlimit, i); + + SendMessage(hwndRichEdit, EM_EXLIMITTEXT, 0, 0); + i = SendMessage(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); + /* default for WParam = 0 */ + ok(65536 == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", 65536, i); + + textlimit = BUFSIZE; + memset(text, 'W', textlimit); + text[BUFSIZE] = 0; + SendMessage(hwndRichEdit, EM_EXLIMITTEXT, 0, textlimit); + /* maxed out text */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text); + + SendMessage(hwndRichEdit, EM_SETSEL, 0, -1); /* select everything */ + SendMessage(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); + len1 = selEnd - selBegin; + + SendMessage(hwndRichEdit, WM_KEYDOWN, VK_BACK, 1); + SendMessage(hwndRichEdit, WM_CHAR, VK_BACK, 1); + SendMessage(hwndRichEdit, WM_KEYUP, VK_BACK, 1); + SendMessage(hwndRichEdit, EM_SETSEL, 0, -1); + SendMessage(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); + len2 = selEnd - selBegin; + + ok(len1 != len2, + "EM_EXLIMITTEXT: Change Expected\nOld Length: %d, New Length: %d, Limit: %d\n", + len1,len2,i); + + SendMessage(hwndRichEdit, WM_KEYDOWN, 'A', 1); + SendMessage(hwndRichEdit, WM_CHAR, 'A', 1); + SendMessage(hwndRichEdit, WM_KEYUP, 'A', 1); + SendMessage(hwndRichEdit, EM_SETSEL, 0, -1); + SendMessage(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); + len1 = selEnd - selBegin; + + ok(len1 != len2, + "EM_EXLIMITTEXT: Change Expected\nOld Length: %d, New Length: %d, Limit: %d\n", + len1,len2,i); + + SendMessage(hwndRichEdit, WM_KEYDOWN, 'A', 1); + SendMessage(hwndRichEdit, WM_CHAR, 'A', 1); + SendMessage(hwndRichEdit, WM_KEYUP, 'A', 1); /* full; should be no effect */ + SendMessage(hwndRichEdit, EM_SETSEL, 0, -1); + SendMessage(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); + len2 = selEnd - selBegin; + + ok(len1 == len2, + "EM_EXLIMITTEXT: No Change Expected\nOld Length: %d, New Length: %d, Limit: %d\n", + len1,len2,i); + + DestroyWindow(hwndRichEdit); +} + +static void test_EM_GETLIMITTEXT(void) +{ + int i; + HWND hwndRichEdit = new_richedit(NULL); + + i = SendMessage(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); + ok(32767 == i, "expected: %d, actual: %d\n", 32767, i); /* default value */ + + SendMessage(hwndRichEdit, EM_EXLIMITTEXT, 0, 50000); + i = SendMessage(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); + ok(50000 == i, "expected: %d, actual: %d\n", 50000, i); + + DestroyWindow(hwndRichEdit); +} + START_TEST( editor ) { MSG msg; @@ -993,6 +1083,8 @@ START_TEST( editor ) test_EM_SETUNDOLIMIT(); test_ES_PASSWORD(); test_EM_SETTEXTEX(); + test_EM_EXLIMITTEXT(); + test_EM_GETLIMITTEXT(); /* Set the environment variable WINETEST_RICHED20 to keep windows * responsive and open for 30 seconds. This is useful for debugging.