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
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 INT_PTR CALLBACK
edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
46 HWND hedit
= GetDlgItem(hdlg
, 1000);
52 PostMessage(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
55 PostMessage(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
58 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
59 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 1);
62 /* more test cases for WM_CHAR */
64 PostMessage(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
65 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 0);
68 PostMessage(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
69 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 0);
72 PostMessage(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
73 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 0);
76 /* more test cases for WM_KEYDOWN + WM_CHAR */
78 PostMessage(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
79 PostMessage(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
80 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 0);
83 PostMessage(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
84 PostMessage(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
85 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 1);
88 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
89 PostMessage(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
90 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 1);
100 if (HIWORD(wparam
) != BN_CLICKED
)
103 switch (LOWORD(wparam
))
106 EndDialog(hdlg
, 111);
110 EndDialog(hdlg
, 222);
121 HWND hok
= GetDlgItem(hdlg
, IDOK
);
122 HWND hedit
= GetDlgItem(hdlg
, 1000);
124 if (wparam
!= 0xdeadbeef)
130 len
= SendMessage(hedit
, WM_GETTEXTLENGTH
, 0, 0);
132 EndDialog(hdlg
, 444);
134 EndDialog(hdlg
, 555);
138 len
= SendMessage(hedit
, WM_GETTEXTLENGTH
, 0, 0);
139 if ((GetFocus() == hok
) && len
== 0)
140 EndDialog(hdlg
, 444);
142 EndDialog(hdlg
, 555);
146 EndDialog(hdlg
, 555);
152 EndDialog(hdlg
, 333);
162 static HINSTANCE hinst
;
164 static const char szEditTest2Class
[] = "EditTest2Class";
165 static const char szEditTest3Class
[] = "EditTest3Class";
166 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
168 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
172 handle
= CreateWindowEx(exstyle
,
177 NULL
, NULL
, hinst
, NULL
);
179 if (winetest_interactive
)
180 ShowWindow (handle
, SW_SHOW
);
184 static HWND
create_child_editcontrol (DWORD style
, DWORD exstyle
)
194 assert(AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
));
196 parentWnd
= CreateWindowEx(0,
197 szEditTextPositionClass
,
200 CW_USEDEFAULT
, CW_USEDEFAULT
,
201 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
202 NULL
, NULL
, hinst
, NULL
);
205 editWnd
= CreateWindowEx(exstyle
,
210 parentWnd
, NULL
, hinst
, NULL
);
212 if (winetest_interactive
)
213 ShowWindow (parentWnd
, SW_SHOW
);
217 static void destroy_child_editcontrol (HWND hwndEdit
)
219 if (GetParent(hwndEdit
))
220 DestroyWindow(GetParent(hwndEdit
));
222 trace("Edit control has no parent!\n");
223 DestroyWindow(hwndEdit
);
227 static LONG
get_edit_style (HWND hwnd
)
229 return GetWindowLongA( hwnd
, GWL_STYLE
) & (
231 /* FIXME: not implemented
250 static void set_client_height(HWND Wnd
, unsigned Height
)
252 RECT ClientRect
, WindowRect
;
254 GetWindowRect(Wnd
, &WindowRect
);
255 GetClientRect(Wnd
, &ClientRect
);
256 SetWindowPos(Wnd
, NULL
, 0, 0,
257 WindowRect
.right
- WindowRect
.left
,
258 Height
+ (WindowRect
.bottom
- WindowRect
.top
) -
259 (ClientRect
.bottom
- ClientRect
.top
),
260 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
262 /* Workaround for a bug in Windows' edit control
264 GetWindowRect(Wnd
, &WindowRect
);
265 SetWindowPos(Wnd
, NULL
, 0, 0,
266 WindowRect
.right
- WindowRect
.left
+ 1,
267 WindowRect
.bottom
- WindowRect
.top
+ 1,
268 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
269 SetWindowPos(Wnd
, NULL
, 0, 0,
270 WindowRect
.right
- WindowRect
.left
,
271 WindowRect
.bottom
- WindowRect
.top
,
272 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
274 GetClientRect(Wnd
, &ClientRect
);
275 ok(ClientRect
.bottom
- ClientRect
.top
== Height
,
276 "The client height should be %ld, but is %ld\n",
277 (long)Height
, (long)(ClientRect
.bottom
- ClientRect
.top
));
280 static void test_edit_control_1(void)
287 msMessage
.message
= WM_KEYDOWN
;
289 trace("EDIT: Single line\n");
290 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
291 r
= get_edit_style(hwEdit
);
292 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
), "Wrong style expected 0xc0 got: 0x%x\n", r
);
293 for (i
=0;i
<65535;i
++)
295 msMessage
.wParam
= i
;
296 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
297 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
298 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
300 DestroyWindow (hwEdit
);
302 trace("EDIT: Single line want returns\n");
303 hwEdit
= create_editcontrol(ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
304 r
= get_edit_style(hwEdit
);
305 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
| ES_WANTRETURN
), "Wrong style expected 0x10c0 got: 0x%x\n", r
);
306 for (i
=0;i
<65535;i
++)
308 msMessage
.wParam
= i
;
309 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
310 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
311 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
313 DestroyWindow (hwEdit
);
315 trace("EDIT: Multiline line\n");
316 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
317 r
= get_edit_style(hwEdit
);
318 ok(r
== (ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0xc4 got: 0x%x\n", r
);
319 for (i
=0;i
<65535;i
++)
321 msMessage
.wParam
= i
;
322 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
323 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
324 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
326 DestroyWindow (hwEdit
);
328 trace("EDIT: Multi line want returns\n");
329 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
330 r
= get_edit_style(hwEdit
);
331 ok(r
== (ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0x10c4 got: 0x%x\n", r
);
332 for (i
=0;i
<65535;i
++)
334 msMessage
.wParam
= i
;
335 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
336 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
337 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
339 DestroyWindow (hwEdit
);
342 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
343 * selection. This test checks that the first 'select all' doesn't generate
344 * an UPDATE message which can escape and (via a handler) change the
345 * selection, which would cause WM_SETTEXT to break. This old bug
346 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
348 static void test_edit_control_2(void)
351 char szLocalString
[MAXLEN
];
353 /* Create main and edit windows. */
354 hwndMain
= CreateWindow(szEditTest2Class
, "ET2", WS_OVERLAPPEDWINDOW
,
355 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
357 if (winetest_interactive
)
358 ShowWindow (hwndMain
, SW_SHOW
);
360 hwndET2
= CreateWindow("EDIT", NULL
,
361 WS_CHILD
|WS_BORDER
|ES_LEFT
|ES_AUTOHSCROLL
,
362 0, 0, 150, 50, /* important this not be 0 size. */
363 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
365 if (winetest_interactive
)
366 ShowWindow (hwndET2
, SW_SHOW
);
368 trace("EDIT: SETTEXT atomicity\n");
369 /* Send messages to "type" in the word 'foo'. */
370 SendMessage(hwndET2
, WM_CHAR
, 'f', 1);
371 SendMessage(hwndET2
, WM_CHAR
, 'o', 1);
372 SendMessage(hwndET2
, WM_CHAR
, 'o', 1);
373 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
374 GetWindowText(hwndET2
, szLocalString
, MAXLEN
);
375 ok(lstrcmp(szLocalString
, "bar")==0,
376 "Wrong contents of edit: %s\n", szLocalString
);
379 DestroyWindow (hwndET2
);
380 DestroyWindow (hwndMain
);
383 static void ET2_check_change(void) {
384 char szLocalString
[MAXLEN
];
385 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
386 GetWindowText(hwndET2
, szLocalString
, MAXLEN
);
387 if (lstrcmp(szLocalString
, "foo")==0) {
388 lstrcpy(szLocalString
, "bar");
389 SendMessage(hwndET2
, WM_SETTEXT
, 0, (LPARAM
) szLocalString
);
391 /* always leave the cursor at the end. */
392 SendMessage(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
394 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
396 if (id
==ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
399 static LRESULT CALLBACK
ET2_WndProc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
403 ET2_OnCommand(hwnd
, LOWORD(wParam
), (HWND
)lParam
, HIWORD(wParam
));
406 return DefWindowProc(hwnd
, iMsg
, wParam
, lParam
);
409 static void zero_notify(void)
411 notifications
.en_change
= 0;
412 notifications
.en_maxtext
= 0;
413 notifications
.en_update
= 0;
416 #define test_notify(enchange, enmaxtext, enupdate) \
417 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
418 "got %d\n", enchange, notifications.en_change); \
419 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
420 "got %d\n", enmaxtext, notifications.en_maxtext); \
421 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
422 "got %d\n", enupdate, notifications.en_update)
425 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
429 switch (HIWORD(wParam
)) {
431 notifications
.en_maxtext
++;
434 notifications
.en_update
++;
437 notifications
.en_change
++;
442 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
445 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
448 static void test_edit_control_3(void)
453 static const char *str
= "this is a long string.";
454 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.";
456 trace("EDIT: Test notifications\n");
458 hParent
= CreateWindowExA(0,
462 CW_USEDEFAULT
, CW_USEDEFAULT
, 10, 10,
463 NULL
, NULL
, NULL
, NULL
);
466 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
467 hWnd
= CreateWindowExA(0,
472 hParent
, NULL
, NULL
, NULL
);
476 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
477 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
478 ok(lstrlenA(str
) > len
, "text should have been truncated\n");
479 test_notify(1, 1, 1);
481 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
483 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
484 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
485 ok(1 == len
, "wrong text length, expected 1, got %d\n", len
);
486 test_notify(1, 0, 1);
489 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
490 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
491 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
492 test_notify(1, 0, 1);
494 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
496 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
498 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
499 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
500 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
501 test_notify(1, 1, 1);
504 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
505 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
506 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
507 test_notify(1, 0, 1);
511 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
512 hWnd
= CreateWindowExA(0,
517 hParent
, NULL
, NULL
, NULL
);
521 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
522 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
523 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
524 test_notify(1, 0, 1);
527 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
528 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
529 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
530 test_notify(1, 0, 1);
532 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
534 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
536 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
537 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
538 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
539 test_notify(1, 1, 1);
542 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
543 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
544 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
545 test_notify(1, 0, 1);
549 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
550 hWnd
= CreateWindowExA(0,
555 hParent
, NULL
, NULL
, NULL
);
559 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
560 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
561 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
562 test_notify(1, 1, 1);
564 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
566 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
567 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
568 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
569 test_notify(1, 0, 1);
572 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
573 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
574 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
575 test_notify(0, 0, 0);
577 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
579 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
581 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
582 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
583 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
584 test_notify(1, 1, 1);
587 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
588 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
589 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
590 test_notify(0, 0, 0);
594 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
595 hWnd
= CreateWindowExA(0,
598 ES_MULTILINE
| ES_AUTOHSCROLL
,
600 hParent
, NULL
, NULL
, NULL
);
604 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
605 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
606 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
607 test_notify(1, 1, 1);
609 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
611 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
612 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
613 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
614 test_notify(1, 0, 1);
617 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
618 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
619 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
620 test_notify(0, 0, 0);
622 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
624 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
626 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
627 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
628 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
629 test_notify(1, 1, 1);
632 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
633 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
634 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
635 test_notify(0, 0, 0);
639 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
640 hWnd
= CreateWindowExA(0,
643 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
645 hParent
, NULL
, NULL
, NULL
);
649 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
650 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
651 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
652 test_notify(1, 0, 1);
655 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
656 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
657 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
658 test_notify(0, 0, 0);
660 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
662 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
664 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
665 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
666 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
667 test_notify(1, 1, 1);
670 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
671 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
672 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
673 test_notify(0, 0, 0);
678 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
680 static void test_edit_control_4(void)
687 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
688 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
689 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
690 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
691 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
692 mid
= lo
+ (hi
- lo
) / 2;
694 for (i
= lo
; i
< mid
; i
++) {
695 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
696 ok(0 == ret
, "expected 0 got %d\n", ret
);
698 for (i
= mid
; i
<= hi
; i
++) {
699 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
700 ok(1 == ret
, "expected 1 got %d\n", ret
);
702 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
703 ok(-1 == ret
, "expected -1 got %d\n", ret
);
704 DestroyWindow(hwEdit
);
706 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
707 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
708 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
709 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
710 mid
= lo
+ (hi
- lo
) / 2;
712 for (i
= lo
; i
< mid
; i
++) {
713 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
714 ok(0 == ret
, "expected 0 got %d\n", ret
);
716 for (i
= mid
; i
<= hi
; i
++) {
717 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
718 ok(1 == ret
, "expected 1 got %d\n", ret
);
720 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
721 ok(-1 == ret
, "expected -1 got %d\n", ret
);
722 DestroyWindow(hwEdit
);
724 hwEdit
= create_editcontrol(ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
725 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
726 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
727 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
728 mid
= lo
+ (hi
- lo
) / 2;
730 for (i
= lo
; i
< mid
; i
++) {
731 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
732 ok(0 == ret
, "expected 0 got %d\n", ret
);
734 for (i
= mid
; i
<= hi
; i
++) {
735 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
736 ok(1 == ret
, "expected 1 got %d\n", ret
);
738 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
739 ok(-1 == ret
, "expected -1 got %d\n", ret
);
740 DestroyWindow(hwEdit
);
742 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
743 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
744 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
745 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
746 mid
= lo
+ (hi
- lo
) / 2 +1;
748 for (i
= lo
; i
< mid
; i
++) {
749 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
750 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
752 for (i
= mid
; i
<= hi
; i
++) {
753 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
754 ok(1 == ret
, "expected 1 got %d\n", ret
);
756 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
757 ok(-1 == ret
, "expected -1 got %d\n", ret
);
758 DestroyWindow(hwEdit
);
760 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
761 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
762 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
763 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
764 mid
= lo
+ (hi
- lo
) / 2 +1;
766 for (i
= lo
; i
< mid
; i
++) {
767 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
768 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
770 for (i
= mid
; i
<= hi
; i
++) {
771 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
772 ok(1 == ret
, "expected 1 got %d\n", ret
);
774 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
775 ok(-1 == ret
, "expected -1 got %d\n", ret
);
776 DestroyWindow(hwEdit
);
778 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
779 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
780 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
781 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
782 mid
= lo
+ (hi
- lo
) / 2 +1;
784 for (i
= lo
; i
< mid
; i
++) {
785 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
786 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
788 for (i
= mid
; i
<= hi
; i
++) {
789 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
790 ok(1 == ret
, "expected 1 got %d\n", ret
);
792 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
793 ok(-1 == ret
, "expected -1 got %d\n", ret
);
794 DestroyWindow(hwEdit
);
797 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
798 * truncates text that doesn't fit.
800 static void test_edit_control_5(void)
802 static const char *str
= "test\r\ntest";
806 hWnd
= CreateWindowEx(0,
811 NULL
, NULL
, NULL
, NULL
);
814 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
815 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
818 hWnd
= CreateWindowEx(0,
823 NULL
, NULL
, NULL
, NULL
);
826 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
827 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
831 static void test_edit_control_limittext(void)
836 /* Test default limit for single-line control */
837 trace("EDIT: buffer limit for single-line\n");
838 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
839 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
840 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
841 SendMessage(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
842 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
843 /* Win9x+ME: 32766; WinNT: 2147483646UL */
844 ok( (r
== 32766) || (r
== 2147483646UL),
845 "got limit %u (expected 32766 or 2147483646)\n", r
);
846 DestroyWindow(hwEdit
);
848 /* Test default limit for multi-line control */
849 trace("EDIT: buffer limit for multi-line\n");
850 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
851 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
852 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
853 SendMessage(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
854 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
855 /* Win9x+ME: 65535; WinNT: 4294967295UL */
856 ok( (r
== 65535) || (r
== 4294967295UL),
857 "got limit %u (expected 65535 or 4294967295)\n", r
);
858 DestroyWindow(hwEdit
);
861 static void test_margins(void)
864 RECT old_rect
, new_rect
;
865 INT old_left_margin
, old_right_margin
;
866 DWORD old_margins
, new_margins
;
868 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
870 old_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
871 old_left_margin
= LOWORD(old_margins
);
872 old_right_margin
= HIWORD(old_margins
);
874 /* Check if setting the margins works */
876 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
877 new_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
878 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
879 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
881 SendMessage(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
882 new_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
883 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
884 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
887 /* The size of the rectangle must decrease if we increase the margin */
889 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
890 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
891 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
892 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
893 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
894 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
895 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
896 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
899 /* If we set the margin to same value as the current margin,
900 the rectangle must not change */
902 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
906 old_rect
.bottom
= 99;
907 SendMessage(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
908 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
909 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
910 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
911 ok(new_rect
.left
== old_rect
.left
, "The left border of the rectangle has changed\n");
912 ok(new_rect
.right
== old_rect
.right
, "The right border of the rectangle has changed\n");
913 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle has changed\n");
914 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle has changed\n");
916 DestroyWindow (hwEdit
);
919 static INT CALLBACK
find_font_proc(const LOGFONT
*elf
, const TEXTMETRIC
*ntm
, DWORD type
, LPARAM lParam
)
924 static void test_margins_font_change(void)
927 DWORD margins
, font_margins
;
932 if(EnumFontFamiliesA(hdc
, "Arial", find_font_proc
, 0))
934 trace("Arial not found - skipping font change margin tests\n");
940 hwEdit
= create_child_editcontrol(0, 0);
942 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
944 memset(&lf
, 0, sizeof(lf
));
945 strcpy(lf
.lfFaceName
, "Arial");
947 lf
.lfCharSet
= DEFAULT_CHARSET
;
948 hfont
= CreateFontIndirectA(&lf
);
950 hfont2
= CreateFontIndirectA(&lf
);
952 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
953 font_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
954 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
955 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
957 /* With 'small' edit controls, test that the margin doesn't get set */
958 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
959 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
960 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
961 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
962 ok(LOWORD(margins
) == 0, "got %d\n", LOWORD(margins
));
963 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
965 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
966 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
967 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
968 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
969 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
971 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
972 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
973 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
974 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
975 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
977 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
978 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
979 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
980 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
981 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
982 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
983 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
984 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
986 /* Above a certain size threshold then the margin is updated */
987 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
988 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
989 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
990 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
991 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
992 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
994 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
995 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
996 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
997 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
998 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1000 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1001 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1002 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1003 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1004 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1005 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1006 ok(LOWORD(margins
) != LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1007 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1009 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
1011 DeleteObject(hfont2
);
1012 DeleteObject(hfont
);
1013 destroy_child_editcontrol(hwEdit
);
1017 #define edit_pos_ok(exp, got, txt) \
1018 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1020 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1024 set_client_height(hwEdit, set_height); \
1025 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1026 left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
1027 edit_pos_ok(test_top, format_rect.top, vertical position); \
1028 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1029 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1032 static void test_text_position_style(DWORD style
)
1035 HFONT font
, oldFont
;
1039 BOOL single_line
= !(style
& ES_MULTILINE
);
1041 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
1046 /* Get a stock font for which we can determine the metrics */
1047 assert(font
= GetStockObject(SYSTEM_FONT
));
1048 assert(dc
= GetDC(NULL
));
1049 oldFont
= SelectObject(dc
, font
);
1050 assert(GetTextMetrics(dc
, &metrics
));
1051 SelectObject(dc
, oldFont
);
1052 ReleaseDC(NULL
, dc
);
1054 /* Windows' edit control has some bugs in multi-line mode:
1055 * - Sometimes the format rectangle doesn't get updated
1056 * (see workaround in set_client_height())
1057 * - If the height of the control is smaller than the height of a text
1058 * line, the format rectangle is still as high as a text line
1059 * (higher than the client rectangle) and the caret is not shown
1062 /* Edit controls that are in a parent window */
1064 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
1065 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1067 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1068 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1069 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1070 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1071 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1072 destroy_child_editcontrol(hwEdit
);
1074 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
1075 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1077 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1078 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1079 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1080 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1081 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1082 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1083 destroy_child_editcontrol(hwEdit
);
1085 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1086 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1088 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1089 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1090 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1091 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1092 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1093 destroy_child_editcontrol(hwEdit
);
1095 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1096 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1098 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1099 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1100 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1101 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1102 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1103 destroy_child_editcontrol(hwEdit
);
1106 /* Edit controls that are popup windows */
1108 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
1109 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1111 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1112 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1113 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1114 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1115 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1116 DestroyWindow(hwEdit
);
1118 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
1119 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1121 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1122 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1123 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1124 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1125 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1126 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1127 DestroyWindow(hwEdit
);
1129 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
1130 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1132 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1133 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1134 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1135 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1136 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1137 DestroyWindow(hwEdit
);
1139 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
1140 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1142 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1143 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1144 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1145 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1146 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1147 DestroyWindow(hwEdit
);
1150 static void test_text_position(void)
1152 trace("EDIT: Text position (Single line)\n");
1153 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1154 trace("EDIT: Text position (Multi line)\n");
1155 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1158 static void test_espassword(void)
1163 const char* password
= "secret";
1165 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
1166 r
= get_edit_style(hwEdit
);
1167 ok(r
== ES_PASSWORD
, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD
, r
);
1169 r
= SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
1170 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
1172 /* select all, cut (ctrl-x) */
1173 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1174 SendMessage(hwEdit
, WM_CHAR
, 24, 0);
1177 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1178 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
1179 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
1181 r
= OpenClipboard(hwEdit
);
1182 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1183 r
= EmptyClipboard();
1184 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1185 r
= CloseClipboard();
1186 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1188 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1189 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1190 SendMessage(hwEdit
, WM_CHAR
, 3, 0);
1191 SendMessage(hwEdit
, WM_CHAR
, 22, 0);
1195 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1196 ok(r
== 0, "Expected: 0, got: %d\n", r
);
1197 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
1199 DestroyWindow (hwEdit
);
1202 static void test_undo(void)
1208 const char* text
= "undo this";
1210 hwEdit
= create_editcontrol(0, 0);
1211 r
= get_edit_style(hwEdit
);
1212 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1215 r
= SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
1216 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1219 cpMin
= cpMax
= 0xdeadbeef;
1220 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1221 r
= SendMessage(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
1222 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
1223 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
1224 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
1227 r
= SendMessage(hwEdit
, WM_CHAR
, 24, 0);
1228 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1232 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1233 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1234 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1237 r
= SendMessage(hwEdit
, WM_CHAR
, 26, 0);
1238 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1242 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1243 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
1244 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
1246 /* undo again (ctrl-z) */
1247 r
= SendMessage(hwEdit
, WM_CHAR
, 26, 0);
1248 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1252 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1253 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
1254 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1256 DestroyWindow (hwEdit
);
1259 static void test_edit_dialog(void)
1263 /* from bug 11841 */
1264 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 0);
1265 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
1266 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 1);
1267 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
1268 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 2);
1269 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1271 /* more tests for WM_CHAR */
1272 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 3);
1273 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1274 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 4);
1275 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1276 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 5);
1277 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1279 /* more tests for WM_KEYDOWN + WM_CHAR */
1280 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 6);
1281 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1282 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 7);
1283 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1284 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 8);
1285 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1287 /* tests with an editable edit control */
1288 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 0);
1289 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
1290 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 1);
1291 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
1292 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 2);
1293 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1295 /* tests for WM_CHAR */
1296 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 3);
1297 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1298 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 4);
1299 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1300 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 5);
1301 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1303 /* tests for WM_KEYDOWN + WM_CHAR */
1304 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 6);
1305 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1306 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 7);
1307 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1308 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 8);
1309 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1312 static BOOL
RegisterWindowClasses (void)
1316 WNDCLASSA text_position
;
1319 test2
.lpfnWndProc
= ET2_WndProc
;
1320 test2
.cbClsExtra
= 0;
1321 test2
.cbWndExtra
= 0;
1322 test2
.hInstance
= hinst
;
1324 test2
.hCursor
= LoadCursorA (NULL
, IDC_ARROW
);
1325 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1326 test2
.lpszMenuName
= NULL
;
1327 test2
.lpszClassName
= szEditTest2Class
;
1328 if (!RegisterClassA(&test2
)) return FALSE
;
1331 test3
.lpfnWndProc
= edit3_wnd_procA
;
1332 test3
.cbClsExtra
= 0;
1333 test3
.cbWndExtra
= 0;
1334 test3
.hInstance
= hinst
;
1336 test3
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
1337 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
1338 test3
.lpszMenuName
= NULL
;
1339 test3
.lpszClassName
= szEditTest3Class
;
1340 if (!RegisterClassA(&test3
)) return FALSE
;
1342 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
1343 text_position
.cbClsExtra
= 0;
1344 text_position
.cbWndExtra
= 0;
1345 text_position
.hInstance
= hinst
;
1346 text_position
.hIcon
= NULL
;
1347 text_position
.hCursor
= LoadCursorA(NULL
, IDC_ARROW
);
1348 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1349 text_position
.lpszMenuName
= NULL
;
1350 text_position
.lpszClassName
= szEditTextPositionClass
;
1351 text_position
.lpfnWndProc
= DefWindowProc
;
1352 if (!RegisterClassA(&text_position
)) return FALSE
;
1357 static void UnregisterWindowClasses (void)
1359 UnregisterClassA(szEditTest2Class
, hinst
);
1360 UnregisterClassA(szEditTest3Class
, hinst
);
1361 UnregisterClassA(szEditTextPositionClass
, hinst
);
1366 hinst
= GetModuleHandleA(NULL
);
1367 assert(RegisterWindowClasses());
1369 test_edit_control_1();
1370 test_edit_control_2();
1371 test_edit_control_3();
1372 test_edit_control_4();
1373 test_edit_control_5();
1374 test_edit_control_limittext();
1376 test_margins_font_change();
1377 test_text_position();
1382 UnregisterWindowClasses();