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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/test.h"
28 #define ES_COMBO 0x200
31 #define ID_EDITTEST2 99
35 int en_change, en_maxtext, en_update;
38 static struct edit_notify notifications;
40 static HINSTANCE hinst;
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)
50 handle = CreateWindowEx(exstyle,
55 NULL, NULL, hinst, NULL);
57 if (winetest_interactive)
58 ShowWindow (handle, SW_SHOW);
62 static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
72 assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
74 parentWnd = CreateWindowEx(0,
75 szEditTextPositionClass,
78 CW_USEDEFAULT, CW_USEDEFAULT,
79 rect.right - rect.left, rect.bottom - rect.top,
80 NULL, NULL, hinst, NULL);
83 editWnd = CreateWindowEx(exstyle,
88 parentWnd, NULL, hinst, NULL);
90 if (winetest_interactive)
91 ShowWindow (parentWnd, SW_SHOW);
95 static void destroy_child_editcontrol (HWND hwndEdit)
97 if (GetParent(hwndEdit))
98 DestroyWindow(GetParent(hwndEdit));
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 ) & (
109 /* FIXME: not implemented
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
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)
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%lx\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 %lx\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%lx\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 %lx\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%lx\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 %lx\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%lx\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 %lx\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)
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);
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);
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);
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)
277 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
281 ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
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)
307 switch (HIWORD(wParam)) {
309 notifications.en_maxtext++;
312 notifications.en_update++;
315 notifications.en_change++;
320 return DefWindowProcA(hWnd, msg, wParam, lParam);
323 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
326 static void test_edit_control_3(void)
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,
340 CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
341 NULL, NULL, NULL, NULL);
344 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
345 hWnd = CreateWindowExA(0,
350 hParent, NULL, NULL, NULL);
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)"");
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);
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)"");
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);
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);
389 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
390 hWnd = CreateWindowExA(0,
395 hParent, NULL, NULL, NULL);
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);
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)"");
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);
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);
427 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
428 hWnd = CreateWindowExA(0,
433 hParent, NULL, NULL, NULL);
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)"");
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);
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)"");
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);
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);
472 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
473 hWnd = CreateWindowExA(0,
476 ES_MULTILINE | ES_AUTOHSCROLL,
478 hParent, NULL, NULL, NULL);
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)"");
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);
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)"");
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);
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);
517 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
518 hWnd = CreateWindowExA(0,
521 ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
523 hParent, NULL, NULL, NULL);
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);
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)"");
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);
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);
556 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
558 static void test_edit_control_4(void)
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, "expected 0 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, "expected 0 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, "expected 0 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";
684 hWnd = CreateWindowEx(0,
689 NULL, NULL, NULL, NULL);
692 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
693 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
696 hWnd = CreateWindowEx(0,
701 NULL, NULL, NULL, NULL);
704 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
705 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
709 static void test_margins(void)
712 RECT old_rect, new_rect;
713 INT old_left_margin, old_right_margin;
714 DWORD old_margins, new_margins;
716 hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
718 old_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
719 old_left_margin = LOWORD(old_margins);
720 old_right_margin = HIWORD(old_margins);
722 /* Check if setting the margins works */
724 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
725 new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
726 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
727 ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
729 SendMessage(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
730 new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
731 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
732 ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
735 /* The size of the rectangle must decrease if we increase the margin */
737 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
738 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
739 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
740 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
741 ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
742 ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
743 ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
744 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
747 /* If we set the margin to same value as the current margin,
748 the rectangle must not change */
750 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
754 old_rect.bottom = 99;
755 SendMessage(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);
756 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
757 SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
758 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
759 ok(new_rect.left == old_rect.left, "The left border of the rectangle has changed\n");
760 ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n");
761 ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n");
762 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n");
764 DestroyWindow (hwEdit);
767 static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
772 static void test_margins_font_change(void)
775 DWORD margins, font_margins;
780 if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
782 trace("Arial not found - skipping font change margin tests\n");
788 hwEdit = create_child_editcontrol(0, 0);
790 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
792 memset(&lf, 0, sizeof(lf));
793 strcpy(lf.lfFaceName, "Arial");
795 lf.lfCharSet = DEFAULT_CHARSET;
796 hfont = CreateFontIndirectA(&lf);
798 hfont2 = CreateFontIndirectA(&lf);
800 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
801 font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
802 ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
803 ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
805 /* With 'small' edit controls, test that the margin doesn't get set */
806 SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
807 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
808 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
809 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
810 ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins));
811 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
813 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
814 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
815 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
816 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
817 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
819 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
820 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
821 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
822 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
823 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
825 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
826 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
827 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
828 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
829 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
830 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
831 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
832 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
834 /* Above a certain size threshold then the margin is updated */
835 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
836 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
837 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
838 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
839 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
840 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
842 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
843 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
844 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
845 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
846 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
848 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
849 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
850 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
851 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
852 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
853 margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
854 ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins));
855 ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins));
857 SendMessageA(hwEdit, WM_SETFONT, 0, 0);
859 DeleteObject(hfont2);
861 destroy_child_editcontrol(hwEdit);
865 #define edit_pos_ok(exp, got, txt) \
866 ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got);
868 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
872 set_client_height(hwEdit, set_height); \
873 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
874 left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
875 edit_pos_ok(test_top, format_rect.top, vertical position); \
876 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
877 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
880 void test_text_position_style(DWORD style)
887 BOOL single_line = !(style & ES_MULTILINE);
889 b = GetSystemMetrics(SM_CYBORDER) + 1;
894 /* Get a stock font for which we can determine the metrics */
895 assert(font = GetStockObject(SYSTEM_FONT));
896 assert(dc = GetDC(NULL));
897 oldFont = SelectObject(dc, font);
898 assert(GetTextMetrics(dc, &metrics));
899 SelectObject(dc, oldFont);
902 /* Windows' edit control has some bugs in multi-line mode:
903 * - Sometimes the format rectangle doesn't get updated
904 * (see workaround in set_client_height())
905 * - If the height of the control is smaller than the height of a text
906 * line, the format rectangle is still as high as a text line
907 * (higher than the client rectangle) and the caret is not shown
910 /* Edit controls that are in a parent window */
912 hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
913 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
915 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
916 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
917 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
918 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
919 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
920 destroy_child_editcontrol(hwEdit);
922 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
923 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
925 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
926 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
927 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
928 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
929 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
930 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
931 destroy_child_editcontrol(hwEdit);
933 hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
934 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
936 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
937 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
938 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
939 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
940 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
941 destroy_child_editcontrol(hwEdit);
943 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
944 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
946 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
947 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
948 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
949 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
950 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
951 destroy_child_editcontrol(hwEdit);
954 /* Edit controls that are popup windows */
956 hwEdit = create_editcontrol(style | WS_POPUP, 0);
957 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
959 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
960 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
961 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
962 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
963 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
964 DestroyWindow(hwEdit);
966 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
967 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
969 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
970 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
971 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
972 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
973 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
974 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
975 DestroyWindow(hwEdit);
977 hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
978 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
980 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
981 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
982 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
983 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
984 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
985 DestroyWindow(hwEdit);
987 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
988 SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
990 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
991 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
992 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
993 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
994 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
995 DestroyWindow(hwEdit);
998 void test_text_position(void)
1000 trace("EDIT: Text position (Single line)\n");
1001 test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1002 trace("EDIT: Text position (Multi line)\n");
1003 test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1006 static BOOL RegisterWindowClasses (void)
1010 WNDCLASSA text_position;
1013 test2.lpfnWndProc = ET2_WndProc;
1014 test2.cbClsExtra = 0;
1015 test2.cbWndExtra = 0;
1016 test2.hInstance = hinst;
1018 test2.hCursor = LoadCursorA (NULL, IDC_ARROW);
1019 test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1020 test2.lpszMenuName = NULL;
1021 test2.lpszClassName = szEditTest2Class;
1022 if (!RegisterClassA(&test2)) return FALSE;
1025 test3.lpfnWndProc = edit3_wnd_procA;
1026 test3.cbClsExtra = 0;
1027 test3.cbWndExtra = 0;
1028 test3.hInstance = hinst;
1030 test3.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1031 test3.hbrBackground = GetStockObject(WHITE_BRUSH);
1032 test3.lpszMenuName = NULL;
1033 test3.lpszClassName = szEditTest3Class;
1034 if (!RegisterClassA(&test3)) return FALSE;
1036 text_position.style = CS_HREDRAW | CS_VREDRAW;
1037 text_position.cbClsExtra = 0;
1038 text_position.cbWndExtra = 0;
1039 text_position.hInstance = hinst;
1040 text_position.hIcon = NULL;
1041 text_position.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW));
1042 text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1043 text_position.lpszMenuName = NULL;
1044 text_position.lpszClassName = szEditTextPositionClass;
1045 text_position.lpfnWndProc = DefWindowProc;
1046 if (!RegisterClassA(&text_position)) return FALSE;
1051 static void UnregisterWindowClasses (void)
1053 UnregisterClassA(szEditTest2Class, hinst);
1054 UnregisterClassA(szEditTest3Class, hinst);
1055 UnregisterClassA(szEditTextPositionClass, hinst);
1060 hinst = GetModuleHandleA(NULL);
1061 assert(RegisterWindowClasses());
1063 test_edit_control_1();
1064 test_edit_control_2();
1065 test_edit_control_3();
1066 test_edit_control_4();
1067 test_edit_control_5();
1069 test_margins_font_change();
1070 test_text_position();
1072 UnregisterWindowClasses();