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
24 #define ES_COMBO 0x200
27 #define ID_EDITTESTDBUTTON 0x123
28 #define ID_EDITTEST2 99
32 int en_change
, en_maxtext
, en_update
;
35 static struct edit_notify notifications
;
37 static INT_PTR CALLBACK
multi_edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
39 static int num_ok_commands
= 0;
44 HWND hedit
= GetDlgItem(hdlg
, 1000);
48 /* test cases related to bug 12319 */
50 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
51 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
54 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
55 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
58 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
59 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
60 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
63 /* test cases for pressing enter */
66 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
67 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
77 if (HIWORD(wparam
) != BN_CLICKED
)
80 switch (LOWORD(wparam
))
93 HWND hfocus
= GetFocus();
94 HWND hedit
= GetDlgItem(hdlg
, 1000);
95 HWND hedit2
= GetDlgItem(hdlg
, 1001);
96 HWND hedit3
= GetDlgItem(hdlg
, 1002);
98 if (wparam
!= 0xdeadbeef)
105 EndDialog(hdlg
, 1111);
106 else if (hfocus
== hedit2
)
107 EndDialog(hdlg
, 2222);
108 else if (hfocus
== hedit3
)
109 EndDialog(hdlg
, 3333);
111 EndDialog(hdlg
, 4444);
114 if ((hfocus
== hedit
) && (num_ok_commands
== 0))
120 EndDialog(hdlg
, 5555);
126 EndDialog(hdlg
, 333);
136 static INT_PTR CALLBACK
edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
142 HWND hedit
= GetDlgItem(hdlg
, 1000);
148 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
151 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
154 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
155 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
158 /* more test cases for WM_CHAR */
160 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
161 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
164 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
165 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
168 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
169 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
172 /* more test cases for WM_KEYDOWN + WM_CHAR */
174 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
175 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
176 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
179 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
180 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
181 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
184 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
185 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
186 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
189 /* multiple tab tests */
191 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
192 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
193 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
196 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
197 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
198 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
199 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
209 if (HIWORD(wparam
) != BN_CLICKED
)
212 switch (LOWORD(wparam
))
215 EndDialog(hdlg
, 111);
219 EndDialog(hdlg
, 222);
230 HWND hok
= GetDlgItem(hdlg
, IDOK
);
231 HWND hcancel
= GetDlgItem(hdlg
, IDCANCEL
);
232 HWND hedit
= GetDlgItem(hdlg
, 1000);
233 HWND hfocus
= GetFocus();
235 if (wparam
!= 0xdeadbeef)
241 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
243 EndDialog(hdlg
, 444);
245 EndDialog(hdlg
, 555);
249 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
250 if ((hfocus
== hok
) && len
== 0)
251 EndDialog(hdlg
, 444);
253 EndDialog(hdlg
, 555);
259 else if (hfocus
== hcancel
)
261 else if (hfocus
== hedit
)
268 EndDialog(hdlg
, 555);
274 EndDialog(hdlg
, 333);
284 static INT_PTR CALLBACK
edit_singleline_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
290 HWND hedit
= GetDlgItem(hdlg
, 1000);
294 /* test cases for WM_KEYDOWN */
296 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
299 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
302 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
303 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
306 /* test cases for WM_CHAR */
308 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
309 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
312 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
313 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
316 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
317 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
320 /* test cases for WM_KEYDOWN + WM_CHAR */
322 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
323 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
326 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
327 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
330 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
331 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
332 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
342 if (HIWORD(wparam
) != BN_CLICKED
)
345 switch (LOWORD(wparam
))
348 EndDialog(hdlg
, 111);
352 EndDialog(hdlg
, 222);
362 HWND hok
= GetDlgItem(hdlg
, IDOK
);
363 HWND hedit
= GetDlgItem(hdlg
, 1000);
364 HWND hfocus
= GetFocus();
365 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
367 if (wparam
!= 0xdeadbeef)
373 if ((hfocus
== hedit
) && len
== 0)
374 EndDialog(hdlg
, 444);
376 EndDialog(hdlg
, 555);
380 if ((hfocus
== hok
) && len
== 0)
381 EndDialog(hdlg
, 444);
383 EndDialog(hdlg
, 555);
393 EndDialog(hdlg
, 333);
403 static INT_PTR CALLBACK
edit_wantreturn_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
409 HWND hedit
= GetDlgItem(hdlg
, 1000);
413 /* test cases for WM_KEYDOWN */
415 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
418 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
419 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
422 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
423 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
426 /* test cases for WM_CHAR */
428 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
429 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
432 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
433 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
436 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
437 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
440 /* test cases for WM_KEYDOWN + WM_CHAR */
442 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
443 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
444 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
447 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
448 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
449 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
452 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
453 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
454 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
464 if (HIWORD(wparam
) != BN_CLICKED
)
467 switch (LOWORD(wparam
))
470 EndDialog(hdlg
, 111);
474 EndDialog(hdlg
, 222);
484 HWND hok
= GetDlgItem(hdlg
, IDOK
);
485 HWND hedit
= GetDlgItem(hdlg
, 1000);
486 HWND hfocus
= GetFocus();
487 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
489 if (wparam
!= 0xdeadbeef)
495 if ((hfocus
== hedit
) && len
== 0)
496 EndDialog(hdlg
, 444);
498 EndDialog(hdlg
, 555);
502 if ((hfocus
== hok
) && len
== 0)
503 EndDialog(hdlg
, 444);
505 EndDialog(hdlg
, 555);
509 if ((hfocus
== hedit
) && len
== 2)
510 EndDialog(hdlg
, 444);
512 EndDialog(hdlg
, 555);
522 EndDialog(hdlg
, 333);
532 static HINSTANCE hinst
;
534 static const char szEditTest2Class
[] = "EditTest2Class";
535 static const char szEditTest3Class
[] = "EditTest3Class";
536 static const char szEditTest4Class
[] = "EditTest4Class";
537 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
539 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
543 handle
= CreateWindowExA(exstyle
,
548 NULL
, NULL
, hinst
, NULL
);
549 ok (handle
!= NULL
, "CreateWindow EDIT Control failed\n");
551 if (winetest_interactive
)
552 ShowWindow (handle
, SW_SHOW
);
556 static HWND
create_editcontrolW(DWORD style
, DWORD exstyle
)
558 static const WCHAR testtextW
[] = {'T','e','s','t',' ','t','e','x','t',0};
561 handle
= CreateWindowExW(exstyle
, WC_EDITW
, testtextW
, style
, 10, 10, 300, 300,
562 NULL
, NULL
, hinst
, NULL
);
563 ok(handle
!= NULL
, "Failed to create Edit control.\n");
567 static HWND
create_child_editcontrol (DWORD style
, DWORD exstyle
)
573 SetRect(&rect
, 0, 0, 300, 300);
574 b
= AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
);
575 ok(b
, "AdjustWindowRect failed\n");
577 parentWnd
= CreateWindowExA(0,
578 szEditTextPositionClass
,
581 CW_USEDEFAULT
, CW_USEDEFAULT
,
582 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
583 NULL
, NULL
, hinst
, NULL
);
584 ok (parentWnd
!= NULL
, "CreateWindow EDIT Test failed\n");
587 editWnd
= CreateWindowExA(exstyle
,
592 parentWnd
, NULL
, hinst
, NULL
);
593 ok (editWnd
!= NULL
, "CreateWindow EDIT Test Text failed\n");
595 if (winetest_interactive
)
596 ShowWindow (parentWnd
, SW_SHOW
);
600 static void destroy_child_editcontrol (HWND hwndEdit
)
602 if (GetParent(hwndEdit
))
603 DestroyWindow(GetParent(hwndEdit
));
605 trace("Edit control has no parent!\n");
606 DestroyWindow(hwndEdit
);
610 static LONG
get_edit_style (HWND hwnd
)
612 return GetWindowLongA( hwnd
, GWL_STYLE
) & (
614 /* FIXME: not implemented
633 static void set_client_height(HWND Wnd
, unsigned Height
)
635 RECT ClientRect
, WindowRect
;
637 GetWindowRect(Wnd
, &WindowRect
);
638 GetClientRect(Wnd
, &ClientRect
);
639 SetWindowPos(Wnd
, NULL
, 0, 0,
640 WindowRect
.right
- WindowRect
.left
,
641 Height
+ (WindowRect
.bottom
- WindowRect
.top
) -
642 (ClientRect
.bottom
- ClientRect
.top
),
643 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
645 /* Workaround for a bug in Windows' edit control
647 GetWindowRect(Wnd
, &WindowRect
);
648 SetWindowPos(Wnd
, NULL
, 0, 0,
649 WindowRect
.right
- WindowRect
.left
+ 1,
650 WindowRect
.bottom
- WindowRect
.top
+ 1,
651 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
652 SetWindowPos(Wnd
, NULL
, 0, 0,
653 WindowRect
.right
- WindowRect
.left
,
654 WindowRect
.bottom
- WindowRect
.top
,
655 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
657 GetClientRect(Wnd
, &ClientRect
);
658 ok(ClientRect
.bottom
- ClientRect
.top
== Height
,
659 "The client height should be %d, but is %d\n",
660 Height
, ClientRect
.bottom
- ClientRect
.top
);
663 static void test_edit_control_1(void)
670 msMessage
.message
= WM_KEYDOWN
;
672 trace("EDIT: Single line\n");
673 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
674 r
= get_edit_style(hwEdit
);
675 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
), "Wrong style expected 0xc0 got: 0x%x\n", r
);
676 for (i
= 0; i
< 65535; i
++)
678 msMessage
.wParam
= i
;
679 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
680 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
681 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
683 DestroyWindow(hwEdit
);
685 trace("EDIT: Single line want returns\n");
686 hwEdit
= create_editcontrol(ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
687 r
= get_edit_style(hwEdit
);
688 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
| ES_WANTRETURN
), "Wrong style expected 0x10c0 got: 0x%x\n", r
);
689 for (i
= 0; i
< 65535; i
++)
691 msMessage
.wParam
= i
;
692 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
693 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
694 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
696 DestroyWindow(hwEdit
);
698 trace("EDIT: Multiline line\n");
699 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
700 r
= get_edit_style(hwEdit
);
701 ok(r
== (ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0xc4 got: 0x%x\n", r
);
702 for (i
= 0; i
< 65535; i
++)
704 msMessage
.wParam
= i
;
705 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
706 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
707 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
709 DestroyWindow(hwEdit
);
711 trace("EDIT: Multi line want returns\n");
712 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
713 r
= get_edit_style(hwEdit
);
714 ok(r
== (ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0x10c4 got: 0x%x\n", r
);
715 for (i
= 0; i
< 65535; i
++)
717 msMessage
.wParam
= i
;
718 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
719 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
720 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
722 DestroyWindow(hwEdit
);
725 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
726 * selection. This test checks that the first 'select all' doesn't generate
727 * an UPDATE message which can escape and (via a handler) change the
728 * selection, which would cause WM_SETTEXT to break. This old bug
729 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
731 static void test_edit_control_2(void)
733 HWND hwndMain
, phwnd
;
734 char szLocalString
[MAXLEN
];
735 LONG r
, w
= 150, h
= 50;
738 /* Create main and edit windows. */
739 hwndMain
= CreateWindowA(szEditTest2Class
, "ET2", WS_OVERLAPPEDWINDOW
,
740 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
742 if (winetest_interactive
)
743 ShowWindow (hwndMain
, SW_SHOW
);
745 hwndET2
= CreateWindowA("EDIT", NULL
,
746 WS_CHILD
|WS_BORDER
|ES_LEFT
|ES_AUTOHSCROLL
,
747 0, 0, w
, h
, /* important this not be 0 size. */
748 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
750 if (winetest_interactive
)
751 ShowWindow (hwndET2
, SW_SHOW
);
753 trace("EDIT: SETTEXT atomicity\n");
754 /* Send messages to "type" in the word 'foo'. */
755 r
= SendMessageA(hwndET2
, WM_CHAR
, 'f', 1);
756 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
757 r
= SendMessageA(hwndET2
, WM_CHAR
, 'o', 1);
758 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
759 r
= SendMessageA(hwndET2
, WM_CHAR
, 'o', 1);
760 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
761 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
762 GetWindowTextA(hwndET2
, szLocalString
, MAXLEN
);
763 ok(strcmp(szLocalString
, "bar")==0,
764 "Wrong contents of edit: %s\n", szLocalString
);
766 /* try setting the caret before it's visible */
767 r
= SetCaretPos(0, 0);
768 todo_wine
ok(0 == r
, "SetCaretPos succeeded unexpectedly, expected: 0, got: %d\n", r
);
769 phwnd
= SetFocus(hwndET2
);
770 ok(phwnd
!= NULL
, "SetFocus failed unexpectedly, expected non-zero, got NULL\n");
771 r
= SetCaretPos(0, 0);
772 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
773 r
= GetCaretPos(&cpos
);
774 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
775 ok(cpos
.x
== 0 && cpos
.y
== 0, "Wrong caret position, expected: (0,0), got: (%d,%d)\n", cpos
.x
, cpos
.y
);
776 r
= SetCaretPos(-1, -1);
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
== -1 && cpos
.y
== -1, "Wrong caret position, expected: (-1,-1), got: (%d,%d)\n", cpos
.x
, cpos
.y
);
781 r
= SetCaretPos(w
<< 1, h
<< 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
== (w
<< 1) && cpos
.y
== (h
<< 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
<< 1, h
<< 1, cpos
.x
, cpos
.y
);
786 r
= SetCaretPos(w
, h
);
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
&& cpos
.y
== h
, "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
, h
, cpos
.x
, cpos
.y
);
791 r
= SetCaretPos(w
- 1, h
- 1);
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
- 1) && cpos
.y
== (h
- 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
- 1, h
- 1, cpos
.x
, cpos
.y
);
797 DestroyWindow(hwndET2
);
798 DestroyWindow(hwndMain
);
801 static void ET2_check_change(void)
803 char szLocalString
[MAXLEN
];
804 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
805 GetWindowTextA(hwndET2
, szLocalString
, MAXLEN
);
806 if (!strcmp(szLocalString
, "foo"))
808 strcpy(szLocalString
, "bar");
809 SendMessageA(hwndET2
, WM_SETTEXT
, 0, (LPARAM
)szLocalString
);
811 /* always leave the cursor at the end. */
812 SendMessageA(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
815 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
817 if (id
== ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
821 static LRESULT CALLBACK
ET2_WndProc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
826 ET2_OnCommand(hwnd
, LOWORD(wParam
), (HWND
)lParam
, HIWORD(wParam
));
829 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
832 static void zero_notify(void)
834 notifications
.en_change
= 0;
835 notifications
.en_maxtext
= 0;
836 notifications
.en_update
= 0;
839 #define test_notify(enchange, enmaxtext, enupdate) \
841 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
842 "got %d\n", enchange, notifications.en_change); \
843 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
844 "got %d\n", enmaxtext, notifications.en_maxtext); \
845 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
846 "got %d\n", enupdate, notifications.en_update); \
849 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
854 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)
876 static const char *str
= "this is a long string.";
877 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.";
883 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
884 ReleaseDC(NULL
, hDC
);
886 trace("EDIT: Test notifications\n");
888 hParent
= CreateWindowExA(0,
892 CW_USEDEFAULT
, CW_USEDEFAULT
, 10, 10,
893 NULL
, NULL
, NULL
, NULL
);
896 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
897 hWnd
= CreateWindowExA(0,
902 hParent
, NULL
, NULL
, NULL
);
906 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
907 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
908 if (len
== lstrlenA(str
)) /* Win 8 */
909 test_notify(1, 0, 1);
911 test_notify(1, 1, 1);
913 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
915 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
916 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
917 ok(1 == len
, "wrong text length, expected 1, got %d\n", len
);
918 test_notify(1, 0, 1);
921 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
922 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
923 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
924 test_notify(1, 0, 1);
926 len
= SendMessageA(hWnd
, EM_GETSEL
, 0, 0);
927 ok(LOWORD(len
)==0, "Unexpected start position for selection %d\n", LOWORD(len
));
928 ok(HIWORD(len
)==0, "Unexpected end position for selection %d\n", HIWORD(len
));
929 SendMessageA(hParent
, WM_SETFOCUS
, 0, (LPARAM
)hWnd
);
930 len
= SendMessageA(hWnd
, EM_GETSEL
, 0, 0);
931 ok(LOWORD(len
)==0, "Unexpected start position for selection %d\n", LOWORD(len
));
932 ok(HIWORD(len
)==0, "Unexpected end position for selection %d\n", HIWORD(len
));
934 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
936 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
938 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
939 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
940 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
941 test_notify(1, 1, 1);
944 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
945 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
946 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
947 test_notify(1, 0, 1);
951 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
952 hWnd
= CreateWindowExA(0,
957 hParent
, NULL
, NULL
, NULL
);
961 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
962 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
963 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
964 test_notify(1, 0, 1);
967 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
968 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
969 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
970 test_notify(1, 0, 1);
972 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
974 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
975 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
976 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
977 test_notify(1, 0, 1);
980 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
981 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
982 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
983 test_notify(1, 0, 1);
985 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
987 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
989 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
990 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
991 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
992 test_notify(1, 1, 1);
995 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
996 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
997 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
998 test_notify(1, 0, 1);
1000 DestroyWindow(hWnd
);
1002 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1003 hWnd
= CreateWindowExA(0,
1007 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1008 hParent
, NULL
, NULL
, NULL
);
1012 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1013 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1014 if (len
== lstrlenA(str
)) /* Win 8 */
1015 test_notify(1, 0, 1);
1018 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1019 test_notify(1, 1, 1);
1022 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1024 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1025 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1026 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1027 test_notify(1, 0, 1);
1030 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1031 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1032 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1033 test_notify(0, 0, 0);
1035 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1037 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1039 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1040 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1041 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1042 test_notify(1, 1, 1);
1045 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1046 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1047 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1048 test_notify(0, 0, 0);
1050 DestroyWindow(hWnd
);
1052 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1053 hWnd
= CreateWindowExA(0,
1056 ES_MULTILINE
| ES_AUTOHSCROLL
,
1057 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1058 hParent
, NULL
, NULL
, NULL
);
1062 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1063 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1064 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1065 test_notify(1, 1, 1);
1067 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1069 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1070 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1071 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1072 test_notify(1, 0, 1);
1075 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1076 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1077 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1078 test_notify(0, 0, 0);
1080 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1082 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1084 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1085 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1086 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1087 test_notify(1, 1, 1);
1090 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1091 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1092 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1093 test_notify(0, 0, 0);
1095 DestroyWindow(hWnd
);
1097 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1098 hWnd
= CreateWindowExA(0,
1101 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
1103 hParent
, NULL
, NULL
, NULL
);
1107 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1108 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1109 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1110 test_notify(1, 0, 1);
1113 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1114 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1115 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1116 test_notify(0, 0, 0);
1118 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1120 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1122 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1123 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1124 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1125 test_notify(1, 1, 1);
1128 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1129 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1130 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1131 test_notify(0, 0, 0);
1133 DestroyWindow(hWnd
);
1136 static void test_char_from_pos(void)
1138 int lo
, hi
, mid
, ret
, i
;
1141 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1142 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1143 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1144 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1145 mid
= lo
+ (hi
- lo
) / 2;
1147 for (i
= lo
; i
< mid
; i
++)
1149 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1150 ok(0 == ret
, "expected 0 got %d\n", ret
);
1153 for (i
= mid
; i
<= hi
; i
++)
1155 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1156 ok(1 == ret
, "expected 1 got %d\n", ret
);
1159 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1160 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1161 DestroyWindow(hwEdit
);
1163 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1164 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1165 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1166 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1167 mid
= lo
+ (hi
- lo
) / 2;
1169 for (i
= lo
; i
< mid
; i
++)
1171 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1172 ok(0 == ret
, "expected 0 got %d\n", ret
);
1175 for (i
= mid
; i
<= hi
; i
++)
1177 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1178 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
++)
1193 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1194 ok(0 == ret
, "expected 0 got %d\n", ret
);
1197 for (i
= mid
; i
<= hi
; i
++)
1199 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1200 ok(1 == ret
, "expected 1 got %d\n", ret
);
1203 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1204 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1205 DestroyWindow(hwEdit
);
1207 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1208 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1209 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1210 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1211 mid
= lo
+ (hi
- lo
) / 2 + 1;
1213 for (i
= lo
; i
< mid
; i
++)
1215 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1216 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1219 for (i
= mid
; i
<= hi
; i
++)
1221 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1222 ok(1 == ret
, "expected 1 got %d\n", ret
);
1225 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1226 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1227 DestroyWindow(hwEdit
);
1229 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1230 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1231 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1232 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1233 mid
= lo
+ (hi
- lo
) / 2 + 1;
1235 for (i
= lo
; i
< mid
; i
++)
1237 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1238 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1241 for (i
= mid
; i
<= hi
; i
++)
1243 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1244 ok(1 == ret
, "expected 1 got %d\n", ret
);
1247 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1248 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1249 DestroyWindow(hwEdit
);
1251 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1252 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
)"aa");
1253 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1254 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1255 mid
= lo
+ (hi
- lo
) / 2 + 1;
1257 for (i
= lo
; i
< mid
; i
++)
1259 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1260 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1263 for (i
= mid
; i
<= hi
; i
++)
1265 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1266 ok(1 == ret
, "expected 1 got %d\n", ret
);
1269 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1270 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1271 DestroyWindow(hwEdit
);
1274 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1275 * truncates text that doesn't fit.
1277 static void test_edit_control_5(void)
1279 static const char *str
= "test\r\ntest";
1283 RECT rc1
= { 10, 10, 11, 11};
1286 /* first show that a non-child won't do for this test */
1287 hWnd
= CreateWindowExA(0,
1292 NULL
, NULL
, NULL
, NULL
);
1294 /* size of non-child edit control is (much) bigger than requested */
1295 GetWindowRect( hWnd
, &rc
);
1296 ok( rc
.right
- rc
.left
> 20, "size of the window (%d) is smaller than expected\n",
1297 rc
.right
- rc
.left
);
1298 DestroyWindow(hWnd
);
1299 /* so create a parent, and give it edit controls children to test with */
1300 parentWnd
= CreateWindowExA(0,
1301 szEditTextPositionClass
,
1302 "Edit Test", WS_VISIBLE
|
1303 WS_OVERLAPPEDWINDOW
,
1304 CW_USEDEFAULT
, CW_USEDEFAULT
,
1306 NULL
, NULL
, hinst
, NULL
);
1308 ShowWindow( parentWnd
, SW_SHOW
);
1310 hWnd
= CreateWindowExA(0,
1312 str
, WS_VISIBLE
| WS_BORDER
|
1314 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1315 parentWnd
, NULL
, NULL
, NULL
);
1317 GetClientRect( hWnd
, &rc
);
1318 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1319 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc
));
1320 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1321 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1322 DestroyWindow(hWnd
);
1324 hWnd
= CreateWindowExA(0,
1327 WS_CHILD
| ES_MULTILINE
,
1328 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1329 parentWnd
, NULL
, NULL
, NULL
);
1331 GetClientRect( hWnd
, &rc
);
1332 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1333 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc
));
1334 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1335 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1336 DestroyWindow(hWnd
);
1337 DestroyWindow(parentWnd
);
1340 /* Test WM_GETTEXT processing
1341 * after destroy messages
1343 static void test_edit_control_6(void)
1345 static const char *str
= "test\r\ntest";
1350 hWnd
= CreateWindowExA(0, "EDIT", "Test", 0, 10, 10, 1, 1, NULL
, NULL
, hinst
, NULL
);
1351 ok(hWnd
!= NULL
, "Failed to create edit control.\n");
1353 ret
= SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1354 ok(ret
== TRUE
, "Expected %d, got %d\n", TRUE
, ret
);
1355 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1356 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1357 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1360 ret
= SendMessageA(hWnd
, WM_DESTROY
, 0, 0);
1362 ok(ret
== 1, "Unexpected return value %d\n", ret
);
1363 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1364 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1365 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1368 ret
= SendMessageA(hWnd
, WM_NCDESTROY
, 0, 0);
1369 ok(ret
== 0, "Expected 0, got %d\n", ret
);
1370 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1372 ok(ret
== strlen("Test"), "Unexpected text length %d\n", ret
);
1373 ok(!strcmp(buf
, "Test"), "Unexpected text %s\n", buf
);
1375 DestroyWindow(hWnd
);
1378 static void test_edit_control_limittext(void)
1383 /* Test default limit for single-line control */
1384 trace("EDIT: buffer limit for single-line\n");
1385 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1386 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1387 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1388 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1389 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1390 ok( r
== 2147483646, "got limit %u (expected 2147483646)\n", r
);
1391 DestroyWindow(hwEdit
);
1393 /* Test default limit for multi-line control */
1394 trace("EDIT: buffer limit for multi-line\n");
1395 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1396 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1397 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1398 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1399 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1400 ok( r
== 4294967295U, "got limit %u (expected 4294967295)\n", r
);
1401 DestroyWindow(hwEdit
);
1404 /* Test EM_SCROLL */
1405 static void test_edit_control_scroll(void)
1407 static const char *single_line_str
= "a";
1408 static const char *multiline_str
= "Test\r\nText";
1412 /* Check the return value when EM_SCROLL doesn't scroll
1413 * anything. Should not return true unless any lines were actually
1415 hwEdit
= CreateWindowA(
1418 WS_VSCROLL
| ES_MULTILINE
,
1420 NULL
, NULL
, hinst
, NULL
);
1424 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1425 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1427 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEUP
, 0);
1428 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1430 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEUP
, 0);
1431 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1433 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEDOWN
, 0);
1434 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1436 DestroyWindow (hwEdit
);
1438 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1439 should not cause EM_SCROLL to return a negative value of
1440 scrolled lines that would put us "before" the beginning. */
1441 hwEdit
= CreateWindowA(
1444 WS_VSCROLL
| ES_MULTILINE
,
1446 NULL
, NULL
, hinst
, NULL
);
1449 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1450 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1452 DestroyWindow (hwEdit
);
1455 static void test_margins_usefontinfo(UINT charset
)
1457 INT margins
, threshold
, expect
, empty_expect
, small_expect
;
1466 memset(&lf
, 0, sizeof(lf
));
1468 lf
.lfWeight
= FW_NORMAL
;
1469 lf
.lfCharSet
= charset
;
1470 strcpy(lf
.lfFaceName
, "Tahoma");
1472 hfont
= CreateFontIndirectA(&lf
);
1473 ok(hfont
!= NULL
, "got %p\n", hfont
);
1475 /* Big window rectangle */
1476 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 5000, 1000, NULL
, NULL
, NULL
, NULL
);
1477 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1478 GetClientRect(hwnd
, &rect
);
1479 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1482 hfont
= SelectObject(hdc
, hfont
);
1483 size
.cx
= GdiGetCharDimensions( hdc
, NULL
, &size
.cy
);
1484 expect
= MAKELONG(size
.cx
/ 2, size
.cx
/ 2);
1486 empty_expect
= size
.cx
>= 28 ? small_expect
: expect
;
1488 charset
= GetTextCharset(hdc
);
1491 case SHIFTJIS_CHARSET
:
1492 case HANGUL_CHARSET
:
1493 case GB2312_CHARSET
:
1494 case CHINESEBIG5_CHARSET
:
1501 hfont
= SelectObject(hdc
, hfont
);
1502 ReleaseDC(hwnd
, hdc
);
1504 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1505 ok(margins
== 0, "got %x\n", margins
);
1506 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1507 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1509 ok(margins
== expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1512 ok(HIWORD(margins
) > 0 && LOWORD(margins
) > 0, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1513 expect
= empty_expect
= small_expect
= margins
;
1515 DestroyWindow(hwnd
);
1517 threshold
= (size
.cx
/ 2 + size
.cx
) * 2;
1519 /* Size below which non-cjk margins are zero */
1520 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, threshold
- 1, 100, NULL
, NULL
, NULL
, NULL
);
1521 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1522 GetClientRect(hwnd
, &rect
);
1523 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1525 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1526 ok(margins
== 0, "got %x\n", margins
);
1528 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1529 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1530 ok(margins
== small_expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1531 DestroyWindow(hwnd
);
1533 /* Size at which non-cjk margins become non-zero */
1534 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, threshold
, 100, NULL
, NULL
, NULL
, NULL
);
1535 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1536 GetClientRect(hwnd
, &rect
);
1537 ok(!IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1539 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1540 ok(margins
== 0, "got %x\n", margins
);
1542 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1543 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1544 ok(margins
== expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1545 DestroyWindow(hwnd
);
1548 hwnd
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
1549 ok(hwnd
!= NULL
, "got %p\n", hwnd
);
1550 GetClientRect(hwnd
, &rect
);
1551 ok(IsRectEmpty(&rect
), "got rect %s\n", wine_dbgstr_rect(&rect
));
1553 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1554 ok(margins
== 0, "got %x\n", margins
);
1556 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1557 margins
= SendMessageA(hwnd
, EM_GETMARGINS
, 0, 0);
1558 ok(margins
== empty_expect
, "%d: got %d, %d\n", charset
, HIWORD(margins
), LOWORD(margins
));
1559 DestroyWindow(hwnd
);
1561 DeleteObject(hfont
);
1564 static void test_margins(void)
1566 DWORD old_margins
, new_margins
;
1567 RECT old_rect
, new_rect
;
1568 INT old_right_margin
;
1571 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1573 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1574 old_right_margin
= HIWORD(old_margins
);
1576 /* Check if setting the margins works */
1578 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
1579 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1580 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1581 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
1583 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
1584 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1585 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1586 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
1588 /* The size of the rectangle must decrease if we increase the margin */
1590 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
1591 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1592 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
1593 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1594 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
1595 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
1596 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
1597 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
1599 /* If we set the margin to same value as the current margin,
1600 the rectangle must not change */
1602 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1603 SetRect(&old_rect
, 1, 1, 99, 99);
1604 SendMessageA(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
1605 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1606 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1607 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1608 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1610 /* The lParam argument of the WM_SIZE message should be ignored. */
1612 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1613 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, 0);
1614 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1615 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1616 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MINIMIZED
, 0);
1617 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1618 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1619 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MAXIMIZED
, 0);
1620 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1621 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1622 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, MAKELONG(10, 10));
1623 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1624 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1626 DestroyWindow (hwEdit
);
1628 test_margins_usefontinfo(ANSI_CHARSET
);
1629 test_margins_usefontinfo(EASTEUROPE_CHARSET
);
1631 test_margins_usefontinfo(SHIFTJIS_CHARSET
);
1632 test_margins_usefontinfo(HANGUL_CHARSET
);
1633 test_margins_usefontinfo(CHINESEBIG5_CHARSET
);
1634 /* Don't test JOHAB_CHARSET. Treated as CJK by Win 8,
1635 but not by < Win 8 and Win 10. */
1637 test_margins_usefontinfo(DEFAULT_CHARSET
);
1640 static INT CALLBACK
find_font_proc(const LOGFONTA
*elf
, const TEXTMETRICA
*ntm
, DWORD type
, LPARAM lParam
)
1645 static void test_margins_font_change(void)
1647 DWORD margins
, font_margins
, ret
;
1648 HFONT hfont
, hfont2
;
1654 ret
= EnumFontFamiliesA(hdc
, "Arial", find_font_proc
, 0);
1658 trace("Arial not found - skipping font change margin tests\n");
1662 hwEdit
= create_child_editcontrol(0, 0);
1664 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1666 memset(&lf
, 0, sizeof(lf
));
1667 strcpy(lf
.lfFaceName
, "Arial");
1669 lf
.lfCharSet
= DEFAULT_CHARSET
;
1670 hfont
= CreateFontIndirectA(&lf
);
1672 hfont2
= CreateFontIndirectA(&lf
);
1674 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1675 font_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1676 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
1677 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
1679 /* With 'small' edit controls, test that the margin doesn't get set */
1680 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1681 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
1682 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1683 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1684 ok(LOWORD(margins
) == 0, "got %d\n", LOWORD(margins
));
1685 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
1687 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1688 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1689 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1690 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1691 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
1693 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1694 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1695 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1696 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1697 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1699 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1700 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1701 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1702 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1704 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1705 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1706 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
1707 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
1709 /* Above a certain size threshold then the margin is updated */
1710 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1711 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1712 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1713 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1714 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1715 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1717 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1718 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1719 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1720 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1721 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1723 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1724 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1725 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1726 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1727 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1728 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1729 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1730 ok(LOWORD(margins
) != LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1731 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1733 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
1735 DeleteObject(hfont2
);
1736 DeleteObject(hfont
);
1737 destroy_child_editcontrol(hwEdit
);
1741 #define edit_pos_ok(exp, got, txt) \
1742 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1744 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1748 set_client_height(hwEdit, set_height); \
1749 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1750 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
1751 edit_pos_ok(test_top, format_rect.top, vertical position); \
1752 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1753 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1756 static void test_text_position_style(DWORD style
)
1759 HFONT font
, oldFont
;
1761 TEXTMETRICA metrics
;
1763 BOOL xb
, single_line
= !(style
& ES_MULTILINE
);
1765 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
1770 /* Get a stock font for which we can determine the metrics */
1771 font
= GetStockObject(SYSTEM_FONT
);
1772 ok (font
!= NULL
, "GetStockObject SYSTEM_FONT failed\n");
1774 ok (dc
!= NULL
, "GetDC() failed\n");
1775 oldFont
= SelectObject(dc
, font
);
1776 xb
= GetTextMetricsA(dc
, &metrics
);
1777 ok (xb
, "GetTextMetrics failed\n");
1778 SelectObject(dc
, oldFont
);
1779 ReleaseDC(NULL
, dc
);
1781 /* Windows' edit control has some bugs in multi-line mode:
1782 * - Sometimes the format rectangle doesn't get updated
1783 * (see workaround in set_client_height())
1784 * - If the height of the control is smaller than the height of a text
1785 * line, the format rectangle is still as high as a text line
1786 * (higher than the client rectangle) and the caret is not shown
1789 /* Edit controls that are in a parent window */
1791 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
1792 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1794 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1795 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1796 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1797 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1798 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1799 destroy_child_editcontrol(hwEdit
);
1801 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
1802 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1804 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1805 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1806 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1807 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1808 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1809 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1810 destroy_child_editcontrol(hwEdit
);
1812 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1813 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1815 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1816 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1817 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1818 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1819 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1820 destroy_child_editcontrol(hwEdit
);
1822 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1823 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1825 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1826 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1827 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1828 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1829 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1830 destroy_child_editcontrol(hwEdit
);
1833 /* Edit controls that are popup windows */
1835 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
1836 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1838 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1839 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1840 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1841 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1842 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1843 DestroyWindow(hwEdit
);
1845 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
1846 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1848 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1849 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1850 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1851 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1852 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1853 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1854 DestroyWindow(hwEdit
);
1856 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
1857 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1859 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1860 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1861 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1862 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1863 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1864 DestroyWindow(hwEdit
);
1866 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
1867 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1869 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1870 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1871 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1872 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1873 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1874 DestroyWindow(hwEdit
);
1877 static void test_text_position(void)
1879 trace("EDIT: Text position (Single line)\n");
1880 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1881 trace("EDIT: Text position (Multi line)\n");
1882 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1885 static void test_espassword(void)
1890 const char* password
= "secret";
1892 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
1893 r
= get_edit_style(hwEdit
);
1894 ok(r
== ES_PASSWORD
, "Wrong style expected ES_PASSWORD got: 0x%x\n", r
);
1896 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
1897 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
1899 /* select all, cut (ctrl-x) */
1900 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1901 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
1902 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1905 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1906 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
1907 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
1909 r
= OpenClipboard(hwEdit
);
1910 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1911 r
= EmptyClipboard();
1912 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1913 r
= CloseClipboard();
1914 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1916 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1917 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1918 r
= SendMessageA(hwEdit
, WM_CHAR
, 3, 0);
1919 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1920 r
= SendMessageA(hwEdit
, WM_CHAR
, 22, 0);
1921 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1925 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1926 ok(r
== 0, "Expected: 0, got: %d\n", r
);
1927 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
1929 DestroyWindow(hwEdit
);
1932 static void test_undo(void)
1938 const char* text
= "undo this";
1940 hwEdit
= create_editcontrol(0, 0);
1941 r
= get_edit_style(hwEdit
);
1942 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1945 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
1946 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1949 cpMin
= cpMax
= 0xdeadbeef;
1950 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1951 r
= SendMessageA(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
1952 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
1953 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
1954 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
1957 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
1958 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1962 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1963 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1964 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1967 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
1968 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1972 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1973 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
1974 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
1976 /* undo again (ctrl-z) */
1977 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
1978 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1982 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1983 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
1984 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1986 DestroyWindow(hwEdit
);
1989 static void test_enter(void)
1996 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
1997 r
= get_edit_style(hwEdit
);
1998 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
2001 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2002 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2004 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2005 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2009 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2010 ok(2 == r
, "Expected: %d, got len %d\n", 2, r
);
2011 ok(0 == strcmp(buffer
, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer
);
2013 DestroyWindow (hwEdit
);
2016 hwEdit
= create_editcontrol(0, 0);
2017 r
= get_edit_style(hwEdit
);
2018 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2021 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2022 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2024 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2025 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2029 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2030 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2031 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2033 DestroyWindow(hwEdit
);
2035 /* single line with ES_WANTRETURN */
2036 hwEdit
= create_editcontrol(ES_WANTRETURN
, 0);
2037 r
= get_edit_style(hwEdit
);
2038 ok(ES_WANTRETURN
== r
, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r
);
2041 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2042 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2044 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
2045 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2049 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2050 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2051 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2053 DestroyWindow(hwEdit
);
2056 static void test_tab(void)
2063 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2064 r
= get_edit_style(hwEdit
);
2065 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
2068 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2069 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2071 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
2072 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2076 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2077 ok(1 == r
, "Expected: %d, got len %d\n", 1, r
);
2078 ok(0 == strcmp(buffer
, "\t"), "expected \"\\t\", got \"%s\"\n", buffer
);
2080 DestroyWindow(hwEdit
);
2083 hwEdit
= create_editcontrol(0, 0);
2084 r
= get_edit_style(hwEdit
);
2085 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
2088 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
2089 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
2091 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
2092 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2096 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2097 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2098 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2100 DestroyWindow(hwEdit
);
2103 static void test_edit_dialog(void)
2107 /* from bug 11841 */
2108 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 0);
2109 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2110 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 1);
2111 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2112 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 2);
2113 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2115 /* more tests for WM_CHAR */
2116 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 3);
2117 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2118 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 4);
2119 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2120 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 5);
2121 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2123 /* more tests for WM_KEYDOWN + WM_CHAR */
2124 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 6);
2125 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2126 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 7);
2127 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2128 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 8);
2129 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2131 /* tests with an editable edit control */
2132 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 0);
2133 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2134 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 1);
2135 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2136 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 2);
2137 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2139 /* tests for WM_CHAR */
2140 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 3);
2141 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2142 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 4);
2143 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2144 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 5);
2145 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2147 /* tests for WM_KEYDOWN + WM_CHAR */
2148 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 6);
2149 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2150 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 7);
2151 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2152 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 8);
2153 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2155 /* multiple tab tests */
2156 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 9);
2157 ok(22 == r
, "Expected %d, got %d\n", 22, r
);
2158 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 10);
2159 ok(33 == r
, "Expected %d, got %d\n", 33, r
);
2162 static void test_multi_edit_dialog(void)
2166 /* test for multiple edit dialogs (bug 12319) */
2167 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 0);
2168 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2169 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 1);
2170 ok(1111 == r
, "Expected %d, got %d\n", 1111, r
);
2171 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 2);
2172 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2173 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 3);
2174 ok(11 == r
, "Expected %d, got %d\n", 11, r
);
2177 static void test_wantreturn_edit_dialog(void)
2181 /* tests for WM_KEYDOWN */
2182 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 0);
2183 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2184 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 1);
2185 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2186 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 2);
2187 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2189 /* tests for WM_CHAR */
2190 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 3);
2191 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2192 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 4);
2193 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2194 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 5);
2195 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2197 /* tests for WM_KEYDOWN + WM_CHAR */
2198 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 6);
2199 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2200 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 7);
2201 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2202 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 8);
2203 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2206 static void test_singleline_wantreturn_edit_dialog(void)
2210 /* tests for WM_KEYDOWN */
2211 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2212 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2213 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2214 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2215 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2216 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2218 /* tests for WM_CHAR */
2219 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2220 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2221 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2222 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2223 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2224 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2226 /* tests for WM_KEYDOWN + WM_CHAR */
2227 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2228 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2229 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2230 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2231 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2232 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2234 /* tests for WM_KEYDOWN */
2235 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2236 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2237 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2238 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2239 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2240 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2242 /* tests for WM_CHAR */
2243 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2244 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2245 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2246 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2247 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2248 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2250 /* tests for WM_KEYDOWN + WM_CHAR */
2251 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2252 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2253 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2254 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2255 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2256 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2259 static int child_edit_wmkeydown_num_messages
= 0;
2260 static INT_PTR CALLBACK
child_edit_wmkeydown_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
2269 child_edit_wmkeydown_num_messages
++;
2276 static void test_child_edit_wmkeydown(void)
2278 HWND hwEdit
, hwParent
;
2281 hwEdit
= create_child_editcontrol(0, 0);
2282 hwParent
= GetParent(hwEdit
);
2283 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)child_edit_wmkeydown_proc
);
2284 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2285 ok(1 == r
, "expected 1, got %d\n", r
);
2286 ok(0 == child_edit_wmkeydown_num_messages
, "expected 0, got %d\n", child_edit_wmkeydown_num_messages
);
2287 destroy_child_editcontrol(hwEdit
);
2290 static BOOL got_en_setfocus
= FALSE
;
2291 static BOOL got_wm_capturechanged
= FALSE
;
2292 static LRESULT (CALLBACK
*p_edit_proc
)(HWND
, UINT
, WPARAM
, LPARAM
);
2294 static LRESULT CALLBACK
edit4_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2298 switch (HIWORD(wParam
))
2301 got_en_setfocus
= TRUE
;
2305 case WM_CAPTURECHANGED
:
2306 if (hWnd
!= (HWND
)lParam
)
2308 got_wm_capturechanged
= TRUE
;
2313 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
2316 struct context_menu_messages
2318 unsigned int wm_command
, em_setsel
;
2321 static struct context_menu_messages menu_messages
;
2323 static LRESULT CALLBACK
child_edit_menu_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2328 if (wParam
== MSGF_MENU
)
2330 HWND hwndMenu
= (HWND
)lParam
;
2331 MENUBARINFO mbi
= { sizeof(mbi
) };
2332 if (GetMenuBarInfo(hwndMenu
, OBJID_CLIENT
, 0, &mbi
))
2334 MENUITEMINFOA mii
= { sizeof(MENUITEMINFOA
), MIIM_STATE
};
2335 if (GetMenuItemInfoA(mbi
.hMenu
, EM_SETSEL
, FALSE
, &mii
))
2337 if (mii
.fState
& MFS_HILITE
)
2339 PostMessageA(hwnd
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2340 PostMessageA(hwnd
, WM_KEYUP
, VK_RETURN
, 0x1c0001);
2344 PostMessageA(hwnd
, WM_KEYDOWN
, VK_DOWN
, 0x500001);
2345 PostMessageA(hwnd
, WM_KEYUP
, VK_DOWN
, 0x500001);
2352 menu_messages
.wm_command
++;
2355 menu_messages
.em_setsel
++;
2358 return CallWindowProcA(p_edit_proc
, hwnd
, msg
, wParam
, lParam
);
2361 static void test_contextmenu(void)
2363 HWND hwndMain
, hwndEdit
;
2366 hwndMain
= CreateWindowA(szEditTest4Class
, "ET4", WS_OVERLAPPEDWINDOW
|WS_VISIBLE
,
2367 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
2370 hwndEdit
= CreateWindowA("EDIT", NULL
,
2371 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|ES_LEFT
|ES_AUTOHSCROLL
,
2372 0, 0, 150, 50, /* important this not be 0 size. */
2373 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
2377 SetCapture(hwndMain
);
2378 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(10, 10));
2379 ok(got_en_setfocus
, "edit box didn't get focused\n");
2380 ok(got_wm_capturechanged
, "main window capture did not change\n");
2382 DestroyWindow(hwndEdit
);
2384 hwndEdit
= CreateWindowA("EDIT", "Test Text",
2385 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
2387 hwndMain
, NULL
, hinst
, NULL
);
2388 memset(&menu_messages
, 0, sizeof(menu_messages
));
2389 p_edit_proc
= (void*)SetWindowLongPtrA(hwndEdit
, GWLP_WNDPROC
,
2390 (ULONG_PTR
)child_edit_menu_proc
);
2393 SendMessageA(hwndEdit
, WM_SETTEXT
, 0, (LPARAM
)"foo");
2394 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(-1, -1));
2395 while (PeekMessageA(&msg
, hwndEdit
, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
2396 ok(menu_messages
.wm_command
== 0,
2397 "Expected no WM_COMMAND messages, got %d\n", menu_messages
.wm_command
);
2398 ok(menu_messages
.em_setsel
== 1,
2399 "Expected 1 EM_SETSEL message, got %d\n", menu_messages
.em_setsel
);
2401 DestroyWindow(hwndEdit
);
2402 DestroyWindow(hwndMain
);
2405 static BOOL
register_classes(void)
2410 WNDCLASSA text_position
;
2413 test2
.lpfnWndProc
= ET2_WndProc
;
2414 test2
.cbClsExtra
= 0;
2415 test2
.cbWndExtra
= 0;
2416 test2
.hInstance
= hinst
;
2418 test2
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2419 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2420 test2
.lpszMenuName
= NULL
;
2421 test2
.lpszClassName
= szEditTest2Class
;
2422 if (!RegisterClassA(&test2
)) return FALSE
;
2425 test3
.lpfnWndProc
= edit3_wnd_procA
;
2426 test3
.cbClsExtra
= 0;
2427 test3
.cbWndExtra
= 0;
2428 test3
.hInstance
= hinst
;
2430 test3
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
2431 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
2432 test3
.lpszMenuName
= NULL
;
2433 test3
.lpszClassName
= szEditTest3Class
;
2434 if (!RegisterClassA(&test3
)) return FALSE
;
2437 test4
.lpfnWndProc
= edit4_wnd_procA
;
2438 test4
.cbClsExtra
= 0;
2439 test4
.cbWndExtra
= 0;
2440 test4
.hInstance
= hinst
;
2442 test4
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2443 test4
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2444 test4
.lpszMenuName
= NULL
;
2445 test4
.lpszClassName
= szEditTest4Class
;
2446 if (!RegisterClassA(&test4
)) return FALSE
;
2448 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
2449 text_position
.cbClsExtra
= 0;
2450 text_position
.cbWndExtra
= 0;
2451 text_position
.hInstance
= hinst
;
2452 text_position
.hIcon
= NULL
;
2453 text_position
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
2454 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2455 text_position
.lpszMenuName
= NULL
;
2456 text_position
.lpszClassName
= szEditTextPositionClass
;
2457 text_position
.lpfnWndProc
= DefWindowProcA
;
2458 if (!RegisterClassA(&text_position
)) return FALSE
;
2463 static void UnregisterWindowClasses (void)
2465 UnregisterClassA(szEditTest2Class
, hinst
);
2466 UnregisterClassA(szEditTest3Class
, hinst
);
2467 UnregisterClassA(szEditTest4Class
, hinst
);
2468 UnregisterClassA(szEditTextPositionClass
, hinst
);
2471 static void test_fontsize(void)
2478 char szLocalString
[MAXLEN
];
2482 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
2483 ReleaseDC(NULL
, hDC
);
2485 memset(&lf
,0,sizeof(LOGFONTA
));
2486 strcpy(lf
.lfFaceName
,"Arial");
2487 lf
.lfHeight
= -300; /* taller than the edit box */
2489 hfont
= CreateFontIndirectA(&lf
);
2491 trace("EDIT: Oversized font (Multi line)\n");
2492 hwEdit
= CreateWindowA("EDIT", NULL
, ES_MULTILINE
|ES_AUTOHSCROLL
,
2493 0, 0, (150 * dpi
) / 96, (50 * dpi
) / 96, NULL
, NULL
,
2496 SendMessageA(hwEdit
,WM_SETFONT
,(WPARAM
)hfont
,0);
2498 if (winetest_interactive
)
2499 ShowWindow (hwEdit
, SW_SHOW
);
2501 r
= SendMessageA(hwEdit
, WM_CHAR
, 'A', 1);
2502 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2503 r
= SendMessageA(hwEdit
, WM_CHAR
, 'B', 1);
2504 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2505 r
= SendMessageA(hwEdit
, WM_CHAR
, 'C', 1);
2506 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2508 GetWindowTextA(hwEdit
, szLocalString
, MAXLEN
);
2509 ok(strcmp(szLocalString
, "ABC")==0,
2510 "Wrong contents of edit: %s\n", szLocalString
);
2512 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,0,0);
2513 ok(r
!= -1,"EM_POSFROMCHAR failed index 0\n");
2514 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,1,0);
2515 ok(r
!= -1,"EM_POSFROMCHAR failed index 1\n");
2516 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,2,0);
2517 ok(r
!= -1,"EM_POSFROMCHAR failed index 2\n");
2518 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,3,0);
2519 ok(r
== -1,"EM_POSFROMCHAR succeeded index 3\n");
2521 DestroyWindow (hwEdit
);
2522 DeleteObject(hfont
);
2525 struct dialog_mode_messages
2527 int wm_getdefid
, wm_close
, wm_command
, wm_nextdlgctl
;
2530 static struct dialog_mode_messages dm_messages
;
2532 static void zero_dm_messages(void)
2534 dm_messages
.wm_command
= 0;
2535 dm_messages
.wm_close
= 0;
2536 dm_messages
.wm_getdefid
= 0;
2537 dm_messages
.wm_nextdlgctl
= 0;
2540 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2541 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2542 "got %d\n", wmcommand, dm_messages.wm_command); \
2543 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2544 "got %d\n", wmclose, dm_messages.wm_close); \
2545 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2546 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2547 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2548 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2550 static LRESULT CALLBACK
dialog_mode_wnd_proc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
2555 dm_messages
.wm_command
++;
2558 dm_messages
.wm_getdefid
++;
2559 return MAKELONG(ID_EDITTESTDBUTTON
, DC_HASDEFID
);
2561 dm_messages
.wm_nextdlgctl
++;
2564 dm_messages
.wm_close
++;
2568 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
2571 static void test_dialogmode(void)
2573 HWND hwEdit
, hwParent
, hwButton
;
2576 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2578 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2579 ok(1 == r
, "expected 1, got %d\n", r
);
2580 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2581 ok(11 == len
, "expected 11, got %d\n", len
);
2583 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, 0);
2584 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2586 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2587 ok(1 == r
, "expected 1, got %d\n", r
);
2588 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2589 ok(13 == len
, "expected 13, got %d\n", len
);
2591 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
)&msg
);
2592 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2593 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2594 ok(1 == r
, "expected 1, got %d\n", r
);
2595 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2596 ok(13 == len
, "expected 13, got %d\n", len
);
2598 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2599 ok(1 == r
, "expected 1, got %d\n", r
);
2600 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2601 ok(13 == len
, "expected 13, got %d\n", len
);
2603 destroy_child_editcontrol(hwEdit
);
2605 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2607 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2608 ok(1 == r
, "expected 1, got %d\n", r
);
2609 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2610 ok(11 == len
, "expected 11, got %d\n", len
);
2613 msg
.message
= WM_KEYDOWN
;
2614 msg
.wParam
= VK_BACK
;
2615 msg
.lParam
= 0xe0001;
2616 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_BACK
, (LPARAM
)&msg
);
2617 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2619 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2620 ok(1 == r
, "expected 1, got %d\n", r
);
2621 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2622 ok(11 == len
, "expected 11, got %d\n", len
);
2624 DestroyWindow(hwEdit
);
2626 hwEdit
= create_child_editcontrol(0, 0);
2627 hwParent
= GetParent(hwEdit
);
2628 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2631 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2632 ok(1 == r
, "expected 1, got %d\n", r
);
2633 test_dm_messages(0, 0, 0, 0);
2636 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2637 ok(1 == r
, "expected 1, got %d\n", r
);
2638 test_dm_messages(0, 0, 0, 0);
2642 msg
.message
= WM_KEYDOWN
;
2643 msg
.wParam
= VK_TAB
;
2644 msg
.lParam
= 0xf0001;
2645 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_TAB
, (LPARAM
)&msg
);
2646 ok(0x89 == r
, "expected 0x89, got 0x%x\n", r
);
2647 test_dm_messages(0, 0, 0, 0);
2650 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2651 ok(1 == r
, "expected 1, got %d\n", r
);
2652 test_dm_messages(0, 0, 0, 0);
2655 destroy_child_editcontrol(hwEdit
);
2657 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2658 hwParent
= GetParent(hwEdit
);
2659 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2661 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2662 ok(1 == r
, "expected 1, got %d\n", r
);
2663 test_dm_messages(0, 0, 0, 0);
2667 msg
.message
= WM_KEYDOWN
;
2668 msg
.wParam
= VK_ESCAPE
;
2669 msg
.lParam
= 0x10001;
2670 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_ESCAPE
, (LPARAM
)&msg
);
2671 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2672 test_dm_messages(0, 0, 0, 0);
2675 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2676 ok(1 == r
, "expected 1, got %d\n", r
);
2677 test_dm_messages(0, 0, 0, 0);
2680 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2681 ok(1 == r
, "expected 1, got %d\n", r
);
2682 test_dm_messages(0, 0, 0, 1);
2685 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2686 ok(1 == r
, "expected 1, got %d\n", r
);
2687 test_dm_messages(0, 0, 1, 0);
2690 hwButton
= CreateWindowA("BUTTON", "OK", WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
,
2691 100, 100, 50, 20, hwParent
, (HMENU
)ID_EDITTESTDBUTTON
, hinst
, NULL
);
2692 ok(hwButton
!=NULL
, "CreateWindow failed with error code %d\n", GetLastError());
2694 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2695 ok(1 == r
, "expected 1, got %d\n", r
);
2696 test_dm_messages(0, 0, 1, 1);
2699 DestroyWindow(hwButton
);
2700 destroy_child_editcontrol(hwEdit
);
2703 static void test_EM_GETHANDLE(void)
2705 static const WCHAR str1W
[] = {'1','1','1','1','+','1','1','1','1','+','1','1','1','1','#',0};
2706 static const WCHAR str2W
[] = {'2','2','2','2','-','2','2','2','2','-','2','2','2','2','-','2','2','2','2','#',0};
2707 static const char str0
[] = "untouched";
2708 static const char str1
[] = "1111+1111+1111#";
2709 static const char str1_1
[] = "2111+1111+1111#";
2710 static const char str2
[] = "2222-2222-2222-2222#";
2711 static const char str3
[] = "3333*3333*3333*3333*3333#";
2721 trace("EDIT: EM_GETHANDLE\n");
2723 /* EM_GETHANDLE is not supported for a single line edit control */
2724 hEdit
= create_editcontrol(WS_BORDER
, 0);
2725 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
2727 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2728 ok(hmem
== NULL
, "got %p (expected NULL)\n", hmem
);
2729 DestroyWindow(hEdit
);
2731 /* EM_GETHANDLE needs a multiline edit control */
2732 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
2733 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
2736 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2737 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2738 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
2740 lstrcpyA(current
, str0
);
2741 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2742 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
2743 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
2745 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2746 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2747 /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
2748 buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
2750 buffer
= LocalLock(hmem
);
2751 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2752 len
= lstrlenW(buffer
);
2754 ok(len
== lstrlenW(str1W
) && !lstrcmpW(buffer
, str1W
), "Unexpected buffer contents %s, length %d.\n",
2755 wine_dbgstr_w(buffer
), len
);
2758 /* See if WM_GETTEXTLENGTH/WM_GETTEXT still work. */
2759 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2760 ok(len
== lstrlenA(str1
), "Unexpected text length %d.\n", len
);
2762 lstrcpyA(current
, str0
);
2763 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2764 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
2765 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
2767 /* Application altered buffer contents, see if WM_GETTEXTLENGTH/WM_GETTEXT pick that up. */
2768 buffer
= LocalLock(hmem
);
2769 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2773 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2774 ok(len
== lstrlenA(str1_1
), "Unexpected text length %d.\n", len
);
2776 lstrcpyA(current
, str0
);
2777 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2779 ok(r
== lstrlenA(str1_1
) && !lstrcmpA(current
, str1_1
),
2780 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1_1
), str1_1
);
2782 /* See if WM_SETTEXT/EM_REPLACESEL work. */
2783 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2784 ok(r
, "Failed to set text.\n");
2786 buffer
= LocalLock(hmem
);
2788 ok(buffer
!= NULL
&& buffer
[0] == '1', "Unexpected buffer contents\n");
2791 r
= SendMessageA(hEdit
, EM_REPLACESEL
, 0, (LPARAM
)str1_1
);
2792 ok(r
, "Failed to replace selection.\n");
2794 buffer
= LocalLock(hmem
);
2796 ok(buffer
!= NULL
&& buffer
[0] == '2', "Unexpected buffer contents\n");
2799 /* use LocalAlloc first to get a different handle */
2800 halloc
= LocalAlloc(LMEM_MOVEABLE
, 42);
2801 ok(halloc
!= NULL
, "got %p (expected != NULL)\n", halloc
);
2802 /* prepare our new memory */
2803 buffer
= LocalLock(halloc
);
2804 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2805 lstrcpyW(buffer
, str2W
);
2806 LocalUnlock(halloc
);
2808 /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
2810 /* use LocalAlloc after the LocalFree to likely consume the handle */
2811 hmem2
= LocalAlloc(LMEM_MOVEABLE
, 42);
2812 ok(hmem2
!= NULL
, "got %p (expected != NULL)\n", hmem2
);
2814 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)halloc
, 0);
2816 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2818 ok(len
== lstrlenA(str2
), "got %d (expected %d)\n", len
, lstrlenA(str2
));
2820 lstrcpyA(current
, str0
);
2821 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2823 ok(r
== lstrlenA(str2
) && !lstrcmpA(current
, str2
),
2824 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str2
), str2
);
2826 /* set a different text */
2827 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str3
);
2828 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2829 ok((r
== 1) && (len
== lstrlenA(str3
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str3
));
2831 lstrcpyA(current
, str0
);
2832 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2833 ok((r
== lstrlenA(str3
)) && !lstrcmpA(current
, str3
),
2834 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str3
), str3
);
2837 DestroyWindow(hEdit
);
2839 /* Some apps have bugs ... */
2840 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
2843 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2844 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2845 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
2847 /* everything is normal up to EM_GETHANDLE */
2848 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2849 /* Some messages still work while other messages fail.
2850 After LocalFree the memory handle, messages can crash the app */
2852 /* A buggy editor used EM_GETHANDLE twice */
2853 hmem2
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2854 ok(hmem2
== hmem
, "got %p (expected %p)\n", hmem2
, hmem
);
2856 /* Let the edit control free the memory handle */
2857 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)hmem2
, 0);
2859 DestroyWindow(hEdit
);
2862 static void test_paste(void)
2864 static const char *str
= "this is a simple text";
2865 static const char *str2
= "first line\r\nsecond line";
2866 HWND hEdit
, hMultilineEdit
;
2867 HANDLE hmem
, hmem_ret
;
2871 hEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
2872 hMultilineEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
, 0);
2874 /* Prepare clipboard data with simple text */
2875 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 255);
2876 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2877 buffer
= GlobalLock(hmem
);
2878 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2879 strcpy(buffer
, str
);
2882 r
= OpenClipboard(hEdit
);
2883 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2884 r
= EmptyClipboard();
2885 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2886 hmem_ret
= SetClipboardData(CF_TEXT
, hmem
);
2887 ok(hmem_ret
== hmem
, "expected %p, got %p\n", hmem
, hmem_ret
);
2888 r
= CloseClipboard();
2889 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2891 /* Paste single line */
2892 SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
2893 r
= SendMessageA(hEdit
, WM_PASTE
, 0, 0);
2894 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2895 ok(strlen(str
) == len
, "got %d\n", len
);
2897 /* Prepare clipboard data with multiline text */
2898 hmem
= GlobalAlloc(GMEM_MOVEABLE
, 255);
2899 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2900 buffer
= GlobalLock(hmem
);
2901 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2902 strcpy(buffer
, str2
);
2905 r
= OpenClipboard(hEdit
);
2906 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2907 r
= EmptyClipboard();
2908 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2909 hmem_ret
= SetClipboardData(CF_TEXT
, hmem
);
2910 ok(hmem_ret
== hmem
, "expected %p, got %p\n", hmem
, hmem_ret
);
2911 r
= CloseClipboard();
2912 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
2914 /* Paste multiline text in singleline edit - should be cut */
2915 SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
2916 r
= SendMessageA(hEdit
, WM_PASTE
, 0, 0);
2917 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2918 ok(strlen("first line") == len
, "got %d\n", len
);
2920 /* Paste multiline text in multiline edit */
2921 SendMessageA(hMultilineEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
2922 r
= SendMessageA(hMultilineEdit
, WM_PASTE
, 0, 0);
2923 len
= SendMessageA(hMultilineEdit
, WM_GETTEXTLENGTH
, 0, 0);
2924 ok(strlen(str2
) == len
, "got %d\n", len
);
2927 DestroyWindow(hEdit
);
2928 DestroyWindow(hMultilineEdit
);
2931 static void test_EM_GETLINE(void)
2936 hwnd
[0] = create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
2937 hwnd
[1] = create_editcontrolW(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
2939 for (i
= 0; i
< sizeof(hwnd
)/sizeof(hwnd
[0]); i
++)
2941 static const WCHAR strW
[] = {'t','e','x','t',0};
2942 static const char *str
= "text";
2947 todo_wine_if(i
== 0)
2948 ok(IsWindowUnicode(hwnd
[i
]), "Expected unicode window.\n");
2950 SendMessageA(hwnd
[i
], WM_SETTEXT
, 0, (LPARAM
)str
);
2952 memset(buff
, 0, sizeof(buff
));
2953 *(WORD
*)buff
= sizeof(buff
);
2954 r
= SendMessageA(hwnd
[i
], EM_GETLINE
, 0, (LPARAM
)buff
);
2955 ok(r
== strlen(str
), "Failed to get a line %d.\n", r
);
2956 ok(!strcmp(buff
, str
), "Unexpected line data %s.\n", buff
);
2958 memset(buff
, 0, sizeof(buff
));
2959 *(WORD
*)buff
= sizeof(buff
);
2960 r
= SendMessageA(hwnd
[i
], EM_GETLINE
, 1, (LPARAM
)buff
);
2961 ok(r
== strlen(str
), "Failed to get a line %d.\n", r
);
2962 ok(!strcmp(buff
, str
), "Unexpected line data %s.\n", buff
);
2964 memset(buffW
, 0, sizeof(buffW
));
2965 *(WORD
*)buffW
= sizeof(buffW
)/sizeof(buffW
[0]);
2966 r
= SendMessageW(hwnd
[i
], EM_GETLINE
, 0, (LPARAM
)buffW
);
2967 ok(r
== lstrlenW(strW
), "Failed to get a line %d.\n", r
);
2968 ok(!lstrcmpW(buffW
, strW
), "Unexpected line data %s.\n", wine_dbgstr_w(buffW
));
2970 memset(buffW
, 0, sizeof(buffW
));
2971 *(WORD
*)buffW
= sizeof(buffW
)/sizeof(buffW
[0]);
2972 r
= SendMessageW(hwnd
[i
], EM_GETLINE
, 1, (LPARAM
)buffW
);
2973 ok(r
== lstrlenW(strW
), "Failed to get a line %d.\n", r
);
2974 ok(!lstrcmpW(buffW
, strW
), "Unexpected line data %s.\n", wine_dbgstr_w(buffW
));
2976 DestroyWindow(hwnd
[i
]);
2982 ULONG_PTR ctx_cookie
;
2986 if (!load_v6_module(&ctx_cookie
, &hCtx
))
2989 hinst
= GetModuleHandleA(NULL
);
2990 b
= register_classes();
2991 ok(b
, "Failed to register test classes.\n");
2994 test_edit_control_1();
2995 test_edit_control_2();
2996 test_edit_control_3();
2997 test_char_from_pos();
2998 test_edit_control_5();
2999 test_edit_control_6();
3000 test_edit_control_limittext();
3001 test_edit_control_scroll();
3003 test_margins_font_change();
3004 test_text_position();
3010 test_multi_edit_dialog();
3011 test_wantreturn_edit_dialog();
3012 test_singleline_wantreturn_edit_dialog();
3013 test_child_edit_wmkeydown();
3017 test_EM_GETHANDLE();
3021 UnregisterWindowClasses();
3023 unload_v6_module(ctx_cookie
, hCtx
);