2 * Unit test suite for rich edit control 1.0
4 * Copyright 2006 Google (Thomas Kho)
5 * Copyright 2007 Matt Finnicum
6 * Copyright 2007 Dmitry Timoshkov
7 * Copyright 2007 Alex VillacĂs Lasso
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include <wine/test.h>
36 static HMODULE hmoduleRichEdit
;
38 static HWND
new_window(LPCTSTR lpClassName
, DWORD dwStyle
, HWND parent
) {
40 hwnd
= CreateWindow(lpClassName
, NULL
, dwStyle
|WS_POPUP
|WS_HSCROLL
|WS_VSCROLL
41 |WS_VISIBLE
, 0, 0, 200, 60, parent
, NULL
,
42 hmoduleRichEdit
, NULL
);
43 ok(hwnd
!= NULL
, "class: %s, error: %d\n", lpClassName
, (int) GetLastError());
47 static HWND
new_richedit(HWND parent
) {
48 return new_window(RICHEDIT_CLASS10A
, ES_MULTILINE
, parent
);
51 static void test_WM_SETTEXT(void)
53 HWND hwndRichEdit
= new_richedit(NULL
);
54 const char * TestItem1
= "TestSomeText";
55 const char * TestItem2
= "TestSomeText\r";
56 const char * TestItem3
= "TestSomeText\rSomeMoreText\r";
57 const char * TestItem4
= "TestSomeText\n\nTestSomeText";
58 const char * TestItem5
= "TestSomeText\r\r\nTestSomeText";
59 const char * TestItem6
= "TestSomeText\r\r\n\rTestSomeText";
60 const char * TestItem7
= "TestSomeText\r\n\r\r\n\rTestSomeText";
61 const char * TestItem8
= "TestSomeText\r\n";
62 const char * TestItem9
= "TestSomeText\r\nSomeMoreText\r\n";
63 const char * TestItem10
= "TestSomeText\r\n\r\nTestSomeText";
64 const char * TestItem11
= "TestSomeText TestSomeText";
65 const char * TestItem12
= "TestSomeText \r\nTestSomeText";
66 const char * TestItem13
= "TestSomeText\r\n \r\nTestSomeText";
67 const char * TestItem14
= "TestSomeText\n";
68 const char * TestItem15
= "TestSomeText\r\r\r";
69 const char * TestItem16
= "TestSomeText\r\r\rSomeMoreText";
73 /* This test attempts to show that WM_SETTEXT on a riched32 control does not
74 * attempt to modify the text that is pasted into the control, and should
75 * return it as is. In particular, \r\r\n is NOT converted, unlike riched20.
77 * For riched32, the rules for breaking lines seem to be the following:
78 * - \r\n is one line break. This is the normal case.
79 * - \r{0,2}\n is one line break. In particular, \n by itself is a line break.
80 * - \r{0,N-1}\r\r\n is N line breaks.
81 * - \n{1,N} are that many line breaks.
82 * - \r with text or other characters (except \n) past it, is a line break. That
83 * is, a run of \r{N} without a terminating \n is considered N line breaks
84 * - \r at the end of the text is NOT a line break. This differs from riched20,
85 * where \r at the end of the text is a proper line break.
88 #define TEST_SETTEXT(a, b, nlines) \
89 result = SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) a); \
90 ok (result == 1, "WM_SETTEXT returned %ld instead of 1\n", result); \
91 result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buf); \
92 ok (result == lstrlen(buf), \
93 "WM_GETTEXT returned %ld instead of expected %u\n", \
94 result, lstrlen(buf)); \
95 result = strcmp(b, buf); \
97 "WM_SETTEXT round trip: strcmp = %ld\n", result); \
98 result = SendMessage(hwndRichEdit, EM_GETLINECOUNT, 0, 0); \
99 ok(result == nlines, "EM_GETLINECOUNT returned %ld, expected %d\n", result, nlines);
101 TEST_SETTEXT(TestItem1
, TestItem1
, 1)
102 TEST_SETTEXT(TestItem2
, TestItem2
, 1)
103 TEST_SETTEXT(TestItem3
, TestItem3
, 2)
104 TEST_SETTEXT(TestItem4
, TestItem4
, 3)
105 TEST_SETTEXT(TestItem5
, TestItem5
, 2)
106 TEST_SETTEXT(TestItem6
, TestItem6
, 3)
107 TEST_SETTEXT(TestItem7
, TestItem7
, 4)
108 TEST_SETTEXT(TestItem8
, TestItem8
, 2)
109 TEST_SETTEXT(TestItem9
, TestItem9
, 3)
110 TEST_SETTEXT(TestItem10
, TestItem10
, 3)
111 TEST_SETTEXT(TestItem11
, TestItem11
, 1)
112 TEST_SETTEXT(TestItem12
, TestItem12
, 2)
113 TEST_SETTEXT(TestItem13
, TestItem13
, 3)
114 TEST_SETTEXT(TestItem14
, TestItem14
, 2)
115 TEST_SETTEXT(TestItem15
, TestItem15
, 3)
116 TEST_SETTEXT(TestItem16
, TestItem16
, 4)
119 DestroyWindow(hwndRichEdit
);
122 static void test_WM_GETTEXTLENGTH(void)
124 HWND hwndRichEdit
= new_richedit(NULL
);
125 static const char text3
[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee";
126 static const char text4
[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee\r\n";
129 /* Test for WM_GETTEXTLENGTH */
130 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) text3
);
131 result
= SendMessage(hwndRichEdit
, WM_GETTEXTLENGTH
, 0, 0);
132 ok(result
== lstrlen(text3
),
133 "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n",
134 result
, lstrlen(text3
));
136 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) text4
);
137 result
= SendMessage(hwndRichEdit
, WM_GETTEXTLENGTH
, 0, 0);
138 ok(result
== lstrlen(text4
),
139 "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n",
140 result
, lstrlen(text4
));
142 DestroyWindow(hwndRichEdit
);
145 static DWORD CALLBACK
test_EM_STREAMIN_esCallback(DWORD_PTR dwCookie
,
150 const char** str
= (const char**)dwCookie
;
151 int size
= strlen(*str
);
157 memcpy(pbBuff
, *str
, *pcb
);
164 static void test_EM_STREAMIN(void)
166 HWND hwndRichEdit
= new_richedit(NULL
);
169 char buffer
[1024] = {0};
171 const char * streamText0
= "{\\rtf1 TestSomeText}";
172 const char * streamText0a
= "{\\rtf1 TestSomeText\\par}";
173 const char * streamText0b
= "{\\rtf1 TestSomeText\\par\\par}";
175 const char * streamText1
=
176 "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang12298{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 System;}}\r\n"
177 "\\viewkind4\\uc1\\pard\\f0\\fs17 TestSomeText\\par\r\n"
180 /* This should be accepted in richedit 1.0 emulation. See bug #8326 */
181 const char * streamText2
=
182 "{{\\colortbl;\\red0\\green255\\blue102;\\red255\\green255\\blue255;"
183 "\\red170\\green255\\blue255;\\red255\\green238\\blue0;\\red51\\green255"
184 "\\blue221;\\red238\\green238\\blue238;}\\tx0 \\tx424 \\tx848 \\tx1272 "
185 "\\tx1696 \\tx2120 \\tx2544 \\tx2968 \\tx3392 \\tx3816 \\tx4240 \\tx4664 "
186 "\\tx5088 \\tx5512 \\tx5936 \\tx6360 \\tx6784 \\tx7208 \\tx7632 \\tx8056 "
187 "\\tx8480 \\tx8904 \\tx9328 \\tx9752 \\tx10176 \\tx10600 \\tx11024 "
188 "\\tx11448 \\tx11872 \\tx12296 \\tx12720 \\tx13144 \\cf2 RichEdit1\\line }";
190 const char * streamText3
= "RichEdit1";
192 /* Minimal test without \par at the end */
193 es
.dwCookie
= (DWORD_PTR
)&streamText0
;
195 es
.pfnCallback
= test_EM_STREAMIN_esCallback
;
196 SendMessage(hwndRichEdit
, EM_STREAMIN
,
197 (WPARAM
)(SF_RTF
), (LPARAM
)&es
);
199 result
= SendMessage(hwndRichEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
201 "EM_STREAMIN: Test 0 returned %ld, expected 12\n", result
);
202 result
= strcmp (buffer
,"TestSomeText");
204 "EM_STREAMIN: Test 0 set wrong text: Result: %s\n",buffer
);
205 ok(es
.dwError
== 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es
.dwError
, 0);
207 /* Native richedit 2.0 ignores last \par */
208 es
.dwCookie
= (DWORD_PTR
)&streamText0a
;
210 es
.pfnCallback
= test_EM_STREAMIN_esCallback
;
211 SendMessage(hwndRichEdit
, EM_STREAMIN
,
212 (WPARAM
)(SF_RTF
), (LPARAM
)&es
);
214 result
= SendMessage(hwndRichEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
216 "EM_STREAMIN: Test 0-a returned %ld, expected 12\n", result
);
217 result
= strcmp (buffer
,"TestSomeText");
219 "EM_STREAMIN: Test 0-a set wrong text: Result: %s\n",buffer
);
220 ok(es
.dwError
== 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es
.dwError
, 0);
222 /* Native richedit 2.0 ignores last \par, next-to-last \par appears */
223 es
.dwCookie
= (DWORD_PTR
)&streamText0b
;
225 es
.pfnCallback
= test_EM_STREAMIN_esCallback
;
226 SendMessage(hwndRichEdit
, EM_STREAMIN
,
227 (WPARAM
)(SF_RTF
), (LPARAM
)&es
);
229 result
= SendMessage(hwndRichEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
231 "EM_STREAMIN: Test 0-b returned %ld, expected 14\n", result
);
232 result
= strcmp (buffer
,"TestSomeText\r\n");
234 "EM_STREAMIN: Test 0-b set wrong text: Result: %s\n",buffer
);
235 ok(es
.dwError
== 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es
.dwError
, 0);
237 es
.dwCookie
= (DWORD_PTR
)&streamText1
;
239 es
.pfnCallback
= test_EM_STREAMIN_esCallback
;
240 SendMessage(hwndRichEdit
, EM_STREAMIN
,
241 (WPARAM
)(SF_RTF
), (LPARAM
)&es
);
243 result
= SendMessage(hwndRichEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
245 "EM_STREAMIN: Test 1 returned %ld, expected 12\n", result
);
246 result
= strcmp (buffer
,"TestSomeText");
248 "EM_STREAMIN: Test 1 set wrong text: Result: %s\n",buffer
);
249 ok(es
.dwError
== 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es
.dwError
, 0);
252 es
.dwCookie
= (DWORD_PTR
)&streamText2
;
254 SendMessage(hwndRichEdit
, EM_STREAMIN
,
255 (WPARAM
)(SF_RTF
), (LPARAM
)&es
);
257 result
= SendMessage(hwndRichEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
260 "EM_STREAMIN: Test 2 returned %ld, expected 9\n", result
);
262 result
= strcmp (buffer
,"RichEdit1");
265 "EM_STREAMIN: Test 2 set wrong text: Result: %s\n",buffer
);
267 ok(es
.dwError
== 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es
.dwError
, 0);
269 es
.dwCookie
= (DWORD_PTR
)&streamText3
;
271 SendMessage(hwndRichEdit
, EM_STREAMIN
,
272 (WPARAM
)(SF_RTF
), (LPARAM
)&es
);
274 result
= SendMessage(hwndRichEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
276 "EM_STREAMIN: Test 3 returned %ld, expected 0\n", result
);
277 ok (strlen(buffer
) == 0,
278 "EM_STREAMIN: Test 3 set wrong text: Result: %s\n",buffer
);
279 ok(es
.dwError
== -16, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es
.dwError
, -16);
281 DestroyWindow(hwndRichEdit
);
284 static DWORD CALLBACK
test_WM_SETTEXT_esCallback(DWORD_PTR dwCookie
,
289 char** str
= (char**)dwCookie
;
292 memcpy(*str
, pbBuff
, *pcb
);
298 static void test_EM_STREAMOUT(void)
300 HWND hwndRichEdit
= new_richedit(NULL
);
303 char buf
[1024] = {0};
306 const char * TestItem1
= "TestSomeText";
307 const char * TestItem2
= "TestSomeText\r";
308 const char * TestItem3
= "TestSomeText\r\n";
310 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) TestItem1
);
312 es
.dwCookie
= (DWORD_PTR
)&p
;
314 es
.pfnCallback
= test_WM_SETTEXT_esCallback
;
315 memset(buf
, 0, sizeof(buf
));
316 SendMessage(hwndRichEdit
, EM_STREAMOUT
,
317 (WPARAM
)(SF_TEXT
), (LPARAM
)&es
);
319 ok(r
== 12, "streamed text length is %d, expecting 12\n", r
);
320 ok(strcmp(buf
, TestItem1
) == 0,
321 "streamed text different, got %s\n", buf
);
323 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) TestItem2
);
325 es
.dwCookie
= (DWORD_PTR
)&p
;
327 es
.pfnCallback
= test_WM_SETTEXT_esCallback
;
328 memset(buf
, 0, sizeof(buf
));
329 SendMessage(hwndRichEdit
, EM_STREAMOUT
,
330 (WPARAM
)(SF_TEXT
), (LPARAM
)&es
);
333 ok(r
== 13, "streamed text length is %d, expecting 13\n", r
);
334 ok(strcmp(buf
, TestItem2
) == 0,
335 "streamed text different, got %s\n", buf
);
337 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) TestItem3
);
339 es
.dwCookie
= (DWORD_PTR
)&p
;
341 es
.pfnCallback
= test_WM_SETTEXT_esCallback
;
342 memset(buf
, 0, sizeof(buf
));
343 SendMessage(hwndRichEdit
, EM_STREAMOUT
,
344 (WPARAM
)(SF_TEXT
), (LPARAM
)&es
);
346 ok(r
== 14, "streamed text length is %d, expecting 14\n", r
);
347 ok(strcmp(buf
, TestItem3
) == 0,
348 "streamed text different, got %s\n", buf
);
350 DestroyWindow(hwndRichEdit
);
353 static const struct getline_s
{
358 {0, 10, "foo bar\r\n"},
364 /* Buffer smaller than line length */
370 static void test_EM_GETLINE(void)
373 HWND hwndRichEdit
= new_richedit(NULL
);
374 static const int nBuf
= 1024;
375 char dest
[1024], origdest
[1024];
376 const char text
[] = "foo bar\r\n"
381 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
383 memset(origdest
, 0xBB, nBuf
);
384 for (i
= 0; i
< sizeof(gl
)/sizeof(struct getline_s
); i
++)
387 int expected_nCopied
= min(gl
[i
].buffer_len
, strlen(gl
[i
].text
));
388 int expected_bytes_written
= min(gl
[i
].buffer_len
, strlen(gl
[i
].text
) + 1);
389 memset(dest
, 0xBB, nBuf
);
390 *(WORD
*) dest
= gl
[i
].buffer_len
;
392 /* EM_GETLINE appends a "\r\0" to the end of the line
393 * nCopied counts up to and including the '\r' */
394 nCopied
= SendMessage(hwndRichEdit
, EM_GETLINE
, gl
[i
].line
, (LPARAM
) dest
);
395 ok(nCopied
== expected_nCopied
, "%d: %d!=%d\n", i
, nCopied
,
397 /* two special cases since a parameter is passed via dest */
398 if (gl
[i
].buffer_len
== 0)
399 ok(!dest
[0] && !dest
[1] && !strncmp(dest
+2, origdest
+2, nBuf
-2),
401 else if (gl
[i
].buffer_len
== 1)
402 ok(dest
[0] == gl
[i
].text
[0] && !dest
[1] &&
403 !strncmp(dest
+2, origdest
+2, nBuf
-2), "buffer_len=1\n");
406 ok(!strncmp(dest
, gl
[i
].text
, expected_bytes_written
),
407 "%d: expected_bytes_written=%d\n", i
, expected_bytes_written
);
408 ok(!strncmp(dest
+ expected_bytes_written
, origdest
409 + expected_bytes_written
, nBuf
- expected_bytes_written
),
410 "%d: expected_bytes_written=%d\n", i
, expected_bytes_written
);
414 DestroyWindow(hwndRichEdit
);
417 static void test_EM_LINELENGTH(void)
419 HWND hwndRichEdit
= new_richedit(NULL
);
429 int offset_test
[16][2] = {
430 {0, 9}, /* Line 1: |richedit1\r */
431 {5, 9}, /* Line 1: riche|dit1\r */
432 {10, 9}, /* Line 2: |richedit1\n */
433 {15, 9}, /* Line 2: riche|dit1\n */
434 {20, 9}, /* Line 3: |richedit1\r\n */
435 {25, 9}, /* Line 3: riche|dit1\r\n */
436 {30, 9}, /* Line 3: richedit1\r|\n */
437 {31, 5}, /* Line 4: |short\r */
438 {42, 9}, /* Line 5: riche|dit1\r */
439 {46, 9}, /* Line 5: richedit1|\r */
440 {47, 0}, /* Line 6: |\r */
441 {48, 0}, /* Line 7: |\r */
442 {49, 0}, /* Line 8: |\r\r\n */
443 {50, 0}, /* Line 8: \r|\r\n */
444 {51, 0}, /* Line 8: \r\r|\n */
445 {52, 0}, /* Line 9: \r\r\n| */
450 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
452 result
= SendMessage(hwndRichEdit
, EM_GETLINECOUNT
, 0, 0);
454 win_skip("Win9x, WinME and NT4 don't handle '\\r only' correctly\n");
457 ok(result
== 9, "Incorrect line count of %ld\n", result
);
459 for (i
= 0; i
< sizeof(offset_test
)/sizeof(offset_test
[0]); i
++) {
460 result
= SendMessage(hwndRichEdit
, EM_LINELENGTH
, offset_test
[i
][0], 0);
461 ok(result
== offset_test
[i
][1], "Length of line at offset %d is %ld, expected %d\n",
462 offset_test
[i
][0], result
, offset_test
[i
][1]);
465 DestroyWindow(hwndRichEdit
);
468 static void test_EM_GETTEXTRANGE(void)
470 HWND hwndRichEdit
= new_richedit(NULL
);
471 const char * text1
= "foo bar\r\nfoo bar";
472 const char * text3
= "foo bar\rfoo bar";
473 const char * expect1
= "bar\r\nfoo";
474 const char * expect2
= "\nfoo";
475 const char * expect3
= "bar\rfoo";
476 char buffer
[1024] = {0};
478 TEXTRANGEA textRange
;
480 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
)text1
);
482 textRange
.lpstrText
= buffer
;
483 textRange
.chrg
.cpMin
= 4;
484 textRange
.chrg
.cpMax
= 12;
485 result
= SendMessage(hwndRichEdit
, EM_GETTEXTRANGE
, 0, (LPARAM
)&textRange
);
486 ok(result
== 8, "EM_GETTEXTRANGE returned %ld\n", result
);
487 ok(!strcmp(expect1
, buffer
), "EM_GETTEXTRANGE filled %s\n", buffer
);
489 textRange
.lpstrText
= buffer
;
490 textRange
.chrg
.cpMin
= 8;
491 textRange
.chrg
.cpMax
= 12;
492 result
= SendMessage(hwndRichEdit
, EM_GETTEXTRANGE
, 0, (LPARAM
)&textRange
);
493 ok(result
== 4, "EM_GETTEXTRANGE returned %ld\n", result
);
494 ok(!strcmp(expect2
, buffer
), "EM_GETTEXTRANGE filled %s\n", buffer
);
496 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
)text3
);
498 textRange
.lpstrText
= buffer
;
499 textRange
.chrg
.cpMin
= 4;
500 textRange
.chrg
.cpMax
= 11;
501 result
= SendMessage(hwndRichEdit
, EM_GETTEXTRANGE
, 0, (LPARAM
)&textRange
);
502 ok(result
== 7, "EM_GETTEXTRANGE returned %ld\n", result
);
504 ok(!strcmp(expect3
, buffer
), "EM_GETTEXTRANGE filled %s\n", buffer
);
507 DestroyWindow(hwndRichEdit
);
510 static void test_EM_GETSELTEXT(void)
512 HWND hwndRichEdit
= new_richedit(NULL
);
513 const char * text1
= "foo bar\r\nfoo bar";
514 const char * text2
= "foo bar\rfoo bar";
515 const char * expect1
= "bar\r\nfoo";
516 const char * expect2
= "bar\rfoo";
517 char buffer
[1024] = {0};
520 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
)text1
);
522 SendMessage(hwndRichEdit
, EM_SETSEL
, 4, 12);
523 result
= SendMessage(hwndRichEdit
, EM_GETSELTEXT
, 0, (LPARAM
)buffer
);
524 ok(result
== 8, "EM_GETTEXTRANGE returned %ld\n", result
);
525 ok(!strcmp(expect1
, buffer
), "EM_GETTEXTRANGE filled %s\n", buffer
);
527 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
)text2
);
529 SendMessage(hwndRichEdit
, EM_SETSEL
, 4, 11);
530 result
= SendMessage(hwndRichEdit
, EM_GETSELTEXT
, 0, (LPARAM
)buffer
);
531 ok(result
== 7, "EM_GETTEXTRANGE returned %ld\n", result
);
533 ok(!strcmp(expect2
, buffer
), "EM_GETTEXTRANGE filled %s\n", buffer
);
536 DestroyWindow(hwndRichEdit
);
539 static const char haystack
[] = "WINEWine wineWine wine WineWine";
542 static const char haystack2
[] = "first\r\r\nsecond";
553 struct find_s find_tests
[] = {
554 /* Find in empty text */
555 {0, -1, "foo", FR_DOWN
, -1},
556 {0, -1, "foo", 0, -1},
557 {0, -1, "", FR_DOWN
, -1},
558 {20, 5, "foo", FR_DOWN
, -1},
559 {5, 20, "foo", FR_DOWN
, -1}
562 struct find_s find_tests2
[] = {
564 {0, -1, "foo", FR_DOWN
| FR_MATCHCASE
, -1},
565 {5, 20, "WINE", FR_DOWN
| FR_MATCHCASE
, -1},
567 /* Subsequent finds */
568 {0, -1, "Wine", FR_DOWN
| FR_MATCHCASE
, 4},
569 {5, 31, "Wine", FR_DOWN
| FR_MATCHCASE
, 13},
570 {14, 31, "Wine", FR_DOWN
| FR_MATCHCASE
, 23},
571 {24, 31, "Wine", FR_DOWN
| FR_MATCHCASE
, 27},
574 {19, 20, "Wine", FR_MATCHCASE
, -1},
575 {10, 20, "Wine", FR_MATCHCASE
, 13},
576 {20, 10, "Wine", FR_MATCHCASE
, -1},
578 /* Case-insensitive */
579 {1, 31, "wInE", FR_DOWN
, 4},
580 {1, 31, "Wine", FR_DOWN
, 4},
582 /* High-to-low ranges */
583 {20, 5, "Wine", FR_DOWN
, -1},
584 {2, 1, "Wine", FR_DOWN
, -1},
585 {30, 29, "Wine", FR_DOWN
, -1},
586 {20, 5, "Wine", 0, /*13*/ -1},
589 {5, 10, "", FR_DOWN
, -1},
590 {10, 5, "", FR_DOWN
, -1},
591 {0, -1, "", FR_DOWN
, -1},
594 /* Whole-word search */
595 {0, -1, "wine", FR_DOWN
| FR_WHOLEWORD
, 18},
596 {0, -1, "win", FR_DOWN
| FR_WHOLEWORD
, -1},
597 {13, -1, "wine", FR_DOWN
| FR_WHOLEWORD
, 18},
598 {0, -1, "winewine", FR_DOWN
| FR_WHOLEWORD
, 0},
599 {10, -1, "winewine", FR_DOWN
| FR_WHOLEWORD
, 23},
600 {11, -1, "winewine", FR_WHOLEWORD
, 23},
601 {31, -1, "winewine", FR_WHOLEWORD
, -1},
604 {5, 200, "XXX", FR_DOWN
, -1},
605 {-20, 20, "Wine", FR_DOWN
, -1},
606 {-20, 20, "Wine", FR_DOWN
, -1},
607 {-15, -20, "Wine", FR_DOWN
, -1},
608 {1<<12, 1<<13, "Wine", FR_DOWN
, -1},
610 /* Check the case noted in bug 4479 where matches at end aren't recognized */
611 {23, 31, "Wine", FR_DOWN
| FR_MATCHCASE
, 23},
612 {27, 31, "Wine", FR_DOWN
| FR_MATCHCASE
, 27},
613 {27, 32, "Wine", FR_DOWN
| FR_MATCHCASE
, 27},
614 {13, 31, "WineWine", FR_DOWN
| FR_MATCHCASE
, 23},
615 {13, 32, "WineWine", FR_DOWN
| FR_MATCHCASE
, 23},
617 /* The backwards case of bug 4479; bounds look right
618 * Fails because backward find is wrong */
619 {19, 20, "WINE", FR_MATCHCASE
, -1},
620 {0, 20, "WINE", FR_MATCHCASE
, 0},
622 {0, -1, "wineWine wine", FR_DOWN
, 0},
623 {0, -1, "wineWine wine", 0, 0},
624 {0, -1, "INEW", 0, 1},
625 {0, 31, "INEW", 0, 1},
626 {4, -1, "INEW", 0, 10},
629 struct find_s find_tests3
[] = {
630 /* Searching for end of line characters */
631 {0, -1, "t\r\r\ns", FR_DOWN
| FR_MATCHCASE
, 4},
632 {6, -1, "\r\n", FR_DOWN
| FR_MATCHCASE
, 6},
633 {7, -1, "\n", FR_DOWN
| FR_MATCHCASE
, 7},
636 static void check_EM_FINDTEXT(HWND hwnd
, const char *name
, struct find_s
*f
, int id
) {
639 memset(&ft
, 0, sizeof(ft
));
640 ft
.chrg
.cpMin
= f
->start
;
641 ft
.chrg
.cpMax
= f
->end
;
642 ft
.lpstrText
= f
->needle
;
643 findloc
= SendMessage(hwnd
, EM_FINDTEXT
, f
->flags
, (LPARAM
) &ft
);
644 ok(findloc
== f
->expected_loc
,
645 "EM_FINDTEXT(%s,%d) '%s' in range(%d,%d), flags %08x, got start at %d, expected %d\n",
646 name
, id
, f
->needle
, f
->start
, f
->end
, f
->flags
, findloc
, f
->expected_loc
);
649 static void check_EM_FINDTEXTEX(HWND hwnd
, const char *name
, struct find_s
*f
,
653 int expected_end_loc
;
655 memset(&ft
, 0, sizeof(ft
));
656 ft
.chrg
.cpMin
= f
->start
;
657 ft
.chrg
.cpMax
= f
->end
;
658 ft
.lpstrText
= f
->needle
;
659 findloc
= SendMessage(hwnd
, EM_FINDTEXTEX
, f
->flags
, (LPARAM
) &ft
);
660 ok(findloc
== f
->expected_loc
,
661 "EM_FINDTEXTEX(%s,%d) '%s' in range(%d,%d), flags %08x, start at %d\n",
662 name
, id
, f
->needle
, f
->start
, f
->end
, f
->flags
, findloc
);
663 ok(ft
.chrgText
.cpMin
== f
->expected_loc
,
664 "EM_FINDTEXTEX(%s,%d) '%s' in range(%d,%d), flags %08x, start at %d, expected %d\n",
665 name
, id
, f
->needle
, f
->start
, f
->end
, f
->flags
, ft
.chrgText
.cpMin
, f
->expected_loc
);
666 expected_end_loc
= ((f
->expected_loc
== -1) ? -1
667 : f
->expected_loc
+ strlen(f
->needle
));
668 ok(ft
.chrgText
.cpMax
== expected_end_loc
,
669 "EM_FINDTEXTEX(%s,%d) '%s' in range(%d,%d), flags %08x, end at %d, expected %d\n",
670 name
, id
, f
->needle
, f
->start
, f
->end
, f
->flags
, ft
.chrgText
.cpMax
, expected_end_loc
);
673 static void run_tests_EM_FINDTEXT(HWND hwnd
, const char *name
, struct find_s
*find
,
678 for (i
= 0; i
< num_tests
; i
++) {
679 check_EM_FINDTEXT(hwnd
, name
, &find
[i
], i
);
680 check_EM_FINDTEXTEX(hwnd
, name
, &find
[i
], i
);
684 static void test_EM_FINDTEXT(void)
686 HWND hwndRichEdit
= new_richedit(NULL
);
688 /* Empty rich edit control */
689 run_tests_EM_FINDTEXT(hwndRichEdit
, "1", find_tests
,
690 sizeof(find_tests
)/sizeof(struct find_s
));
692 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) haystack
);
695 run_tests_EM_FINDTEXT(hwndRichEdit
, "2", find_tests2
,
696 sizeof(find_tests2
)/sizeof(struct find_s
));
698 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) haystack2
);
700 /* Haystack text 2 (with EOL characters) */
701 run_tests_EM_FINDTEXT(hwndRichEdit
, "3", find_tests3
,
702 sizeof(find_tests3
)/sizeof(struct find_s
));
704 DestroyWindow(hwndRichEdit
);
707 static void test_EM_POSFROMCHAR(void)
709 HWND hwndRichEdit
= new_richedit(NULL
);
713 unsigned int height
= 0;
715 static const char text
[] = "aa\n"
716 "this is a long line of text that should be longer than the "
725 /* Fill the control to lines to ensure that most of them are offscreen */
726 for (i
= 0; i
< 50; i
++)
728 /* Do not modify the string; it is exactly 16 characters long. */
729 SendMessage(hwndRichEdit
, EM_SETSEL
, 0, 0);
730 SendMessage(hwndRichEdit
, EM_REPLACESEL
, 0, (LPARAM
)"0123456789ABCD\r\n");
734 Richedit 1.0 receives a POINTL* on wParam and character offset on lParam, returns void.
735 Richedit 2.0 receives character offset on wParam, ignores lParam, returns MAKELONG(x,y)
736 Richedit 3.0 accepts either of the above API conventions.
739 /* Testing Richedit 1.0 API format */
741 /* Testing start of lines. X-offset should be constant on all cases (native is 1).
742 Since all lines are identical and drawn with the same font,
743 they should have the same height... right?
745 for (i
= 0; i
< 50; i
++)
747 /* All the lines are 16 characters long */
748 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, i
* 16);
749 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
752 ok(pl
.y
== 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", pl
.y
);
753 ok(pl
.x
== 1, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
758 ok(pl
.y
> 0, "EM_POSFROMCHAR reports y=%d, expected > 0\n", pl
.y
);
759 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
764 ok(pl
.y
== i
* height
, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl
.y
, i
* height
);
765 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
769 /* Testing position at end of text */
770 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, 50 * 16);
771 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
772 ok(pl
.y
== 50 * height
, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl
.y
, 50 * height
);
773 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
775 /* Testing position way past end of text */
776 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, 55 * 16);
777 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
778 ok(pl
.y
== 50 * height
, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl
.y
, 50 * height
);
779 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
782 /* Testing that vertical scrolling does, in fact, have an effect on EM_POSFROMCHAR */
783 SendMessage(hwndRichEdit
, EM_SCROLL
, SB_LINEDOWN
, 0); /* line down */
784 for (i
= 0; i
< 50; i
++)
786 /* All the lines are 16 characters long */
787 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, i
* 16);
788 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
789 ok(pl
.y
== (i
- 1) * height
,
790 "EM_POSFROMCHAR reports y=%d, expected %d\n",
791 pl
.y
, (i
- 1) * height
);
792 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
795 /* Testing position at end of text */
796 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, 50 * 16);
797 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
798 ok(pl
.y
== (50 - 1) * height
, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl
.y
, (50 - 1) * height
);
799 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
801 /* Testing position way past end of text */
802 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, 55 * 16);
803 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
804 ok(pl
.y
== (50 - 1) * height
, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl
.y
, (50 - 1) * height
);
805 ok(pl
.x
== xpos
, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
807 /* Testing that horizontal scrolling does, in fact, have an effect on EM_POSFROMCHAR */
808 SendMessage(hwndRichEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
809 SendMessage(hwndRichEdit
, EM_SCROLL
, SB_LINEUP
, 0); /* line up */
811 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, 0);
812 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
813 ok(pl
.y
== 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", pl
.y
);
814 ok(pl
.x
== 1, "EM_POSFROMCHAR reports x=%d, expected 1\n", pl
.x
);
817 SendMessage(hwndRichEdit
, WM_HSCROLL
, SB_LINERIGHT
, 0);
818 result
= SendMessage(hwndRichEdit
, EM_POSFROMCHAR
, (WPARAM
)&pl
, 0);
819 ok(result
== 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result
);
820 ok(pl
.y
== 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", pl
.y
);
822 /* Fails on builtin because horizontal scrollbar is not being shown */
823 ok(pl
.x
< xpos
, "EM_POSFROMCHAR reports x=%hd, expected value less than %d\n", pl
.x
, xpos
);
825 DestroyWindow(hwndRichEdit
);
828 static void test_word_wrap(void)
831 POINTL point
= {0, 60}; /* This point must be below the first line */
832 const char *text
= "Must be long enough to test line wrapping";
833 DWORD dwCommonStyle
= WS_VISIBLE
|WS_POPUP
|WS_VSCROLL
|ES_MULTILINE
;
836 /* Test the effect of WS_HSCROLL and ES_AUTOHSCROLL styles on wrapping
837 * when specified on window creation and set later. */
838 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
, dwCommonStyle
,
839 0, 0, 200, 80, NULL
, NULL
, hmoduleRichEdit
, NULL
);
840 ok(hwnd
!= NULL
, "error: %d\n", (int) GetLastError());
841 res
= SendMessage(hwnd
, WM_SETTEXT
, 0, (LPARAM
) text
);
842 ok(res
, "WM_SETTEXT failed.\n");
843 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
844 ok(pos
, "pos=%d indicating no word wrap when it is expected.\n", pos
);
845 lines
= SendMessage(hwnd
, EM_GETLINECOUNT
, 0, 0);
846 ok(lines
> 1, "Line was expected to wrap (lines=%d).\n", lines
);
848 SetWindowLong(hwnd
, GWL_STYLE
, dwCommonStyle
|WS_HSCROLL
|ES_AUTOHSCROLL
);
849 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
850 ok(pos
, "pos=%d indicating no word wrap when it is expected.\n", pos
);
853 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
, dwCommonStyle
|WS_HSCROLL
,
854 0, 0, 200, 80, NULL
, NULL
, hmoduleRichEdit
, NULL
);
855 ok(hwnd
!= NULL
, "error: %d\n", (int) GetLastError());
857 res
= SendMessage(hwnd
, WM_SETTEXT
, 0, (LPARAM
) text
);
858 ok(res
, "WM_SETTEXT failed.\n");
859 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
860 ok(pos
, "pos=%d indicating no word wrap when it is expected.\n", pos
);
861 lines
= SendMessage(hwnd
, EM_GETLINECOUNT
, 0, 0);
862 ok(lines
> 1, "Line was expected to wrap (lines=%d).\n", lines
);
864 SetWindowLong(hwnd
, GWL_STYLE
, dwCommonStyle
|WS_HSCROLL
|ES_AUTOHSCROLL
);
865 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
866 ok(pos
, "pos=%d indicating no word wrap when it is expected.\n", pos
);
869 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
, dwCommonStyle
|ES_AUTOHSCROLL
,
870 0, 0, 200, 80, NULL
, NULL
, hmoduleRichEdit
, NULL
);
871 ok(hwnd
!= NULL
, "error: %d\n", (int) GetLastError());
872 res
= SendMessage(hwnd
, WM_SETTEXT
, 0, (LPARAM
) text
);
873 ok(res
, "WM_SETTEXT failed.\n");
874 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
875 ok(!pos
, "pos=%d indicating word wrap when none is expected.\n", pos
);
877 SetWindowLong(hwnd
, GWL_STYLE
, dwCommonStyle
);
878 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
879 ok(!pos
, "pos=%d indicating word wrap when none is expected.\n", pos
);
882 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
,
883 dwCommonStyle
|WS_HSCROLL
|ES_AUTOHSCROLL
,
884 0, 0, 200, 80, NULL
, NULL
, hmoduleRichEdit
, NULL
);
885 ok(hwnd
!= NULL
, "error: %d\n", (int) GetLastError());
886 res
= SendMessage(hwnd
, WM_SETTEXT
, 0, (LPARAM
) text
);
887 ok(res
, "WM_SETTEXT failed.\n");
888 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
889 ok(!pos
, "pos=%d indicating word wrap when none is expected.\n", pos
);
891 SetWindowLong(hwnd
, GWL_STYLE
, dwCommonStyle
);
892 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
893 ok(!pos
, "pos=%d indicating word wrap when none is expected.\n", pos
);
895 /* Test the effect of EM_SETTARGETDEVICE on word wrap. */
896 res
= SendMessage(hwnd
, EM_SETTARGETDEVICE
, 0, 1);
897 ok(res
, "EM_SETTARGETDEVICE failed (returned %d).\n", res
);
898 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
899 ok(!pos
, "pos=%d indicating word wrap when none is expected.\n", pos
);
901 res
= SendMessage(hwnd
, EM_SETTARGETDEVICE
, 0, 0);
902 ok(res
, "EM_SETTARGETDEVICE failed (returned %d).\n", res
);
903 pos
= SendMessage(hwnd
, EM_CHARFROMPOS
, 0, (LPARAM
) &point
);
904 ok(pos
, "pos=%d indicating no word wrap when it is expected.\n", pos
);
907 /* Test to see if wrapping happens with redraw disabled. */
908 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
, dwCommonStyle
,
909 0, 0, 400, 80, NULL
, NULL
, hmoduleRichEdit
, NULL
);
910 ok(hwnd
!= NULL
, "error: %d\n", (int) GetLastError());
911 ok(IsWindowVisible(hwnd
), "Window should be visible.\n");
912 SendMessage(hwnd
, WM_SETREDRAW
, FALSE
, 0);
913 /* redraw is disabled by making the window invisible. */
914 ok(!IsWindowVisible(hwnd
), "Window shouldn't be visible.\n");
915 res
= SendMessage(hwnd
, EM_REPLACESEL
, FALSE
, (LPARAM
) text
);
916 ok(res
, "EM_REPLACESEL failed.\n");
917 MoveWindow(hwnd
, 0, 0, 100, 80, TRUE
);
918 SendMessage(hwnd
, WM_SETREDRAW
, TRUE
, 0);
919 /* Wrapping didn't happen while redraw was disabled. */
920 lines
= SendMessage(hwnd
, EM_GETLINECOUNT
, 0, 0);
921 todo_wine
ok(lines
== 1, "Line wasn't expected to wrap (lines=%d).\n", lines
);
922 /* There isn't even a rewrap from resizing the window. */
923 lines
= SendMessage(hwnd
, EM_GETLINECOUNT
, 0, 0);
924 todo_wine
ok(lines
== 1, "Line wasn't expected to wrap (lines=%d).\n", lines
);
925 res
= SendMessage(hwnd
, EM_REPLACESEL
, FALSE
, (LPARAM
) text
);
926 ok(res
, "EM_REPLACESEL failed.\n");
927 lines
= SendMessage(hwnd
, EM_GETLINECOUNT
, 0, 0);
928 ok(lines
> 1, "Line was expected to wrap (lines=%d).\n", lines
);
933 static void test_EM_GETOPTIONS(void)
938 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
,
940 0, 0, 200, 60, NULL
, NULL
, hmoduleRichEdit
, NULL
);
941 options
= SendMessage(hwnd
, EM_GETOPTIONS
, 0, 0);
942 ok(options
== 0, "Incorrect options %x\n", options
);
945 hwnd
= CreateWindow(RICHEDIT_CLASS10A
, NULL
,
946 WS_POPUP
|WS_VSCROLL
|WS_HSCROLL
,
947 0, 0, 200, 60, NULL
, NULL
, hmoduleRichEdit
, NULL
);
948 options
= SendMessage(hwnd
, EM_GETOPTIONS
, 0, 0);
949 ok(options
== ECO_AUTOVSCROLL
,
950 "Incorrect initial options %x\n", options
);
954 static void test_autoscroll(void)
959 /* The WS_VSCROLL and WS_HSCROLL styles implicitly set
960 * auto vertical/horizontal scrolling options. */
961 hwnd
= CreateWindowEx(0, RICHEDIT_CLASS10A
, NULL
,
962 WS_POPUP
|ES_MULTILINE
|WS_VSCROLL
|WS_HSCROLL
,
963 0, 0, 200, 60, NULL
, NULL
, hmoduleRichEdit
, NULL
);
964 ok(hwnd
!= NULL
, "class: %s, error: %d\n", RICHEDIT_CLASS
, (int) GetLastError());
965 ret
= SendMessage(hwnd
, EM_GETOPTIONS
, 0, 0);
966 ok(ret
& ECO_AUTOVSCROLL
, "ECO_AUTOVSCROLL isn't set.\n");
967 ok(!(ret
& ECO_AUTOHSCROLL
), "ECO_AUTOHSCROLL is set.\n");
968 ret
= GetWindowLong(hwnd
, GWL_STYLE
);
969 todo_wine
ok(ret
& ES_AUTOVSCROLL
, "ES_AUTOVSCROLL isn't set.\n");
970 ok(!(ret
& ES_AUTOHSCROLL
), "ES_AUTOHSCROLL is set.\n");
973 hwnd
= CreateWindowEx(0, RICHEDIT_CLASS
, NULL
,
974 WS_POPUP
|ES_MULTILINE
,
975 0, 0, 200, 60, NULL
, NULL
, hmoduleRichEdit
, NULL
);
976 ok(hwnd
!= NULL
, "class: %s, error: %d\n", RICHEDIT_CLASS
, (int) GetLastError());
977 ret
= SendMessage(hwnd
, EM_GETOPTIONS
, 0, 0);
978 ok(!(ret
& ECO_AUTOVSCROLL
), "ECO_AUTOVSCROLL is set.\n");
979 ok(!(ret
& ECO_AUTOHSCROLL
), "ECO_AUTOHSCROLL is set.\n");
980 ret
= GetWindowLong(hwnd
, GWL_STYLE
);
981 ok(!(ret
& ES_AUTOVSCROLL
), "ES_AUTOVSCROLL is set.\n");
982 ok(!(ret
& ES_AUTOHSCROLL
), "ES_AUTOHSCROLL is set.\n");
991 /* Must explicitly LoadLibrary(). The test has no references to functions in
992 * RICHED32.DLL, so the linker doesn't actually link to it. */
993 hmoduleRichEdit
= LoadLibrary("RICHED32.DLL");
994 ok(hmoduleRichEdit
!= NULL
, "error: %d\n", (int) GetLastError());
997 test_EM_GETTEXTRANGE();
998 test_EM_GETSELTEXT();
999 test_WM_GETTEXTLENGTH();
1001 test_EM_STREAMOUT();
1003 test_EM_LINELENGTH();
1005 test_EM_POSFROMCHAR();
1007 test_EM_GETOPTIONS();
1010 /* Set the environment variable WINETEST_RICHED32 to keep windows
1011 * responsive and open for 30 seconds. This is useful for debugging.
1013 * The message pump uses PeekMessage() to empty the queue and then sleeps for
1014 * 50ms before retrying the queue. */
1015 end
= time(NULL
) + 30;
1016 if (getenv( "WINETEST_RICHED32" )) {
1017 while (time(NULL
) < end
) {
1018 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
1019 TranslateMessage(&msg
);
1020 DispatchMessage(&msg
);
1027 OleFlushClipboard();
1028 ok(FreeLibrary(hmoduleRichEdit
) != 0, "error: %d\n", (int) GetLastError());