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"
29 #define ES_COMBO 0x200
32 #define ID_EDITTESTDBUTTON 0x123
33 #define ID_EDITTEST2 99
37 int en_change
, en_maxtext
, en_update
;
40 static struct edit_notify notifications
;
42 static INT_PTR CALLBACK
multi_edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
44 static int num_ok_commands
= 0;
49 HWND hedit
= GetDlgItem(hdlg
, 1000);
53 /* test cases related to bug 12319 */
55 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
56 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
59 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
60 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
63 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
64 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
65 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
68 /* test cases for pressing enter */
71 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
72 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
82 if (HIWORD(wparam
) != BN_CLICKED
)
85 switch (LOWORD(wparam
))
98 HWND hfocus
= GetFocus();
99 HWND hedit
= GetDlgItem(hdlg
, 1000);
100 HWND hedit2
= GetDlgItem(hdlg
, 1001);
101 HWND hedit3
= GetDlgItem(hdlg
, 1002);
103 if (wparam
!= 0xdeadbeef)
110 EndDialog(hdlg
, 1111);
111 else if (hfocus
== hedit2
)
112 EndDialog(hdlg
, 2222);
113 else if (hfocus
== hedit3
)
114 EndDialog(hdlg
, 3333);
116 EndDialog(hdlg
, 4444);
119 if ((hfocus
== hedit
) && (num_ok_commands
== 0))
125 EndDialog(hdlg
, 5555);
131 EndDialog(hdlg
, 333);
141 static INT_PTR CALLBACK
edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
147 HWND hedit
= GetDlgItem(hdlg
, 1000);
153 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
156 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
159 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
160 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
163 /* more test cases for WM_CHAR */
165 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
166 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
169 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
170 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
173 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
174 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
177 /* more test cases for WM_KEYDOWN + WM_CHAR */
179 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
180 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
181 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
184 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
185 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
186 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
189 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
190 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
191 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
194 /* multiple tab tests */
196 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
197 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
198 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
201 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
202 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
203 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
204 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
214 if (HIWORD(wparam
) != BN_CLICKED
)
217 switch (LOWORD(wparam
))
220 EndDialog(hdlg
, 111);
224 EndDialog(hdlg
, 222);
235 HWND hok
= GetDlgItem(hdlg
, IDOK
);
236 HWND hcancel
= GetDlgItem(hdlg
, IDCANCEL
);
237 HWND hedit
= GetDlgItem(hdlg
, 1000);
238 HWND hfocus
= GetFocus();
240 if (wparam
!= 0xdeadbeef)
246 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
248 EndDialog(hdlg
, 444);
250 EndDialog(hdlg
, 555);
254 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
255 if ((hfocus
== hok
) && len
== 0)
256 EndDialog(hdlg
, 444);
258 EndDialog(hdlg
, 555);
264 else if (hfocus
== hcancel
)
266 else if (hfocus
== hedit
)
273 EndDialog(hdlg
, 555);
279 EndDialog(hdlg
, 333);
289 static INT_PTR CALLBACK
edit_singleline_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
295 HWND hedit
= GetDlgItem(hdlg
, 1000);
299 /* test cases for WM_KEYDOWN */
301 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
304 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
307 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
308 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
311 /* test cases for WM_CHAR */
313 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
314 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
317 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
318 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
321 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
322 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
325 /* test cases for WM_KEYDOWN + WM_CHAR */
327 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
328 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
331 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
332 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
335 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
336 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
337 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
347 if (HIWORD(wparam
) != BN_CLICKED
)
350 switch (LOWORD(wparam
))
353 EndDialog(hdlg
, 111);
357 EndDialog(hdlg
, 222);
367 HWND hok
= GetDlgItem(hdlg
, IDOK
);
368 HWND hedit
= GetDlgItem(hdlg
, 1000);
369 HWND hfocus
= GetFocus();
370 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
372 if (wparam
!= 0xdeadbeef)
378 if ((hfocus
== hedit
) && len
== 0)
379 EndDialog(hdlg
, 444);
381 EndDialog(hdlg
, 555);
385 if ((hfocus
== hok
) && len
== 0)
386 EndDialog(hdlg
, 444);
388 EndDialog(hdlg
, 555);
398 EndDialog(hdlg
, 333);
408 static INT_PTR CALLBACK
edit_wantreturn_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
414 HWND hedit
= GetDlgItem(hdlg
, 1000);
418 /* test cases for WM_KEYDOWN */
420 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
423 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
424 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
427 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
428 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
431 /* test cases for WM_CHAR */
433 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
434 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
437 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
438 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
441 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
442 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
445 /* test cases for WM_KEYDOWN + WM_CHAR */
447 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
448 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
449 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
452 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
453 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
454 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
457 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
458 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
459 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
469 if (HIWORD(wparam
) != BN_CLICKED
)
472 switch (LOWORD(wparam
))
475 EndDialog(hdlg
, 111);
479 EndDialog(hdlg
, 222);
489 HWND hok
= GetDlgItem(hdlg
, IDOK
);
490 HWND hedit
= GetDlgItem(hdlg
, 1000);
491 HWND hfocus
= GetFocus();
492 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
494 if (wparam
!= 0xdeadbeef)
500 if ((hfocus
== hedit
) && len
== 0)
501 EndDialog(hdlg
, 444);
503 EndDialog(hdlg
, 555);
507 if ((hfocus
== hok
) && len
== 0)
508 EndDialog(hdlg
, 444);
510 EndDialog(hdlg
, 555);
514 if ((hfocus
== hedit
) && len
== 2)
515 EndDialog(hdlg
, 444);
517 EndDialog(hdlg
, 555);
527 EndDialog(hdlg
, 333);
537 static HINSTANCE hinst
;
539 static const char szEditTest2Class
[] = "EditTest2Class";
540 static const char szEditTest3Class
[] = "EditTest3Class";
541 static const char szEditTest4Class
[] = "EditTest4Class";
542 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
544 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
548 handle
= CreateWindowExA(exstyle
,
553 NULL
, NULL
, hinst
, NULL
);
554 ok (handle
!= NULL
, "CreateWindow EDIT Control failed\n");
556 if (winetest_interactive
)
557 ShowWindow (handle
, SW_SHOW
);
561 static HWND
create_editcontrolW(DWORD style
, DWORD exstyle
)
563 static const WCHAR testtextW
[] = {'T','e','s','t',' ','t','e','x','t',0};
566 handle
= CreateWindowExW(exstyle
, WC_EDITW
, testtextW
, style
, 10, 10, 300, 300,
567 NULL
, NULL
, hinst
, NULL
);
568 ok(handle
!= NULL
, "Failed to create Edit control.\n");
572 static HWND
create_child_editcontrol (DWORD style
, DWORD exstyle
)
578 SetRect(&rect
, 0, 0, 300, 300);
579 b
= AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
);
580 ok(b
, "AdjustWindowRect failed\n");
582 parentWnd
= CreateWindowExA(0,
583 szEditTextPositionClass
,
586 CW_USEDEFAULT
, CW_USEDEFAULT
,
587 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
588 NULL
, NULL
, hinst
, NULL
);
589 ok (parentWnd
!= NULL
, "CreateWindow EDIT Test failed\n");
592 editWnd
= CreateWindowExA(exstyle
,
597 parentWnd
, NULL
, hinst
, NULL
);
598 ok (editWnd
!= NULL
, "CreateWindow EDIT Test Text failed\n");
600 if (winetest_interactive
)
601 ShowWindow (parentWnd
, SW_SHOW
);
605 static void destroy_child_editcontrol (HWND hwndEdit
)
607 if (GetParent(hwndEdit
))
608 DestroyWindow(GetParent(hwndEdit
));
610 trace("Edit control has no parent!\n");
611 DestroyWindow(hwndEdit
);
615 static LONG
get_edit_style (HWND hwnd
)
617 return GetWindowLongA( hwnd
, GWL_STYLE
) & (
619 /* FIXME: not implemented
638 static void set_client_height(HWND Wnd
, unsigned Height
)
640 RECT ClientRect
, WindowRect
;
642 GetWindowRect(Wnd
, &WindowRect
);
643 GetClientRect(Wnd
, &ClientRect
);
644 SetWindowPos(Wnd
, NULL
, 0, 0,
645 WindowRect
.right
- WindowRect
.left
,
646 Height
+ (WindowRect
.bottom
- WindowRect
.top
) -
647 (ClientRect
.bottom
- ClientRect
.top
),
648 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
650 /* Workaround for a bug in Windows' edit control
652 GetWindowRect(Wnd
, &WindowRect
);
653 SetWindowPos(Wnd
, NULL
, 0, 0,
654 WindowRect
.right
- WindowRect
.left
+ 1,
655 WindowRect
.bottom
- WindowRect
.top
+ 1,
656 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
657 SetWindowPos(Wnd
, NULL
, 0, 0,
658 WindowRect
.right
- WindowRect
.left
,
659 WindowRect
.bottom
- WindowRect
.top
,
660 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
662 GetClientRect(Wnd
, &ClientRect
);
663 ok(ClientRect
.bottom
- ClientRect
.top
== Height
,
664 "The client height should be %d, but is %d\n",
665 Height
, ClientRect
.bottom
- ClientRect
.top
);
668 static void test_edit_control_1(void)
675 msMessage
.message
= WM_KEYDOWN
;
677 trace("EDIT: Single line\n");
678 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
679 r
= get_edit_style(hwEdit
);
680 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
), "Wrong style expected 0xc0 got: 0x%x\n", r
);
681 for (i
= 0; i
< 65535; i
++)
683 msMessage
.wParam
= i
;
684 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
685 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
686 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
688 DestroyWindow(hwEdit
);
690 trace("EDIT: Single line want returns\n");
691 hwEdit
= create_editcontrol(ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
692 r
= get_edit_style(hwEdit
);
693 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
| ES_WANTRETURN
), "Wrong style expected 0x10c0 got: 0x%x\n", r
);
694 for (i
= 0; i
< 65535; i
++)
696 msMessage
.wParam
= i
;
697 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
698 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
699 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
701 DestroyWindow(hwEdit
);
703 trace("EDIT: Multiline line\n");
704 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
705 r
= get_edit_style(hwEdit
);
706 ok(r
== (ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0xc4 got: 0x%x\n", r
);
707 for (i
= 0; i
< 65535; i
++)
709 msMessage
.wParam
= i
;
710 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
711 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
712 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
714 DestroyWindow(hwEdit
);
716 trace("EDIT: Multi line want returns\n");
717 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
718 r
= get_edit_style(hwEdit
);
719 ok(r
== (ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0x10c4 got: 0x%x\n", r
);
720 for (i
= 0; i
< 65535; i
++)
722 msMessage
.wParam
= i
;
723 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
724 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
725 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
727 DestroyWindow(hwEdit
);
730 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
731 * selection. This test checks that the first 'select all' doesn't generate
732 * an UPDATE message which can escape and (via a handler) change the
733 * selection, which would cause WM_SETTEXT to break. This old bug
734 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
736 static void test_edit_control_2(void)
738 HWND hwndMain
, phwnd
;
739 char szLocalString
[MAXLEN
];
740 LONG r
, w
= 150, h
= 50;
743 /* Create main and edit windows. */
744 hwndMain
= CreateWindowA(szEditTest2Class
, "ET2", WS_OVERLAPPEDWINDOW
,
745 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
747 if (winetest_interactive
)
748 ShowWindow (hwndMain
, SW_SHOW
);
750 hwndET2
= CreateWindowA("EDIT", NULL
,
751 WS_CHILD
|WS_BORDER
|ES_LEFT
|ES_AUTOHSCROLL
,
752 0, 0, w
, h
, /* important this not be 0 size. */
753 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
755 if (winetest_interactive
)
756 ShowWindow (hwndET2
, SW_SHOW
);
758 trace("EDIT: SETTEXT atomicity\n");
759 /* Send messages to "type" in the word 'foo'. */
760 r
= SendMessageA(hwndET2
, WM_CHAR
, 'f', 1);
761 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
762 r
= SendMessageA(hwndET2
, WM_CHAR
, 'o', 1);
763 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
764 r
= SendMessageA(hwndET2
, WM_CHAR
, 'o', 1);
765 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
766 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
767 GetWindowTextA(hwndET2
, szLocalString
, MAXLEN
);
768 ok(strcmp(szLocalString
, "bar")==0,
769 "Wrong contents of edit: %s\n", szLocalString
);
771 /* try setting the caret before it's visible */
772 r
= SetCaretPos(0, 0);
773 todo_wine
ok(0 == r
, "SetCaretPos succeeded unexpectedly, expected: 0, got: %d\n", r
);
774 phwnd
= SetFocus(hwndET2
);
775 ok(phwnd
!= NULL
, "SetFocus failed unexpectedly, expected non-zero, got NULL\n");
776 r
= SetCaretPos(0, 0);
777 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
778 r
= GetCaretPos(&cpos
);
779 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
780 ok(cpos
.x
== 0 && cpos
.y
== 0, "Wrong caret position, expected: (0,0), got: (%d,%d)\n", cpos
.x
, cpos
.y
);
781 r
= SetCaretPos(-1, -1);
782 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
783 r
= GetCaretPos(&cpos
);
784 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
785 ok(cpos
.x
== -1 && cpos
.y
== -1, "Wrong caret position, expected: (-1,-1), got: (%d,%d)\n", cpos
.x
, cpos
.y
);
786 r
= SetCaretPos(w
<< 1, h
<< 1);
787 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
788 r
= GetCaretPos(&cpos
);
789 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
790 ok(cpos
.x
== (w
<< 1) && cpos
.y
== (h
<< 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
<< 1, h
<< 1, cpos
.x
, cpos
.y
);
791 r
= SetCaretPos(w
, h
);
792 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
793 r
= GetCaretPos(&cpos
);
794 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
795 ok(cpos
.x
== w
&& cpos
.y
== h
, "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
, h
, cpos
.x
, cpos
.y
);
796 r
= SetCaretPos(w
- 1, h
- 1);
797 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
798 r
= GetCaretPos(&cpos
);
799 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
800 ok(cpos
.x
== (w
- 1) && cpos
.y
== (h
- 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
- 1, h
- 1, cpos
.x
, cpos
.y
);
802 DestroyWindow(hwndET2
);
803 DestroyWindow(hwndMain
);
806 static void ET2_check_change(void)
808 char szLocalString
[MAXLEN
];
809 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
810 GetWindowTextA(hwndET2
, szLocalString
, MAXLEN
);
811 if (!strcmp(szLocalString
, "foo"))
813 strcpy(szLocalString
, "bar");
814 SendMessageA(hwndET2
, WM_SETTEXT
, 0, (LPARAM
)szLocalString
);
816 /* always leave the cursor at the end. */
817 SendMessageA(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
820 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
822 if (id
== ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
826 static LRESULT CALLBACK
ET2_WndProc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
831 ET2_OnCommand(hwnd
, LOWORD(wParam
), (HWND
)lParam
, HIWORD(wParam
));
834 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
837 static void zero_notify(void)
839 notifications
.en_change
= 0;
840 notifications
.en_maxtext
= 0;
841 notifications
.en_update
= 0;
844 #define test_notify(enchange, enmaxtext, enupdate) \
846 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
847 "got %d\n", enchange, notifications.en_change); \
848 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
849 "got %d\n", enmaxtext, notifications.en_maxtext); \
850 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
851 "got %d\n", enupdate, notifications.en_update); \
854 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
859 switch (HIWORD(wParam
))
862 notifications
.en_maxtext
++;
865 notifications
.en_update
++;
868 notifications
.en_change
++;
873 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
876 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response
879 static void test_edit_control_3(void)
881 static const char *str
= "this is a long string.";
882 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.";
888 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
889 ReleaseDC(NULL
, hDC
);
891 trace("EDIT: Test notifications\n");
893 hParent
= CreateWindowExA(0,
897 CW_USEDEFAULT
, CW_USEDEFAULT
, 10, 10,
898 NULL
, NULL
, NULL
, NULL
);
901 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
902 hWnd
= CreateWindowExA(0,
907 hParent
, NULL
, NULL
, NULL
);
911 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
912 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
913 if (len
== lstrlenA(str
)) /* Win 8 */
914 test_notify(1, 0, 1);
916 test_notify(1, 1, 1);
918 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
920 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
921 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
922 ok(1 == len
, "wrong text length, expected 1, got %d\n", len
);
923 test_notify(1, 0, 1);
926 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
927 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
928 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
929 test_notify(1, 0, 1);
931 len
= SendMessageA(hWnd
, EM_GETSEL
, 0, 0);
932 ok(LOWORD(len
)==0, "Unexpected start position for selection %d\n", LOWORD(len
));
933 ok(HIWORD(len
)==0, "Unexpected end position for selection %d\n", HIWORD(len
));
934 SendMessageA(hParent
, WM_SETFOCUS
, 0, (LPARAM
)hWnd
);
935 len
= SendMessageA(hWnd
, EM_GETSEL
, 0, 0);
936 ok(LOWORD(len
)==0, "Unexpected start position for selection %d\n", LOWORD(len
));
937 ok(HIWORD(len
)==0, "Unexpected end position for selection %d\n", HIWORD(len
));
939 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
941 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
943 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
944 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
945 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
946 test_notify(1, 1, 1);
949 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
950 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
951 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
952 test_notify(1, 0, 1);
956 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
957 hWnd
= CreateWindowExA(0,
962 hParent
, NULL
, NULL
, NULL
);
966 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
967 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
968 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
969 test_notify(1, 0, 1);
972 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
973 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
974 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
975 test_notify(1, 0, 1);
977 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
979 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
980 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
981 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
982 test_notify(1, 0, 1);
985 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
986 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
987 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
988 test_notify(1, 0, 1);
990 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
992 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
994 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
995 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
996 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
997 test_notify(1, 1, 1);
1000 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1001 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1002 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1003 test_notify(1, 0, 1);
1005 DestroyWindow(hWnd
);
1007 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1008 hWnd
= CreateWindowExA(0,
1012 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1013 hParent
, NULL
, NULL
, NULL
);
1017 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1018 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1019 if (len
== lstrlenA(str
)) /* Win 8 */
1020 test_notify(1, 0, 1);
1023 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1024 test_notify(1, 1, 1);
1027 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1029 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1030 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1031 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1032 test_notify(1, 0, 1);
1035 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1036 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1037 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1038 test_notify(0, 0, 0);
1040 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1042 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1044 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1045 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1046 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1047 test_notify(1, 1, 1);
1050 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1051 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1052 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1053 test_notify(0, 0, 0);
1055 DestroyWindow(hWnd
);
1057 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1058 hWnd
= CreateWindowExA(0,
1061 ES_MULTILINE
| ES_AUTOHSCROLL
,
1062 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1063 hParent
, NULL
, NULL
, NULL
);
1067 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1068 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1069 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1070 test_notify(1, 1, 1);
1072 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1074 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1075 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1076 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1077 test_notify(1, 0, 1);
1080 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1081 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1082 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1083 test_notify(0, 0, 0);
1085 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1087 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1089 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1090 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1091 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1092 test_notify(1, 1, 1);
1095 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1096 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1097 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1098 test_notify(0, 0, 0);
1100 DestroyWindow(hWnd
);
1102 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1103 hWnd
= CreateWindowExA(0,
1106 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
1108 hParent
, NULL
, NULL
, NULL
);
1112 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1113 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1114 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1115 test_notify(1, 0, 1);
1118 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1119 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1120 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1121 test_notify(0, 0, 0);
1123 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1125 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1127 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1128 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1129 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1130 test_notify(1, 1, 1);
1133 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1134 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1135 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1136 test_notify(0, 0, 0);
1138 DestroyWindow(hWnd
);
1141 static void test_char_from_pos(void)
1143 int lo
, hi
, mid
, ret
, i
;
1146 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1147 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1148 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1149 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1150 mid
= lo
+ (hi
- lo
) / 2;
1152 for (i
= lo
; i
< mid
; i
++)
1154 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1155 ok(0 == ret
, "expected 0 got %d\n", ret
);
1158 for (i
= mid
; i
<= hi
; i
++)
1160 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1161 ok(1 == ret
, "expected 1 got %d\n", ret
);
1164 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1165 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1166 DestroyWindow(hwEdit
);
1168 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1169 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1170 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1171 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1172 mid
= lo
+ (hi
- lo
) / 2;
1174 for (i
= lo
; i
< mid
; i
++)
1176 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1177 ok(0 == ret
, "expected 0 got %d\n", ret
);
1180 for (i
= mid
; i
<= hi
; i
++)
1182 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1183 ok(1 == ret
, "expected 1 got %d\n", ret
);
1186 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1187 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1188 DestroyWindow(hwEdit
);
1190 hwEdit
= create_editcontrol(ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1191 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1192 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1193 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1194 mid
= lo
+ (hi
- lo
) / 2;
1196 for (i
= lo
; i
< mid
; i
++)
1198 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1199 ok(0 == ret
, "expected 0 got %d\n", ret
);
1202 for (i
= mid
; i
<= hi
; i
++)
1204 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1205 ok(1 == ret
, "expected 1 got %d\n", ret
);
1208 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1209 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1210 DestroyWindow(hwEdit
);
1212 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1213 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1214 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1215 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1216 mid
= lo
+ (hi
- lo
) / 2 + 1;
1218 for (i
= lo
; i
< mid
; i
++)
1220 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1221 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1224 for (i
= mid
; i
<= hi
; i
++)
1226 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1227 ok(1 == ret
, "expected 1 got %d\n", ret
);
1230 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1231 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1232 DestroyWindow(hwEdit
);
1234 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1235 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1236 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1237 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1238 mid
= lo
+ (hi
- lo
) / 2 + 1;
1240 for (i
= lo
; i
< mid
; i
++)
1242 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1243 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1246 for (i
= mid
; i
<= hi
; i
++)
1248 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1249 ok(1 == ret
, "expected 1 got %d\n", ret
);
1252 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1253 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1254 DestroyWindow(hwEdit
);
1256 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1257 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1258 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1259 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1260 mid
= lo
+ (hi
- lo
) / 2 + 1;
1262 for (i
= lo
; i
< mid
; i
++)
1264 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1265 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1268 for (i
= mid
; i
<= hi
; i
++)
1270 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1271 ok(1 == ret
, "expected 1 got %d\n", ret
);
1274 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1275 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1276 DestroyWindow(hwEdit
);
1279 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1280 * truncates text that doesn't fit.
1282 static void test_edit_control_5(void)
1284 static const char *str
= "test\r\ntest";
1288 RECT rc1
= { 10, 10, 11, 11};
1291 /* first show that a non-child won't do for this test */
1292 hWnd
= CreateWindowExA(0,
1297 NULL
, NULL
, NULL
, NULL
);
1299 /* size of non-child edit control is (much) bigger than requested */
1300 GetWindowRect( hWnd
, &rc
);
1301 ok( rc
.right
- rc
.left
> 20, "size of the window (%d) is smaller than expected\n",
1302 rc
.right
- rc
.left
);
1303 DestroyWindow(hWnd
);
1304 /* so create a parent, and give it edit controls children to test with */
1305 parentWnd
= CreateWindowExA(0,
1306 szEditTextPositionClass
,
1307 "Edit Test", WS_VISIBLE
|
1308 WS_OVERLAPPEDWINDOW
,
1309 CW_USEDEFAULT
, CW_USEDEFAULT
,
1311 NULL
, NULL
, hinst
, NULL
);
1313 ShowWindow( parentWnd
, SW_SHOW
);
1315 hWnd
= CreateWindowExA(0,
1317 str
, WS_VISIBLE
| WS_BORDER
|
1319 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1320 parentWnd
, NULL
, NULL
, NULL
);
1322 GetClientRect( hWnd
, &rc
);
1323 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1324 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc
));
1325 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1326 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1327 DestroyWindow(hWnd
);
1329 hWnd
= CreateWindowExA(0,
1332 WS_CHILD
| ES_MULTILINE
,
1333 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1334 parentWnd
, NULL
, NULL
, NULL
);
1336 GetClientRect( hWnd
, &rc
);
1337 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1338 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc
));
1339 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1340 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1341 DestroyWindow(hWnd
);
1342 DestroyWindow(parentWnd
);
1345 /* Test WM_GETTEXT processing
1346 * after destroy messages
1348 static void test_edit_control_6(void)
1350 static const char *str
= "test\r\ntest";
1355 hWnd
= CreateWindowExA(0, "EDIT", "Test", 0, 10, 10, 1, 1, NULL
, NULL
, hinst
, NULL
);
1356 ok(hWnd
!= NULL
, "Failed to create edit control.\n");
1358 ret
= SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1359 ok(ret
== TRUE
, "Expected %d, got %d\n", TRUE
, ret
);
1360 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1361 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1362 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1365 ret
= SendMessageA(hWnd
, WM_DESTROY
, 0, 0);
1367 ok(ret
== 1, "Unexpected return value %d\n", ret
);
1368 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1369 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1370 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1373 ret
= SendMessageA(hWnd
, WM_NCDESTROY
, 0, 0);
1374 ok(ret
== 0, "Expected 0, got %d\n", ret
);
1375 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1377 ok(ret
== strlen("Test"), "Unexpected text length %d\n", ret
);
1378 ok(!strcmp(buf
, "Test"), "Unexpected text %s\n", buf
);
1380 DestroyWindow(hWnd
);
1383 static void test_edit_control_limittext(void)
1388 /* Test default limit for single-line control */
1389 trace("EDIT: buffer limit for single-line\n");
1390 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1391 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1392 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1393 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1394 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1395 ok( r
== 2147483646, "got limit %u (expected 2147483646)\n", r
);
1396 DestroyWindow(hwEdit
);
1398 /* Test default limit for multi-line control */
1399 trace("EDIT: buffer limit for multi-line\n");
1400 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1401 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1402 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1403 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1404 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1405 ok( r
== 4294967295U, "got limit %u (expected 4294967295)\n", r
);
1406 DestroyWindow(hwEdit
);
1409 /* Test EM_SCROLL */
1410 static void test_edit_control_scroll(void)
1412 static const char *single_line_str
= "a";
1413 static const char *multiline_str
= "Test\r\nText";
1417 /* Check the return value when EM_SCROLL doesn't scroll
1418 * anything. Should not return true unless any lines were actually
1420 hwEdit
= CreateWindowA(
1423 WS_VSCROLL
| ES_MULTILINE
,
1425 NULL
, NULL
, hinst
, NULL
);
1429 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1430 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1432 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEUP
, 0);
1433 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1435 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEUP
, 0);
1436 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1438 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEDOWN
, 0);
1439 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1441 DestroyWindow (hwEdit
);
1443 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1444 should not cause EM_SCROLL to return a negative value of
1445 scrolled lines that would put us "before" the beginning. */
1446 hwEdit
= CreateWindowA(
1449 WS_VSCROLL
| ES_MULTILINE
,
1451 NULL
, NULL
, hinst
, NULL
);
1454 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1455 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1457 DestroyWindow (hwEdit
);
1460 static void test_margins_usefontinfo(UINT charset
)
1462 INT margins
, threshold
, expect
, empty_expect
, small_expect
;
1471 memset(&lf
, 0, sizeof(lf
));
1473 lf
.lfWeight
= FW_NORMAL
;
1474 lf
.lfCharSet
= charset
;
1475 strcpy(lf
.lfFaceName
, "Tahoma");
1477 hfont
= CreateFontIndirectA(&lf
);
1478 ok(hfont
!= NULL
, "got %p\n", hfont
);
1480 /* Big window rectangle */
1481 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 5000, 1000, NULL
, NULL
, NULL
, NULL
);
1482 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1483 GetClientRect(hwnd
, &rect
);
1484 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1487 hfont
= SelectObject(hdc
, hfont
);
1488 size
.cx
= GdiGetCharDimensions( hdc
, NULL
, &size
.cy
);
1489 expect
= MAKELONG(size
.cx
/ 2, size
.cx
/ 2);
1491 empty_expect
= size
.cx
>= 28 ? small_expect
: expect
;
1493 charset
= GetTextCharset(hdc
);
1496 case SHIFTJIS_CHARSET
:
1497 case HANGUL_CHARSET
:
1498 case GB2312_CHARSET
:
1499 case CHINESEBIG5_CHARSET
:
1506 hfont
= SelectObject(hdc
, hfont
);
1507 ReleaseDC(hwnd
, hdc
);
1509 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1510 ok(margins
== 0, "got %x\n", margins
);
1511 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1512 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1514 ok(margins
== expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1517 ok(HIWORD(margins
) > 0 && LOWORD(margins
) > 0, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1518 expect
= empty_expect
= small_expect
= margins
;
1520 DestroyWindow(hwnd
);
1522 threshold
= (size
.cx
/ 2 + size
.cx
) * 2;
1524 /* Size below which non-cjk margins are zero */
1525 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, threshold
- 1, 100, NULL
, NULL
, NULL
, NULL
);
1526 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1527 GetClientRect(hwnd
, &rect
);
1528 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1530 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1531 ok(margins
== 0, "got %x\n", margins
);
1533 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1534 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1535 ok(margins
== small_expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1536 DestroyWindow(hwnd
);
1538 /* Size at which non-cjk margins become non-zero */
1539 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, threshold
, 100, NULL
, NULL
, NULL
, NULL
);
1540 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1541 GetClientRect(hwnd
, &rect
);
1542 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1544 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1545 ok(margins
== 0, "got %x\n", margins
);
1547 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1548 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1549 ok(margins
== expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1550 DestroyWindow(hwnd
);
1553 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1554 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1555 GetClientRect(hwnd
, &rect
);
1556 ok(IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1558 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1559 ok(margins
== 0, "got %x\n", margins
);
1561 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1562 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1563 ok(margins
== empty_expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1564 DestroyWindow(hwnd
);
1566 DeleteObject(hfont
);
1569 static void test_margins(void)
1571 DWORD old_margins
, new_margins
;
1572 RECT old_rect
, new_rect
;
1573 INT old_right_margin
;
1576 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1578 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1579 old_right_margin
= HIWORD(old_margins
);
1581 /* Check if setting the margins works */
1583 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
1584 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1585 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1586 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
1588 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
1589 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1590 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1591 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
1593 /* The size of the rectangle must decrease if we increase the margin */
1595 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
1596 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1597 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
1598 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1599 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
1600 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
1601 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
1602 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
1604 /* If we set the margin to same value as the current margin,
1605 the rectangle must not change */
1607 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1608 SetRect(&old_rect
, 1, 1, 99, 99);
1609 SendMessageA(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
1610 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1611 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1612 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1613 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1615 /* The lParam argument of the WM_SIZE message should be ignored. */
1617 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1618 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, 0);
1619 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1620 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1621 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MINIMIZED
, 0);
1622 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1623 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1624 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MAXIMIZED
, 0);
1625 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1626 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1627 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, MAKELONG(10, 10));
1628 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1629 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1631 DestroyWindow (hwEdit
);
1633 test_margins_usefontinfo(ANSI_CHARSET
);
1634 test_margins_usefontinfo(EASTEUROPE_CHARSET
);
1636 test_margins_usefontinfo(SHIFTJIS_CHARSET
);
1637 test_margins_usefontinfo(HANGUL_CHARSET
);
1638 test_margins_usefontinfo(CHINESEBIG5_CHARSET
);
1639 /* Don't test JOHAB_CHARSET. Treated as CJK by Win 8,
1640 but not by < Win 8 and Win 10. */
1642 test_margins_usefontinfo(DEFAULT_CHARSET
);
1645 static INT CALLBACK
find_font_proc(const LOGFONTA
*elf
, const TEXTMETRICA
*ntm
, DWORD type
, LPARAM lParam
)
1650 static void test_margins_font_change(void)
1652 DWORD margins
, font_margins
, ret
;
1653 HFONT hfont
, hfont2
;
1659 ret
= EnumFontFamiliesA(hdc
, "Arial", find_font_proc
, 0);
1663 trace("Arial not found - skipping font change margin tests\n");
1667 hwEdit
= create_child_editcontrol(0, 0);
1669 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1671 memset(&lf
, 0, sizeof(lf
));
1672 strcpy(lf
.lfFaceName
, "Arial");
1674 lf
.lfCharSet
= DEFAULT_CHARSET
;
1675 hfont
= CreateFontIndirectA(&lf
);
1677 hfont2
= CreateFontIndirectA(&lf
);
1679 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1680 font_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1681 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
1682 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
1684 /* With 'small' edit controls, test that the margin doesn't get set */
1685 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1686 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
1687 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1688 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1689 ok(LOWORD(margins
) == 0, "got %d\n", LOWORD(margins
));
1690 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
1692 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1693 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1694 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1695 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1696 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
1698 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1699 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1700 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1701 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1702 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1704 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1705 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1706 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1707 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1709 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1710 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1711 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1712 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1714 /* Above a certain size threshold then the margin is updated */
1715 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1716 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1717 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1718 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1719 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1720 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1722 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1723 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1724 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1725 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1726 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1728 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1729 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1730 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1731 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1732 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1733 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1734 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1735 ok(LOWORD(margins
) != LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1736 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1738 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
1740 DeleteObject(hfont2
);
1741 DeleteObject(hfont
);
1742 destroy_child_editcontrol(hwEdit
);
1746 #define edit_pos_ok(exp, got, txt) \
1747 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1749 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1753 set_client_height(hwEdit, set_height); \
1754 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1755 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
1756 edit_pos_ok(test_top, format_rect.top, vertical position); \
1757 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1758 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1761 static void test_text_position_style(DWORD style
)
1764 HFONT font
, oldFont
;
1766 TEXTMETRICA metrics
;
1768 BOOL xb
, single_line
= !(style
& ES_MULTILINE
);
1770 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
1775 /* Get a stock font for which we can determine the metrics */
1776 font
= GetStockObject(SYSTEM_FONT
);
1777 ok (font
!= NULL
, "GetStockObject SYSTEM_FONT failed\n");
1779 ok (dc
!= NULL
, "GetDC() failed\n");
1780 oldFont
= SelectObject(dc
, font
);
1781 xb
= GetTextMetricsA(dc
, &metrics
);
1782 ok (xb
, "GetTextMetrics failed\n");
1783 SelectObject(dc
, oldFont
);
1784 ReleaseDC(NULL
, dc
);
1786 /* Windows' edit control has some bugs in multi-line mode:
1787 * - Sometimes the format rectangle doesn't get updated
1788 * (see workaround in set_client_height())
1789 * - If the height of the control is smaller than the height of a text
1790 * line, the format rectangle is still as high as a text line
1791 * (higher than the client rectangle) and the caret is not shown
1794 /* Edit controls that are in a parent window */
1796 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
1797 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1799 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1800 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1801 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1802 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1803 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1804 destroy_child_editcontrol(hwEdit
);
1806 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
1807 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1809 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1810 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1811 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1812 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1813 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1814 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1815 destroy_child_editcontrol(hwEdit
);
1817 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1818 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1820 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1821 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1822 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1823 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1824 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1825 destroy_child_editcontrol(hwEdit
);
1827 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1828 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1830 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1831 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1832 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1833 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1834 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1835 destroy_child_editcontrol(hwEdit
);
1838 /* Edit controls that are popup windows */
1840 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
1841 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1843 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1844 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1845 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1846 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1847 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1848 DestroyWindow(hwEdit
);
1850 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
1851 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1853 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1854 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1855 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1856 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1857 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1858 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1859 DestroyWindow(hwEdit
);
1861 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
1862 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1864 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1865 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1866 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1867 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1868 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1869 DestroyWindow(hwEdit
);
1871 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
1872 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1874 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1875 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1876 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1877 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1878 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1879 DestroyWindow(hwEdit
);
1882 static void test_text_position(void)
1884 trace("EDIT: Text position (Single line)\n");
1885 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1886 trace("EDIT: Text position (Multi line)\n");
1887 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1890 static void test_espassword(void)
1895 const char* password
= "secret";
1897 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
1898 r
= get_edit_style(hwEdit
);
1899 ok(r
== ES_PASSWORD
, "Wrong style expected ES_PASSWORD got: 0x%x\n", r
);
1901 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
1902 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
1904 /* select all, cut (ctrl-x) */
1905 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1906 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
1907 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1910 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1911 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
1912 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
1914 r
= OpenClipboard(hwEdit
);
1915 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1916 r
= EmptyClipboard();
1917 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1918 r
= CloseClipboard();
1919 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1921 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1922 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1923 r
= SendMessageA(hwEdit
, WM_CHAR
, 3, 0);
1924 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1925 r
= SendMessageA(hwEdit
, WM_CHAR
, 22, 0);
1926 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1930 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1931 ok(r
== 0, "Expected: 0, got: %d\n", r
);
1932 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
1934 DestroyWindow(hwEdit
);
1937 static void test_undo(void)
1943 const char* text
= "undo this";
1945 hwEdit
= create_editcontrol(0, 0);
1946 r
= get_edit_style(hwEdit
);
1947 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1950 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
1951 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1954 cpMin
= cpMax
= 0xdeadbeef;
1955 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1956 r
= SendMessageA(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
1957 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
1958 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
1959 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
1962 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
1963 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1967 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1968 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1969 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1972 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
1973 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1977 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1978 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
1979 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
1981 /* undo again (ctrl-z) */
1982 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
1983 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1987 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1988 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
1989 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1991 DestroyWindow(hwEdit
);
1994 static void test_enter(void)
2001 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2002 r
= get_edit_style(hwEdit
);
2003 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
2006 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2007 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2009 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2010 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2014 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2015 ok(2 == r
, "Expected: %d, got len %d\n", 2, r
);
2016 ok(0 == strcmp(buffer
, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer
);
2018 DestroyWindow (hwEdit
);
2021 hwEdit
= create_editcontrol(0, 0);
2022 r
= get_edit_style(hwEdit
);
2023 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2026 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2027 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2029 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2030 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2034 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2035 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2036 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2038 DestroyWindow(hwEdit
);
2040 /* single line with ES_WANTRETURN */
2041 hwEdit
= create_editcontrol(ES_WANTRETURN
, 0);
2042 r
= get_edit_style(hwEdit
);
2043 ok(ES_WANTRETURN
== r
, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r
);
2046 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2047 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2049 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2050 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2054 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2055 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2056 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2058 DestroyWindow(hwEdit
);
2061 static void test_tab(void)
2068 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2069 r
= get_edit_style(hwEdit
);
2070 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
2073 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2074 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2076 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
2077 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2081 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2082 ok(1 == r
, "Expected: %d, got len %d\n", 1, r
);
2083 ok(0 == strcmp(buffer
, "\t"), "expected \"\\t\", got \"%s\"\n", buffer
);
2085 DestroyWindow(hwEdit
);
2088 hwEdit
= create_editcontrol(0, 0);
2089 r
= get_edit_style(hwEdit
);
2090 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2093 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2094 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2096 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
2097 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2101 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2102 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2103 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2105 DestroyWindow(hwEdit
);
2108 static void test_edit_dialog(void)
2112 /* from bug 11841 */
2113 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 0);
2114 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2115 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 1);
2116 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2117 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 2);
2118 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2120 /* more tests for WM_CHAR */
2121 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 3);
2122 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2123 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 4);
2124 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2125 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 5);
2126 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2128 /* more tests for WM_KEYDOWN + WM_CHAR */
2129 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 6);
2130 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2131 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 7);
2132 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2133 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 8);
2134 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2136 /* tests with an editable edit control */
2137 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 0);
2138 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2139 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 1);
2140 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2141 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 2);
2142 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2144 /* tests for WM_CHAR */
2145 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 3);
2146 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2147 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 4);
2148 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2149 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 5);
2150 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2152 /* tests for WM_KEYDOWN + WM_CHAR */
2153 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 6);
2154 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2155 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 7);
2156 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2157 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 8);
2158 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2160 /* multiple tab tests */
2161 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 9);
2162 ok(22 == r
, "Expected %d, got %d\n", 22, r
);
2163 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 10);
2164 ok(33 == r
, "Expected %d, got %d\n", 33, r
);
2167 static void test_multi_edit_dialog(void)
2171 /* test for multiple edit dialogs (bug 12319) */
2172 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 0);
2173 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2174 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 1);
2175 ok(1111 == r
, "Expected %d, got %d\n", 1111, r
);
2176 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 2);
2177 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2178 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 3);
2179 ok(11 == r
, "Expected %d, got %d\n", 11, r
);
2182 static void test_wantreturn_edit_dialog(void)
2186 /* tests for WM_KEYDOWN */
2187 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 0);
2188 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2189 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 1);
2190 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2191 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 2);
2192 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2194 /* tests for WM_CHAR */
2195 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 3);
2196 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2197 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 4);
2198 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2199 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 5);
2200 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2202 /* tests for WM_KEYDOWN + WM_CHAR */
2203 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 6);
2204 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2205 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 7);
2206 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2207 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 8);
2208 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2211 static void test_singleline_wantreturn_edit_dialog(void)
2215 /* tests for WM_KEYDOWN */
2216 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2217 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2218 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2219 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2220 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2221 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2223 /* tests for WM_CHAR */
2224 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2225 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2226 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2227 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2228 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2229 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2231 /* tests for WM_KEYDOWN + WM_CHAR */
2232 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2233 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2234 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2235 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2236 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2237 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2239 /* tests for WM_KEYDOWN */
2240 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2241 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2242 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2243 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2244 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2245 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2247 /* tests for WM_CHAR */
2248 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2249 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2250 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2251 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2252 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2253 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2255 /* tests for WM_KEYDOWN + WM_CHAR */
2256 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2257 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2258 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2259 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2260 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2261 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2264 static int child_edit_wmkeydown_num_messages
= 0;
2265 static INT_PTR CALLBACK
child_edit_wmkeydown_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
2274 child_edit_wmkeydown_num_messages
++;
2281 static void test_child_edit_wmkeydown(void)
2283 HWND hwEdit
, hwParent
;
2286 hwEdit
= create_child_editcontrol(0, 0);
2287 hwParent
= GetParent(hwEdit
);
2288 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)child_edit_wmkeydown_proc
);
2289 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2290 ok(1 == r
, "expected 1, got %d\n", r
);
2291 ok(0 == child_edit_wmkeydown_num_messages
, "expected 0, got %d\n", child_edit_wmkeydown_num_messages
);
2292 destroy_child_editcontrol(hwEdit
);
2295 static BOOL got_en_setfocus
= FALSE
;
2296 static BOOL got_wm_capturechanged
= FALSE
;
2297 static LRESULT (CALLBACK
*p_edit_proc
)(HWND
, UINT
, WPARAM
, LPARAM
);
2299 static LRESULT CALLBACK
edit4_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2303 switch (HIWORD(wParam
))
2306 got_en_setfocus
= TRUE
;
2310 case WM_CAPTURECHANGED
:
2311 if (hWnd
!= (HWND
)lParam
)
2313 got_wm_capturechanged
= TRUE
;
2318 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
2321 struct context_menu_messages
2323 unsigned int wm_command
, em_setsel
;
2326 static struct context_menu_messages menu_messages
;
2328 static LRESULT CALLBACK
child_edit_menu_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2333 if (wParam
== MSGF_MENU
)
2335 HWND hwndMenu
= (HWND
)lParam
;
2336 MENUBARINFO mbi
= { sizeof(mbi
) };
2337 if (GetMenuBarInfo(hwndMenu
, OBJID_CLIENT
, 0, &mbi
))
2339 MENUITEMINFOA mii
= { sizeof(MENUITEMINFOA
), MIIM_STATE
};
2340 if (GetMenuItemInfoA(mbi
.hMenu
, EM_SETSEL
, FALSE
, &mii
))
2342 if (mii
.fState
& MFS_HILITE
)
2344 PostMessageA(hwnd
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2345 PostMessageA(hwnd
, WM_KEYUP
, VK_RETURN
, 0x1c0001);
2349 PostMessageA(hwnd
, WM_KEYDOWN
, VK_DOWN
, 0x500001);
2350 PostMessageA(hwnd
, WM_KEYUP
, VK_DOWN
, 0x500001);
2357 menu_messages
.wm_command
++;
2360 menu_messages
.em_setsel
++;
2363 return CallWindowProcA(p_edit_proc
, hwnd
, msg
, wParam
, lParam
);
2366 static void test_contextmenu(void)
2368 HWND hwndMain
, hwndEdit
;
2371 hwndMain
= CreateWindowA(szEditTest4Class
, "ET4", WS_OVERLAPPEDWINDOW
|WS_VISIBLE
,
2372 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
2375 hwndEdit
= CreateWindowA("EDIT", NULL
,
2376 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|ES_LEFT
|ES_AUTOHSCROLL
,
2377 0, 0, 150, 50, /* important this not be 0 size. */
2378 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
2382 SetCapture(hwndMain
);
2383 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(10, 10));
2384 ok(got_en_setfocus
, "edit box didn't get focused\n");
2385 ok(got_wm_capturechanged
, "main window capture did not change\n");
2387 DestroyWindow(hwndEdit
);
2389 hwndEdit
= CreateWindowA("EDIT", "Test Text",
2390 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
2392 hwndMain
, NULL
, hinst
, NULL
);
2393 memset(&menu_messages
, 0, sizeof(menu_messages
));
2394 p_edit_proc
= (void*)SetWindowLongPtrA(hwndEdit
, GWLP_WNDPROC
,
2395 (ULONG_PTR
)child_edit_menu_proc
);
2398 SendMessageA(hwndEdit
, WM_SETTEXT
, 0, (LPARAM
)"foo");
2399 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(-1, -1));
2400 while (PeekMessageA(&msg
, hwndEdit
, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
2401 ok(menu_messages
.wm_command
== 0,
2402 "Expected no WM_COMMAND messages, got %d\n", menu_messages
.wm_command
);
2403 ok(menu_messages
.em_setsel
== 1,
2404 "Expected 1 EM_SETSEL message, got %d\n", menu_messages
.em_setsel
);
2406 DestroyWindow(hwndEdit
);
2407 DestroyWindow(hwndMain
);
2410 static BOOL
register_classes(void)
2415 WNDCLASSA text_position
;
2418 test2
.lpfnWndProc
= ET2_WndProc
;
2419 test2
.cbClsExtra
= 0;
2420 test2
.cbWndExtra
= 0;
2421 test2
.hInstance
= hinst
;
2423 test2
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2424 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2425 test2
.lpszMenuName
= NULL
;
2426 test2
.lpszClassName
= szEditTest2Class
;
2427 if (!RegisterClassA(&test2
)) return FALSE
;
2430 test3
.lpfnWndProc
= edit3_wnd_procA
;
2431 test3
.cbClsExtra
= 0;
2432 test3
.cbWndExtra
= 0;
2433 test3
.hInstance
= hinst
;
2435 test3
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
2436 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
2437 test3
.lpszMenuName
= NULL
;
2438 test3
.lpszClassName
= szEditTest3Class
;
2439 if (!RegisterClassA(&test3
)) return FALSE
;
2442 test4
.lpfnWndProc
= edit4_wnd_procA
;
2443 test4
.cbClsExtra
= 0;
2444 test4
.cbWndExtra
= 0;
2445 test4
.hInstance
= hinst
;
2447 test4
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2448 test4
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2449 test4
.lpszMenuName
= NULL
;
2450 test4
.lpszClassName
= szEditTest4Class
;
2451 if (!RegisterClassA(&test4
)) return FALSE
;
2453 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
2454 text_position
.cbClsExtra
= 0;
2455 text_position
.cbWndExtra
= 0;
2456 text_position
.hInstance
= hinst
;
2457 text_position
.hIcon
= NULL
;
2458 text_position
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
2459 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2460 text_position
.lpszMenuName
= NULL
;
2461 text_position
.lpszClassName
= szEditTextPositionClass
;
2462 text_position
.lpfnWndProc
= DefWindowProcA
;
2463 if (!RegisterClassA(&text_position
)) return FALSE
;
2468 static void UnregisterWindowClasses (void)
2470 UnregisterClassA(szEditTest2Class
, hinst
);
2471 UnregisterClassA(szEditTest3Class
, hinst
);
2472 UnregisterClassA(szEditTest4Class
, hinst
);
2473 UnregisterClassA(szEditTextPositionClass
, hinst
);
2476 static void test_fontsize(void)
2483 char szLocalString
[MAXLEN
];
2487 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
2488 ReleaseDC(NULL
, hDC
);
2490 memset(&lf
,0,sizeof(LOGFONTA
));
2491 strcpy(lf
.lfFaceName
,"Arial");
2492 lf
.lfHeight
= -300; /* taller than the edit box */
2494 hfont
= CreateFontIndirectA(&lf
);
2496 trace("EDIT: Oversized font (Multi line)\n");
2497 hwEdit
= CreateWindowA("EDIT", NULL
, ES_MULTILINE
|ES_AUTOHSCROLL
,
2498 0, 0, (150 * dpi
) / 96, (50 * dpi
) / 96, NULL
, NULL
,
2501 SendMessageA(hwEdit
,WM_SETFONT
,(WPARAM
)hfont
,0);
2503 if (winetest_interactive
)
2504 ShowWindow (hwEdit
, SW_SHOW
);
2506 r
= SendMessageA(hwEdit
, WM_CHAR
, 'A', 1);
2507 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2508 r
= SendMessageA(hwEdit
, WM_CHAR
, 'B', 1);
2509 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2510 r
= SendMessageA(hwEdit
, WM_CHAR
, 'C', 1);
2511 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2513 GetWindowTextA(hwEdit
, szLocalString
, MAXLEN
);
2514 ok(strcmp(szLocalString
, "ABC")==0,
2515 "Wrong contents of edit: %s\n", szLocalString
);
2517 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,0,0);
2518 ok(r
!= -1,"EM_POSFROMCHAR failed index 0\n");
2519 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,1,0);
2520 ok(r
!= -1,"EM_POSFROMCHAR failed index 1\n");
2521 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,2,0);
2522 ok(r
!= -1,"EM_POSFROMCHAR failed index 2\n");
2523 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,3,0);
2524 ok(r
== -1,"EM_POSFROMCHAR succeeded index 3\n");
2526 DestroyWindow (hwEdit
);
2527 DeleteObject(hfont
);
2530 struct dialog_mode_messages
2532 int wm_getdefid
, wm_close
, wm_command
, wm_nextdlgctl
;
2535 static struct dialog_mode_messages dm_messages
;
2537 static void zero_dm_messages(void)
2539 dm_messages
.wm_command
= 0;
2540 dm_messages
.wm_close
= 0;
2541 dm_messages
.wm_getdefid
= 0;
2542 dm_messages
.wm_nextdlgctl
= 0;
2545 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2546 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2547 "got %d\n", wmcommand, dm_messages.wm_command); \
2548 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2549 "got %d\n", wmclose, dm_messages.wm_close); \
2550 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2551 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2552 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2553 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2555 static LRESULT CALLBACK
dialog_mode_wnd_proc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
2560 dm_messages
.wm_command
++;
2563 dm_messages
.wm_getdefid
++;
2564 return MAKELONG(ID_EDITTESTDBUTTON
, DC_HASDEFID
);
2566 dm_messages
.wm_nextdlgctl
++;
2569 dm_messages
.wm_close
++;
2573 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
2576 static void test_dialogmode(void)
2578 HWND hwEdit
, hwParent
, hwButton
;
2581 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2583 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2584 ok(1 == r
, "expected 1, got %d\n", r
);
2585 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2586 ok(11 == len
, "expected 11, got %d\n", len
);
2588 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, 0);
2589 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2591 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2592 ok(1 == r
, "expected 1, got %d\n", r
);
2593 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2594 ok(13 == len
, "expected 13, got %d\n", len
);
2596 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
)&msg
);
2597 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2598 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2599 ok(1 == r
, "expected 1, got %d\n", r
);
2600 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2601 ok(13 == len
, "expected 13, got %d\n", len
);
2603 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2604 ok(1 == r
, "expected 1, got %d\n", r
);
2605 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2606 ok(13 == len
, "expected 13, got %d\n", len
);
2608 destroy_child_editcontrol(hwEdit
);
2610 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2612 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2613 ok(1 == r
, "expected 1, got %d\n", r
);
2614 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2615 ok(11 == len
, "expected 11, got %d\n", len
);
2618 msg
.message
= WM_KEYDOWN
;
2619 msg
.wParam
= VK_BACK
;
2620 msg
.lParam
= 0xe0001;
2621 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_BACK
, (LPARAM
)&msg
);
2622 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2624 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2625 ok(1 == r
, "expected 1, got %d\n", r
);
2626 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2627 ok(11 == len
, "expected 11, got %d\n", len
);
2629 DestroyWindow(hwEdit
);
2631 hwEdit
= create_child_editcontrol(0, 0);
2632 hwParent
= GetParent(hwEdit
);
2633 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2636 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2637 ok(1 == r
, "expected 1, got %d\n", r
);
2638 test_dm_messages(0, 0, 0, 0);
2641 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2642 ok(1 == r
, "expected 1, got %d\n", r
);
2643 test_dm_messages(0, 0, 0, 0);
2647 msg
.message
= WM_KEYDOWN
;
2648 msg
.wParam
= VK_TAB
;
2649 msg
.lParam
= 0xf0001;
2650 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_TAB
, (LPARAM
)&msg
);
2651 ok(0x89 == r
, "expected 0x89, got 0x%x\n", r
);
2652 test_dm_messages(0, 0, 0, 0);
2655 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2656 ok(1 == r
, "expected 1, got %d\n", r
);
2657 test_dm_messages(0, 0, 0, 0);
2660 destroy_child_editcontrol(hwEdit
);
2662 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2663 hwParent
= GetParent(hwEdit
);
2664 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2666 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2667 ok(1 == r
, "expected 1, got %d\n", r
);
2668 test_dm_messages(0, 0, 0, 0);
2672 msg
.message
= WM_KEYDOWN
;
2673 msg
.wParam
= VK_ESCAPE
;
2674 msg
.lParam
= 0x10001;
2675 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_ESCAPE
, (LPARAM
)&msg
);
2676 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2677 test_dm_messages(0, 0, 0, 0);
2680 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2681 ok(1 == r
, "expected 1, got %d\n", r
);
2682 test_dm_messages(0, 0, 0, 0);
2685 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2686 ok(1 == r
, "expected 1, got %d\n", r
);
2687 test_dm_messages(0, 0, 0, 1);
2690 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2691 ok(1 == r
, "expected 1, got %d\n", r
);
2692 test_dm_messages(0, 0, 1, 0);
2695 hwButton
= CreateWindowA("BUTTON", "OK", WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
,
2696 100, 100, 50, 20, hwParent
, (HMENU
)ID_EDITTESTDBUTTON
, hinst
, NULL
);
2697 ok(hwButton
!=NULL
, "CreateWindow failed with error code %d\n", GetLastError());
2699 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2700 ok(1 == r
, "expected 1, got %d\n", r
);
2701 test_dm_messages(0, 0, 1, 1);
2704 DestroyWindow(hwButton
);
2705 destroy_child_editcontrol(hwEdit
);
2708 static void test_EM_GETHANDLE(void)
2710 static const WCHAR str1W
[] = {'1','1','1','1','+','1','1','1','1','+','1','1','1','1','#',0};
2711 static const WCHAR str2W
[] = {'2','2','2','2','-','2','2','2','2','-','2','2','2','2','-','2','2','2','2','#',0};
2712 static const char str0
[] = "untouched";
2713 static const char str1
[] = "1111+1111+1111#";
2714 static const char str1_1
[] = "2111+1111+1111#";
2715 static const char str2
[] = "2222-2222-2222-2222#";
2716 static const char str3
[] = "3333*3333*3333*3333*3333#";
2726 trace("EDIT: EM_GETHANDLE\n");
2728 /* EM_GETHANDLE is not supported for a single line edit control */
2729 hEdit
= create_editcontrol(WS_BORDER
, 0);
2730 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
2732 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2733 ok(hmem
== NULL
, "got %p (expected NULL)\n", hmem
);
2734 DestroyWindow(hEdit
);
2736 /* EM_GETHANDLE needs a multiline edit control */
2737 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
2738 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
2741 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2742 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2743 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
2745 lstrcpyA(current
, str0
);
2746 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2747 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
2748 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
2750 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2751 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2752 /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
2753 buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
2755 buffer
= LocalLock(hmem
);
2756 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2757 len
= lstrlenW(buffer
);
2759 ok(len
== lstrlenW(str1W
) && !lstrcmpW(buffer
, str1W
), "Unexpected buffer contents %s, length %d.\n",
2760 wine_dbgstr_w(buffer
), len
);
2763 /* See if WM_GETTEXTLENGTH/WM_GETTEXT still work. */
2764 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2765 ok(len
== lstrlenA(str1
), "Unexpected text length %d.\n", len
);
2767 lstrcpyA(current
, str0
);
2768 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2769 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
2770 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
2772 /* Application altered buffer contents, see if WM_GETTEXTLENGTH/WM_GETTEXT pick that up. */
2773 buffer
= LocalLock(hmem
);
2774 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2778 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2779 ok(len
== lstrlenA(str1_1
), "Unexpected text length %d.\n", len
);
2781 lstrcpyA(current
, str0
);
2782 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2784 ok(r
== lstrlenA(str1_1
) && !lstrcmpA(current
, str1_1
),
2785 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1_1
), str1_1
);
2787 /* See if WM_SETTEXT/EM_REPLACESEL work. */
2788 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2789 ok(r
, "Failed to set text.\n");
2791 buffer
= LocalLock(hmem
);
2793 ok(buffer
!= NULL
&& buffer
[0] == '1', "Unexpected buffer contents\n");
2796 r
= SendMessageA(hEdit
, EM_REPLACESEL
, 0, (LPARAM
)str1_1
);
2797 ok(r
, "Failed to replace selection.\n");
2799 buffer
= LocalLock(hmem
);
2801 ok(buffer
!= NULL
&& buffer
[0] == '2', "Unexpected buffer contents\n");
2804 /* use LocalAlloc first to get a different handle */
2805 halloc
= LocalAlloc(LMEM_MOVEABLE
, 42);
2806 ok(halloc
!= NULL
, "got %p (expected != NULL)\n", halloc
);
2807 /* prepare our new memory */
2808 buffer
= LocalLock(halloc
);
2809 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2810 lstrcpyW(buffer
, str2W
);
2811 LocalUnlock(halloc
);
2813 /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
2815 /* use LocalAlloc after the LocalFree to likely consume the handle */
2816 hmem2
= LocalAlloc(LMEM_MOVEABLE
, 42);
2817 ok(hmem2
!= NULL
, "got %p (expected != NULL)\n", hmem2
);
2819 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)halloc
, 0);
2821 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2823 ok(len
== lstrlenA(str2
), "got %d (expected %d)\n", len
, lstrlenA(str2
));
2825 lstrcpyA(current
, str0
);
2826 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2828 ok(r
== lstrlenA(str2
) && !lstrcmpA(current
, str2
),
2829 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str2
), str2
);
2831 /* set a different text */
2832 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str3
);
2833 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2834 ok((r
== 1) && (len
== lstrlenA(str3
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str3
));
2836 lstrcpyA(current
, str0
);
2837 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2838 ok((r
== lstrlenA(str3
)) && !lstrcmpA(current
, str3
),
2839 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str3
), str3
);
2842 DestroyWindow(hEdit
);
2844 /* Some apps have bugs ... */
2845 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
2848 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2849 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2850 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
2852 /* everything is normal up to EM_GETHANDLE */
2853 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2854 /* Some messages still work while other messages fail.
2855 After LocalFree the memory handle, messages can crash the app */
2857 /* A buggy editor used EM_GETHANDLE twice */
2858 hmem2
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2859 ok(hmem2
== hmem
, "got %p (expected %p)\n", hmem2
, hmem
);
2861 /* Let the edit control free the memory handle */
2862 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)hmem2
, 0);
2864 DestroyWindow(hEdit
);
2867 static void test_paste(void)
2869 static const char *str
= "this is a simple text";
2870 static const char *str2
= "first line\r\nsecond line";
2871 HWND hEdit
, hMultilineEdit
;
2872 HANDLE hmem
, hmem_ret
;
2876 hEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
2877 hMultilineEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
, 0);
2879 /* Prepare clipboard data with simple text */
2880 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 255);
2881 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2882 buffer
= GlobalLock(hmem
);
2883 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2884 strcpy(buffer
, str
);
2887 r
= OpenClipboard(hEdit
);
2888 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2889 r
= EmptyClipboard();
2890 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2891 hmem_ret
= SetClipboardData(CF_TEXT
, hmem
);
2892 ok(hmem_ret
== hmem
, "expected %p, got %p\n", hmem
, hmem_ret
);
2893 r
= CloseClipboard();
2894 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2896 /* Paste single line */
2897 SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
2898 r
= SendMessageA(hEdit
, WM_PASTE
, 0, 0);
2899 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2900 ok(strlen(str
) == len
, "got %d\n", len
);
2902 /* Prepare clipboard data with multiline text */
2903 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 255);
2904 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2905 buffer
= GlobalLock(hmem
);
2906 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2907 strcpy(buffer
, str2
);
2910 r
= OpenClipboard(hEdit
);
2911 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2912 r
= EmptyClipboard();
2913 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2914 hmem_ret
= SetClipboardData(CF_TEXT
, hmem
);
2915 ok(hmem_ret
== hmem
, "expected %p, got %p\n", hmem
, hmem_ret
);
2916 r
= CloseClipboard();
2917 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2919 /* Paste multiline text in singleline edit - should be cut */
2920 SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
2921 r
= SendMessageA(hEdit
, WM_PASTE
, 0, 0);
2922 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2923 ok(strlen("first line") == len
, "got %d\n", len
);
2925 /* Paste multiline text in multiline edit */
2926 SendMessageA(hMultilineEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
2927 r
= SendMessageA(hMultilineEdit
, WM_PASTE
, 0, 0);
2928 len
= SendMessageA(hMultilineEdit
, WM_GETTEXTLENGTH
, 0, 0);
2929 ok(strlen(str2
) == len
, "got %d\n", len
);
2932 DestroyWindow(hEdit
);
2933 DestroyWindow(hMultilineEdit
);
2936 static void test_EM_GETLINE(void)
2941 hwnd
[0] = create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
2942 hwnd
[1] = create_editcontrolW(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
2944 for (i
= 0; i
< sizeof(hwnd
)/sizeof(hwnd
[0]); i
++)
2946 static const WCHAR strW
[] = {'t','e','x','t',0};
2947 static const char *str
= "text";
2952 todo_wine_if(i
== 0)
2953 ok(IsWindowUnicode(hwnd
[i
]), "Expected unicode window.\n");
2955 SendMessageA(hwnd
[i
], WM_SETTEXT
, 0, (LPARAM
)str
);
2957 memset(buff
, 0, sizeof(buff
));
2958 *(WORD
*)buff
= sizeof(buff
);
2959 r
= SendMessageA(hwnd
[i
], EM_GETLINE
, 0, (LPARAM
)buff
);
2960 ok(r
== strlen(str
), "Failed to get a line %d.\n", r
);
2961 ok(!strcmp(buff
, str
), "Unexpected line data %s.\n", buff
);
2963 memset(buff
, 0, sizeof(buff
));
2964 *(WORD
*)buff
= sizeof(buff
);
2965 r
= SendMessageA(hwnd
[i
], EM_GETLINE
, 1, (LPARAM
)buff
);
2966 ok(r
== strlen(str
), "Failed to get a line %d.\n", r
);
2967 ok(!strcmp(buff
, str
), "Unexpected line data %s.\n", buff
);
2969 memset(buffW
, 0, sizeof(buffW
));
2970 *(WORD
*)buffW
= sizeof(buffW
)/sizeof(buffW
[0]);
2971 r
= SendMessageW(hwnd
[i
], EM_GETLINE
, 0, (LPARAM
)buffW
);
2972 ok(r
== lstrlenW(strW
), "Failed to get a line %d.\n", r
);
2973 ok(!lstrcmpW(buffW
, strW
), "Unexpected line data %s.\n", wine_dbgstr_w(buffW
));
2975 memset(buffW
, 0, sizeof(buffW
));
2976 *(WORD
*)buffW
= sizeof(buffW
)/sizeof(buffW
[0]);
2977 r
= SendMessageW(hwnd
[i
], EM_GETLINE
, 1, (LPARAM
)buffW
);
2978 ok(r
== lstrlenW(strW
), "Failed to get a line %d.\n", r
);
2979 ok(!lstrcmpW(buffW
, strW
), "Unexpected line data %s.\n", wine_dbgstr_w(buffW
));
2981 DestroyWindow(hwnd
[i
]);
2987 ULONG_PTR ctx_cookie
;
2991 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2994 hinst
= GetModuleHandleA(NULL
);
2995 b
= register_classes();
2996 ok(b
, "Failed to register test classes.\n");
2999 test_edit_control_1();
3000 test_edit_control_2();
3001 test_edit_control_3();
3002 test_char_from_pos();
3003 test_edit_control_5();
3004 test_edit_control_6();
3005 test_edit_control_limittext();
3006 test_edit_control_scroll();
3008 test_margins_font_change();
3009 test_text_position();
3015 test_multi_edit_dialog();
3016 test_wantreturn_edit_dialog();
3017 test_singleline_wantreturn_edit_dialog();
3018 test_child_edit_wmkeydown();
3022 test_EM_GETHANDLE();
3026 UnregisterWindowClasses();
3028 unload_v6_module(ctx_cookie
, hCtx
);