user32: Make the edit tests pass on Vista.
[wine/multimedia.git] / dlls / user32 / tests / edit.c
blobfae1bd121b57072d4ebe058a7f82ba465e75ef5e
1 /* Unit test suite for edit control.
3 * Copyright 2004 Vitaliy Margolen
4 * Copyright 2005 C. Scott Ananian
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <assert.h>
22 #include <windows.h>
23 #include <commctrl.h>
25 #include "wine/test.h"
27 #ifndef ES_COMBO
28 #define ES_COMBO 0x200
29 #endif
31 #define ID_EDITTEST2 99
32 #define MAXLEN 200
34 struct edit_notify {
35 int en_change, en_maxtext, en_update;
38 static struct edit_notify notifications;
40 static HINSTANCE hinst;
41 static HWND hwndET2;
42 static const char szEditTest2Class[] = "EditTest2Class";
43 static const char szEditTest3Class[] = "EditTest3Class";
44 static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
46 static HWND create_editcontrol (DWORD style, DWORD exstyle)
48 HWND handle;
50 handle = CreateWindowEx(exstyle,
51 "EDIT",
52 "Test Text",
53 style,
54 10, 10, 300, 300,
55 NULL, NULL, hinst, NULL);
56 assert (handle);
57 if (winetest_interactive)
58 ShowWindow (handle, SW_SHOW);
59 return handle;
62 static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
64 HWND parentWnd;
65 HWND editWnd;
66 RECT rect;
68 rect.left = 0;
69 rect.top = 0;
70 rect.right = 300;
71 rect.bottom = 300;
72 assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
74 parentWnd = CreateWindowEx(0,
75 szEditTextPositionClass,
76 "Edit Test",
77 WS_OVERLAPPEDWINDOW,
78 CW_USEDEFAULT, CW_USEDEFAULT,
79 rect.right - rect.left, rect.bottom - rect.top,
80 NULL, NULL, hinst, NULL);
81 assert(parentWnd);
83 editWnd = CreateWindowEx(exstyle,
84 "EDIT",
85 "Test Text",
86 WS_CHILD | style,
87 0, 0, 300, 300,
88 parentWnd, NULL, hinst, NULL);
89 assert(editWnd);
90 if (winetest_interactive)
91 ShowWindow (parentWnd, SW_SHOW);
92 return editWnd;
95 static void destroy_child_editcontrol (HWND hwndEdit)
97 if (GetParent(hwndEdit))
98 DestroyWindow(GetParent(hwndEdit));
99 else {
100 trace("Edit control has no parent!\n");
101 DestroyWindow(hwndEdit);
105 static LONG get_edit_style (HWND hwnd)
107 return GetWindowLongA( hwnd, GWL_STYLE ) & (
108 ES_LEFT |
109 /* FIXME: not implemented
110 ES_CENTER |
111 ES_RIGHT |
112 ES_OEMCONVERT |
114 ES_MULTILINE |
115 ES_UPPERCASE |
116 ES_LOWERCASE |
117 ES_PASSWORD |
118 ES_AUTOVSCROLL |
119 ES_AUTOHSCROLL |
120 ES_NOHIDESEL |
121 ES_COMBO |
122 ES_READONLY |
123 ES_WANTRETURN |
124 ES_NUMBER
128 static void set_client_height(HWND Wnd, unsigned Height)
130 RECT ClientRect, WindowRect;
132 GetWindowRect(Wnd, &WindowRect);
133 GetClientRect(Wnd, &ClientRect);
134 SetWindowPos(Wnd, NULL, 0, 0,
135 WindowRect.right - WindowRect.left,
136 Height + (WindowRect.bottom - WindowRect.top) -
137 (ClientRect.bottom - ClientRect.top),
138 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
140 /* Workaround for a bug in Windows' edit control
141 (multi-line mode) */
142 GetWindowRect(Wnd, &WindowRect);
143 SetWindowPos(Wnd, NULL, 0, 0,
144 WindowRect.right - WindowRect.left + 1,
145 WindowRect.bottom - WindowRect.top + 1,
146 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
147 SetWindowPos(Wnd, NULL, 0, 0,
148 WindowRect.right - WindowRect.left,
149 WindowRect.bottom - WindowRect.top,
150 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
152 GetClientRect(Wnd, &ClientRect);
153 ok(ClientRect.bottom - ClientRect.top == Height,
154 "The client height should be %ld, but is %ld\n",
155 (long)Height, (long)(ClientRect.bottom - ClientRect.top));
158 static void test_edit_control_1(void)
160 HWND hwEdit;
161 MSG msMessage;
162 int i;
163 LONG r;
165 msMessage.message = WM_KEYDOWN;
167 trace("EDIT: Single line\n");
168 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
169 r = get_edit_style(hwEdit);
170 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%x\n", r);
171 for (i=0;i<65535;i++)
173 msMessage.wParam = i;
174 r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
175 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
176 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
178 DestroyWindow (hwEdit);
180 trace("EDIT: Single line want returns\n");
181 hwEdit = create_editcontrol(ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
182 r = get_edit_style(hwEdit);
183 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%x\n", r);
184 for (i=0;i<65535;i++)
186 msMessage.wParam = i;
187 r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
188 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
189 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
191 DestroyWindow (hwEdit);
193 trace("EDIT: Multiline line\n");
194 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
195 r = get_edit_style(hwEdit);
196 ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%x\n", r);
197 for (i=0;i<65535;i++)
199 msMessage.wParam = i;
200 r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
201 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
202 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
204 DestroyWindow (hwEdit);
206 trace("EDIT: Multi line want returns\n");
207 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
208 r = get_edit_style(hwEdit);
209 ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%x\n", r);
210 for (i=0;i<65535;i++)
212 msMessage.wParam = i;
213 r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
214 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
215 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
217 DestroyWindow (hwEdit);
220 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
221 * selection. This test checks that the first 'select all' doesn't generate
222 * an UPDATE message which can escape and (via a handler) change the
223 * selection, which would cause WM_SETTEXT to break. This old bug
224 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
226 static void test_edit_control_2(void)
228 HWND hwndMain;
229 char szLocalString[MAXLEN];
231 /* Create main and edit windows. */
232 hwndMain = CreateWindow(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW,
233 0, 0, 200, 200, NULL, NULL, hinst, NULL);
234 assert(hwndMain);
235 if (winetest_interactive)
236 ShowWindow (hwndMain, SW_SHOW);
238 hwndET2 = CreateWindow("EDIT", NULL,
239 WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
240 0, 0, 150, 50, /* important this not be 0 size. */
241 hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
242 assert(hwndET2);
243 if (winetest_interactive)
244 ShowWindow (hwndET2, SW_SHOW);
246 trace("EDIT: SETTEXT atomicity\n");
247 /* Send messages to "type" in the word 'foo'. */
248 SendMessage(hwndET2, WM_CHAR, 'f', 1);
249 SendMessage(hwndET2, WM_CHAR, 'o', 1);
250 SendMessage(hwndET2, WM_CHAR, 'o', 1);
251 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
252 GetWindowText(hwndET2, szLocalString, MAXLEN);
253 ok(lstrcmp(szLocalString, "bar")==0,
254 "Wrong contents of edit: %s\n", szLocalString);
256 /* OK, done! */
257 DestroyWindow (hwndET2);
258 DestroyWindow (hwndMain);
261 static void ET2_check_change(void) {
262 char szLocalString[MAXLEN];
263 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
264 GetWindowText(hwndET2, szLocalString, MAXLEN);
265 if (lstrcmp(szLocalString, "foo")==0) {
266 lstrcpy(szLocalString, "bar");
267 SendMessage(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
269 /* always leave the cursor at the end. */
270 SendMessage(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
272 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
274 if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
275 ET2_check_change();
277 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
279 switch (iMsg) {
280 case WM_COMMAND:
281 ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
282 break;
284 return DefWindowProc(hwnd, iMsg, wParam, lParam);
287 static void zero_notify(void)
289 notifications.en_change = 0;
290 notifications.en_maxtext = 0;
291 notifications.en_update = 0;
294 #define test_notify(enchange, enmaxtext, enupdate) \
295 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
296 "got %d\n", enchange, notifications.en_change); \
297 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
298 "got %d\n", enmaxtext, notifications.en_maxtext); \
299 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
300 "got %d\n", enupdate, notifications.en_update)
303 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
305 switch (msg) {
306 case WM_COMMAND:
307 switch (HIWORD(wParam)) {
308 case EN_MAXTEXT:
309 notifications.en_maxtext++;
310 break;
311 case EN_UPDATE:
312 notifications.en_update++;
313 break;
314 case EN_CHANGE:
315 notifications.en_change++;
316 break;
318 break;
320 return DefWindowProcA(hWnd, msg, wParam, lParam);
323 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
324 * to these messages.
326 static void test_edit_control_3(void)
328 HWND hWnd;
329 HWND hParent;
330 int len;
331 static const char *str = "this is a long string.";
332 static const char *str2 = "this is a long string.\r\nthis is a long string.\r\nthis is a long string.\r\nthis is a long string.";
334 trace("EDIT: Test notifications\n");
336 hParent = CreateWindowExA(0,
337 szEditTest3Class,
338 NULL,
340 CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
341 NULL, NULL, NULL, NULL);
342 assert(hParent);
344 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
345 hWnd = CreateWindowExA(0,
346 "EDIT",
347 NULL,
349 10, 10, 50, 50,
350 hParent, NULL, NULL, NULL);
351 assert(hWnd);
353 zero_notify();
354 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
355 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
356 ok(lstrlenA(str) > len, "text should have been truncated\n");
357 test_notify(1, 1, 1);
359 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
360 zero_notify();
361 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
362 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
363 ok(1 == len, "wrong text length, expected 1, got %d\n", len);
364 test_notify(1, 0, 1);
366 zero_notify();
367 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
368 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
369 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
370 test_notify(1, 0, 1);
372 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
374 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
375 zero_notify();
376 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
377 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
378 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
379 test_notify(1, 1, 1);
381 zero_notify();
382 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
383 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
384 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
385 test_notify(1, 0, 1);
387 DestroyWindow(hWnd);
389 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
390 hWnd = CreateWindowExA(0,
391 "EDIT",
392 NULL,
393 ES_AUTOHSCROLL,
394 10, 10, 50, 50,
395 hParent, NULL, NULL, NULL);
396 assert(hWnd);
398 zero_notify();
399 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
400 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
401 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
402 test_notify(1, 0, 1);
404 zero_notify();
405 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
406 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
407 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
408 test_notify(1, 0, 1);
410 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
412 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
413 zero_notify();
414 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
415 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
416 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
417 test_notify(1, 1, 1);
419 zero_notify();
420 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
421 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
422 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
423 test_notify(1, 0, 1);
425 DestroyWindow(hWnd);
427 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
428 hWnd = CreateWindowExA(0,
429 "EDIT",
430 NULL,
431 ES_MULTILINE,
432 10, 10, 50, 50,
433 hParent, NULL, NULL, NULL);
434 assert(hWnd);
436 zero_notify();
437 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
438 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
439 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
440 test_notify(1, 1, 1);
442 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
443 zero_notify();
444 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
445 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
446 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
447 test_notify(1, 0, 1);
449 zero_notify();
450 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
451 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
452 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
453 test_notify(0, 0, 0);
455 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
457 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
458 zero_notify();
459 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
460 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
461 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
462 test_notify(1, 1, 1);
464 zero_notify();
465 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
466 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
467 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
468 test_notify(0, 0, 0);
470 DestroyWindow(hWnd);
472 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
473 hWnd = CreateWindowExA(0,
474 "EDIT",
475 NULL,
476 ES_MULTILINE | ES_AUTOHSCROLL,
477 10, 10, 50, 50,
478 hParent, NULL, NULL, NULL);
479 assert(hWnd);
481 zero_notify();
482 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
483 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
484 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
485 test_notify(1, 1, 1);
487 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
488 zero_notify();
489 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
490 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
491 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
492 test_notify(1, 0, 1);
494 zero_notify();
495 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
496 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
497 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
498 test_notify(0, 0, 0);
500 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
502 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
503 zero_notify();
504 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
505 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
506 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
507 test_notify(1, 1, 1);
509 zero_notify();
510 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
511 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
512 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
513 test_notify(0, 0, 0);
515 DestroyWindow(hWnd);
517 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
518 hWnd = CreateWindowExA(0,
519 "EDIT",
520 NULL,
521 ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
522 10, 10, 50, 50,
523 hParent, NULL, NULL, NULL);
524 assert(hWnd);
526 zero_notify();
527 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
528 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
529 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
530 test_notify(1, 0, 1);
532 zero_notify();
533 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
534 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
535 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
536 test_notify(0, 0, 0);
538 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
540 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
541 zero_notify();
542 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
543 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
544 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
545 test_notify(1, 1, 1);
547 zero_notify();
548 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
549 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
550 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
551 test_notify(0, 0, 0);
553 DestroyWindow(hWnd);
556 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
558 static void test_edit_control_4(void)
560 HWND hwEdit;
561 int lo, hi, mid;
562 int ret;
563 int i;
565 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
566 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
567 SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
568 lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
569 hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
570 mid = lo + (hi - lo) / 2;
572 for (i = lo; i < mid; i++) {
573 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
574 ok(0 == ret, "expected 0 got %d\n", ret);
576 for (i = mid; i <= hi; i++) {
577 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
578 ok(1 == ret, "expected 1 got %d\n", ret);
580 ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
581 ok(-1 == ret, "expected -1 got %d\n", ret);
582 DestroyWindow(hwEdit);
584 hwEdit = create_editcontrol(ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
585 SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
586 lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
587 hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
588 mid = lo + (hi - lo) / 2;
590 for (i = lo; i < mid; i++) {
591 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
592 ok(0 == ret, "expected 0 got %d\n", ret);
594 for (i = mid; i <= hi; i++) {
595 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
596 ok(1 == ret, "expected 1 got %d\n", ret);
598 ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
599 ok(-1 == ret, "expected -1 got %d\n", ret);
600 DestroyWindow(hwEdit);
602 hwEdit = create_editcontrol(ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
603 SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
604 lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
605 hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
606 mid = lo + (hi - lo) / 2;
608 for (i = lo; i < mid; i++) {
609 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
610 ok(0 == ret, "expected 0 got %d\n", ret);
612 for (i = mid; i <= hi; i++) {
613 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
614 ok(1 == ret, "expected 1 got %d\n", ret);
616 ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
617 ok(-1 == ret, "expected -1 got %d\n", ret);
618 DestroyWindow(hwEdit);
620 hwEdit = create_editcontrol(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
621 SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
622 lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
623 hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
624 mid = lo + (hi - lo) / 2 +1;
626 for (i = lo; i < mid; i++) {
627 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
628 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
630 for (i = mid; i <= hi; i++) {
631 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
632 ok(1 == ret, "expected 1 got %d\n", ret);
634 ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
635 ok(-1 == ret, "expected -1 got %d\n", ret);
636 DestroyWindow(hwEdit);
638 hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
639 SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
640 lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
641 hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
642 mid = lo + (hi - lo) / 2 +1;
644 for (i = lo; i < mid; i++) {
645 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
646 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
648 for (i = mid; i <= hi; i++) {
649 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
650 ok(1 == ret, "expected 1 got %d\n", ret);
652 ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
653 ok(-1 == ret, "expected -1 got %d\n", ret);
654 DestroyWindow(hwEdit);
656 hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
657 SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
658 lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
659 hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
660 mid = lo + (hi - lo) / 2 +1;
662 for (i = lo; i < mid; i++) {
663 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
664 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
666 for (i = mid; i <= hi; i++) {
667 ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
668 ok(1 == ret, "expected 1 got %d\n", ret);
670 ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
671 ok(-1 == ret, "expected -1 got %d\n", ret);
672 DestroyWindow(hwEdit);
675 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
676 * truncates text that doesn't fit.
678 static void test_edit_control_5(void)
680 static const char *str = "test\r\ntest";
681 HWND hWnd;
682 int len;
684 hWnd = CreateWindowEx(0,
685 "EDIT",
686 str,
688 10, 10, 1, 1,
689 NULL, NULL, NULL, NULL);
690 assert(hWnd);
692 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
693 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
694 DestroyWindow(hWnd);
696 hWnd = CreateWindowEx(0,
697 "EDIT",
698 str,
699 ES_MULTILINE,
700 10, 10, 1, 1,
701 NULL, NULL, NULL, NULL);
702 assert(hWnd);
704 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
705 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
706 DestroyWindow(hWnd);
709 static void test_edit_control_limittext(void)
711 HWND hwEdit;
712 DWORD r;
714 /* Test default limit for single-line control */
715 trace("EDIT: buffer limit for single-line\n");
716 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
717 r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
718 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
719 SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
720 r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
721 /* Win9x+ME: 32766; WinNT: 2147483646UL */
722 ok( (r == 32766) || (r == 2147483646UL),
723 "got limit %u (expected 32766 or 2147483646)\n", r);
724 DestroyWindow(hwEdit);
726 /* Test default limit for multi-line control */
727 trace("EDIT: buffer limit for multi-line\n");
728 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
729 r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
730 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
731 SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
732 r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
733 /* Win9x+ME: 65535; WinNT: 4294967295UL */
734 ok( (r == 65535) || (r == 4294967295UL),
735 "got limit %u (expected 65535 or 4294967295)\n", r);
736 DestroyWindow(hwEdit);
739 static void test_margins(void)
741 HWND hwEdit;
742 RECT old_rect, new_rect;
743 INT old_left_margin, old_right_margin;
744 DWORD old_margins, new_margins;
746 hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
748 old_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
749 old_left_margin = LOWORD(old_margins);
750 old_right_margin = HIWORD(old_margins);
752 /* Check if setting the margins works */
754 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
755 new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
756 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
757 ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
759 SendMessage(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
760 new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
761 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
762 ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
765 /* The size of the rectangle must decrease if we increase the margin */
767 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
768 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
769 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
770 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
771 ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
772 ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
773 ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
774 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
777 /* If we set the margin to same value as the current margin,
778 the rectangle must not change */
780 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
781 old_rect.left = 1;
782 old_rect.right = 99;
783 old_rect.top = 1;
784 old_rect.bottom = 99;
785 SendMessage(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);
786 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
787 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
788 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
789 ok(new_rect.left == old_rect.left, "The left border of the rectangle has changed\n");
790 ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n");
791 ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n");
792 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n");
794 DestroyWindow (hwEdit);
797 static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
799 return 0;
802 static void test_margins_font_change(void)
804 HWND hwEdit;
805 DWORD margins, font_margins;
806 LOGFONT lf;
807 HFONT hfont, hfont2;
808 HDC hdc = GetDC(0);
810 if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
812 trace("Arial not found - skipping font change margin tests\n");
813 ReleaseDC(0, hdc);
814 return;
816 ReleaseDC(0, hdc);
818 hwEdit = create_child_editcontrol(0, 0);
820 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
822 memset(&lf, 0, sizeof(lf));
823 strcpy(lf.lfFaceName, "Arial");
824 lf.lfHeight = 16;
825 lf.lfCharSet = DEFAULT_CHARSET;
826 hfont = CreateFontIndirectA(&lf);
827 lf.lfHeight = 30;
828 hfont2 = CreateFontIndirectA(&lf);
830 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
831 font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
832 ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
833 ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
835 /* With 'small' edit controls, test that the margin doesn't get set */
836 SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
837 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
838 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
839 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
840 ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins));
841 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
843 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
844 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
845 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
846 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
847 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
849 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
850 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
851 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
852 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
853 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
855 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
856 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
857 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
858 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
859 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
860 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
861 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
862 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
864 /* Above a certain size threshold then the margin is updated */
865 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
866 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
867 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
868 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
869 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
870 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
872 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
873 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
874 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
875 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
876 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
878 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
879 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
880 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
881 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
882 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
883 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
884 ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins));
885 ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins));
887 SendMessageA(hwEdit, WM_SETFONT, 0, 0);
889 DeleteObject(hfont2);
890 DeleteObject(hfont);
891 destroy_child_editcontrol(hwEdit);
895 #define edit_pos_ok(exp, got, txt) \
896 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
898 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
899 do { \
900 RECT format_rect; \
901 int left_margin; \
902 set_client_height(hwEdit, set_height); \
903 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
904 left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
905 edit_pos_ok(test_top, format_rect.top, vertical position); \
906 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
907 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
908 } while(0)
910 static void test_text_position_style(DWORD style)
912 HWND hwEdit;
913 HFONT font, oldFont;
914 HDC dc;
915 TEXTMETRIC metrics;
916 INT b, bm, b2, b3;
917 BOOL single_line = !(style & ES_MULTILINE);
919 b = GetSystemMetrics(SM_CYBORDER) + 1;
920 b2 = 2 * b;
921 b3 = 3 * b;
922 bm = b2 - 1;
924 /* Get a stock font for which we can determine the metrics */
925 assert(font = GetStockObject(SYSTEM_FONT));
926 assert(dc = GetDC(NULL));
927 oldFont = SelectObject(dc, font);
928 assert(GetTextMetrics(dc, &metrics));
929 SelectObject(dc, oldFont);
930 ReleaseDC(NULL, dc);
932 /* Windows' edit control has some bugs in multi-line mode:
933 * - Sometimes the format rectangle doesn't get updated
934 * (see workaround in set_client_height())
935 * - If the height of the control is smaller than the height of a text
936 * line, the format rectangle is still as high as a text line
937 * (higher than the client rectangle) and the caret is not shown
940 /* Edit controls that are in a parent window */
942 hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
943 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
944 if (single_line)
945 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
946 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
947 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
948 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
949 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
950 destroy_child_editcontrol(hwEdit);
952 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
953 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
954 if (single_line)
955 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
956 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
957 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
958 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
959 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
960 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
961 destroy_child_editcontrol(hwEdit);
963 hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
964 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
965 if (single_line)
966 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
967 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
968 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
969 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
970 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
971 destroy_child_editcontrol(hwEdit);
973 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
974 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
975 if (single_line)
976 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
977 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
978 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
979 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
980 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
981 destroy_child_editcontrol(hwEdit);
984 /* Edit controls that are popup windows */
986 hwEdit = create_editcontrol(style | WS_POPUP, 0);
987 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
988 if (single_line)
989 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
990 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
991 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
992 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
993 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
994 DestroyWindow(hwEdit);
996 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
997 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
998 if (single_line)
999 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
1000 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
1001 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
1002 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
1003 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
1004 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
1005 DestroyWindow(hwEdit);
1007 hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
1008 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1009 if (single_line)
1010 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1011 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1012 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1013 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1014 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1015 DestroyWindow(hwEdit);
1017 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
1018 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1019 if (single_line)
1020 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1021 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1022 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1023 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1024 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1025 DestroyWindow(hwEdit);
1028 static void test_text_position(void)
1030 trace("EDIT: Text position (Single line)\n");
1031 test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1032 trace("EDIT: Text position (Multi line)\n");
1033 test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1036 static void test_espassword(void)
1038 HWND hwEdit;
1039 LONG r;
1040 char buffer[1024];
1041 const char* password = "secret";
1043 hwEdit = create_editcontrol(ES_PASSWORD, 0);
1044 r = get_edit_style(hwEdit);
1045 ok(r == ES_PASSWORD, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD, r);
1046 /* set text */
1047 r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
1048 ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
1050 /* select all, cut (ctrl-x) */
1051 SendMessage(hwEdit, EM_SETSEL, 0, -1);
1052 SendMessage(hwEdit, WM_CHAR, 24, 0);
1054 /* get text */
1055 r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1056 ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
1057 ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
1059 r = OpenClipboard(hwEdit);
1060 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1061 r = EmptyClipboard();
1062 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1063 r = CloseClipboard();
1064 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1066 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1067 SendMessage(hwEdit, EM_SETSEL, 0, -1);
1068 SendMessage(hwEdit, WM_CHAR, 3, 0);
1069 SendMessage(hwEdit, WM_CHAR, 22, 0);
1071 /* get text */
1072 buffer[0] = 0;
1073 r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1074 ok(r == 0, "Expected: 0, got: %d\n", r);
1075 ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
1077 DestroyWindow (hwEdit);
1080 static void test_undo(void)
1082 HWND hwEdit;
1083 LONG r;
1084 DWORD cpMin, cpMax;
1085 char buffer[1024];
1086 const char* text = "undo this";
1088 hwEdit = create_editcontrol(0, 0);
1089 r = get_edit_style(hwEdit);
1090 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1092 /* set text */
1093 r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
1094 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1096 /* select all, */
1097 cpMin = cpMax = 0xdeadbeef;
1098 SendMessage(hwEdit, EM_SETSEL, 0, -1);
1099 r = SendMessage(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
1100 ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
1101 ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
1102 ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
1104 /* cut (ctrl-x) */
1105 r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1106 todo_wine { ok(1 == r, "Expected: %d, got: %d\n", 1, r); }
1108 /* get text */
1109 buffer[0] = 0;
1110 r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1111 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1112 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1114 /* undo (ctrl-z) */
1115 r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1116 todo_wine { ok(1 == r, "Expected: %d, got: %d\n", 1, r); }
1118 /* get text */
1119 buffer[0] = 0;
1120 r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1121 ok(strlen(text) == r, "Unexpected length %d\n", r);
1122 ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
1124 /* undo again (ctrl-z) */
1125 r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1126 todo_wine { ok(1 == r, "Expected: %d, got: %d\n", 1, r); }
1128 /* get text */
1129 buffer[0] = 0;
1130 r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1131 ok(r == 0, "Expected: %d, got len %d\n", 0, r);
1132 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1134 DestroyWindow (hwEdit);
1137 static BOOL RegisterWindowClasses (void)
1139 WNDCLASSA test2;
1140 WNDCLASSA test3;
1141 WNDCLASSA text_position;
1143 test2.style = 0;
1144 test2.lpfnWndProc = ET2_WndProc;
1145 test2.cbClsExtra = 0;
1146 test2.cbWndExtra = 0;
1147 test2.hInstance = hinst;
1148 test2.hIcon = NULL;
1149 test2.hCursor = LoadCursorA (NULL, IDC_ARROW);
1150 test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1151 test2.lpszMenuName = NULL;
1152 test2.lpszClassName = szEditTest2Class;
1153 if (!RegisterClassA(&test2)) return FALSE;
1155 test3.style = 0;
1156 test3.lpfnWndProc = edit3_wnd_procA;
1157 test3.cbClsExtra = 0;
1158 test3.cbWndExtra = 0;
1159 test3.hInstance = hinst;
1160 test3.hIcon = 0;
1161 test3.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1162 test3.hbrBackground = GetStockObject(WHITE_BRUSH);
1163 test3.lpszMenuName = NULL;
1164 test3.lpszClassName = szEditTest3Class;
1165 if (!RegisterClassA(&test3)) return FALSE;
1167 text_position.style = CS_HREDRAW | CS_VREDRAW;
1168 text_position.cbClsExtra = 0;
1169 text_position.cbWndExtra = 0;
1170 text_position.hInstance = hinst;
1171 text_position.hIcon = NULL;
1172 text_position.hCursor = LoadCursorA(NULL, IDC_ARROW);
1173 text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1174 text_position.lpszMenuName = NULL;
1175 text_position.lpszClassName = szEditTextPositionClass;
1176 text_position.lpfnWndProc = DefWindowProc;
1177 if (!RegisterClassA(&text_position)) return FALSE;
1179 return TRUE;
1182 static void UnregisterWindowClasses (void)
1184 UnregisterClassA(szEditTest2Class, hinst);
1185 UnregisterClassA(szEditTest3Class, hinst);
1186 UnregisterClassA(szEditTextPositionClass, hinst);
1189 START_TEST(edit)
1191 hinst = GetModuleHandleA(NULL);
1192 assert(RegisterWindowClasses());
1194 test_edit_control_1();
1195 test_edit_control_2();
1196 test_edit_control_3();
1197 test_edit_control_4();
1198 test_edit_control_5();
1199 test_edit_control_limittext();
1200 test_margins();
1201 test_margins_font_change();
1202 test_text_position();
1203 test_espassword();
1204 test_undo();
1206 UnregisterWindowClasses();