1 /* Unit test suite for edit control.
3 * Copyright 2004 Vitaliy Margolen
4 * Copyright 2005 C. Scott Ananian
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
28 #define ES_COMBO 0x200
31 #define ID_EDITTESTDBUTTON 0x123
32 #define ID_EDITTEST2 99
36 int en_change
, en_maxtext
, en_update
;
39 static struct edit_notify notifications
;
41 static INT_PTR CALLBACK
multi_edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
43 static int num_ok_commands
= 0;
48 HWND hedit
= GetDlgItem(hdlg
, 1000);
52 /* test cases related to bug 12319 */
54 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
55 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
58 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
59 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
62 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
63 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
64 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
67 /* test cases for pressing enter */
70 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
71 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
81 if (HIWORD(wparam
) != BN_CLICKED
)
84 switch (LOWORD(wparam
))
97 HWND hfocus
= GetFocus();
98 HWND hedit
= GetDlgItem(hdlg
, 1000);
99 HWND hedit2
= GetDlgItem(hdlg
, 1001);
100 HWND hedit3
= GetDlgItem(hdlg
, 1002);
102 if (wparam
!= 0xdeadbeef)
109 EndDialog(hdlg
, 1111);
110 else if (hfocus
== hedit2
)
111 EndDialog(hdlg
, 2222);
112 else if (hfocus
== hedit3
)
113 EndDialog(hdlg
, 3333);
115 EndDialog(hdlg
, 4444);
118 if ((hfocus
== hedit
) && (num_ok_commands
== 0))
124 EndDialog(hdlg
, 5555);
130 EndDialog(hdlg
, 333);
140 static INT_PTR CALLBACK
edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
146 HWND hedit
= GetDlgItem(hdlg
, 1000);
152 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
155 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
158 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
159 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
162 /* more test cases for WM_CHAR */
164 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
165 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
168 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
169 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
172 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
173 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
176 /* more test cases for WM_KEYDOWN + WM_CHAR */
178 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
179 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
180 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
183 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
184 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
185 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
188 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
189 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
190 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
193 /* multiple tab tests */
195 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
196 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
197 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
200 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
201 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
202 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
203 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
213 if (HIWORD(wparam
) != BN_CLICKED
)
216 switch (LOWORD(wparam
))
219 EndDialog(hdlg
, 111);
223 EndDialog(hdlg
, 222);
234 HWND hok
= GetDlgItem(hdlg
, IDOK
);
235 HWND hcancel
= GetDlgItem(hdlg
, IDCANCEL
);
236 HWND hedit
= GetDlgItem(hdlg
, 1000);
237 HWND hfocus
= GetFocus();
239 if (wparam
!= 0xdeadbeef)
245 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
247 EndDialog(hdlg
, 444);
249 EndDialog(hdlg
, 555);
253 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
254 if ((hfocus
== hok
) && len
== 0)
255 EndDialog(hdlg
, 444);
257 EndDialog(hdlg
, 555);
263 else if (hfocus
== hcancel
)
265 else if (hfocus
== hedit
)
272 EndDialog(hdlg
, 555);
278 EndDialog(hdlg
, 333);
288 static INT_PTR CALLBACK
edit_singleline_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
294 HWND hedit
= GetDlgItem(hdlg
, 1000);
298 /* test cases for WM_KEYDOWN */
300 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
303 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
306 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
307 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
310 /* test cases for WM_CHAR */
312 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
313 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
316 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
317 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
320 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
321 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
324 /* test cases for WM_KEYDOWN + WM_CHAR */
326 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
327 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
330 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
331 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
334 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
335 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
336 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
346 if (HIWORD(wparam
) != BN_CLICKED
)
349 switch (LOWORD(wparam
))
352 EndDialog(hdlg
, 111);
356 EndDialog(hdlg
, 222);
366 HWND hok
= GetDlgItem(hdlg
, IDOK
);
367 HWND hedit
= GetDlgItem(hdlg
, 1000);
368 HWND hfocus
= GetFocus();
369 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
371 if (wparam
!= 0xdeadbeef)
377 if ((hfocus
== hedit
) && len
== 0)
378 EndDialog(hdlg
, 444);
380 EndDialog(hdlg
, 555);
384 if ((hfocus
== hok
) && len
== 0)
385 EndDialog(hdlg
, 444);
387 EndDialog(hdlg
, 555);
397 EndDialog(hdlg
, 333);
407 static INT_PTR CALLBACK
edit_wantreturn_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
413 HWND hedit
= GetDlgItem(hdlg
, 1000);
417 /* test cases for WM_KEYDOWN */
419 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
422 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
423 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
426 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
427 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
430 /* test cases for WM_CHAR */
432 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
433 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
436 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
437 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
440 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
441 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
444 /* test cases for WM_KEYDOWN + WM_CHAR */
446 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
447 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
448 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
451 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
452 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
453 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
456 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
457 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
458 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
468 if (HIWORD(wparam
) != BN_CLICKED
)
471 switch (LOWORD(wparam
))
474 EndDialog(hdlg
, 111);
478 EndDialog(hdlg
, 222);
488 HWND hok
= GetDlgItem(hdlg
, IDOK
);
489 HWND hedit
= GetDlgItem(hdlg
, 1000);
490 HWND hfocus
= GetFocus();
491 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
493 if (wparam
!= 0xdeadbeef)
499 if ((hfocus
== hedit
) && len
== 0)
500 EndDialog(hdlg
, 444);
502 EndDialog(hdlg
, 555);
506 if ((hfocus
== hok
) && len
== 0)
507 EndDialog(hdlg
, 444);
509 EndDialog(hdlg
, 555);
513 if ((hfocus
== hedit
) && len
== 2)
514 EndDialog(hdlg
, 444);
516 EndDialog(hdlg
, 555);
526 EndDialog(hdlg
, 333);
536 static HINSTANCE hinst
;
538 static const char szEditTest2Class
[] = "EditTest2Class";
539 static const char szEditTest3Class
[] = "EditTest3Class";
540 static const char szEditTest4Class
[] = "EditTest4Class";
541 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
543 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
547 handle
= CreateWindowExA(exstyle
,
552 NULL
, NULL
, hinst
, NULL
);
553 ok (handle
!= NULL
, "CreateWindow EDIT Control failed\n");
555 if (winetest_interactive
)
556 ShowWindow (handle
, SW_SHOW
);
560 static HWND
create_editcontrolW(DWORD style
, DWORD exstyle
)
562 static const WCHAR testtextW
[] = {'T','e','s','t',' ','t','e','x','t',0};
563 static const WCHAR editW
[] = {'E','d','i','t',0};
566 handle
= CreateWindowExW(exstyle
, 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
);
803 DestroyWindow (hwndET2
);
804 DestroyWindow (hwndMain
);
807 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")==0) {
812 strcpy(szLocalString
, "bar");
813 SendMessageA(hwndET2
, WM_SETTEXT
, 0, (LPARAM
) szLocalString
);
815 /* always leave the cursor at the end. */
816 SendMessageA(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
818 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
820 if (id
==ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
823 static LRESULT CALLBACK
ET2_WndProc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
827 ET2_OnCommand(hwnd
, LOWORD(wParam
), (HWND
)lParam
, HIWORD(wParam
));
830 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
833 static void zero_notify(void)
835 notifications
.en_change
= 0;
836 notifications
.en_maxtext
= 0;
837 notifications
.en_update
= 0;
840 #define test_notify(enchange, enmaxtext, enupdate) \
842 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
843 "got %d\n", enchange, notifications.en_change); \
844 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
845 "got %d\n", enmaxtext, notifications.en_maxtext); \
846 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
847 "got %d\n", enupdate, notifications.en_update); \
851 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
855 switch (HIWORD(wParam
)) {
857 notifications
.en_maxtext
++;
860 notifications
.en_update
++;
863 notifications
.en_change
++;
868 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
871 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response
874 static void test_edit_control_3(void)
880 static const char *str
= "this is a long string.";
881 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.";
884 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
885 ReleaseDC(NULL
, hDC
);
887 trace("EDIT: Test notifications\n");
889 hParent
= CreateWindowExA(0,
893 CW_USEDEFAULT
, CW_USEDEFAULT
, 10, 10,
894 NULL
, NULL
, NULL
, NULL
);
897 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
898 hWnd
= CreateWindowExA(0,
903 hParent
, NULL
, NULL
, NULL
);
907 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
908 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
909 if (len
== lstrlenA(str
)) /* Win 8 */
910 test_notify(1, 0, 1);
912 test_notify(1, 1, 1);
914 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
916 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
917 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
918 ok(1 == len
, "wrong text length, expected 1, got %d\n", len
);
919 test_notify(1, 0, 1);
922 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
923 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
924 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
925 test_notify(1, 0, 1);
927 len
= SendMessageA(hWnd
, EM_GETSEL
, 0, 0);
928 ok(LOWORD(len
)==0, "Unexpected start position for selection %d\n", LOWORD(len
));
929 ok(HIWORD(len
)==0, "Unexpected end position for selection %d\n", HIWORD(len
));
930 SendMessageA(hParent
, WM_SETFOCUS
, 0, (LPARAM
)hWnd
);
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
));
935 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
937 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
939 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
940 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
941 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
942 test_notify(1, 1, 1);
945 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
946 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
947 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
948 test_notify(1, 0, 1);
952 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
953 hWnd
= CreateWindowExA(0,
958 hParent
, NULL
, NULL
, NULL
);
962 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
963 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
964 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
965 test_notify(1, 0, 1);
968 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
969 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
970 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
971 test_notify(1, 0, 1);
973 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
975 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
976 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
977 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
978 test_notify(1, 0, 1);
981 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
982 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
983 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
984 test_notify(1, 0, 1);
986 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
988 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
990 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
991 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
992 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
993 test_notify(1, 1, 1);
996 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
997 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
998 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
999 test_notify(1, 0, 1);
1001 DestroyWindow(hWnd
);
1003 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1004 hWnd
= CreateWindowExA(0,
1008 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1009 hParent
, NULL
, NULL
, NULL
);
1013 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1014 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1015 if (len
== lstrlenA(str
)) /* Win 8 */
1016 test_notify(1, 0, 1);
1019 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1020 test_notify(1, 1, 1);
1023 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1025 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1026 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1027 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1028 test_notify(1, 0, 1);
1031 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1032 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1033 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1034 test_notify(0, 0, 0);
1036 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1038 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1040 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1041 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1042 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1043 test_notify(1, 1, 1);
1046 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1047 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1048 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1049 test_notify(0, 0, 0);
1051 DestroyWindow(hWnd
);
1053 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1054 hWnd
= CreateWindowExA(0,
1057 ES_MULTILINE
| ES_AUTOHSCROLL
,
1058 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1059 hParent
, NULL
, NULL
, NULL
);
1063 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1064 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1065 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1066 test_notify(1, 1, 1);
1068 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1070 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1071 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1072 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1073 test_notify(1, 0, 1);
1076 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1077 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1078 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1079 test_notify(0, 0, 0);
1081 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1083 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1085 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1086 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1087 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1088 test_notify(1, 1, 1);
1091 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1092 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1093 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1094 test_notify(0, 0, 0);
1096 DestroyWindow(hWnd
);
1098 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1099 hWnd
= CreateWindowExA(0,
1102 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
1104 hParent
, NULL
, NULL
, NULL
);
1108 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1109 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1110 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1111 test_notify(1, 0, 1);
1114 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1115 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1116 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1117 test_notify(0, 0, 0);
1119 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1121 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1123 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1124 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1125 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1126 test_notify(1, 1, 1);
1129 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1130 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1131 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1132 test_notify(0, 0, 0);
1134 DestroyWindow(hWnd
);
1137 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
1139 static void test_char_from_pos(void)
1148 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
1149 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1150 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1151 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1152 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1153 mid
= lo
+ (hi
- lo
) / 2;
1155 for (i
= lo
; i
< mid
; i
++) {
1156 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1157 ok(0 == ret
, "expected 0 got %d\n", ret
);
1159 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
);
1163 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1164 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1165 DestroyWindow(hwEdit
);
1167 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1168 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1169 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1170 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1171 mid
= lo
+ (hi
- lo
) / 2;
1173 for (i
= lo
; i
< mid
; i
++) {
1174 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1175 ok(0 == ret
, "expected 0 got %d\n", ret
);
1177 for (i
= mid
; i
<= hi
; i
++) {
1178 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1179 ok(1 == ret
, "expected 1 got %d\n", ret
);
1181 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1182 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1183 DestroyWindow(hwEdit
);
1185 hwEdit
= create_editcontrol(ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1186 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1187 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1188 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1189 mid
= lo
+ (hi
- lo
) / 2;
1191 for (i
= lo
; i
< mid
; i
++) {
1192 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1193 ok(0 == ret
, "expected 0 got %d\n", ret
);
1195 for (i
= mid
; i
<= hi
; i
++) {
1196 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1197 ok(1 == ret
, "expected 1 got %d\n", ret
);
1199 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1200 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1201 DestroyWindow(hwEdit
);
1203 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1204 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1205 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1206 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1207 mid
= lo
+ (hi
- lo
) / 2 +1;
1209 for (i
= lo
; i
< mid
; i
++) {
1210 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1211 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1213 for (i
= mid
; i
<= hi
; i
++) {
1214 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1215 ok(1 == ret
, "expected 1 got %d\n", ret
);
1217 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1218 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1219 DestroyWindow(hwEdit
);
1221 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1222 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1223 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1224 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1225 mid
= lo
+ (hi
- lo
) / 2 +1;
1227 for (i
= lo
; i
< mid
; i
++) {
1228 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1229 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1231 for (i
= mid
; i
<= hi
; i
++) {
1232 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1233 ok(1 == ret
, "expected 1 got %d\n", ret
);
1235 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1236 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1237 DestroyWindow(hwEdit
);
1239 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1240 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1241 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1242 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1243 mid
= lo
+ (hi
- lo
) / 2 +1;
1245 for (i
= lo
; i
< mid
; i
++) {
1246 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1247 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1249 for (i
= mid
; i
<= hi
; i
++) {
1250 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1251 ok(1 == ret
, "expected 1 got %d\n", ret
);
1253 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1254 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1255 DestroyWindow(hwEdit
);
1257 /* Scrolled to the right with partially visible line, position on next line. */
1258 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1261 GetTextExtentPoint32A(dc
, "w", 1, &size
);
1262 ReleaseDC(hwEdit
, dc
);
1264 SetWindowPos(hwEdit
, NULL
, 0, 0, size
.cx
* 15, size
.cy
* 5, SWP_NOMOVE
| SWP_NOZORDER
);
1265 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"wwwwwwwwwwwwwwwwwwww\r\n\r\n");
1266 SendMessageA(hwEdit
, EM_SETSEL
, 40, 40);
1268 lo
= (short)SendMessageA(hwEdit
, EM_POSFROMCHAR
, 22, 0);
1269 ret
= (short)SendMessageA(hwEdit
, EM_POSFROMCHAR
, 20, 0);
1270 ret
-= 20 * size
.cx
; /* Calculate expected position, 20 characters back. */
1271 ok(ret
== lo
, "Unexpected position %d vs %d.\n", lo
, ret
);
1273 DestroyWindow(hwEdit
);
1276 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1277 * truncates text that doesn't fit.
1279 static void test_edit_control_5(void)
1281 static const char *str
= "test\r\ntest";
1285 RECT rc1
= { 10, 10, 11, 11};
1288 /* first show that a non-child won't do for this test */
1289 hWnd
= CreateWindowExA(0,
1294 NULL
, NULL
, NULL
, NULL
);
1296 /* size of non-child edit control is (much) bigger than requested */
1297 GetWindowRect( hWnd
, &rc
);
1298 ok( rc
.right
- rc
.left
> 20, "size of the window (%d) is smaller than expected\n",
1299 rc
.right
- rc
.left
);
1300 DestroyWindow(hWnd
);
1301 /* so create a parent, and give it edit controls children to test with */
1302 parentWnd
= CreateWindowExA(0,
1303 szEditTextPositionClass
,
1304 "Edit Test", WS_VISIBLE
|
1305 WS_OVERLAPPEDWINDOW
,
1306 CW_USEDEFAULT
, CW_USEDEFAULT
,
1308 NULL
, NULL
, hinst
, NULL
);
1310 ShowWindow( parentWnd
, SW_SHOW
);
1312 hWnd
= CreateWindowExA(0,
1314 str
, WS_VISIBLE
| WS_BORDER
|
1316 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1317 parentWnd
, NULL
, NULL
, NULL
);
1319 GetClientRect( hWnd
, &rc
);
1320 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1321 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc
));
1322 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1323 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1324 DestroyWindow(hWnd
);
1326 hWnd
= CreateWindowExA(0,
1329 WS_CHILD
| ES_MULTILINE
,
1330 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1331 parentWnd
, NULL
, NULL
, NULL
);
1333 GetClientRect( hWnd
, &rc
);
1334 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1335 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc
));
1336 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1337 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1338 DestroyWindow(hWnd
);
1339 DestroyWindow(parentWnd
);
1342 /* Test WM_GETTEXT processing
1343 * after destroy messages
1345 static void test_edit_control_6(void)
1347 static const char *str
= "test\r\ntest";
1352 hWnd
= CreateWindowExA(0,
1357 NULL
, NULL
, hinst
, NULL
);
1360 ret
= SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1361 ok(ret
== TRUE
, "Expected %d, got %d\n", TRUE
, ret
);
1362 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1363 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1364 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1366 ret
= SendMessageA(hWnd
, WM_DESTROY
, 0, 0);
1367 ok(ret
== 0, "Expected 0, got %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
);
1372 ret
= SendMessageA(hWnd
, WM_NCDESTROY
, 0, 0);
1373 ok(ret
== 0, "Expected 0, got %d\n", ret
);
1374 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1375 ok(ret
== 0, "Expected 0, got len %d\n", ret
);
1376 ok(!strcmp(buf
, ""), "Expected empty string, got %s\n", buf
);
1378 DestroyWindow(hWnd
);
1381 static void test_edit_control_limittext(void)
1386 /* Test default limit for single-line control */
1387 trace("EDIT: buffer limit for single-line\n");
1388 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1389 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1390 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1391 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1392 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1393 ok( r
== 2147483646, "got limit %u (expected 2147483646)\n", r
);
1394 DestroyWindow(hwEdit
);
1396 /* Test default limit for multi-line control */
1397 trace("EDIT: buffer limit for multi-line\n");
1398 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1399 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1400 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1401 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1402 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1403 ok( r
== 4294967295U, "got limit %u (expected 4294967295)\n", r
);
1404 DestroyWindow(hwEdit
);
1407 /* Test EM_SCROLL */
1408 static void test_edit_control_scroll(void)
1410 static const char *single_line_str
= "a";
1411 static const char *multiline_str
= "Test\r\nText";
1415 /* Check the return value when EM_SCROLL doesn't scroll
1416 * anything. Should not return true unless any lines were actually
1418 hwEdit
= CreateWindowA(
1421 WS_VSCROLL
| ES_MULTILINE
,
1423 NULL
, NULL
, hinst
, NULL
);
1427 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1428 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1430 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEUP
, 0);
1431 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1433 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEUP
, 0);
1434 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1436 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEDOWN
, 0);
1437 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1439 DestroyWindow (hwEdit
);
1441 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1442 should not cause EM_SCROLL to return a negative value of
1443 scrolled lines that would put us "before" the beginning. */
1444 hwEdit
= CreateWindowA(
1447 WS_VSCROLL
| ES_MULTILINE
,
1449 NULL
, NULL
, hinst
, NULL
);
1452 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1453 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1455 DestroyWindow (hwEdit
);
1458 static BOOL
is_cjk_charset(HDC dc
)
1460 switch (GdiGetCodePage(dc
)) {
1461 case 932: case 936: case 949: case 950: case 1361:
1468 static void test_margins_usefontinfo(UINT charset
)
1477 INT margins
, threshold
, expect
, empty_expect
;
1478 const UINT small_margins
= MAKELONG(1, 5);
1480 memset(&lf
, 0, sizeof(lf
));
1482 lf
.lfWeight
= FW_NORMAL
;
1483 lf
.lfCharSet
= charset
;
1484 strcpy(lf
.lfFaceName
, "Tahoma");
1486 hfont
= CreateFontIndirectA(&lf
);
1487 ok(hfont
!= NULL
, "got %p\n", hfont
);
1489 /* Big window rectangle */
1490 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 5000, 1000, NULL
, NULL
, NULL
, NULL
);
1491 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1492 GetClientRect(hwnd
, &rect
);
1493 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1496 hfont
= SelectObject(hdc
, hfont
);
1497 size
.cx
= GdiGetCharDimensions( hdc
, &tm
, &size
.cy
);
1498 if ((charset
!= tm
.tmCharSet
&& charset
!= DEFAULT_CHARSET
) ||
1499 !(tm
.tmPitchAndFamily
& (TMPF_TRUETYPE
| TMPF_VECTOR
))) {
1500 skip("%s for charset %d isn't available\n", lf
.lfFaceName
, charset
);
1501 hfont
= SelectObject(hdc
, hfont
);
1502 ReleaseDC(hwnd
, hdc
);
1503 DestroyWindow(hwnd
);
1504 DeleteObject(hfont
);
1507 expect
= MAKELONG(size
.cx
/ 2, size
.cx
/ 2);
1508 hfont
= SelectObject(hdc
, hfont
);
1509 ReleaseDC(hwnd
, hdc
);
1511 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1512 ok(margins
== 0, "got %x\n", margins
);
1513 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1514 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
, EC_USEFONTINFO
));
1515 expect
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1516 DestroyWindow(hwnd
);
1518 threshold
= HIWORD(expect
) + LOWORD(expect
) + size
.cx
* 2;
1519 empty_expect
= threshold
> 80 ? small_margins
: expect
;
1521 /* Size below the threshold, margins remain unchanged */
1522 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, threshold
- 1, 100, NULL
, NULL
, NULL
, NULL
);
1523 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1524 GetClientRect(hwnd
, &rect
);
1525 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1527 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1528 ok(margins
== 0, "got %x\n", margins
);
1530 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1531 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1532 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
, EC_USEFONTINFO
));
1533 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1534 ok(margins
== small_margins
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1535 DestroyWindow(hwnd
);
1537 /* Size at the threshold, margins become non-zero */
1538 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, threshold
, 100, NULL
, NULL
, NULL
, NULL
);
1539 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1540 GetClientRect(hwnd
, &rect
);
1541 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1543 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1544 ok(margins
== 0, "got %x\n", margins
);
1546 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1547 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1548 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
, EC_USEFONTINFO
));
1549 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1550 ok(margins
== expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1551 DestroyWindow(hwnd
);
1554 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1555 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1556 GetClientRect(hwnd
, &rect
);
1557 ok(IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1559 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1560 ok(margins
== 0, "got %x\n", margins
);
1562 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1563 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1564 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
, EC_USEFONTINFO
));
1565 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1566 ok(margins
== empty_expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1567 DestroyWindow(hwnd
);
1569 DeleteObject(hfont
);
1572 static BOOL
is_cjk_font(HDC dc
)
1574 const DWORD FS_DBCS_MASK
= FS_JISJAPAN
|FS_CHINESESIMP
|FS_WANSUNG
|FS_CHINESETRAD
|FS_JOHAB
;
1576 return (GetTextCharsetInfo(dc
, &fs
, 0) != DEFAULT_CHARSET
&&
1577 (fs
.fsCsb
[0] & FS_DBCS_MASK
));
1580 static INT
get_cjk_fontinfo_margin(INT width
, INT side_bearing
)
1583 if (side_bearing
< 0)
1584 margin
= min(-side_bearing
, width
/2);
1590 static DWORD
get_cjk_font_margins(HDC hdc
, BOOL unicode
)
1598 if (!GetCharABCWidthsW(hdc
, 0, 255, abc
))
1602 if (!GetCharABCWidthsA(hdc
, 0, 255, abc
))
1605 for (i
= 0; i
< ARRAY_SIZE(abc
); i
++) {
1606 if (-abc
[i
].abcA
> right
) right
= -abc
[i
].abcA
;
1607 if (-abc
[i
].abcC
> left
) left
= -abc
[i
].abcC
;
1609 return MAKELONG(left
, right
);
1612 static void test_margins_default(const char* facename
, UINT charset
)
1618 BOOL cjk_charset
, cjk_font
;
1622 INT margins
, expect
, font_expect
;
1623 const UINT small_margins
= MAKELONG(1, 5);
1624 const WCHAR EditW
[] = {'E','d','i','t',0}, strW
[] = {'W',0};
1625 struct char_width_info
{
1626 INT lsb
, rsb
, unknown
;
1629 BOOL (WINAPI
*pGetCharWidthInfo
)(HDC
, struct char_width_info
*);
1631 hgdi32
= GetModuleHandleA("gdi32.dll");
1632 pGetCharWidthInfo
= (void *)GetProcAddress(hgdi32
, "GetCharWidthInfo");
1634 memset(&lf
, 0, sizeof(lf
));
1636 lf
.lfWeight
= FW_NORMAL
;
1637 lf
.lfCharSet
= charset
;
1638 strcpy(lf
.lfFaceName
, facename
);
1640 hfont
= CreateFontIndirectA(&lf
);
1641 ok(hfont
!= NULL
, "got %p\n", hfont
);
1643 /* Unicode version */
1644 hwnd
= CreateWindowExW(0, EditW
, strW
, WS_POPUP
, 0, 0, 5000, 1000, NULL
, NULL
, NULL
, NULL
);
1645 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1646 GetClientRect(hwnd
, &rect
);
1647 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1650 hfont
= SelectObject(hdc
, hfont
);
1651 size
.cx
= GdiGetCharDimensions( hdc
, &tm
, &size
.cy
);
1652 if ((charset
!= tm
.tmCharSet
&& charset
!= DEFAULT_CHARSET
) ||
1653 !(tm
.tmPitchAndFamily
& (TMPF_TRUETYPE
| TMPF_VECTOR
))) {
1654 skip("%s for charset %d isn't available\n", lf
.lfFaceName
, charset
);
1655 hfont
= SelectObject(hdc
, hfont
);
1656 ReleaseDC(hwnd
, hdc
);
1657 DestroyWindow(hwnd
);
1658 DeleteObject(hfont
);
1661 cjk_charset
= is_cjk_charset(hdc
);
1662 cjk_font
= is_cjk_font(hdc
);
1663 if ((cjk_charset
|| cjk_font
) &&
1664 pGetCharWidthInfo
&& pGetCharWidthInfo(hdc
, &info
)) {
1667 left
= get_cjk_fontinfo_margin(size
.cx
, info
.lsb
);
1668 right
= get_cjk_fontinfo_margin(size
.cx
, info
.rsb
);
1669 expect
= MAKELONG(left
, right
);
1671 font_expect
= get_cjk_font_margins(hdc
, TRUE
);
1673 /* In this case, margins aren't updated */
1674 font_expect
= small_margins
;
1677 font_expect
= expect
= MAKELONG(size
.cx
/ 2, size
.cx
/ 2);
1679 hfont
= SelectObject(hdc
, hfont
);
1680 ReleaseDC(hwnd
, hdc
);
1682 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1683 ok(margins
== 0, "got %x\n", margins
);
1684 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1685 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1686 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1687 ok(margins
== font_expect
, "%s:%d: expected %d, %d, got %d, %d\n", facename
, charset
, HIWORD(font_expect
), LOWORD(font_expect
), HIWORD(margins
), LOWORD(margins
));
1688 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1689 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
, EC_USEFONTINFO
));
1690 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1691 ok(margins
== expect
, "%s:%d: expected %d, %d, got %d, %d\n", facename
, charset
, HIWORD(expect
), LOWORD(expect
), HIWORD(margins
), LOWORD(margins
));
1692 DestroyWindow(hwnd
);
1695 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 5000, 1000, NULL
, NULL
, NULL
, NULL
);
1696 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1697 GetClientRect(hwnd
, &rect
);
1698 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1702 hfont
= SelectObject(hdc
, hfont
);
1703 font_expect
= get_cjk_font_margins(hdc
, FALSE
);
1705 /* In this case, margins aren't updated */
1706 font_expect
= small_margins
;
1707 hfont
= SelectObject(hdc
, hfont
);
1708 ReleaseDC(hwnd
, hdc
);
1711 /* we expect EC_USEFONTINFO size */
1712 font_expect
= expect
;
1714 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1715 ok(margins
== 0, "got %x\n", margins
);
1716 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1717 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1718 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1719 ok(margins
== font_expect
, "%s:%d: expected %d, %d, got %d, %d\n", facename
, charset
, HIWORD(font_expect
), LOWORD(font_expect
), HIWORD(margins
), LOWORD(margins
));
1720 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, small_margins
);
1721 SendMessageA(hwnd
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
, EC_USEFONTINFO
));
1722 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1723 ok(margins
== expect
, "%s:%d: expected %d, %d, got %d, %d\n", facename
, charset
, HIWORD(expect
), LOWORD(expect
), HIWORD(margins
), LOWORD(margins
));
1724 DestroyWindow(hwnd
);
1726 DeleteObject(hfont
);
1729 static INT CALLBACK
find_font_proc(const LOGFONTA
*elf
, const TEXTMETRICA
*ntm
, DWORD type
, LPARAM lParam
)
1734 static BOOL
is_font_installed(const char*name
)
1736 HDC hdc
= GetDC(NULL
);
1739 if (!EnumFontFamiliesA(hdc
, name
, find_font_proc
, 0))
1742 ReleaseDC(NULL
, hdc
);
1746 static WNDPROC orig_class_proc
;
1748 static LRESULT CALLBACK
test_class_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1756 result
= CallWindowProcA(orig_class_proc
, hwnd
, message
, wParam
, lParam
);
1758 memset(&rect
, 0, sizeof(rect
));
1759 SendMessageA(hwnd
, EM_GETRECT
, 0, (LPARAM
)&rect
);
1760 ok(!rect
.right
&& !rect
.bottom
, "Invalid size after NCCREATE: %d x %d\n", rect
.right
, rect
.bottom
);
1762 /* test that messages between WM_NCCREATE and WM_CREATE
1763 don't crash or cause unexpected behavior */
1764 r
= SendMessageA(hwnd
, EM_SETSEL
, 0, 0);
1765 ok(r
== 1, "Returned %ld, expected 1.\n", r
);
1766 r
= SendMessageA(hwnd
, WM_SIZE
, 0, 0x00100010);
1767 todo_wine
ok(r
== 1, "Returned %ld, expected 1.\n", r
);
1768 r
= SendMessageA(hwnd
, EM_LINESCROLL
, 1, 1);
1769 ok(r
== 1, "Returned %ld, expected 1.\n", r
);
1774 /* test that messages between WM_NCCREATE and WM_CREATE
1775 don't crash or cause unexpected behavior */
1776 r
= SendMessageA(hwnd
, EM_SETSEL
, 0, 0);
1777 ok(r
== 1, "Returned %ld, expected 1.\n", r
);
1778 r
= SendMessageA(hwnd
, WM_SIZE
, 0, 0x00100010);
1779 todo_wine
ok(r
== 1, "Returned %ld, expected 1.\n", r
);
1780 r
= SendMessageA(hwnd
, EM_LINESCROLL
, 1, 1);
1781 ok(r
== 1, "Returned %ld, expected 1.\n", r
);
1786 return CallWindowProcA(orig_class_proc
, hwnd
, message
, wParam
, lParam
);
1789 static void test_initialization(void)
1796 ret
= GetClassInfoA(NULL
, "Edit", &cls
);
1797 ok(ret
, "Failed to get class info.\n");
1799 orig_class_proc
= cls
.lpfnWndProc
;
1800 cls
.lpfnWndProc
= test_class_proc
;
1801 cls
.lpszClassName
= "TestClassName";
1803 atom
= RegisterClassA(&cls
);
1804 ok(atom
!= 0, "Failed to register class.\n");
1806 hwEdit
= CreateWindowExA(0, (LPCSTR
)MAKEINTATOM(atom
), "Text Text",
1807 ES_MULTILINE
| WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| WS_VSCROLL
,
1808 10, 10, 300, 300, NULL
, NULL
, hinst
, NULL
);
1809 ok(hwEdit
!= NULL
, "Failed to create a window.\n");
1811 DestroyWindow(hwEdit
);
1812 UnregisterClassA((LPCSTR
)MAKEINTATOM(atom
), hinst
);
1815 static void test_margins(void)
1818 RECT old_rect
, new_rect
;
1819 INT old_right_margin
;
1820 DWORD old_margins
, new_margins
;
1822 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1824 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1825 old_right_margin
= HIWORD(old_margins
);
1827 /* Check if setting the margins works */
1829 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
1830 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1831 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1832 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
1834 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
1835 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1836 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1837 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
1839 /* The size of the rectangle must decrease if we increase the margin */
1841 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
1842 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1843 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
1844 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1845 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
1846 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
1847 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
1848 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
1850 /* If we set the margin to same value as the current margin,
1851 the rectangle must not change */
1853 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1854 SetRect(&old_rect
, 1, 1, 99, 99);
1855 SendMessageA(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
1856 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1857 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1858 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1859 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1861 /* The lParam argument of the WM_SIZE message should be ignored. */
1863 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1864 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, 0);
1865 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1866 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1867 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MINIMIZED
, 0);
1868 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1869 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1870 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MAXIMIZED
, 0);
1871 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1872 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1873 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, MAKELONG(10, 10));
1874 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1875 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1877 DestroyWindow (hwEdit
);
1879 test_margins_usefontinfo(ANSI_CHARSET
);
1880 test_margins_usefontinfo(EASTEUROPE_CHARSET
);
1882 test_margins_usefontinfo(SHIFTJIS_CHARSET
);
1883 test_margins_usefontinfo(HANGUL_CHARSET
);
1884 test_margins_usefontinfo(CHINESEBIG5_CHARSET
);
1885 /* Don't test JOHAB_CHARSET. Treated as CJK by Win 8,
1886 but not by < Win 8 and Win 10. */
1888 test_margins_usefontinfo(DEFAULT_CHARSET
);
1890 test_margins_default("Tahoma", ANSI_CHARSET
);
1891 test_margins_default("Tahoma", EASTEUROPE_CHARSET
);
1893 test_margins_default("Tahoma", HANGUL_CHARSET
);
1894 test_margins_default("Tahoma", CHINESEBIG5_CHARSET
);
1896 if (is_font_installed("MS PGothic")) {
1897 test_margins_default("MS PGothic", SHIFTJIS_CHARSET
);
1898 test_margins_default("MS PGothic", GREEK_CHARSET
);
1901 skip("MS PGothic is not available, skipping some margin tests\n");
1903 if (is_font_installed("Ume P Gothic")) {
1904 test_margins_default("Ume P Gothic", SHIFTJIS_CHARSET
);
1905 test_margins_default("Ume P Gothic", GREEK_CHARSET
);
1908 skip("Ume P Gothic is not available, skipping some margin tests\n");
1910 if (is_font_installed("SimSun")) {
1911 test_margins_default("SimSun", GB2312_CHARSET
);
1912 test_margins_default("SimSun", ANSI_CHARSET
);
1915 skip("SimSun is not available, skipping some margin tests\n");
1918 static void test_margins_font_change(void)
1921 DWORD margins
, font_margins
;
1923 HFONT hfont
, hfont2
;
1925 if (!is_font_installed("Arial"))
1927 skip("Arial not found - skipping font change margin tests\n");
1931 hwEdit
= create_child_editcontrol(0, 0);
1933 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1935 memset(&lf
, 0, sizeof(lf
));
1936 strcpy(lf
.lfFaceName
, "Arial");
1938 lf
.lfCharSet
= GREEK_CHARSET
; /* to avoid associated charset feature */
1939 hfont
= CreateFontIndirectA(&lf
);
1941 hfont2
= CreateFontIndirectA(&lf
);
1943 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1944 font_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1945 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
1946 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
1948 /* With 'small' edit controls, test that the margin doesn't get set */
1949 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1950 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
1951 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1952 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1953 ok(LOWORD(margins
) == 0,
1954 "got %d\n", LOWORD(margins
));
1955 ok(HIWORD(margins
) == 0,
1956 "got %d\n", HIWORD(margins
));
1958 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1959 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1960 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1961 ok(LOWORD(margins
) == 1,
1962 "got %d\n", LOWORD(margins
));
1963 ok(HIWORD(margins
) == 0,
1964 "got %d\n", HIWORD(margins
));
1966 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1967 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1968 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1969 ok(LOWORD(margins
) == 1,
1970 "got %d\n", LOWORD(margins
));
1971 ok(HIWORD(margins
) == 1,
1972 "got %d\n", HIWORD(margins
));
1974 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1975 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1976 ok(LOWORD(margins
) == 1,
1977 "got %d\n", LOWORD(margins
));
1978 ok(HIWORD(margins
) == 1,
1979 "got %d\n", HIWORD(margins
));
1981 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1982 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1983 ok(LOWORD(margins
) == 1,
1984 "got %d\n", LOWORD(margins
));
1985 ok(HIWORD(margins
) == 1,
1986 "got %d\n", HIWORD(margins
));
1988 /* Above a certain size threshold then the margin is updated */
1989 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1990 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1991 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1992 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1993 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1994 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1996 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1997 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1998 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1999 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
2000 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
2002 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
2003 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
2004 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
2005 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
2006 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
2007 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
2008 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
2009 ok(LOWORD(margins
) != LOWORD(font_margins
),
2010 "got %d\n", LOWORD(margins
));
2011 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
2013 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
2015 DeleteObject(hfont2
);
2016 DeleteObject(hfont
);
2017 destroy_child_editcontrol(hwEdit
);
2021 #define edit_pos_ok(exp, got, txt) \
2022 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
2024 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
2028 set_client_height(hwEdit, set_height); \
2029 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
2030 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
2031 edit_pos_ok(test_top, format_rect.top, vertical position); \
2032 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
2033 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
2036 static void test_text_position_style(DWORD style
)
2039 HFONT font
, oldFont
;
2041 TEXTMETRICA metrics
;
2043 BOOL xb
, single_line
= !(style
& ES_MULTILINE
);
2045 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
2050 /* Get a stock font for which we can determine the metrics */
2051 font
= GetStockObject(SYSTEM_FONT
);
2052 ok (font
!= NULL
, "GetStockObject SYSTEM_FONT failed\n");
2054 ok (dc
!= NULL
, "GetDC() failed\n");
2055 oldFont
= SelectObject(dc
, font
);
2056 xb
= GetTextMetricsA(dc
, &metrics
);
2057 ok (xb
, "GetTextMetrics failed\n");
2058 SelectObject(dc
, oldFont
);
2059 ReleaseDC(NULL
, dc
);
2061 /* Windows' edit control has some bugs in multi-line mode:
2062 * - Sometimes the format rectangle doesn't get updated
2063 * (see workaround in set_client_height())
2064 * - If the height of the control is smaller than the height of a text
2065 * line, the format rectangle is still as high as a text line
2066 * (higher than the client rectangle) and the caret is not shown
2069 /* Edit controls that are in a parent window */
2071 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
2072 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2074 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
2075 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
2076 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
2077 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
2078 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
2079 destroy_child_editcontrol(hwEdit
);
2081 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
2082 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2084 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
2085 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
2086 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
2087 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
2088 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
2089 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
2090 destroy_child_editcontrol(hwEdit
);
2092 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
2093 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2095 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
2096 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
2097 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
2098 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
2099 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
2100 destroy_child_editcontrol(hwEdit
);
2102 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
2103 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2105 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
2106 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
2107 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
2108 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
2109 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
2110 destroy_child_editcontrol(hwEdit
);
2113 /* Edit controls that are popup windows */
2115 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
2116 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2118 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
2119 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
2120 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
2121 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
2122 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
2123 DestroyWindow(hwEdit
);
2125 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
2126 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2128 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
2129 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
2130 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
2131 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
2132 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
2133 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
2134 DestroyWindow(hwEdit
);
2136 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
2137 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2139 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
2140 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
2141 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
2142 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
2143 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
2144 DestroyWindow(hwEdit
);
2146 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
2147 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
2149 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
2150 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
2151 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
2152 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
2153 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
2154 DestroyWindow(hwEdit
);
2157 static void test_text_position(void)
2159 trace("EDIT: Text position (Single line)\n");
2160 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
2161 trace("EDIT: Text position (Multi line)\n");
2162 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
2165 static void test_espassword(void)
2170 const char* password
= "secret";
2172 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
2173 r
= get_edit_style(hwEdit
);
2174 ok(r
== ES_PASSWORD
, "Wrong style expected ES_PASSWORD got: 0x%x\n", r
);
2176 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
2177 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
2179 /* select all, cut (ctrl-x) */
2180 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
2181 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
2182 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2185 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
2186 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
2187 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
2189 r
= OpenClipboard(hwEdit
);
2190 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2191 r
= EmptyClipboard();
2192 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2193 r
= CloseClipboard();
2194 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2196 /* select all, copy (ctrl-c) and paste (ctrl-v) */
2197 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
2198 r
= SendMessageA(hwEdit
, WM_CHAR
, 3, 0);
2199 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2200 r
= SendMessageA(hwEdit
, WM_CHAR
, 22, 0);
2201 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2205 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
2206 ok(r
== 0, "Expected: 0, got: %d\n", r
);
2207 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
2209 DestroyWindow (hwEdit
);
2212 static void test_undo(void)
2218 const char* text
= "undo this";
2220 hwEdit
= create_editcontrol(0, 0);
2221 r
= get_edit_style(hwEdit
);
2222 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2225 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
2226 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2229 cpMin
= cpMax
= 0xdeadbeef;
2230 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
2231 r
= SendMessageA(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
2232 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
2233 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
2234 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
2237 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
2238 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2242 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
2243 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2244 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
2247 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
2248 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2252 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
2253 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
2254 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
2256 /* undo again (ctrl-z) */
2257 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
2258 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2262 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
2263 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
2264 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
2266 DestroyWindow (hwEdit
);
2269 static void test_enter(void)
2276 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2277 r
= get_edit_style(hwEdit
);
2278 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
2281 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2282 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2284 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2285 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2289 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2290 ok(2 == r
, "Expected: %d, got len %d\n", 2, r
);
2291 ok(0 == strcmp(buffer
, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer
);
2293 DestroyWindow (hwEdit
);
2296 hwEdit
= create_editcontrol(0, 0);
2297 r
= get_edit_style(hwEdit
);
2298 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2301 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2302 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2304 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2305 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2309 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2310 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2311 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2313 DestroyWindow (hwEdit
);
2315 /* single line with ES_WANTRETURN */
2316 hwEdit
= create_editcontrol(ES_WANTRETURN
, 0);
2317 r
= get_edit_style(hwEdit
);
2318 ok(ES_WANTRETURN
== r
, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r
);
2321 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2322 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2324 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2325 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2329 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2330 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2331 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2333 DestroyWindow (hwEdit
);
2336 static void test_tab(void)
2343 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2344 r
= get_edit_style(hwEdit
);
2345 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
2348 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2349 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2351 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
2352 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2356 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2357 ok(1 == r
, "Expected: %d, got len %d\n", 1, r
);
2358 ok(0 == strcmp(buffer
, "\t"), "expected \"\\t\", got \"%s\"\n", buffer
);
2360 DestroyWindow (hwEdit
);
2363 hwEdit
= create_editcontrol(0, 0);
2364 r
= get_edit_style(hwEdit
);
2365 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2368 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2369 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2371 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
2372 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2376 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2377 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2378 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2380 DestroyWindow (hwEdit
);
2383 static void test_edit_dialog(void)
2387 /* from bug 11841 */
2388 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 0);
2389 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2390 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 1);
2391 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2392 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 2);
2393 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2395 /* more tests for WM_CHAR */
2396 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 3);
2397 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2398 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 4);
2399 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2400 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 5);
2401 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2403 /* more tests for WM_KEYDOWN + WM_CHAR */
2404 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 6);
2405 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2406 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 7);
2407 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2408 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 8);
2409 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2411 /* tests with an editable edit control */
2412 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 0);
2413 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2414 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 1);
2415 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2416 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 2);
2417 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2419 /* tests for WM_CHAR */
2420 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 3);
2421 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2422 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 4);
2423 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2424 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 5);
2425 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2427 /* tests for WM_KEYDOWN + WM_CHAR */
2428 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 6);
2429 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2430 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 7);
2431 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2432 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 8);
2433 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2435 /* multiple tab tests */
2436 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 9);
2437 ok(22 == r
, "Expected %d, got %d\n", 22, r
);
2438 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 10);
2439 ok(33 == r
, "Expected %d, got %d\n", 33, r
);
2442 static void test_multi_edit_dialog(void)
2446 /* test for multiple edit dialogs (bug 12319) */
2447 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 0);
2448 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2449 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 1);
2450 ok(1111 == r
, "Expected %d, got %d\n", 1111, r
);
2451 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 2);
2452 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2453 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 3);
2454 ok(11 == r
, "Expected %d, got %d\n", 11, r
);
2457 static void test_wantreturn_edit_dialog(void)
2461 /* tests for WM_KEYDOWN */
2462 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 0);
2463 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2464 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 1);
2465 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2466 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 2);
2467 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2469 /* tests for WM_CHAR */
2470 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 3);
2471 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2472 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 4);
2473 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2474 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 5);
2475 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2477 /* tests for WM_KEYDOWN + WM_CHAR */
2478 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 6);
2479 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2480 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 7);
2481 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2482 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 8);
2483 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2486 static void test_singleline_wantreturn_edit_dialog(void)
2490 /* tests for WM_KEYDOWN */
2491 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2492 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2493 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2494 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2495 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2496 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2498 /* tests for WM_CHAR */
2499 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2500 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2501 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2502 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2503 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2504 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2506 /* tests for WM_KEYDOWN + WM_CHAR */
2507 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2508 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2509 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2510 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2511 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2512 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2514 /* tests for WM_KEYDOWN */
2515 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2516 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2517 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2518 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2519 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2520 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2522 /* tests for WM_CHAR */
2523 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2524 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2525 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2526 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2527 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2528 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2530 /* tests for WM_KEYDOWN + WM_CHAR */
2531 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2532 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2533 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2534 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2535 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2536 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2539 static int child_edit_wmkeydown_num_messages
= 0;
2540 static INT_PTR CALLBACK
child_edit_wmkeydown_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
2549 child_edit_wmkeydown_num_messages
++;
2556 static void test_child_edit_wmkeydown(void)
2558 HWND hwEdit
, hwParent
;
2561 hwEdit
= create_child_editcontrol(0, 0);
2562 hwParent
= GetParent(hwEdit
);
2563 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)child_edit_wmkeydown_proc
);
2564 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2565 ok(1 == r
, "expected 1, got %d\n", r
);
2566 ok(0 == child_edit_wmkeydown_num_messages
, "expected 0, got %d\n", child_edit_wmkeydown_num_messages
);
2567 destroy_child_editcontrol(hwEdit
);
2570 static BOOL got_en_setfocus
= FALSE
;
2571 static BOOL got_wm_capturechanged
= FALSE
;
2572 static LRESULT (CALLBACK
*p_edit_proc
)(HWND
, UINT
, WPARAM
, LPARAM
);
2574 static LRESULT CALLBACK
edit4_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2578 switch (HIWORD(wParam
)) {
2580 got_en_setfocus
= TRUE
;
2584 case WM_CAPTURECHANGED
:
2585 if (hWnd
!= (HWND
)lParam
)
2587 got_wm_capturechanged
= TRUE
;
2592 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
2595 static LRESULT CALLBACK
edit_proc_proxy(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2598 case WM_ENTERIDLE
: {
2601 HWND ctx_menu
= (HWND
)lParam
;
2603 memset(&mbi
, 0, sizeof(mbi
));
2604 mbi
.cbSize
= sizeof(mbi
);
2605 SetLastError(0xdeadbeef);
2606 ret
= GetMenuBarInfo(ctx_menu
, OBJID_CLIENT
, 0, &mbi
);
2607 ok(ret
, "GetMenuBarInfo failed\n");
2610 ok(mbi
.hMenu
!= NULL
, "mbi.hMenu = NULL\n");
2611 ok(!mbi
.hwndMenu
, "mbi.hwndMenu != NULL\n");
2612 ok(mbi
.fBarFocused
, "mbi.fBarFocused = FALSE\n");
2613 ok(mbi
.fFocused
, "mbi.fFocused = FALSE\n");
2616 memset(&mbi
, 0, sizeof(mbi
));
2617 mbi
.cbSize
= sizeof(mbi
);
2618 SetLastError(0xdeadbeef);
2619 ret
= GetMenuBarInfo(ctx_menu
, OBJID_CLIENT
, 1, &mbi
);
2620 ok(ret
, "GetMenuBarInfo failed\n");
2623 ok(mbi
.hMenu
!= NULL
, "mbi.hMenu = NULL\n");
2624 ok(!mbi
.hwndMenu
, "mbi.hwndMenu != NULL\n");
2625 ok(mbi
.fBarFocused
, "mbi.fBarFocused = FALSE\n");
2626 ok(!mbi
.fFocused
, "mbi.fFocused = TRUE\n");
2633 return p_edit_proc(hWnd
, msg
, wParam
, lParam
);
2636 struct context_menu_messages
2638 unsigned int wm_command
, em_setsel
;
2641 static struct context_menu_messages menu_messages
;
2643 static LRESULT CALLBACK
child_edit_menu_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2647 if (wParam
== MSGF_MENU
) {
2648 HWND hwndMenu
= (HWND
)lParam
;
2649 MENUBARINFO mbi
= { sizeof(MENUBARINFO
) };
2650 if (GetMenuBarInfo(hwndMenu
, OBJID_CLIENT
, 0, &mbi
)) {
2651 MENUITEMINFOA mii
= { sizeof(MENUITEMINFOA
), MIIM_STATE
};
2652 if (GetMenuItemInfoA(mbi
.hMenu
, EM_SETSEL
, FALSE
, &mii
)) {
2653 if (mii
.fState
& MFS_HILITE
) {
2654 PostMessageA(hwnd
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2655 PostMessageA(hwnd
, WM_KEYUP
, VK_RETURN
, 0x1c0001);
2658 PostMessageA(hwnd
, WM_KEYDOWN
, VK_DOWN
, 0x500001);
2659 PostMessageA(hwnd
, WM_KEYUP
, VK_DOWN
, 0x500001);
2666 menu_messages
.wm_command
++;
2669 menu_messages
.em_setsel
++;
2672 return CallWindowProcA(p_edit_proc
, hwnd
, msg
, wParam
, lParam
);
2675 static void test_contextmenu(void)
2677 HWND hwndMain
, hwndEdit
;
2680 hwndMain
= CreateWindowA(szEditTest4Class
, "ET4", WS_OVERLAPPEDWINDOW
|WS_VISIBLE
,
2681 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
2684 hwndEdit
= CreateWindowA("EDIT", NULL
,
2685 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|ES_LEFT
|ES_AUTOHSCROLL
,
2686 0, 0, 150, 50, /* important this not be 0 size. */
2687 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
2691 SetCapture(hwndMain
);
2692 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(10, 10));
2693 ok(got_en_setfocus
, "edit box didn't get focused\n");
2694 ok(got_wm_capturechanged
, "main window capture did not change\n");
2696 p_edit_proc
= (void*)SetWindowLongPtrA(hwndEdit
, GWLP_WNDPROC
, (ULONG_PTR
)edit_proc_proxy
);
2697 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(10, 10));
2699 DestroyWindow (hwndEdit
);
2701 hwndEdit
= CreateWindowA("EDIT", "Test Text",
2702 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
2704 hwndMain
, NULL
, hinst
, NULL
);
2705 memset(&menu_messages
, 0, sizeof(menu_messages
));
2706 p_edit_proc
= (void*)SetWindowLongPtrA(hwndEdit
, GWLP_WNDPROC
,
2707 (ULONG_PTR
)child_edit_menu_proc
);
2710 SendMessageA(hwndEdit
, WM_SETTEXT
, 0, (LPARAM
)"foo");
2711 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(-1, -1));
2712 while (PeekMessageA(&msg
, hwndEdit
, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
2713 ok(menu_messages
.wm_command
== 0,
2714 "Expected no WM_COMMAND messages, got %d\n", menu_messages
.wm_command
);
2715 ok(menu_messages
.em_setsel
== 1,
2716 "Expected 1 EM_SETSEL message, got %d\n", menu_messages
.em_setsel
);
2718 DestroyWindow (hwndEdit
);
2719 DestroyWindow (hwndMain
);
2722 static BOOL
RegisterWindowClasses (void)
2727 WNDCLASSA text_position
;
2730 test2
.lpfnWndProc
= ET2_WndProc
;
2731 test2
.cbClsExtra
= 0;
2732 test2
.cbWndExtra
= 0;
2733 test2
.hInstance
= hinst
;
2735 test2
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2736 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2737 test2
.lpszMenuName
= NULL
;
2738 test2
.lpszClassName
= szEditTest2Class
;
2739 if (!RegisterClassA(&test2
)) return FALSE
;
2742 test3
.lpfnWndProc
= edit3_wnd_procA
;
2743 test3
.cbClsExtra
= 0;
2744 test3
.cbWndExtra
= 0;
2745 test3
.hInstance
= hinst
;
2747 test3
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
2748 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
2749 test3
.lpszMenuName
= NULL
;
2750 test3
.lpszClassName
= szEditTest3Class
;
2751 if (!RegisterClassA(&test3
)) return FALSE
;
2754 test4
.lpfnWndProc
= edit4_wnd_procA
;
2755 test4
.cbClsExtra
= 0;
2756 test4
.cbWndExtra
= 0;
2757 test4
.hInstance
= hinst
;
2759 test4
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2760 test4
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2761 test4
.lpszMenuName
= NULL
;
2762 test4
.lpszClassName
= szEditTest4Class
;
2763 if (!RegisterClassA(&test4
)) return FALSE
;
2765 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
2766 text_position
.cbClsExtra
= 0;
2767 text_position
.cbWndExtra
= 0;
2768 text_position
.hInstance
= hinst
;
2769 text_position
.hIcon
= NULL
;
2770 text_position
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
2771 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2772 text_position
.lpszMenuName
= NULL
;
2773 text_position
.lpszClassName
= szEditTextPositionClass
;
2774 text_position
.lpfnWndProc
= DefWindowProcA
;
2775 if (!RegisterClassA(&text_position
)) return FALSE
;
2780 static void UnregisterWindowClasses (void)
2782 UnregisterClassA(szEditTest2Class
, hinst
);
2783 UnregisterClassA(szEditTest3Class
, hinst
);
2784 UnregisterClassA(szEditTest4Class
, hinst
);
2785 UnregisterClassA(szEditTextPositionClass
, hinst
);
2788 static void test_fontsize(void)
2795 char szLocalString
[MAXLEN
];
2799 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
2800 ReleaseDC(NULL
, hDC
);
2802 memset(&lf
,0,sizeof(LOGFONTA
));
2803 strcpy(lf
.lfFaceName
,"Arial");
2804 lf
.lfHeight
= -300; /* taller than the edit box */
2806 hfont
= CreateFontIndirectA(&lf
);
2808 trace("EDIT: Oversized font (Multi line)\n");
2809 hwEdit
= CreateWindowA("EDIT", NULL
, ES_MULTILINE
|ES_AUTOHSCROLL
,
2810 0, 0, (150 * dpi
) / 96, (50 * dpi
) / 96, NULL
, NULL
,
2813 SendMessageA(hwEdit
,WM_SETFONT
,(WPARAM
)hfont
,0);
2815 if (winetest_interactive
)
2816 ShowWindow (hwEdit
, SW_SHOW
);
2818 r
= SendMessageA(hwEdit
, WM_CHAR
, 'A', 1);
2819 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2820 r
= SendMessageA(hwEdit
, WM_CHAR
, 'B', 1);
2821 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2822 r
= SendMessageA(hwEdit
, WM_CHAR
, 'C', 1);
2823 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2825 GetWindowTextA(hwEdit
, szLocalString
, MAXLEN
);
2826 ok(strcmp(szLocalString
, "ABC")==0,
2827 "Wrong contents of edit: %s\n", szLocalString
);
2829 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,0,0);
2830 ok(r
!= -1,"EM_POSFROMCHAR failed index 0\n");
2831 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,1,0);
2832 ok(r
!= -1,"EM_POSFROMCHAR failed index 1\n");
2833 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,2,0);
2834 ok(r
!= -1,"EM_POSFROMCHAR failed index 2\n");
2835 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,3,0);
2836 ok(r
== -1,"EM_POSFROMCHAR succeeded index 3\n");
2838 DestroyWindow (hwEdit
);
2839 DeleteObject(hfont
);
2842 struct dialog_mode_messages
2844 int wm_getdefid
, wm_close
, wm_command
, wm_nextdlgctl
;
2847 static struct dialog_mode_messages dm_messages
;
2849 static void zero_dm_messages(void)
2851 dm_messages
.wm_command
= 0;
2852 dm_messages
.wm_close
= 0;
2853 dm_messages
.wm_getdefid
= 0;
2854 dm_messages
.wm_nextdlgctl
= 0;
2857 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2858 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2859 "got %d\n", wmcommand, dm_messages.wm_command); \
2860 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2861 "got %d\n", wmclose, dm_messages.wm_close); \
2862 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2863 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2864 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2865 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2867 static LRESULT CALLBACK
dialog_mode_wnd_proc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
2872 dm_messages
.wm_command
++;
2875 dm_messages
.wm_getdefid
++;
2876 return MAKELONG(ID_EDITTESTDBUTTON
, DC_HASDEFID
);
2878 dm_messages
.wm_nextdlgctl
++;
2881 dm_messages
.wm_close
++;
2885 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
2888 static void test_dialogmode(void)
2890 HWND hwEdit
, hwParent
, hwButton
;
2893 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2895 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2896 ok(1 == r
, "expected 1, got %d\n", r
);
2897 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2898 ok(11 == len
, "expected 11, got %d\n", len
);
2900 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, 0);
2901 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2903 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2904 ok(1 == r
, "expected 1, got %d\n", r
);
2905 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2906 ok(13 == len
, "expected 13, got %d\n", len
);
2908 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
)&msg
);
2909 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2910 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2911 ok(1 == r
, "expected 1, got %d\n", r
);
2912 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2913 ok(13 == len
, "expected 13, got %d\n", len
);
2915 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2916 ok(1 == r
, "expected 1, got %d\n", r
);
2917 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2918 ok(13 == len
, "expected 13, got %d\n", len
);
2920 destroy_child_editcontrol(hwEdit
);
2922 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2924 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2925 ok(1 == r
, "expected 1, got %d\n", r
);
2926 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2927 ok(11 == len
, "expected 11, got %d\n", len
);
2930 msg
.message
= WM_KEYDOWN
;
2931 msg
.wParam
= VK_BACK
;
2932 msg
.lParam
= 0xe0001;
2933 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_BACK
, (LPARAM
)&msg
);
2934 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2936 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2937 ok(1 == r
, "expected 1, got %d\n", r
);
2938 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2939 ok(11 == len
, "expected 11, got %d\n", len
);
2941 DestroyWindow(hwEdit
);
2943 hwEdit
= create_child_editcontrol(0, 0);
2944 hwParent
= GetParent(hwEdit
);
2945 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2948 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2949 ok(1 == r
, "expected 1, got %d\n", r
);
2950 test_dm_messages(0, 0, 0, 0);
2953 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2954 ok(1 == r
, "expected 1, got %d\n", r
);
2955 test_dm_messages(0, 0, 0, 0);
2959 msg
.message
= WM_KEYDOWN
;
2960 msg
.wParam
= VK_TAB
;
2961 msg
.lParam
= 0xf0001;
2962 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_TAB
, (LPARAM
)&msg
);
2963 ok(0x89 == r
, "expected 0x89, got 0x%x\n", r
);
2964 test_dm_messages(0, 0, 0, 0);
2967 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2968 ok(1 == r
, "expected 1, got %d\n", r
);
2969 test_dm_messages(0, 0, 0, 0);
2972 destroy_child_editcontrol(hwEdit
);
2974 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2975 hwParent
= GetParent(hwEdit
);
2976 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2978 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2979 ok(1 == r
, "expected 1, got %d\n", r
);
2980 test_dm_messages(0, 0, 0, 0);
2984 msg
.message
= WM_KEYDOWN
;
2985 msg
.wParam
= VK_ESCAPE
;
2986 msg
.lParam
= 0x10001;
2987 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_ESCAPE
, (LPARAM
)&msg
);
2988 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2989 test_dm_messages(0, 0, 0, 0);
2992 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2993 ok(1 == r
, "expected 1, got %d\n", r
);
2994 test_dm_messages(0, 0, 0, 0);
2997 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2998 ok(1 == r
, "expected 1, got %d\n", r
);
2999 test_dm_messages(0, 0, 0, 1);
3002 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
3003 ok(1 == r
, "expected 1, got %d\n", r
);
3004 test_dm_messages(0, 0, 1, 0);
3007 hwButton
= CreateWindowA("BUTTON", "OK", WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
,
3008 100, 100, 50, 20, hwParent
, (HMENU
)ID_EDITTESTDBUTTON
, hinst
, NULL
);
3009 ok(hwButton
!=NULL
, "CreateWindow failed with error code %d\n", GetLastError());
3011 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
3012 ok(1 == r
, "expected 1, got %d\n", r
);
3013 test_dm_messages(0, 0, 1, 1);
3016 DestroyWindow(hwButton
);
3017 destroy_child_editcontrol(hwEdit
);
3020 static void test_EM_GETHANDLE(void)
3022 static const char str0
[] = "untouched";
3023 static const char str1
[] = "1111+1111+1111#";
3024 static const char str1_1
[] = "2111+1111+1111#";
3025 static const char str2
[] = "2222-2222-2222-2222#";
3026 static const char str3
[] = "3333*3333*3333*3333*3333#";
3036 trace("EDIT: EM_GETHANDLE\n");
3038 /* EM_GETHANDLE is not supported for a single line edit control */
3039 hEdit
= create_editcontrol(WS_BORDER
, 0);
3040 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
3042 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
3043 ok(hmem
== NULL
, "got %p (expected NULL)\n", hmem
);
3044 DestroyWindow(hEdit
);
3047 /* EM_GETHANDLE needs a multiline edit control */
3048 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
3049 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
3052 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
3053 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3054 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
3056 lstrcpyA(current
, str0
);
3057 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
3058 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
3059 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
3061 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
3062 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
3063 /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
3064 buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
3066 buffer
= LocalLock(hmem
);
3067 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
3068 len
= lstrlenA(buffer
);
3069 ok((len
== lstrlenA(str1
)) && !lstrcmpA(buffer
, str1
),
3070 "got %d and \"%s\" (expected %d and \"%s\")\n", len
, buffer
, lstrlenA(str1
), str1
);
3073 /* See if WM_GETTEXTLENGTH/WM_GETTEXT still work. */
3074 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3075 ok(len
== lstrlenA(str1
), "Unexpected text length %d.\n", len
);
3077 lstrcpyA(current
, str0
);
3078 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
3079 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
3080 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
3082 /* Application altered buffer contents, see if WM_GETTEXTLENGTH/WM_GETTEXT pick that up. */
3083 buffer
= LocalLock(hmem
);
3084 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
3088 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3089 ok(len
== lstrlenA(str1_1
), "Unexpected text length %d.\n", len
);
3091 lstrcpyA(current
, str0
);
3092 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
3093 ok((r
== lstrlenA(str1_1
)) && !lstrcmpA(current
, str1_1
),
3094 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1_1
), str1_1
);
3096 /* See if WM_SETTEXT/EM_REPLACESEL work. */
3097 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
3098 ok(r
, "Failed to set text.\n");
3100 buffer
= LocalLock(hmem
);
3101 ok(buffer
!= NULL
&& buffer
[0] == '1', "Unexpected buffer contents\n");
3104 r
= SendMessageA(hEdit
, EM_REPLACESEL
, 0, (LPARAM
)str1_1
);
3105 ok(r
, "Failed to replace selection.\n");
3107 buffer
= LocalLock(hmem
);
3108 ok(buffer
!= NULL
&& buffer
[0] == '2', "Unexpected buffer contents\n");
3111 /* use LocalAlloc first to get a different handle */
3112 halloc
= LocalAlloc(LMEM_MOVEABLE
, 42);
3113 ok(halloc
!= NULL
, "got %p (expected != NULL)\n", halloc
);
3114 /* prepare our new memory */
3115 buffer
= LocalLock(halloc
);
3116 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
3117 lstrcpyA(buffer
, str2
);
3118 LocalUnlock(halloc
);
3120 /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
3122 /* use LocalAlloc after the LocalFree to likely consume the handle */
3123 hmem2
= LocalAlloc(LMEM_MOVEABLE
, 42);
3124 ok(hmem2
!= NULL
, "got %p (expected != NULL)\n", hmem2
);
3126 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)halloc
, 0);
3128 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3129 ok(len
== lstrlenA(str2
), "got %d (expected %d)\n", len
, lstrlenA(str2
));
3131 lstrcpyA(current
, str0
);
3132 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
3133 ok((r
== lstrlenA(str2
)) && !lstrcmpA(current
, str2
),
3134 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str2
), str2
);
3136 /* set a different text */
3137 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str3
);
3138 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3139 ok((r
== 1) && (len
== lstrlenA(str3
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str3
));
3141 lstrcpyA(current
, str0
);
3142 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
3143 ok((r
== lstrlenA(str3
)) && !lstrcmpA(current
, str3
),
3144 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str3
), str3
);
3147 DestroyWindow(hEdit
);
3149 /* Some apps have bugs ... */
3150 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
3153 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
3154 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3155 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
3157 /* everything is normal up to EM_GETHANDLE */
3158 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
3159 /* Some messages still work while other messages fail.
3160 After LocalFree the memory handle, messages can crash the app */
3162 /* A buggy editor used EM_GETHANDLE twice */
3163 hmem2
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
3164 ok(hmem2
== hmem
, "got %p (expected %p)\n", hmem2
, hmem
);
3166 /* Let the edit control free the memory handle */
3167 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)hmem2
, 0);
3169 DestroyWindow(hEdit
);
3172 static void test_paste(void)
3174 HWND hEdit
, hMultilineEdit
;
3175 HANDLE hmem
, hmem_ret
;
3178 static const char *str
= "this is a simple text";
3179 static const char *str2
= "first line\r\nsecond line";
3181 hEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
3182 hMultilineEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
, 0);
3184 /* Prepare clipboard data with simple text */
3185 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 255);
3186 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
3187 buffer
= GlobalLock(hmem
);
3188 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
3189 strcpy(buffer
, str
);
3192 r
= OpenClipboard(hEdit
);
3193 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
3194 r
= EmptyClipboard();
3195 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
3196 hmem_ret
= SetClipboardData(CF_TEXT
, hmem
);
3197 ok(hmem_ret
== hmem
, "expected %p, got %p\n", hmem
, hmem_ret
);
3198 r
= CloseClipboard();
3199 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
3201 /* Paste single line */
3202 SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
3203 r
= SendMessageA(hEdit
, WM_PASTE
, 0, 0);
3204 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3205 ok(strlen(str
) == len
, "got %d\n", len
);
3207 /* Prepare clipboard data with multiline text */
3208 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 255);
3209 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
3210 buffer
= GlobalLock(hmem
);
3211 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
3212 strcpy(buffer
, str2
);
3215 r
= OpenClipboard(hEdit
);
3216 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
3217 r
= EmptyClipboard();
3218 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
3219 hmem_ret
= SetClipboardData(CF_TEXT
, hmem
);
3220 ok(hmem_ret
== hmem
, "expected %p, got %p\n", hmem
, hmem_ret
);
3221 r
= CloseClipboard();
3222 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
3224 /* Paste multiline text in singleline edit - should be cut */
3225 SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
3226 r
= SendMessageA(hEdit
, WM_PASTE
, 0, 0);
3227 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
3228 ok(strlen("first line") == len
, "got %d\n", len
);
3230 /* Paste multiline text in multiline edit */
3231 SendMessageA(hMultilineEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
3232 r
= SendMessageA(hMultilineEdit
, WM_PASTE
, 0, 0);
3233 len
= SendMessageA(hMultilineEdit
, WM_GETTEXTLENGTH
, 0, 0);
3234 ok(strlen(str2
) == len
, "got %d\n", len
);
3237 DestroyWindow(hEdit
);
3238 DestroyWindow(hMultilineEdit
);
3241 static void test_EM_GETLINE(void)
3246 hwnd
[0] = create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
3247 hwnd
[1] = create_editcontrolW(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
3249 for (i
= 0; i
< ARRAY_SIZE(hwnd
); i
++)
3251 static const WCHAR strW
[] = {'t','e','x','t',0};
3252 static const char *str
= "text";
3258 ok(!IsWindowUnicode(hwnd
[i
]), "Expected ansi window.\n");
3260 ok(IsWindowUnicode(hwnd
[i
]), "Expected unicode window.\n");
3262 SendMessageA(hwnd
[i
], WM_SETTEXT
, 0, (LPARAM
)str
);
3264 memset(buff
, 0, sizeof(buff
));
3265 *(WORD
*)buff
= sizeof(buff
);
3266 r
= SendMessageA(hwnd
[i
], EM_GETLINE
, 0, (LPARAM
)buff
);
3267 ok(r
== strlen(str
), "Failed to get a line %d.\n", r
);
3268 ok(!strcmp(buff
, str
), "Unexpected line data %s.\n", buff
);
3270 memset(buff
, 0, sizeof(buff
));
3271 *(WORD
*)buff
= sizeof(buff
);
3272 r
= SendMessageA(hwnd
[i
], EM_GETLINE
, 1, (LPARAM
)buff
);
3273 ok(r
== strlen(str
), "Failed to get a line %d.\n", r
);
3274 ok(!strcmp(buff
, str
), "Unexpected line data %s.\n", buff
);
3276 memset(buffW
, 0, sizeof(buffW
));
3277 *(WORD
*)buffW
= ARRAY_SIZE(buffW
);
3278 r
= SendMessageW(hwnd
[i
], EM_GETLINE
, 0, (LPARAM
)buffW
);
3279 ok(r
== lstrlenW(strW
), "Failed to get a line %d.\n", r
);
3280 ok(!lstrcmpW(buffW
, strW
), "Unexpected line data %s.\n", wine_dbgstr_w(buffW
));
3282 memset(buffW
, 0, sizeof(buffW
));
3283 *(WORD
*)buffW
= ARRAY_SIZE(buffW
);
3284 r
= SendMessageW(hwnd
[i
], EM_GETLINE
, 1, (LPARAM
)buffW
);
3285 ok(r
== lstrlenW(strW
), "Failed to get a line %d.\n", r
);
3286 ok(!lstrcmpW(buffW
, strW
), "Unexpected line data %s.\n", wine_dbgstr_w(buffW
));
3288 DestroyWindow(hwnd
[i
]);
3292 static int CALLBACK
test_wordbreak_procA(char *text
, int current
, int length
, int code
)
3297 static void test_wordbreak_proc(void)
3299 EDITWORDBREAKPROCA proc
;
3303 hwnd
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
3305 proc
= (void *)SendMessageA(hwnd
, EM_GETWORDBREAKPROC
, 0, 0);
3306 ok(proc
== NULL
, "Unexpected wordbreak proc %p.\n", proc
);
3308 ret
= SendMessageA(hwnd
, EM_SETWORDBREAKPROC
, 0, (LPARAM
)test_wordbreak_procA
);
3309 ok(ret
== 1, "Unexpected return value %ld.\n", ret
);
3311 proc
= (void *)SendMessageA(hwnd
, EM_GETWORDBREAKPROC
, 0, 0);
3312 ok(proc
== test_wordbreak_procA
, "Unexpected wordbreak proc %p.\n", proc
);
3314 ret
= SendMessageA(hwnd
, EM_SETWORDBREAKPROC
, 0, 0);
3315 ok(ret
== 1, "Unexpected return value %ld.\n", ret
);
3317 proc
= (void *)SendMessageA(hwnd
, EM_GETWORDBREAKPROC
, 0, 0);
3318 ok(proc
== NULL
, "Unexpected wordbreak proc %p.\n", proc
);
3320 DestroyWindow(hwnd
);
3327 hinst
= GetModuleHandleA(NULL
);
3328 b
= RegisterWindowClasses();
3329 ok (b
, "RegisterWindowClasses failed\n");
3332 test_edit_control_1();
3333 test_edit_control_2();
3334 test_edit_control_3();
3335 test_char_from_pos();
3336 test_edit_control_5();
3337 test_edit_control_6();
3338 test_edit_control_limittext();
3339 test_edit_control_scroll();
3340 test_initialization();
3342 test_margins_font_change();
3343 test_text_position();
3349 test_multi_edit_dialog();
3350 test_wantreturn_edit_dialog();
3351 test_singleline_wantreturn_edit_dialog();
3352 test_child_edit_wmkeydown();
3356 test_EM_GETHANDLE();
3359 test_wordbreak_proc();
3361 UnregisterWindowClasses();