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);
93 /* multiple tab tests */
95 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
96 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
97 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 2);
100 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
101 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
102 PostMessage(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
103 PostMessage(hdlg
, WM_USER
, 0xdeadbeef, 2);
113 if (HIWORD(wparam
) != BN_CLICKED
)
116 switch (LOWORD(wparam
))
119 EndDialog(hdlg
, 111);
123 EndDialog(hdlg
, 222);
134 HWND hok
= GetDlgItem(hdlg
, IDOK
);
135 HWND hcancel
= GetDlgItem(hdlg
, IDCANCEL
);
136 HWND hedit
= GetDlgItem(hdlg
, 1000);
137 HWND hfocus
= GetFocus();
139 if (wparam
!= 0xdeadbeef)
145 len
= SendMessage(hedit
, WM_GETTEXTLENGTH
, 0, 0);
147 EndDialog(hdlg
, 444);
149 EndDialog(hdlg
, 555);
153 len
= SendMessage(hedit
, WM_GETTEXTLENGTH
, 0, 0);
154 if ((hfocus
== hok
) && len
== 0)
155 EndDialog(hdlg
, 444);
157 EndDialog(hdlg
, 555);
163 else if (hfocus
== hcancel
)
165 else if (hfocus
== hedit
)
172 EndDialog(hdlg
, 555);
178 EndDialog(hdlg
, 333);
188 static HINSTANCE hinst
;
190 static const char szEditTest2Class
[] = "EditTest2Class";
191 static const char szEditTest3Class
[] = "EditTest3Class";
192 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
194 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
198 handle
= CreateWindowEx(exstyle
,
203 NULL
, NULL
, hinst
, NULL
);
205 if (winetest_interactive
)
206 ShowWindow (handle
, SW_SHOW
);
210 static HWND
create_child_editcontrol (DWORD style
, DWORD exstyle
)
220 assert(AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
));
222 parentWnd
= CreateWindowEx(0,
223 szEditTextPositionClass
,
226 CW_USEDEFAULT
, CW_USEDEFAULT
,
227 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
228 NULL
, NULL
, hinst
, NULL
);
231 editWnd
= CreateWindowEx(exstyle
,
236 parentWnd
, NULL
, hinst
, NULL
);
238 if (winetest_interactive
)
239 ShowWindow (parentWnd
, SW_SHOW
);
243 static void destroy_child_editcontrol (HWND hwndEdit
)
245 if (GetParent(hwndEdit
))
246 DestroyWindow(GetParent(hwndEdit
));
248 trace("Edit control has no parent!\n");
249 DestroyWindow(hwndEdit
);
253 static LONG
get_edit_style (HWND hwnd
)
255 return GetWindowLongA( hwnd
, GWL_STYLE
) & (
257 /* FIXME: not implemented
276 static void set_client_height(HWND Wnd
, unsigned Height
)
278 RECT ClientRect
, WindowRect
;
280 GetWindowRect(Wnd
, &WindowRect
);
281 GetClientRect(Wnd
, &ClientRect
);
282 SetWindowPos(Wnd
, NULL
, 0, 0,
283 WindowRect
.right
- WindowRect
.left
,
284 Height
+ (WindowRect
.bottom
- WindowRect
.top
) -
285 (ClientRect
.bottom
- ClientRect
.top
),
286 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
288 /* Workaround for a bug in Windows' edit control
290 GetWindowRect(Wnd
, &WindowRect
);
291 SetWindowPos(Wnd
, NULL
, 0, 0,
292 WindowRect
.right
- WindowRect
.left
+ 1,
293 WindowRect
.bottom
- WindowRect
.top
+ 1,
294 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
295 SetWindowPos(Wnd
, NULL
, 0, 0,
296 WindowRect
.right
- WindowRect
.left
,
297 WindowRect
.bottom
- WindowRect
.top
,
298 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
300 GetClientRect(Wnd
, &ClientRect
);
301 ok(ClientRect
.bottom
- ClientRect
.top
== Height
,
302 "The client height should be %ld, but is %ld\n",
303 (long)Height
, (long)(ClientRect
.bottom
- ClientRect
.top
));
306 static void test_edit_control_1(void)
313 msMessage
.message
= WM_KEYDOWN
;
315 trace("EDIT: Single line\n");
316 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
317 r
= get_edit_style(hwEdit
);
318 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
), "Wrong style expected 0xc0 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_WANTARROWS
),
324 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
326 DestroyWindow (hwEdit
);
328 trace("EDIT: Single line want returns\n");
329 hwEdit
= create_editcontrol(ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
330 r
= get_edit_style(hwEdit
);
331 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
| ES_WANTRETURN
), "Wrong style expected 0x10c0 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_WANTARROWS
),
337 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
339 DestroyWindow (hwEdit
);
341 trace("EDIT: Multiline line\n");
342 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
343 r
= get_edit_style(hwEdit
);
344 ok(r
== (ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0xc4 got: 0x%x\n", r
);
345 for (i
=0;i
<65535;i
++)
347 msMessage
.wParam
= i
;
348 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
349 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
350 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
352 DestroyWindow (hwEdit
);
354 trace("EDIT: Multi line want returns\n");
355 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
356 r
= get_edit_style(hwEdit
);
357 ok(r
== (ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0x10c4 got: 0x%x\n", r
);
358 for (i
=0;i
<65535;i
++)
360 msMessage
.wParam
= i
;
361 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
362 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
363 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
365 DestroyWindow (hwEdit
);
368 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
369 * selection. This test checks that the first 'select all' doesn't generate
370 * an UPDATE message which can escape and (via a handler) change the
371 * selection, which would cause WM_SETTEXT to break. This old bug
372 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
374 static void test_edit_control_2(void)
377 char szLocalString
[MAXLEN
];
379 /* Create main and edit windows. */
380 hwndMain
= CreateWindow(szEditTest2Class
, "ET2", WS_OVERLAPPEDWINDOW
,
381 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
383 if (winetest_interactive
)
384 ShowWindow (hwndMain
, SW_SHOW
);
386 hwndET2
= CreateWindow("EDIT", NULL
,
387 WS_CHILD
|WS_BORDER
|ES_LEFT
|ES_AUTOHSCROLL
,
388 0, 0, 150, 50, /* important this not be 0 size. */
389 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
391 if (winetest_interactive
)
392 ShowWindow (hwndET2
, SW_SHOW
);
394 trace("EDIT: SETTEXT atomicity\n");
395 /* Send messages to "type" in the word 'foo'. */
396 SendMessage(hwndET2
, WM_CHAR
, 'f', 1);
397 SendMessage(hwndET2
, WM_CHAR
, 'o', 1);
398 SendMessage(hwndET2
, WM_CHAR
, 'o', 1);
399 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
400 GetWindowText(hwndET2
, szLocalString
, MAXLEN
);
401 ok(lstrcmp(szLocalString
, "bar")==0,
402 "Wrong contents of edit: %s\n", szLocalString
);
405 DestroyWindow (hwndET2
);
406 DestroyWindow (hwndMain
);
409 static void ET2_check_change(void) {
410 char szLocalString
[MAXLEN
];
411 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
412 GetWindowText(hwndET2
, szLocalString
, MAXLEN
);
413 if (lstrcmp(szLocalString
, "foo")==0) {
414 lstrcpy(szLocalString
, "bar");
415 SendMessage(hwndET2
, WM_SETTEXT
, 0, (LPARAM
) szLocalString
);
417 /* always leave the cursor at the end. */
418 SendMessage(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
420 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
422 if (id
==ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
425 static LRESULT CALLBACK
ET2_WndProc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
429 ET2_OnCommand(hwnd
, LOWORD(wParam
), (HWND
)lParam
, HIWORD(wParam
));
432 return DefWindowProc(hwnd
, iMsg
, wParam
, lParam
);
435 static void zero_notify(void)
437 notifications
.en_change
= 0;
438 notifications
.en_maxtext
= 0;
439 notifications
.en_update
= 0;
442 #define test_notify(enchange, enmaxtext, enupdate) \
443 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
444 "got %d\n", enchange, notifications.en_change); \
445 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
446 "got %d\n", enmaxtext, notifications.en_maxtext); \
447 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
448 "got %d\n", enupdate, notifications.en_update)
451 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
455 switch (HIWORD(wParam
)) {
457 notifications
.en_maxtext
++;
460 notifications
.en_update
++;
463 notifications
.en_change
++;
468 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
471 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
474 static void test_edit_control_3(void)
479 static const char *str
= "this is a long string.";
480 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.";
482 trace("EDIT: Test notifications\n");
484 hParent
= CreateWindowExA(0,
488 CW_USEDEFAULT
, CW_USEDEFAULT
, 10, 10,
489 NULL
, NULL
, NULL
, NULL
);
492 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
493 hWnd
= CreateWindowExA(0,
498 hParent
, NULL
, NULL
, NULL
);
502 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
503 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
504 ok(lstrlenA(str
) > len
, "text should have been truncated\n");
505 test_notify(1, 1, 1);
507 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
509 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
510 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
511 ok(1 == len
, "wrong text length, expected 1, got %d\n", len
);
512 test_notify(1, 0, 1);
515 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
516 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
517 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
518 test_notify(1, 0, 1);
520 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
522 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
524 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
525 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
526 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
527 test_notify(1, 1, 1);
530 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
531 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
532 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
533 test_notify(1, 0, 1);
537 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
538 hWnd
= CreateWindowExA(0,
543 hParent
, NULL
, NULL
, NULL
);
547 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
548 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
549 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
550 test_notify(1, 0, 1);
553 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
554 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
555 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
556 test_notify(1, 0, 1);
558 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
560 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
562 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
563 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
564 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
565 test_notify(1, 1, 1);
568 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
569 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
570 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
571 test_notify(1, 0, 1);
575 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
576 hWnd
= CreateWindowExA(0,
581 hParent
, NULL
, NULL
, NULL
);
585 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
586 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
587 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
588 test_notify(1, 1, 1);
590 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
592 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
593 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
594 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
595 test_notify(1, 0, 1);
598 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
599 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
600 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
601 test_notify(0, 0, 0);
603 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
605 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
607 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
608 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
609 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
610 test_notify(1, 1, 1);
613 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
614 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
615 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
616 test_notify(0, 0, 0);
620 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
621 hWnd
= CreateWindowExA(0,
624 ES_MULTILINE
| ES_AUTOHSCROLL
,
626 hParent
, NULL
, NULL
, NULL
);
630 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
631 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
632 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
633 test_notify(1, 1, 1);
635 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
637 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
638 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
639 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
640 test_notify(1, 0, 1);
643 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
644 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
645 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
646 test_notify(0, 0, 0);
648 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
650 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
652 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
653 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
654 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
655 test_notify(1, 1, 1);
658 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
659 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
660 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
661 test_notify(0, 0, 0);
665 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
666 hWnd
= CreateWindowExA(0,
669 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
671 hParent
, NULL
, NULL
, NULL
);
675 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
676 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
677 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
678 test_notify(1, 0, 1);
681 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
682 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
683 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
684 test_notify(0, 0, 0);
686 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
688 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
690 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
691 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
692 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
693 test_notify(1, 1, 1);
696 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
697 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
698 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
699 test_notify(0, 0, 0);
704 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
706 static void test_edit_control_4(void)
713 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
714 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
715 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
716 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
717 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
718 mid
= lo
+ (hi
- lo
) / 2;
720 for (i
= lo
; i
< mid
; i
++) {
721 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
722 ok(0 == ret
, "expected 0 got %d\n", ret
);
724 for (i
= mid
; i
<= hi
; i
++) {
725 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
726 ok(1 == ret
, "expected 1 got %d\n", ret
);
728 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
729 ok(-1 == ret
, "expected -1 got %d\n", ret
);
730 DestroyWindow(hwEdit
);
732 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
733 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
734 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
735 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
736 mid
= lo
+ (hi
- lo
) / 2;
738 for (i
= lo
; i
< mid
; i
++) {
739 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
740 ok(0 == ret
, "expected 0 got %d\n", ret
);
742 for (i
= mid
; i
<= hi
; i
++) {
743 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
744 ok(1 == ret
, "expected 1 got %d\n", ret
);
746 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
747 ok(-1 == ret
, "expected -1 got %d\n", ret
);
748 DestroyWindow(hwEdit
);
750 hwEdit
= create_editcontrol(ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
751 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
752 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
753 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
754 mid
= lo
+ (hi
- lo
) / 2;
756 for (i
= lo
; i
< mid
; i
++) {
757 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
758 ok(0 == ret
, "expected 0 got %d\n", ret
);
760 for (i
= mid
; i
<= hi
; i
++) {
761 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
762 ok(1 == ret
, "expected 1 got %d\n", ret
);
764 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
765 ok(-1 == ret
, "expected -1 got %d\n", ret
);
766 DestroyWindow(hwEdit
);
768 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
769 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
770 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
771 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
772 mid
= lo
+ (hi
- lo
) / 2 +1;
774 for (i
= lo
; i
< mid
; i
++) {
775 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
776 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
778 for (i
= mid
; i
<= hi
; i
++) {
779 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
780 ok(1 == ret
, "expected 1 got %d\n", ret
);
782 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
783 ok(-1 == ret
, "expected -1 got %d\n", ret
);
784 DestroyWindow(hwEdit
);
786 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
787 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
788 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
789 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
790 mid
= lo
+ (hi
- lo
) / 2 +1;
792 for (i
= lo
; i
< mid
; i
++) {
793 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
794 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
796 for (i
= mid
; i
<= hi
; i
++) {
797 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
798 ok(1 == ret
, "expected 1 got %d\n", ret
);
800 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
801 ok(-1 == ret
, "expected -1 got %d\n", ret
);
802 DestroyWindow(hwEdit
);
804 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
805 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
806 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
807 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
808 mid
= lo
+ (hi
- lo
) / 2 +1;
810 for (i
= lo
; i
< mid
; i
++) {
811 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
812 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
814 for (i
= mid
; i
<= hi
; i
++) {
815 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
816 ok(1 == ret
, "expected 1 got %d\n", ret
);
818 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
819 ok(-1 == ret
, "expected -1 got %d\n", ret
);
820 DestroyWindow(hwEdit
);
823 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
824 * truncates text that doesn't fit.
826 static void test_edit_control_5(void)
828 static const char *str
= "test\r\ntest";
832 hWnd
= CreateWindowEx(0,
837 NULL
, NULL
, NULL
, NULL
);
840 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
841 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
844 hWnd
= CreateWindowEx(0,
849 NULL
, NULL
, NULL
, NULL
);
852 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
853 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
857 static void test_edit_control_limittext(void)
862 /* Test default limit for single-line control */
863 trace("EDIT: buffer limit for single-line\n");
864 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
865 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
866 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
867 SendMessage(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
868 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
869 /* Win9x+ME: 32766; WinNT: 2147483646UL */
870 ok( (r
== 32766) || (r
== 2147483646UL),
871 "got limit %u (expected 32766 or 2147483646)\n", r
);
872 DestroyWindow(hwEdit
);
874 /* Test default limit for multi-line control */
875 trace("EDIT: buffer limit for multi-line\n");
876 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
877 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
878 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
879 SendMessage(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
880 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
881 /* Win9x+ME: 65535; WinNT: 4294967295UL */
882 ok( (r
== 65535) || (r
== 4294967295UL),
883 "got limit %u (expected 65535 or 4294967295)\n", r
);
884 DestroyWindow(hwEdit
);
887 static void test_margins(void)
890 RECT old_rect
, new_rect
;
891 INT old_left_margin
, old_right_margin
;
892 DWORD old_margins
, new_margins
;
894 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
896 old_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
897 old_left_margin
= LOWORD(old_margins
);
898 old_right_margin
= HIWORD(old_margins
);
900 /* Check if setting the margins works */
902 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
903 new_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
904 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
905 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
907 SendMessage(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
908 new_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
909 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
910 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
913 /* The size of the rectangle must decrease if we increase the margin */
915 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
916 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
917 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
918 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
919 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
920 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
921 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
922 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
925 /* If we set the margin to same value as the current margin,
926 the rectangle must not change */
928 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
932 old_rect
.bottom
= 99;
933 SendMessage(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
934 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
935 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
936 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
937 ok(new_rect
.left
== old_rect
.left
, "The left border of the rectangle has changed\n");
938 ok(new_rect
.right
== old_rect
.right
, "The right border of the rectangle has changed\n");
939 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle has changed\n");
940 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle has changed\n");
942 DestroyWindow (hwEdit
);
945 static INT CALLBACK
find_font_proc(const LOGFONT
*elf
, const TEXTMETRIC
*ntm
, DWORD type
, LPARAM lParam
)
950 static void test_margins_font_change(void)
953 DWORD margins
, font_margins
;
958 if(EnumFontFamiliesA(hdc
, "Arial", find_font_proc
, 0))
960 trace("Arial not found - skipping font change margin tests\n");
966 hwEdit
= create_child_editcontrol(0, 0);
968 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
970 memset(&lf
, 0, sizeof(lf
));
971 strcpy(lf
.lfFaceName
, "Arial");
973 lf
.lfCharSet
= DEFAULT_CHARSET
;
974 hfont
= CreateFontIndirectA(&lf
);
976 hfont2
= CreateFontIndirectA(&lf
);
978 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
979 font_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
980 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
981 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
983 /* With 'small' edit controls, test that the margin doesn't get set */
984 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
985 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
986 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
987 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
988 ok(LOWORD(margins
) == 0, "got %d\n", LOWORD(margins
));
989 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
991 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
992 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
993 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
994 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
995 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
997 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
998 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
999 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1000 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1001 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1003 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1004 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1005 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1006 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1007 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1008 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1009 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1010 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1012 /* Above a certain size threshold then the margin is updated */
1013 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1014 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1015 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1016 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1017 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1018 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1020 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1021 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1022 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1023 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1024 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1026 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1027 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1028 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1029 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1030 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1031 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
1032 ok(LOWORD(margins
) != LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1033 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1035 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
1037 DeleteObject(hfont2
);
1038 DeleteObject(hfont
);
1039 destroy_child_editcontrol(hwEdit
);
1043 #define edit_pos_ok(exp, got, txt) \
1044 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1046 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1050 set_client_height(hwEdit, set_height); \
1051 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1052 left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
1053 edit_pos_ok(test_top, format_rect.top, vertical position); \
1054 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1055 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1058 static void test_text_position_style(DWORD style
)
1061 HFONT font
, oldFont
;
1065 BOOL single_line
= !(style
& ES_MULTILINE
);
1067 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
1072 /* Get a stock font for which we can determine the metrics */
1073 assert(font
= GetStockObject(SYSTEM_FONT
));
1074 assert(dc
= GetDC(NULL
));
1075 oldFont
= SelectObject(dc
, font
);
1076 assert(GetTextMetrics(dc
, &metrics
));
1077 SelectObject(dc
, oldFont
);
1078 ReleaseDC(NULL
, dc
);
1080 /* Windows' edit control has some bugs in multi-line mode:
1081 * - Sometimes the format rectangle doesn't get updated
1082 * (see workaround in set_client_height())
1083 * - If the height of the control is smaller than the height of a text
1084 * line, the format rectangle is still as high as a text line
1085 * (higher than the client rectangle) and the caret is not shown
1088 /* Edit controls that are in a parent window */
1090 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
1091 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1093 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1094 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1095 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1096 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1097 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1098 destroy_child_editcontrol(hwEdit
);
1100 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
1101 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1103 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1104 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1105 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1106 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1107 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1108 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1109 destroy_child_editcontrol(hwEdit
);
1111 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1112 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1114 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1115 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1116 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1117 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1118 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1119 destroy_child_editcontrol(hwEdit
);
1121 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1122 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1124 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1125 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1126 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1127 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1128 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1129 destroy_child_editcontrol(hwEdit
);
1132 /* Edit controls that are popup windows */
1134 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
1135 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1137 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1138 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1139 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1140 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1141 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1142 DestroyWindow(hwEdit
);
1144 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
1145 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1147 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1148 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1149 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1150 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1151 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1152 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1153 DestroyWindow(hwEdit
);
1155 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
1156 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1158 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1159 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1160 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1161 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1162 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1163 DestroyWindow(hwEdit
);
1165 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
1166 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1168 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1169 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1170 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1171 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1172 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1173 DestroyWindow(hwEdit
);
1176 static void test_text_position(void)
1178 trace("EDIT: Text position (Single line)\n");
1179 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1180 trace("EDIT: Text position (Multi line)\n");
1181 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1184 static void test_espassword(void)
1189 const char* password
= "secret";
1191 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
1192 r
= get_edit_style(hwEdit
);
1193 ok(r
== ES_PASSWORD
, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD
, r
);
1195 r
= SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
1196 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
1198 /* select all, cut (ctrl-x) */
1199 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1200 SendMessage(hwEdit
, WM_CHAR
, 24, 0);
1203 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1204 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
1205 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
1207 r
= OpenClipboard(hwEdit
);
1208 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1209 r
= EmptyClipboard();
1210 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1211 r
= CloseClipboard();
1212 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1214 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1215 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1216 SendMessage(hwEdit
, WM_CHAR
, 3, 0);
1217 SendMessage(hwEdit
, WM_CHAR
, 22, 0);
1221 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1222 ok(r
== 0, "Expected: 0, got: %d\n", r
);
1223 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
1225 DestroyWindow (hwEdit
);
1228 static void test_undo(void)
1234 const char* text
= "undo this";
1236 hwEdit
= create_editcontrol(0, 0);
1237 r
= get_edit_style(hwEdit
);
1238 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1241 r
= SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
1242 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1245 cpMin
= cpMax
= 0xdeadbeef;
1246 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1247 r
= SendMessage(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
1248 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
1249 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
1250 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
1253 r
= SendMessage(hwEdit
, WM_CHAR
, 24, 0);
1254 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1258 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1259 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1260 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1263 r
= SendMessage(hwEdit
, WM_CHAR
, 26, 0);
1264 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1268 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1269 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
1270 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
1272 /* undo again (ctrl-z) */
1273 r
= SendMessage(hwEdit
, WM_CHAR
, 26, 0);
1274 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1278 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1279 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
1280 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1282 DestroyWindow (hwEdit
);
1285 static void test_edit_dialog(void)
1289 /* from bug 11841 */
1290 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 0);
1291 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
1292 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 1);
1293 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
1294 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 2);
1295 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1297 /* more tests for WM_CHAR */
1298 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 3);
1299 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1300 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 4);
1301 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1302 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 5);
1303 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1305 /* more tests for WM_KEYDOWN + WM_CHAR */
1306 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 6);
1307 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1308 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 7);
1309 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1310 r
= DialogBoxParam(hinst
, "EDIT_READONLY_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 8);
1311 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1313 /* tests with an editable edit control */
1314 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 0);
1315 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
1316 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 1);
1317 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
1318 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 2);
1319 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1321 /* tests for WM_CHAR */
1322 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 3);
1323 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1324 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 4);
1325 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1326 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 5);
1327 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1329 /* tests for WM_KEYDOWN + WM_CHAR */
1330 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 6);
1331 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1332 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 7);
1333 todo_wine
ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1334 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 8);
1335 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
1337 /* multiple tab tests */
1338 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 9);
1339 ok(22 == r
, "Expected %d, got %d\n", 22, r
);
1340 r
= DialogBoxParam(hinst
, "EDIT_DIALOG", NULL
, (DLGPROC
)edit_dialog_proc
, 10);
1341 ok(33 == r
, "Expected %d, got %d\n", 33, r
);
1344 static BOOL
RegisterWindowClasses (void)
1348 WNDCLASSA text_position
;
1351 test2
.lpfnWndProc
= ET2_WndProc
;
1352 test2
.cbClsExtra
= 0;
1353 test2
.cbWndExtra
= 0;
1354 test2
.hInstance
= hinst
;
1356 test2
.hCursor
= LoadCursorA (NULL
, IDC_ARROW
);
1357 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1358 test2
.lpszMenuName
= NULL
;
1359 test2
.lpszClassName
= szEditTest2Class
;
1360 if (!RegisterClassA(&test2
)) return FALSE
;
1363 test3
.lpfnWndProc
= edit3_wnd_procA
;
1364 test3
.cbClsExtra
= 0;
1365 test3
.cbWndExtra
= 0;
1366 test3
.hInstance
= hinst
;
1368 test3
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
1369 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
1370 test3
.lpszMenuName
= NULL
;
1371 test3
.lpszClassName
= szEditTest3Class
;
1372 if (!RegisterClassA(&test3
)) return FALSE
;
1374 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
1375 text_position
.cbClsExtra
= 0;
1376 text_position
.cbWndExtra
= 0;
1377 text_position
.hInstance
= hinst
;
1378 text_position
.hIcon
= NULL
;
1379 text_position
.hCursor
= LoadCursorA(NULL
, IDC_ARROW
);
1380 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1381 text_position
.lpszMenuName
= NULL
;
1382 text_position
.lpszClassName
= szEditTextPositionClass
;
1383 text_position
.lpfnWndProc
= DefWindowProc
;
1384 if (!RegisterClassA(&text_position
)) return FALSE
;
1389 static void UnregisterWindowClasses (void)
1391 UnregisterClassA(szEditTest2Class
, hinst
);
1392 UnregisterClassA(szEditTest3Class
, hinst
);
1393 UnregisterClassA(szEditTextPositionClass
, hinst
);
1398 hinst
= GetModuleHandleA(NULL
);
1399 assert(RegisterWindowClasses());
1401 test_edit_control_1();
1402 test_edit_control_2();
1403 test_edit_control_3();
1404 test_edit_control_4();
1405 test_edit_control_5();
1406 test_edit_control_limittext();
1408 test_margins_font_change();
1409 test_text_position();
1414 UnregisterWindowClasses();