Author: pschweitzer
Date: Tue Jul 8 05:09:42 2008
New Revision: 34368
URL:
http://svn.reactos.org/svn/reactos?rev=34368&view=rev
Log:
Synced riched20_winetest.exe with Wine HEAD
Added:
trunk/rostests/winetests/riched20/richole.c (with props)
Modified:
trunk/rostests/winetests/riched20/editor.c
trunk/rostests/winetests/riched20/riched20.rbuild
trunk/rostests/winetests/riched20/testlist.c
Modified: trunk/rostests/winetests/riched20/editor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/editor…
==============================================================================
--- trunk/rostests/winetests/riched20/editor.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/riched20/editor.c [iso-8859-1] Tue Jul 8 05:09:42 2008
@@ -47,6 +47,40 @@
return new_window(RICHEDIT_CLASS, ES_MULTILINE, parent);
}
+static void processPendingMessages(void)
+{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+static void pressKeyWithModifier(HWND hwnd, BYTE mod_vk, BYTE vk)
+{
+ BYTE mod_scan_code = MapVirtualKey(mod_vk, MAPVK_VK_TO_VSC);
+ BYTE scan_code = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
+ SetFocus(hwnd);
+ keybd_event(mod_vk, mod_scan_code, 0, 0);
+ keybd_event(vk, scan_code, 0, 0);
+ keybd_event(vk, scan_code, KEYEVENTF_KEYUP, 0);
+ keybd_event(mod_vk, mod_scan_code, KEYEVENTF_KEYUP, 0);
+ processPendingMessages();
+}
+
+static void simulate_typing_characters(HWND hwnd, const char* szChars)
+{
+ int ret;
+
+ while (*szChars != '\0') {
+ SendMessageA(hwnd, WM_KEYDOWN, *szChars, 1);
+ ret = SendMessageA(hwnd, WM_CHAR, *szChars, 1);
+ ok(ret == 0, "WM_CHAR('%c') ret=%d\n", *szChars, ret);
+ SendMessageA(hwnd, WM_KEYUP, *szChars, 1);
+ szChars++;
+ }
+}
+
static const char haystack[] = "WINEWine wineWine wine WineWine";
/* ^0 ^10 ^20 ^30 */
@@ -141,14 +175,16 @@
ft.lpstrText = f->needle;
findloc = SendMessage(hwnd, EM_FINDTEXT, f->flags, (LPARAM) &ft);
ok(findloc == f->expected_loc,
- "EM_FINDTEXT(%s,%d) '%s' in range(%d,%d), flags %08x, got start at
%d\n",
- name, id, f->needle, f->start, f->end, f->flags, findloc);
+ "EM_FINDTEXT(%s,%d) '%s' in range(%d,%d), flags %08x, got start at %d,
expected %d\n",
+ name, id, f->needle, f->start, f->end, f->flags, findloc,
f->expected_loc);
}
static void check_EM_FINDTEXTEX(HWND hwnd, const char *name, struct find_s *f,
int id) {
int findloc;
FINDTEXTEX ft;
+ int expected_end_loc;
+
memset(&ft, 0, sizeof(ft));
ft.chrg.cpMin = f->start;
ft.chrg.cpMax = f->end;
@@ -160,10 +196,11 @@
ok(ft.chrgText.cpMin == f->expected_loc,
"EM_FINDTEXTEX(%s,%d) '%s' in range(%d,%d), flags %08x, start at
%d\n",
name, id, f->needle, f->start, f->end, f->flags, ft.chrgText.cpMin);
- ok(ft.chrgText.cpMax == ((f->expected_loc == -1) ? -1
- : f->expected_loc + strlen(f->needle)),
- "EM_FINDTEXTEX(%s,%d) '%s' in range(%d,%d), flags %08x, end at
%d\n",
- name, id, f->needle, f->start, f->end, f->flags, ft.chrgText.cpMax);
+ expected_end_loc = ((f->expected_loc == -1) ? -1
+ : f->expected_loc + strlen(f->needle));
+ ok(ft.chrgText.cpMax == expected_end_loc,
+ "EM_FINDTEXTEX(%s,%d) '%s' in range(%d,%d), flags %08x, end at %d,
expected %d\n",
+ name, id, f->needle, f->start, f->end, f->flags, ft.chrgText.cpMax,
expected_end_loc);
}
static void run_tests_EM_FINDTEXT(HWND hwnd, const char *name, struct find_s *find,
@@ -187,6 +224,7 @@
static void test_EM_FINDTEXT(void)
{
HWND hwndRichEdit = new_richedit(NULL);
+ CHARFORMAT2 cf2;
/* Empty rich edit control */
run_tests_EM_FINDTEXT(hwndRichEdit, "1", find_tests,
@@ -196,6 +234,30 @@
/* Haystack text */
run_tests_EM_FINDTEXT(hwndRichEdit, "2", find_tests2,
+ sizeof(find_tests2)/sizeof(struct find_s));
+
+ /* Setting a format on an arbitrary range should have no effect in search
+ results. This tests correct offset reporting across runs. */
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_DEFAULT,
+ (LPARAM) &cf2);
+ cf2.dwMask = CFM_ITALIC | cf2.dwMask;
+ cf2.dwEffects = CFE_ITALIC ^ cf2.dwEffects;
+ SendMessage(hwndRichEdit, EM_SETSEL, 6, 20);
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ /* Haystack text, again */
+ run_tests_EM_FINDTEXT(hwndRichEdit, "2-bis", find_tests2,
+ sizeof(find_tests2)/sizeof(struct find_s));
+
+ /* Yet another range */
+ cf2.dwMask = CFM_BOLD | cf2.dwMask;
+ cf2.dwEffects = CFE_BOLD ^ cf2.dwEffects;
+ SendMessage(hwndRichEdit, EM_SETSEL, 11, 15);
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ /* Haystack text, again */
+ run_tests_EM_FINDTEXT(hwndRichEdit, "2-bisbis", find_tests2,
sizeof(find_tests2)/sizeof(struct find_s));
DestroyWindow(hwndRichEdit);
@@ -369,11 +431,141 @@
DestroyWindow(hwndRichEdit);
}
+static void test_EM_POSFROMCHAR(void)
+{
+ HWND hwndRichEdit = new_richedit(NULL);
+ int i;
+ LRESULT result;
+ unsigned int height = 0;
+ int xpos = 0;
+ static const char text[] = "aa\n"
+ "this is a long line of text that should be longer than the "
+ "control's width\n"
+ "cc\n"
+ "dd\n"
+ "ee\n"
+ "ff\n"
+ "gg\n"
+ "hh\n";
+
+ /* Fill the control to lines to ensure that most of them are offscreen */
+ for (i = 0; i < 50; i++)
+ {
+ /* Do not modify the string; it is exactly 16 characters long. */
+ SendMessage(hwndRichEdit, EM_SETSEL, 0, 0);
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"0123456789ABCDE\n");
+ }
+
+ /*
+ Richedit 1.0 receives a POINTL* on wParam and character offset on lParam, returns
void.
+ Richedit 2.0 receives character offset on wParam, ignores lParam, returns
MAKELONG(x,y)
+ Richedit 3.0 accepts either of the above API conventions.
+ */
+
+ /* Testing Richedit 2.0 API format */
+
+ /* Testing start of lines. X-offset should be constant on all cases (native is 1).
+ Since all lines are identical and drawn with the same font,
+ they should have the same height... right?
+ */
+ for (i = 0; i < 50; i++)
+ {
+ /* All the lines are 16 characters long */
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, i * 16, 0);
+ if (i == 0)
+ {
+ ok(HIWORD(result) == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n",
HIWORD(result));
+ todo_wine {
+ ok(LOWORD(result) == 1, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+ }
+ xpos = LOWORD(result);
+ }
+ else if (i == 1)
+ {
+ ok(HIWORD(result) > 0, "EM_POSFROMCHAR reports y=%d, expected >
0\n", HIWORD(result));
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+ height = HIWORD(result);
+ }
+ else
+ {
+ ok(HIWORD(result) == i * height, "EM_POSFROMCHAR reports y=%d, expected
%d\n", HIWORD(result), i * height);
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+ }
+ }
+
+ /* Testing position at end of text */
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 50 * 16, 0);
+ ok(HIWORD(result) == 50 * height, "EM_POSFROMCHAR reports y=%d, expected
%d\n", HIWORD(result), 50 * height);
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+
+ /* Testing position way past end of text */
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 55 * 16, 0);
+ ok(HIWORD(result) == 50 * height, "EM_POSFROMCHAR reports y=%d, expected
%d\n", HIWORD(result), 50 * height);
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+
+ /* Testing that vertical scrolling does, in fact, have an effect on EM_POSFROMCHAR */
+ SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEDOWN, 0); /* line down */
+ for (i = 0; i < 50; i++)
+ {
+ /* All the lines are 16 characters long */
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, i * 16, 0);
+ ok((signed short)(HIWORD(result)) == (i - 1) * height,
+ "EM_POSFROMCHAR reports y=%hd, expected %d\n",
+ (signed short)(HIWORD(result)), (i - 1) * height);
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+ }
+
+ /* Testing position at end of text */
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 50 * 16, 0);
+ ok(HIWORD(result) == (50 - 1) * height, "EM_POSFROMCHAR reports y=%d, expected
%d\n", HIWORD(result), (50 - 1) * height);
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+
+ /* Testing position way past end of text */
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 55 * 16, 0);
+ ok(HIWORD(result) == (50 - 1) * height, "EM_POSFROMCHAR reports y=%d, expected
%d\n", HIWORD(result), (50 - 1) * height);
+ ok(LOWORD(result) == xpos, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+
+ /* Testing that horizontal scrolling does, in fact, have an effect on EM_POSFROMCHAR
*/
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text);
+ SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEUP, 0); /* line up */
+
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 0, 0);
+ ok(HIWORD(result) == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n",
HIWORD(result));
+ todo_wine {
+ ok(LOWORD(result) == 1, "EM_POSFROMCHAR reports x=%d, expected 1\n",
LOWORD(result));
+ }
+ xpos = LOWORD(result);
+
+ SendMessage(hwndRichEdit, WM_HSCROLL, SB_LINERIGHT, 0);
+ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 0, 0);
+ ok(HIWORD(result) == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n",
HIWORD(result));
+ todo_wine {
+ /* Fails on builtin because horizontal scrollbar is not being shown */
+ ok((signed short)(LOWORD(result)) < xpos,
+ "EM_POSFROMCHAR reports x=%hd, expected value less than %d\n",
+ (signed short)(LOWORD(result)), xpos);
+ }
+ DestroyWindow(hwndRichEdit);
+}
+
static void test_EM_SETCHARFORMAT(void)
{
HWND hwndRichEdit = new_richedit(NULL);
CHARFORMAT2 cf2;
int rc = 0;
+ int tested_effects[] = {
+ CFE_BOLD,
+ CFE_ITALIC,
+ CFE_UNDERLINE,
+ CFE_STRIKEOUT,
+ CFE_PROTECTED,
+ CFE_LINK,
+ CFE_SUBSCRIPT,
+ CFE_SUPERSCRIPT,
+ 0
+ };
+ int i;
+ CHARRANGE cr;
/* Invalid flags, CHARFORMAT2 structure blanked out */
memset(&cf2, 0, sizeof(cf2));
@@ -411,6 +603,9 @@
rc = SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) 0xfffffff0,
(LPARAM) &cf2);
ok(rc == 1, "EM_SETCHARFORMAT returned %d instead of 1\n", rc);
+ rc = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ ok(rc == FALSE, "Should not be able to undo here.\n");
+ SendMessage(hwndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0);
/* A valid flag, CHARFORMAT2 structure minimally filled */
memset(&cf2, 0, sizeof(cf2));
@@ -418,6 +613,9 @@
rc = SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_DEFAULT,
(LPARAM) &cf2);
ok(rc == 1, "EM_SETCHARFORMAT returned %d instead of 1\n", rc);
+ rc = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ todo_wine ok(rc == FALSE, "Should not be able to undo here.\n");
+ SendMessage(hwndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0);
/* A valid flag, CHARFORMAT2 structure minimally filled */
memset(&cf2, 0, sizeof(cf2));
@@ -425,6 +623,9 @@
rc = SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_SELECTION,
(LPARAM) &cf2);
ok(rc == 1, "EM_SETCHARFORMAT returned %d instead of 1\n", rc);
+ rc = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ ok(rc == FALSE, "Should not be able to undo here.\n");
+ SendMessage(hwndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0);
/* A valid flag, CHARFORMAT2 structure minimally filled */
memset(&cf2, 0, sizeof(cf2));
@@ -432,6 +633,9 @@
rc = SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_WORD,
(LPARAM) &cf2);
ok(rc == 1, "EM_SETCHARFORMAT returned %d instead of 1\n", rc);
+ rc = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ todo_wine ok(rc == TRUE, "Should not be able to undo here.\n");
+ SendMessage(hwndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0);
/* A valid flag, CHARFORMAT2 structure minimally filled */
memset(&cf2, 0, sizeof(cf2));
@@ -439,6 +643,9 @@
rc = SendMessage(hwndRichEdit, EM_SETCHARFORMAT, (WPARAM) SCF_ALL,
(LPARAM) &cf2);
ok(rc == 1, "EM_SETCHARFORMAT returned %d instead of 1\n", rc);
+ rc = SendMessage(hwndRichEdit, EM_CANUNDO, 0, 0);
+ todo_wine ok(rc == TRUE, "Should not be able to undo here.\n");
+ SendMessage(hwndRichEdit, EM_EMPTYUNDOBUFFER, 0, 0);
cf2.cbSize = sizeof(CHARFORMAT2);
SendMessage(hwndRichEdit, EM_GETCHARFORMAT, (WPARAM) SCF_DEFAULT,
@@ -492,6 +699,251 @@
ok(rc == -1, "Text not marked as modified, expected modified! (%d)\n", rc);
DestroyWindow(hwndRichEdit);
+
+ /* EM_GETCHARFORMAT tests */
+ for (i = 0; tested_effects[i]; i++)
+ {
+ hwndRichEdit = new_richedit(NULL);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
+
+ /* Need to set a TrueType font to get consistent CFM_BOLD results */
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = CFM_FACE|CFM_WEIGHT;
+ cf2.dwEffects = 0;
+ strcpy(cf2.szFaceName, "Courier New");
+ cf2.wWeight = FW_DONTCARE;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf2);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 0, 4);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == CFM_SUPERSCRIPT)
+ ||
+ (cf2.dwMask & tested_effects[i]) == tested_effects[i]),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
tested_effects[i]);
+ ok((cf2.dwEffects & tested_effects[i]) == 0,
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x clear\n", i,
cf2.dwEffects, tested_effects[i]);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = tested_effects[i];
+ if (cf2.dwMask == CFE_SUBSCRIPT || cf2.dwMask == CFE_SUPERSCRIPT)
+ cf2.dwMask = CFM_SUPERSCRIPT;
+ cf2.dwEffects = tested_effects[i];
+ SendMessage(hwndRichEdit, EM_SETSEL, 0, 2);
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 0, 2);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == CFM_SUPERSCRIPT)
+ ||
+ (cf2.dwMask & tested_effects[i]) == tested_effects[i]),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
tested_effects[i]);
+ ok((cf2.dwEffects & tested_effects[i]) == tested_effects[i],
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i,
cf2.dwEffects, tested_effects[i]);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 4);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == CFM_SUPERSCRIPT)
+ ||
+ (cf2.dwMask & tested_effects[i]) == tested_effects[i]),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
tested_effects[i]);
+ ok((cf2.dwEffects & tested_effects[i]) == 0,
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x clear\n", i,
cf2.dwEffects, tested_effects[i]);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 1, 3);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == 0)
+ ||
+ (cf2.dwMask & tested_effects[i]) == 0),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x clear\n", i, cf2.dwMask,
tested_effects[i]);
+
+ DestroyWindow(hwndRichEdit);
+ }
+
+ for (i = 0; tested_effects[i]; i++)
+ {
+ hwndRichEdit = new_richedit(NULL);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
+
+ /* Need to set a TrueType font to get consistent CFM_BOLD results */
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = CFM_FACE|CFM_WEIGHT;
+ cf2.dwEffects = 0;
+ strcpy(cf2.szFaceName, "Courier New");
+ cf2.wWeight = FW_DONTCARE;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf2);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = tested_effects[i];
+ if (cf2.dwMask == CFE_SUBSCRIPT || cf2.dwMask == CFE_SUPERSCRIPT)
+ cf2.dwMask = CFM_SUPERSCRIPT;
+ cf2.dwEffects = tested_effects[i];
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 4);
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 0, 2);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == CFM_SUPERSCRIPT)
+ ||
+ (cf2.dwMask & tested_effects[i]) == tested_effects[i]),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
tested_effects[i]);
+ ok((cf2.dwEffects & tested_effects[i]) == 0,
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x clear\n", i,
cf2.dwEffects, tested_effects[i]);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 4);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == CFM_SUPERSCRIPT)
+ ||
+ (cf2.dwMask & tested_effects[i]) == tested_effects[i]),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
tested_effects[i]);
+ ok((cf2.dwEffects & tested_effects[i]) == tested_effects[i],
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i,
cf2.dwEffects, tested_effects[i]);
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 1, 3);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ ok ((((tested_effects[i] == CFE_SUBSCRIPT || tested_effects[i] == CFE_SUPERSCRIPT)
&&
+ (cf2.dwMask & CFM_SUPERSCRIPT) == 0)
+ ||
+ (cf2.dwMask & tested_effects[i]) == 0),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x clear\n", i, cf2.dwMask,
tested_effects[i]);
+ ok((cf2.dwEffects & tested_effects[i]) == tested_effects[i],
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x set\n", i,
cf2.dwEffects, tested_effects[i]);
+
+ DestroyWindow(hwndRichEdit);
+ }
+
+ /* Effects applied on an empty selection should take effect when selection is
+ replaced with text */
+ hwndRichEdit = new_richedit(NULL);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = CFM_BOLD;
+ cf2.dwEffects = CFE_BOLD;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ /* Selection is now nonempty */
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"newi");
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 6);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ ok (((cf2.dwMask & CFM_BOLD) == CFM_BOLD),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
CFM_BOLD);
+ ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD,
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects,
CFE_BOLD);
+
+
+ /* Set two effects on an empty selection */
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = CFM_BOLD;
+ cf2.dwEffects = CFE_BOLD;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+ cf2.dwMask = CFM_ITALIC;
+ cf2.dwEffects = CFE_ITALIC;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ /* Selection is now nonempty */
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"newi");
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 6);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ ok (((cf2.dwMask & (CFM_BOLD|CFM_ITALIC)) == (CFM_BOLD|CFM_ITALIC)),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
(CFM_BOLD|CFM_ITALIC));
+ ok((cf2.dwEffects & (CFE_BOLD|CFE_ITALIC)) == (CFE_BOLD|CFE_ITALIC),
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects,
(CFE_BOLD|CFE_ITALIC));
+
+ /* Setting the (empty) selection to exactly the same place as before should
+ NOT clear the insertion style! */
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 2); /* Empty selection */
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = CFM_BOLD;
+ cf2.dwEffects = CFE_BOLD;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ /* Empty selection in same place, insert style should NOT be forgotten here. */
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 2);
+
+ /* Selection is now nonempty */
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"newi");
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ SendMessage(hwndRichEdit, EM_SETSEL, 2, 6);
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ ok (((cf2.dwMask & CFM_BOLD) == CFM_BOLD),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
CFM_BOLD);
+ ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD,
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects,
CFE_BOLD);
+
+ /* Ditto with EM_EXSETSEL */
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine");
+ cr.cpMin = 2; cr.cpMax = 2;
+ SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr); /* Empty selection */
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cf2.dwMask = CFM_BOLD;
+ cf2.dwEffects = CFE_BOLD;
+ SendMessage(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ /* Empty selection in same place, insert style should NOT be forgotten here. */
+ cr.cpMin = 2; cr.cpMax = 2;
+ SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr); /* Empty selection */
+
+ /* Selection is now nonempty */
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"newi");
+
+ memset(&cf2, 0, sizeof(CHARFORMAT2));
+ cf2.cbSize = sizeof(CHARFORMAT2);
+ cr.cpMin = 2; cr.cpMax = 6;
+ SendMessage(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr); /* Empty selection */
+ SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf2);
+
+ ok (((cf2.dwMask & CFM_BOLD) == CFM_BOLD),
+ "%d, cf2.dwMask == 0x%08x expected mask 0x%08x\n", i, cf2.dwMask,
CFM_BOLD);
+ ok((cf2.dwEffects & CFE_BOLD) == CFE_BOLD,
+ "%d, cf2.dwEffects == 0x%08x expected effect 0x%08x\n", i, cf2.dwEffects,
CFE_BOLD);
+
+ DestroyWindow(hwndRichEdit);
}
static void test_EM_SETTEXTMODE(void)
@@ -901,14 +1353,20 @@
DestroyWindow(hwndRichEdit);
}
+static int check_CFE_LINK_selection(HWND hwnd, int sel_start, int sel_end)
+{
+ CHARFORMAT2W text_format;
+ text_format.cbSize = sizeof(text_format);
+ SendMessage(hwnd, EM_SETSEL, sel_start, sel_end);
+ SendMessage(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &text_format);
+ return (text_format.dwEffects & CFE_LINK) ? 1 : 0;
+}
+
static void check_CFE_LINK_rcvd(HWND hwnd, int is_url, const char * url)
{
- CHARFORMAT2W text_format;
int link_present = 0;
- text_format.cbSize = sizeof(text_format);
- SendMessage(hwnd, EM_SETSEL, 0, 1);
- SendMessage(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &text_format);
- link_present = text_format.dwEffects & CFE_LINK;
+
+ link_present = check_CFE_LINK_selection(hwnd, 0, 1);
if (is_url)
{ /* control text is url; should get CFE_LINK */
ok(0 != link_present, "URL Case: CFE_LINK not set for [%s].\n", url);
@@ -943,9 +1401,69 @@
{"wais:waisserver", 1}
};
- int i;
+ int i, j;
int urlRet=-1;
HWND hwndRichEdit, parent;
+
+ /* All of the following should cause the URL to be detected */
+ const char * templates_delim[] = {
+ "This is some text with X on it",
+ "This is some text with (X) on it",
+ "This is some text with X\r on it",
+ "This is some text with ---X--- on it",
+ "This is some text with \"X\" on it",
+ "This is some text with 'X' on it",
+ "This is some text with 'X' on it",
+ "This is some text with :X: on it",
+
+ "This text ends with X",
+
+ "This is some text with X) on it",
+ "This is some text with X--- on it",
+ "This is some text with X\" on it",
+ "This is some text with X' on it",
+ "This is some text with X: on it",
+
+ "This is some text with (X on it",
+ "This is some text with \rX on it",
+ "This is some text with ---X on it",
+ "This is some text with \"X on it",
+ "This is some text with 'X on it",
+ "This is some text with :X on it",
+ };
+ /* None of these should cause the URL to be detected */
+ const char * templates_non_delim[] = {
+ "This is some text with |X| on it",
+ "This is some text with *X* on it",
+ "This is some text with /X/ on it",
+ "This is some text with +X+ on it",
+ "This is some text with %X% on it",
+ "This is some text with #X# on it",
+ "This is some text with @X@ on it",
+ "This is some text with \\X\\ on it",
+ "This is some text with |X on it",
+ "This is some text with *X on it",
+ "This is some text with /X on it",
+ "This is some text with +X on it",
+ "This is some text with %X on it",
+ "This is some text with #X on it",
+ "This is some text with @X on it",
+ "This is some text with \\X on it",
+ };
+ /* All of these cause the URL detection to be extended by one more byte,
+ thus demonstrating that the tested character is considered as part
+ of the URL. */
+ const char * templates_xten_delim[] = {
+ "This is some text with X| on it",
+ "This is some text with X* on it",
+ "This is some text with X/ on it",
+ "This is some text with X+ on it",
+ "This is some text with X% on it",
+ "This is some text with X# on it",
+ "This is some text with X@ on it",
+ "This is some text with X\\ on it",
+ };
+ char buffer[1024];
parent = new_static_wnd(NULL);
hwndRichEdit = new_richedit(parent);
@@ -961,16 +1479,612 @@
ok(urlRet==E_INVALIDARG, "Bad wParam2: urlRet is: %d\n", urlRet);
/* for each url, check the text to see if CFE_LINK effect is present */
for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+
SendMessage(hwndRichEdit, EM_AUTOURLDETECT, FALSE, 0);
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) urls[i].text);
- SendMessage(hwndRichEdit, WM_CHAR, 0, 0);
check_CFE_LINK_rcvd(hwndRichEdit, 0, urls[i].text);
+
+ /* Link detection should happen immediately upon WM_SETTEXT */
SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) urls[i].text);
- SendMessage(hwndRichEdit, WM_CHAR, 0, 0);
check_CFE_LINK_rcvd(hwndRichEdit, urls[i].is_url, urls[i].text);
}
DestroyWindow(hwndRichEdit);
+
+ /* Test detection of URLs within normal text - WM_SETTEXT case. */
+ for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+ hwndRichEdit = new_richedit(parent);
+
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ strncpy(buffer, templates_delim[j], at_offset);
+ buffer[at_offset] = '\0';
+ strcat(buffer, urls[i].text);
+ strcat(buffer, templates_delim[j] + at_offset + 1);
+ end_offset = at_offset + strlen(urls[i].text);
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ for (j = 0; j < sizeof(templates_non_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_non_delim[j], 'X');
+ at_offset = at_pos - templates_non_delim[j];
+ strncpy(buffer, templates_non_delim[j], at_offset);
+ buffer[at_offset] = '\0';
+ strcat(buffer, urls[i].text);
+ strcat(buffer, templates_non_delim[j] + at_offset + 1);
+ end_offset = at_offset + strlen(urls[i].text);
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset, at_offset
+ 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ for (j = 0; j < sizeof(templates_xten_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_xten_delim[j], 'X');
+ at_offset = at_pos - templates_xten_delim[j];
+ strncpy(buffer, templates_xten_delim[j], at_offset);
+ buffer[at_offset] = '\0';
+ strcat(buffer, urls[i].text);
+ strcat(buffer, templates_xten_delim[j] + at_offset + 1);
+ end_offset = at_offset + strlen(urls[i].text);
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset, end_offset +1,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset +1, buffer);
+ }
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset + 2, buffer);
+ if (buffer[end_offset +2] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +2, end_offset +3),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +2,
end_offset +3, buffer);
+ }
+ }
+ }
+
+ DestroyWindow(hwndRichEdit);
+ hwndRichEdit = NULL;
+ }
+
+ /* Test detection of URLs within normal text - WM_CHAR case. */
+ for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+ hwndRichEdit = new_richedit(parent);
+
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+ int u, v;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ end_offset = at_offset + strlen(urls[i].text);
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0);
+ for (u = 0; templates_delim[j][u]; u++) {
+ if (templates_delim[j][u] == '\r') {
+ simulate_typing_characters(hwndRichEdit, "\r");
+ } else if (templates_delim[j][u] != 'X') {
+ SendMessage(hwndRichEdit, WM_CHAR, templates_delim[j][u], 1);
+ } else {
+ for (v = 0; urls[i].text[v]; v++) {
+ SendMessage(hwndRichEdit, WM_CHAR, urls[i].text[v], 1);
+ }
+ }
+ }
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ trace("Using template: %s\n", templates_delim[j]);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+
+ /* The following will insert a paragraph break after the first character
+ of the URL candidate, thus breaking the URL. It is expected that the
+ CFE_LINK attribute should break across both pieces of the URL */
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset+1, at_offset+1);
+ simulate_typing_characters(hwndRichEdit, "\r");
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset, at_offset
+ 1, buffer);
+ /* end_offset moved because of paragraph break */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset+1, buffer);
+ ok(buffer[end_offset], "buffer \"%s\" ended prematurely. Is it
missing a newline character?\n", buffer);
+ if (buffer[end_offset] != 0 && buffer[end_offset+1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset+1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset+1,
end_offset +2, buffer);
+ if (buffer[end_offset +2] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +2, end_offset +3),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +2,
end_offset +3, buffer);
+ }
+ }
+
+ /* The following will remove the just-inserted paragraph break, thus
+ restoring the URL */
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset+2, at_offset+2);
+ simulate_typing_characters(hwndRichEdit, "\b");
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+ DestroyWindow(hwndRichEdit);
+ hwndRichEdit = NULL;
+ }
+
+ /* Test detection of URLs within normal text - EM_SETTEXTEX case. */
+ for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+ SETTEXTEX st;
+
+ hwndRichEdit = new_richedit(parent);
+
+ /* There are at least three ways in which EM_SETTEXTEX must cause URLs to
+ be detected:
+ 1) Set entire text, a la WM_SETTEXT
+ 2) Set a selection of the text to the URL
+ 3) Set a portion of the text at a time, which eventually results in
+ an URL
+ All of them should give equivalent results
+ */
+
+ /* Set entire text in one go, like WM_SETTEXT */
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ st.codepage = CP_ACP;
+ st.flags = ST_DEFAULT;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ strncpy(buffer, templates_delim[j], at_offset);
+ buffer[at_offset] = '\0';
+ strcat(buffer, urls[i].text);
+ strcat(buffer, templates_delim[j] + at_offset + 1);
+ end_offset = at_offset + strlen(urls[i].text);
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM) buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ /* Set selection with X to the URL */
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ end_offset = at_offset + strlen(urls[i].text);
+
+ st.codepage = CP_ACP;
+ st.flags = ST_DEFAULT;
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)
templates_delim[j]);
+ st.flags = ST_SELECTION;
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset, at_offset+1);
+ SendMessage(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM) urls[i].text);
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ /* Set selection with X to the first character of the URL, then the rest */
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ end_offset = at_offset + strlen(urls[i].text);
+
+ strcpy(buffer, "YY");
+ buffer[0] = urls[i].text[0];
+
+ st.codepage = CP_ACP;
+ st.flags = ST_DEFAULT;
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)
templates_delim[j]);
+ st.flags = ST_SELECTION;
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset, at_offset+1);
+ SendMessage(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM) buffer);
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset+1, at_offset+2);
+ SendMessage(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)(urls[i].text +
1));
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ DestroyWindow(hwndRichEdit);
+ hwndRichEdit = NULL;
+ }
+
+ /* Test detection of URLs within normal text - EM_REPLACESEL case. */
+ for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+ hwndRichEdit = new_richedit(parent);
+
+ /* Set selection with X to the URL */
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ end_offset = at_offset + strlen(urls[i].text);
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) templates_delim[j]);
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset, at_offset+1);
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM) urls[i].text);
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ /* Set selection with X to the first character of the URL, then the rest */
+ for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+ char * at_pos;
+ int at_offset;
+ int end_offset;
+
+ at_pos = strchr(templates_delim[j], 'X');
+ at_offset = at_pos - templates_delim[j];
+ end_offset = at_offset + strlen(urls[i].text);
+
+ strcpy(buffer, "YY");
+ buffer[0] = urls[i].text[0];
+
+ SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) templates_delim[j]);
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset, at_offset+1);
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM) buffer);
+ SendMessage(hwndRichEdit, EM_SETSEL, at_offset+1, at_offset+2);
+ SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)(urls[i].text + 1));
+ SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+
+ /* This assumes no templates start with the URL itself, and that they
+ have at least two characters before the URL text */
+ ok(!check_CFE_LINK_selection(hwndRichEdit, 0, 1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", 0, 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -2, at_offset -1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -2,
at_offset -1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset -1, at_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset -1,
at_offset, buffer);
+
+ if (urls[i].is_url)
+ {
+ ok(check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK not set in (%d-%d), text: %s\n", at_offset, at_offset +1,
buffer);
+ ok(check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK not set in (%d-%d), text: %s\n", end_offset -1, end_offset,
buffer);
+ }
+ else
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, at_offset, at_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", at_offset,
at_offset + 1, buffer);
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset -1, end_offset),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset -1,
end_offset, buffer);
+ }
+ if (buffer[end_offset] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset, end_offset +1),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset,
end_offset + 1, buffer);
+ if (buffer[end_offset +1] != '\0')
+ {
+ ok(!check_CFE_LINK_selection(hwndRichEdit, end_offset +1, end_offset +2),
+ "CFE_LINK incorrectly set in (%d-%d), text: %s\n", end_offset +1,
end_offset +2, buffer);
+ }
+ }
+ }
+
+ DestroyWindow(hwndRichEdit);
+ hwndRichEdit = NULL;
+ }
+
DestroyWindow(parent);
}
@@ -2353,23 +3467,18 @@
r = SendMessage(hwndRichEdit, EM_GETLINECOUNT, 0, 0);
ok(r == 7, "EM_GETLINECOUNT returned %d, expected 7\n", r);
+ if (!redraw)
+ /* This is needed to avoid interferring with keybd_event calls
+ * on other tests that simulate keyboard events. */
+ SendMessage(hwndRichEdit, WM_SETREDRAW, TRUE, 0);
+
DestroyWindow(hwndRichEdit);
}
static void test_WM_PASTE(void)
{
- MSG msg;
int result;
char buffer[1024] = {0};
- char key_info[][3] =
- {
- /* VirtualKey, ScanCode, WM_CHAR code */
- {'C', 0x2e, 3}, /* Ctrl-C */
- {'X', 0x2d, 24}, /* Ctrl-X */
- {'V', 0x2f, 22}, /* Ctrl-V */
- {'Z', 0x2c, 26}, /* Ctrl-Z */
- {'Y', 0x15, 25}, /* Ctrl-Y */
- };
const char* text1 = "testing paste\r";
const char* text1_step1 = "testing paste\r\ntesting paste\r\n";
const char* text1_after = "testing paste\r\n";
@@ -2382,34 +3491,25 @@
messages, probably because it inspects the keyboard state itself.
Therefore, native requires this in order to obey Ctrl-<key> keystrokes.
*/
-#define SEND_CTRL_KEY(hwnd, k) \
- keybd_event(VK_CONTROL, 0x1d, 0, 0);\
- keybd_event(k[0], k[1], 0, 0);\
- keybd_event(k[0], k[1], KEYEVENTF_KEYUP, 0);\
- keybd_event(VK_CONTROL, 0x1d, KEYEVENTF_KEYUP, 0); \
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { \
- TranslateMessage(&msg); \
- DispatchMessage(&msg); \
- }
-
-#define SEND_CTRL_C(hwnd) SEND_CTRL_KEY(hwnd, key_info[0])
-#define SEND_CTRL_X(hwnd) SEND_CTRL_KEY(hwnd, key_info[1])
-#define SEND_CTRL_V(hwnd) SEND_CTRL_KEY(hwnd, key_info[2])
-#define SEND_CTRL_Z(hwnd) SEND_CTRL_KEY(hwnd, key_info[3])
-#define SEND_CTRL_Y(hwnd) SEND_CTRL_KEY(hwnd, key_info[4])
+
+#define SEND_CTRL_C(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, 'C')
+#define SEND_CTRL_X(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, 'X')
+#define SEND_CTRL_V(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, 'V')
+#define SEND_CTRL_Z(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, 'Z')
+#define SEND_CTRL_Y(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, 'Y')
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text1);
SendMessage(hwndRichEdit, EM_SETSEL, 0, 14);
- SEND_CTRL_C(hwndRichEdit) /* Copy */
+ SEND_CTRL_C(hwndRichEdit); /* Copy */
SendMessage(hwndRichEdit, EM_SETSEL, 14, 14);
- SEND_CTRL_V(hwndRichEdit) /* Paste */
+ SEND_CTRL_V(hwndRichEdit); /* Paste */
SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
/* Pasted text should be visible at this step */
result = strcmp(text1_step1, buffer);
ok(result == 0,
"test paste: strcmp = %i\n", result);
- SEND_CTRL_Z(hwndRichEdit) /* Undo */
+ SEND_CTRL_Z(hwndRichEdit); /* Undo */
SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
/* Text should be the same as before (except for \r -> \r\n conversion) */
result = strcmp(text1_after, buffer);
@@ -2418,21 +3518,21 @@
SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text2);
SendMessage(hwndRichEdit, EM_SETSEL, 8, 13);
- SEND_CTRL_C(hwndRichEdit) /* Copy */
+ SEND_CTRL_C(hwndRichEdit); /* Copy */
SendMessage(hwndRichEdit, EM_SETSEL, 14, 14);
- SEND_CTRL_V(hwndRichEdit) /* Paste */
+ SEND_CTRL_V(hwndRichEdit); /* Paste */
SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
/* Pasted text should be visible at this step */
result = strcmp(text3, buffer);
ok(result == 0,
"test paste: strcmp = %i\n", result);
- SEND_CTRL_Z(hwndRichEdit) /* Undo */
+ SEND_CTRL_Z(hwndRichEdit); /* Undo */
SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
/* Text should be the same as before (except for \r -> \r\n conversion) */
result = strcmp(text2_after, buffer);
ok(result == 0,
"test paste: strcmp = %i\n", result);
- SEND_CTRL_Y(hwndRichEdit) /* Redo */
+ SEND_CTRL_Y(hwndRichEdit); /* Redo */
SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
/* Text should revert to post-paste state */
result = strcmp(buffer,text3);
@@ -2531,6 +3631,30 @@
return 0;
}
+struct StringWithLength {
+ int length;
+ char *buffer;
+};
+
+/* This callback is used to handled the null characters in a string. */
+static DWORD CALLBACK test_EM_STREAMIN_esCallback2(DWORD_PTR dwCookie,
+ LPBYTE pbBuff,
+ LONG cb,
+ LONG *pcb)
+{
+ struct StringWithLength* str = (struct StringWithLength*)dwCookie;
+ int size = str->length;
+ *pcb = cb;
+ if (*pcb > size) {
+ *pcb = size;
+ }
+ if (*pcb > 0) {
+ memcpy(pbBuff, str->buffer, *pcb);
+ str->buffer += *pcb;
+ str->length -= *pcb;
+ }
+ return 0;
+}
static void test_EM_STREAMIN(void)
{
@@ -2560,6 +3684,15 @@
const char * streamText3 = "RichEdit1";
+ struct StringWithLength cookieForStream4;
+ const char * streamText4 =
+ "This text just needs to be long enough to cause run to be split onto "\
+ "two seperate lines and make sure the null terminating character is "\
+ "handled properly.\0";
+ int length4 = strlen(streamText4) + 1;
+ cookieForStream4.buffer = (char *)streamText4;
+ cookieForStream4.length = length4;
+
/* Minimal test without \par at the end */
es.dwCookie = (DWORD_PTR)&streamText0;
es.dwError = 0;
@@ -2642,6 +3775,17 @@
ok (strlen(buffer) == 0,
"EM_STREAMIN: Test 3 set wrong text: Result: %s\n",buffer);
ok(es.dwError == -16, "EM_STREAMIN: Test 3 set error %d, expected %d\n",
es.dwError, -16);
+
+ es.dwCookie = (DWORD_PTR)&cookieForStream4;
+ es.dwError = 0;
+ es.pfnCallback = test_EM_STREAMIN_esCallback2;
+ SendMessage(hwndRichEdit, EM_STREAMIN,
+ (WPARAM)(SF_TEXT), (LPARAM)&es);
+
+ result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
+ ok (result == length4,
+ "EM_STREAMIN: Test 4 returned %ld, expected %d\n", result, length4);
+ ok(es.dwError == 0, "EM_STREAMIN: Test 4 set error %d, expected %d\n",
es.dwError, 0);
DestroyWindow(hwndRichEdit);
}
@@ -2718,6 +3862,7 @@
"EM_STREAMIN with SFF_SELECTION and selection set "
"should create an undo\n");
+ DestroyWindow(hwndRichEdit);
}
static BOOL is_em_settextex_supported(HWND hwnd)
@@ -3208,6 +4353,203 @@
DestroyWindow(parent);
}
+static void test_undo_coalescing(void)
+{
+ HWND hwnd;
+ int result;
+ char buffer[64] = {0};
+
+ /* multi-line control inserts CR normally */
+ hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP|ES_MULTILINE,
+ 0, 0, 200, 60, 0, 0, 0, 0);
+ ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
+
+ result = SendMessage(hwnd, EM_CANUNDO, 0, 0);
+ ok (result == FALSE, "Can undo after window creation.\n");
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == FALSE, "Undo operation successful with nothing to undo.\n");
+ result = SendMessage(hwnd, EM_CANREDO, 0, 0);
+ ok (result == FALSE, "Can redo after window creation.\n");
+ result = SendMessage(hwnd, EM_REDO, 0, 0);
+ ok (result == FALSE, "Redo operation successful with nothing undone.\n");
+
+ /* Test the effect of arrows keys during typing on undo transactions*/
+ simulate_typing_characters(hwnd, "one two three");
+ SendMessage(hwnd, WM_KEYDOWN, VK_RIGHT, 1);
+ SendMessage(hwnd, WM_KEYUP, VK_RIGHT, 1);
+ simulate_typing_characters(hwnd, " four five six");
+
+ result = SendMessage(hwnd, EM_CANREDO, 0, 0);
+ ok (result == FALSE, "Can redo before anything is undone.\n");
+ result = SendMessage(hwnd, EM_CANUNDO, 0, 0);
+ ok (result == TRUE, "Cannot undo typed characters.\n");
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "EM_UNDO Failed to undo typed characters.\n");
+ result = SendMessage(hwnd, EM_CANREDO, 0, 0);
+ ok (result == TRUE, "Cannot redo after undo.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "one two three");
+ ok (result == 0, "expected '%s' but got '%s'\n", "one
two three", buffer);
+
+ result = SendMessage(hwnd, EM_CANUNDO, 0, 0);
+ ok (result == TRUE, "Cannot undo typed characters.\n");
+ result = SendMessage(hwnd, WM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "");
+ ok (result == 0, "expected '%s' but got '%s'\n",
"", buffer);
+
+ /* Test the effect of focus changes during typing on undo transactions*/
+ simulate_typing_characters(hwnd, "one two three");
+ result = SendMessage(hwnd, EM_CANREDO, 0, 0);
+ ok (result == FALSE, "Redo buffer should have been cleared by typing.\n");
+ SendMessage(hwnd, WM_KILLFOCUS, (WPARAM)NULL, 0);
+ SendMessage(hwnd, WM_SETFOCUS, (WPARAM)NULL, 0);
+ simulate_typing_characters(hwnd, " four five six");
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "one two three");
+ ok (result == 0, "expected '%s' but got '%s'\n", "one
two three", buffer);
+
+ /* Test the effect of the back key during typing on undo transactions */
+ SendMessage(hwnd, EM_EMPTYUNDOBUFFER, 0, 0);
+ result = SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"");
+ ok (result == TRUE, "Failed to clear the text.\n");
+ simulate_typing_characters(hwnd, "one two threa");
+ result = SendMessage(hwnd, EM_CANREDO, 0, 0);
+ ok (result == FALSE, "Redo buffer should have been cleared by typing.\n");
+ SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 1);
+ SendMessage(hwnd, WM_KEYUP, VK_BACK, 1);
+ simulate_typing_characters(hwnd, "e four five six");
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "");
+ ok (result == 0, "expected '%s' but got '%s'\n",
"", buffer);
+
+ /* Test the effect of the delete key during typing on undo transactions */
+ SendMessage(hwnd, EM_EMPTYUNDOBUFFER, 0, 0);
+ result = SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"abcd");
+ ok(result == TRUE, "Failed to set the text.\n");
+ SendMessage(hwnd, EM_SETSEL, (WPARAM)1, (LPARAM)1);
+ SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);
+ SendMessage(hwnd, WM_KEYUP, VK_DELETE, 1);
+ SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);
+ SendMessage(hwnd, WM_KEYUP, VK_DELETE, 1);
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "acd");
+ ok (result == 0, "expected '%s' but got '%s'\n",
"acd", buffer);
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "abcd");
+ ok (result == 0, "expected '%s' but got '%s'\n",
"abcd", buffer);
+
+ /* Test the effect of EM_STOPGROUPTYPING on undo transactions*/
+ SendMessage(hwnd, EM_EMPTYUNDOBUFFER, 0, 0);
+ result = SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"");
+ ok (result == TRUE, "Failed to clear the text.\n");
+ simulate_typing_characters(hwnd, "one two three");
+ result = SendMessage(hwnd, EM_STOPGROUPTYPING, 0, 0);
+ ok (result == 0, "expected %d but got %d\n", 0, result);
+ simulate_typing_characters(hwnd, " four five six");
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "one two three");
+ ok (result == 0, "expected '%s' but got '%s'\n", "one
two three", buffer);
+ result = SendMessage(hwnd, EM_UNDO, 0, 0);
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ ok (result == TRUE, "Failed to undo typed characters.\n");
+ SendMessageA(hwnd, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
+ result = strcmp(buffer, "");
+ ok (result == 0, "expected '%s' but got '%s'\n",
"", buffer);
+
+ DestroyWindow(hwnd);
+}
+
+#define SEND_CTRL_LEFT(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, VK_LEFT)
+#define SEND_CTRL_RIGHT(hwnd) pressKeyWithModifier(hwnd, VK_CONTROL, VK_RIGHT)
+
+static void test_word_movement(void)
+{
+ HWND hwnd;
+ int result;
+ int sel_start, sel_end;
+
+ /* multi-line control inserts CR normally */
+ hwnd = new_richedit(NULL);
+
+ result = SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"one two three");
+ ok (result == TRUE, "Failed to clear the text.\n");
+ SendMessage(hwnd, EM_SETSEL, 0, 0);
+ /* |one two three */
+
+ SEND_CTRL_RIGHT(hwnd);
+ /* one |two three */
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+ ok(sel_start == sel_end, "Selection should be empty\n");
+ ok(sel_start == 4, "Cursur is at %d instead of %d\n", sel_start, 4);
+
+ SEND_CTRL_RIGHT(hwnd);
+ /* one two |three */
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+ ok(sel_start == sel_end, "Selection should be empty\n");
+ ok(sel_start == 9, "Cursur is at %d instead of %d\n", sel_start, 9);
+
+ SEND_CTRL_LEFT(hwnd);
+ /* one |two three */
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+ ok(sel_start == sel_end, "Selection should be empty\n");
+ ok(sel_start == 4, "Cursur is at %d instead of %d\n", sel_start, 4);
+
+ SEND_CTRL_LEFT(hwnd);
+ /* |one two three */
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+ ok(sel_start == sel_end, "Selection should be empty\n");
+ ok(sel_start == 0, "Cursur is at %d instead of %d\n", sel_start, 0);
+
+ SendMessage(hwnd, EM_SETSEL, 8, 8);
+ /* one two | three */
+ SEND_CTRL_RIGHT(hwnd);
+ /* one two |three */
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+ ok(sel_start == sel_end, "Selection should be empty\n");
+ ok(sel_start == 9, "Cursur is at %d instead of %d\n", sel_start, 9);
+
+ SendMessage(hwnd, EM_SETSEL, 11, 11);
+ /* one two th|ree */
+ SEND_CTRL_LEFT(hwnd);
+ /* one two |three */
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+ ok(sel_start == sel_end, "Selection should be empty\n");
+ ok(sel_start == 9, "Cursur is at %d instead of %d\n", sel_start, 9);
+
+ DestroyWindow(hwnd);
+}
+
+static void test_EM_CHARFROMPOS(void)
+{
+ HWND hwnd;
+ int result;
+ POINTL point;
+ point.x = 0;
+ point.y = 50;
+
+ /* multi-line control inserts CR normally */
+ hwnd = new_richedit(NULL);
+ result = SendMessageA(hwnd, WM_SETTEXT, 0,
+ (LPARAM)"one two three four five six seven");
+
+ result = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&point);
+ ok(result == 0, "expected character index of 0 but got %d\n", result);
+
+ DestroyWindow(hwnd);
+}
+
START_TEST( editor )
{
MSG msg;
@@ -3220,6 +4562,7 @@
test_WM_CHAR();
test_EM_FINDTEXT();
test_EM_GETLINE();
+ test_EM_POSFROMCHAR();
test_EM_SCROLLCARET();
test_EM_SCROLL();
test_WM_SETTEXT();
@@ -3231,7 +4574,6 @@
test_WM_GETTEXT();
test_EM_GETTEXTRANGE();
test_EM_GETSELTEXT();
- test_EM_AUTOURLDETECT();
test_EM_SETUNDOLIMIT();
test_ES_PASSWORD();
test_EM_SETTEXTEX();
@@ -3251,7 +4593,11 @@
test_EM_REPLACESEL(1);
test_EM_REPLACESEL(0);
test_WM_NOTIFY();
+ test_EM_AUTOURLDETECT();
test_eventMask();
+ test_undo_coalescing();
+ test_word_movement();
+ test_EM_CHARFROMPOS();
/* Set the environment variable WINETEST_RICHED20 to keep windows
* responsive and open for 30 seconds. This is useful for debugging.
Modified: trunk/rostests/winetests/riched20/riched20.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/riched…
==============================================================================
--- trunk/rostests/winetests/riched20/riched20.rbuild [iso-8859-1] (original)
+++ trunk/rostests/winetests/riched20/riched20.rbuild [iso-8859-1] Tue Jul 8 05:09:42
2008
@@ -6,8 +6,10 @@
<define name="WINVER">0x600</define>
<define name="_WIN32_WINNT">0x600</define>
<file>editor.c</file>
+ <file>richole.c</file>
<file>testlist.c</file>
<library>wine</library>
+ <library>uuid</library>
<library>ole32</library>
<library>user32</library>
<library>gdi32</library>
Added: trunk/rostests/winetests/riched20/richole.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/richol…
==============================================================================
--- trunk/rostests/winetests/riched20/richole.c (added)
+++ trunk/rostests/winetests/riched20/richole.c [iso-8859-1] Tue Jul 8 05:09:42 2008
@@ -1,0 +1,120 @@
+/*
+ * Tests for IRichEditOle and friends.
+ *
+ * Copyright 2008 Google (Dan Hipschman)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include <stdarg.h>
+#include <assert.h>
+#include <windef.h>
+#include <winbase.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include <ole2.h>
+#include <richedit.h>
+#include <richole.h>
+#include <tom.h>
+#include <wine/test.h>
+
+#include <initguid.h>
+DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00,
0x47, 0xbe, 0x5d);
+DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00,
0x47, 0xbe, 0x5d);
+DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00,
0x47, 0xbe, 0x5d);
+
+static HMODULE hmoduleRichEdit;
+
+static HWND new_window(LPCTSTR lpClassName, DWORD dwStyle, HWND parent)
+{
+ HWND hwnd
+ = CreateWindow(lpClassName, NULL,
+ dwStyle | WS_POPUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
+ 0, 0, 200, 60, parent, NULL, hmoduleRichEdit, NULL);
+ ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int)
GetLastError());
+ return hwnd;
+}
+
+static HWND new_richedit(HWND parent)
+{
+ return new_window(RICHEDIT_CLASS, ES_MULTILINE, parent);
+}
+
+
+START_TEST(richole)
+{
+ IRichEditOle *reOle = NULL;
+ ITextDocument *txtDoc = NULL;
+ ITextSelection *txtSel = NULL;
+ IUnknown *punk;
+ HRESULT hres;
+ LRESULT res;
+ HWND w;
+
+ /* Must explicitly LoadLibrary(). The test has no references to functions in
+ * RICHED20.DLL, so the linker doesn't actually link to it. */
+ hmoduleRichEdit = LoadLibrary("RICHED20.DLL");
+ ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
+
+ w = new_richedit(NULL);
+ if (!w) {
+ skip("Couldn't create window\n");
+ return;
+ }
+
+ res = SendMessage(w, EM_GETOLEINTERFACE, 0, (LPARAM) &reOle);
+ ok(res, "SendMessage\n");
+ ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
+
+ hres = IUnknown_QueryInterface(reOle, &IID_ITextDocument,
+ (void **) &txtDoc);
+ ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
+ ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
+
+ hres = ITextDocument_GetSelection(txtDoc, &txtSel);
+ ok(hres == S_OK, "ITextDocument_GetSelection\n");
+ ok(txtSel != NULL, "ITextDocument_GetSelection\n");
+
+ punk = NULL;
+ hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **)
&punk);
+ ok(hres == S_OK, "ITextSelection_QueryInterface\n");
+ ok(punk != NULL, "ITextSelection_QueryInterface\n");
+ IUnknown_Release(punk);
+
+ punk = NULL;
+ hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **)
&punk);
+ ok(hres == S_OK, "ITextSelection_QueryInterface\n");
+ ok(punk != NULL, "ITextSelection_QueryInterface\n");
+ IUnknown_Release(punk);
+
+ punk = NULL;
+ hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
+ ok(hres == S_OK, "ITextSelection_QueryInterface\n");
+ ok(punk != NULL, "ITextSelection_QueryInterface\n");
+ IUnknown_Release(punk);
+
+ ITextDocument_Release(txtDoc);
+ IUnknown_Release(reOle);
+ DestroyWindow(w);
+
+ /* Methods should return CO_E_RELEASED if the backing document has
+ been released. One test should suffice. */
+ hres = ITextSelection_CanEdit(txtSel, NULL);
+ ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
+
+ ITextSelection_Release(txtSel);
+}
Propchange: trunk/rostests/winetests/riched20/richole.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/winetests/riched20/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/testli…
==============================================================================
--- trunk/rostests/winetests/riched20/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/riched20/testlist.c [iso-8859-1] Tue Jul 8 05:09:42 2008
@@ -7,9 +7,11 @@
#include "wine/test.h"
extern void func_editor(void);
+extern void func_richole(void);
const struct test winetest_testlist[] =
{
{ "editor", func_editor },
+ { "richole", func_richole },
{ 0, 0 }
};