1 /* Unit test suite for edit control.
3 * Copyright 2004 Vitaliy Margolen
4 * Copyright 2005 C. Scott Ananian
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
28 #define ES_COMBO 0x200
31 #define ID_EDITTESTDBUTTON 0x123
32 #define ID_EDITTEST2 99
36 int en_change
, en_maxtext
, en_update
;
39 static struct edit_notify notifications
;
41 static BOOL (WINAPI
*pEndMenu
) (void);
42 static BOOL (WINAPI
*pGetMenuBarInfo
)(HWND
,LONG
,LONG
,PMENUBARINFO
);
44 static void init_function_pointers(void)
46 HMODULE hdll
= GetModuleHandleA("user32");
48 pEndMenu
= (void*)GetProcAddress(hdll
, "EndMenu");
49 pGetMenuBarInfo
= (void*)GetProcAddress(hdll
, "GetMenuBarInfo");
52 static INT_PTR CALLBACK
multi_edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
54 static int num_ok_commands
= 0;
59 HWND hedit
= GetDlgItem(hdlg
, 1000);
63 /* test cases related to bug 12319 */
65 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
66 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
69 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
70 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
73 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
74 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
75 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
78 /* test cases for pressing enter */
81 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
82 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
92 if (HIWORD(wparam
) != BN_CLICKED
)
95 switch (LOWORD(wparam
))
108 HWND hfocus
= GetFocus();
109 HWND hedit
= GetDlgItem(hdlg
, 1000);
110 HWND hedit2
= GetDlgItem(hdlg
, 1001);
111 HWND hedit3
= GetDlgItem(hdlg
, 1002);
113 if (wparam
!= 0xdeadbeef)
120 EndDialog(hdlg
, 1111);
121 else if (hfocus
== hedit2
)
122 EndDialog(hdlg
, 2222);
123 else if (hfocus
== hedit3
)
124 EndDialog(hdlg
, 3333);
126 EndDialog(hdlg
, 4444);
129 if ((hfocus
== hedit
) && (num_ok_commands
== 0))
135 EndDialog(hdlg
, 5555);
141 EndDialog(hdlg
, 333);
151 static INT_PTR CALLBACK
edit_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
157 HWND hedit
= GetDlgItem(hdlg
, 1000);
163 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
166 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
169 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
170 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
173 /* more test cases for WM_CHAR */
175 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
176 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
179 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
180 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
183 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
184 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
187 /* more test cases for WM_KEYDOWN + WM_CHAR */
189 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
190 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
191 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
194 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
195 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
196 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
199 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
200 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
201 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
204 /* multiple tab tests */
206 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
207 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
208 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
211 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
212 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
213 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
214 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
224 if (HIWORD(wparam
) != BN_CLICKED
)
227 switch (LOWORD(wparam
))
230 EndDialog(hdlg
, 111);
234 EndDialog(hdlg
, 222);
245 HWND hok
= GetDlgItem(hdlg
, IDOK
);
246 HWND hcancel
= GetDlgItem(hdlg
, IDCANCEL
);
247 HWND hedit
= GetDlgItem(hdlg
, 1000);
248 HWND hfocus
= GetFocus();
250 if (wparam
!= 0xdeadbeef)
256 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
258 EndDialog(hdlg
, 444);
260 EndDialog(hdlg
, 555);
264 len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
265 if ((hfocus
== hok
) && len
== 0)
266 EndDialog(hdlg
, 444);
268 EndDialog(hdlg
, 555);
274 else if (hfocus
== hcancel
)
276 else if (hfocus
== hedit
)
283 EndDialog(hdlg
, 555);
289 EndDialog(hdlg
, 333);
299 static INT_PTR CALLBACK
edit_singleline_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
305 HWND hedit
= GetDlgItem(hdlg
, 1000);
309 /* test cases for WM_KEYDOWN */
311 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
314 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
317 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
318 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
321 /* test cases for WM_CHAR */
323 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
324 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
327 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
328 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
331 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
332 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
335 /* test cases for WM_KEYDOWN + WM_CHAR */
337 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
338 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
341 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
342 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
345 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
346 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
347 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
357 if (HIWORD(wparam
) != BN_CLICKED
)
360 switch (LOWORD(wparam
))
363 EndDialog(hdlg
, 111);
367 EndDialog(hdlg
, 222);
377 HWND hok
= GetDlgItem(hdlg
, IDOK
);
378 HWND hedit
= GetDlgItem(hdlg
, 1000);
379 HWND hfocus
= GetFocus();
380 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
382 if (wparam
!= 0xdeadbeef)
388 if ((hfocus
== hedit
) && len
== 0)
389 EndDialog(hdlg
, 444);
391 EndDialog(hdlg
, 555);
395 if ((hfocus
== hok
) && len
== 0)
396 EndDialog(hdlg
, 444);
398 EndDialog(hdlg
, 555);
408 EndDialog(hdlg
, 333);
418 static INT_PTR CALLBACK
edit_wantreturn_dialog_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
424 HWND hedit
= GetDlgItem(hdlg
, 1000);
428 /* test cases for WM_KEYDOWN */
430 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
433 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
434 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
437 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
438 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
441 /* test cases for WM_CHAR */
443 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
444 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
447 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
448 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
451 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
452 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
455 /* test cases for WM_KEYDOWN + WM_CHAR */
457 PostMessageA(hedit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
458 PostMessageA(hedit
, WM_CHAR
, VK_ESCAPE
, 0x10001);
459 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 0);
462 PostMessageA(hedit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
463 PostMessageA(hedit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
464 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 2);
467 PostMessageA(hedit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
468 PostMessageA(hedit
, WM_CHAR
, VK_TAB
, 0xf0001);
469 PostMessageA(hdlg
, WM_USER
, 0xdeadbeef, 1);
479 if (HIWORD(wparam
) != BN_CLICKED
)
482 switch (LOWORD(wparam
))
485 EndDialog(hdlg
, 111);
489 EndDialog(hdlg
, 222);
499 HWND hok
= GetDlgItem(hdlg
, IDOK
);
500 HWND hedit
= GetDlgItem(hdlg
, 1000);
501 HWND hfocus
= GetFocus();
502 int len
= SendMessageA(hedit
, WM_GETTEXTLENGTH
, 0, 0);
504 if (wparam
!= 0xdeadbeef)
510 if ((hfocus
== hedit
) && len
== 0)
511 EndDialog(hdlg
, 444);
513 EndDialog(hdlg
, 555);
517 if ((hfocus
== hok
) && len
== 0)
518 EndDialog(hdlg
, 444);
520 EndDialog(hdlg
, 555);
524 if ((hfocus
== hedit
) && len
== 2)
525 EndDialog(hdlg
, 444);
527 EndDialog(hdlg
, 555);
537 EndDialog(hdlg
, 333);
547 static HINSTANCE hinst
;
549 static const char szEditTest2Class
[] = "EditTest2Class";
550 static const char szEditTest3Class
[] = "EditTest3Class";
551 static const char szEditTest4Class
[] = "EditTest4Class";
552 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
554 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
558 handle
= CreateWindowExA(exstyle
,
563 NULL
, NULL
, hinst
, NULL
);
564 ok (handle
!= NULL
, "CreateWindow EDIT Control failed\n");
566 if (winetest_interactive
)
567 ShowWindow (handle
, SW_SHOW
);
571 static HWND
create_child_editcontrol (DWORD style
, DWORD exstyle
)
577 SetRect(&rect
, 0, 0, 300, 300);
578 b
= AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
);
579 ok(b
, "AdjustWindowRect failed\n");
581 parentWnd
= CreateWindowExA(0,
582 szEditTextPositionClass
,
585 CW_USEDEFAULT
, CW_USEDEFAULT
,
586 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
587 NULL
, NULL
, hinst
, NULL
);
588 ok (parentWnd
!= NULL
, "CreateWindow EDIT Test failed\n");
591 editWnd
= CreateWindowExA(exstyle
,
596 parentWnd
, NULL
, hinst
, NULL
);
597 ok (editWnd
!= NULL
, "CreateWindow EDIT Test Text failed\n");
599 if (winetest_interactive
)
600 ShowWindow (parentWnd
, SW_SHOW
);
604 static void destroy_child_editcontrol (HWND hwndEdit
)
606 if (GetParent(hwndEdit
))
607 DestroyWindow(GetParent(hwndEdit
));
609 trace("Edit control has no parent!\n");
610 DestroyWindow(hwndEdit
);
614 static LONG
get_edit_style (HWND hwnd
)
616 return GetWindowLongA( hwnd
, GWL_STYLE
) & (
618 /* FIXME: not implemented
637 static void set_client_height(HWND Wnd
, unsigned Height
)
639 RECT ClientRect
, WindowRect
;
641 GetWindowRect(Wnd
, &WindowRect
);
642 GetClientRect(Wnd
, &ClientRect
);
643 SetWindowPos(Wnd
, NULL
, 0, 0,
644 WindowRect
.right
- WindowRect
.left
,
645 Height
+ (WindowRect
.bottom
- WindowRect
.top
) -
646 (ClientRect
.bottom
- ClientRect
.top
),
647 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
649 /* Workaround for a bug in Windows' edit control
651 GetWindowRect(Wnd
, &WindowRect
);
652 SetWindowPos(Wnd
, NULL
, 0, 0,
653 WindowRect
.right
- WindowRect
.left
+ 1,
654 WindowRect
.bottom
- WindowRect
.top
+ 1,
655 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
656 SetWindowPos(Wnd
, NULL
, 0, 0,
657 WindowRect
.right
- WindowRect
.left
,
658 WindowRect
.bottom
- WindowRect
.top
,
659 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
661 GetClientRect(Wnd
, &ClientRect
);
662 ok(ClientRect
.bottom
- ClientRect
.top
== Height
,
663 "The client height should be %d, but is %d\n",
664 Height
, ClientRect
.bottom
- ClientRect
.top
);
667 static void test_edit_control_1(void)
674 msMessage
.message
= WM_KEYDOWN
;
676 trace("EDIT: Single line\n");
677 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
678 r
= get_edit_style(hwEdit
);
679 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
), "Wrong style expected 0xc0 got: 0x%x\n", r
);
680 for (i
=0;i
<65535;i
++)
682 msMessage
.wParam
= i
;
683 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
684 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
685 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
687 DestroyWindow (hwEdit
);
689 trace("EDIT: Single line want returns\n");
690 hwEdit
= create_editcontrol(ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
691 r
= get_edit_style(hwEdit
);
692 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
| ES_WANTRETURN
), "Wrong style expected 0x10c0 got: 0x%x\n", r
);
693 for (i
=0;i
<65535;i
++)
695 msMessage
.wParam
= i
;
696 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
697 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
698 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
700 DestroyWindow (hwEdit
);
702 trace("EDIT: Multiline line\n");
703 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
704 r
= get_edit_style(hwEdit
);
705 ok(r
== (ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0xc4 got: 0x%x\n", r
);
706 for (i
=0;i
<65535;i
++)
708 msMessage
.wParam
= i
;
709 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
710 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
711 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
713 DestroyWindow (hwEdit
);
715 trace("EDIT: Multi line want returns\n");
716 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
717 r
= get_edit_style(hwEdit
);
718 ok(r
== (ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0x10c4 got: 0x%x\n", r
);
719 for (i
=0;i
<65535;i
++)
721 msMessage
.wParam
= i
;
722 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
723 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
724 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
726 DestroyWindow (hwEdit
);
729 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
730 * selection. This test checks that the first 'select all' doesn't generate
731 * an UPDATE message which can escape and (via a handler) change the
732 * selection, which would cause WM_SETTEXT to break. This old bug
733 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
735 static void test_edit_control_2(void)
737 HWND hwndMain
, phwnd
;
738 char szLocalString
[MAXLEN
];
739 LONG r
, w
= 150, h
= 50;
742 /* Create main and edit windows. */
743 hwndMain
= CreateWindowA(szEditTest2Class
, "ET2", WS_OVERLAPPEDWINDOW
,
744 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
746 if (winetest_interactive
)
747 ShowWindow (hwndMain
, SW_SHOW
);
749 hwndET2
= CreateWindowA("EDIT", NULL
,
750 WS_CHILD
|WS_BORDER
|ES_LEFT
|ES_AUTOHSCROLL
,
751 0, 0, w
, h
, /* important this not be 0 size. */
752 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
754 if (winetest_interactive
)
755 ShowWindow (hwndET2
, SW_SHOW
);
757 trace("EDIT: SETTEXT atomicity\n");
758 /* Send messages to "type" in the word 'foo'. */
759 r
= SendMessageA(hwndET2
, WM_CHAR
, 'f', 1);
760 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
761 r
= SendMessageA(hwndET2
, WM_CHAR
, 'o', 1);
762 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
763 r
= SendMessageA(hwndET2
, WM_CHAR
, 'o', 1);
764 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
765 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
766 GetWindowTextA(hwndET2
, szLocalString
, MAXLEN
);
767 ok(strcmp(szLocalString
, "bar")==0,
768 "Wrong contents of edit: %s\n", szLocalString
);
770 /* try setting the caret before it's visible */
771 r
= SetCaretPos(0, 0);
772 todo_wine
ok(0 == r
, "SetCaretPos succeeded unexpectedly, expected: 0, got: %d\n", r
);
773 phwnd
= SetFocus(hwndET2
);
774 ok(phwnd
!= NULL
, "SetFocus failed unexpectedly, expected non-zero, got NULL\n");
775 r
= SetCaretPos(0, 0);
776 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
777 r
= GetCaretPos(&cpos
);
778 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
779 ok(cpos
.x
== 0 && cpos
.y
== 0, "Wrong caret position, expected: (0,0), got: (%d,%d)\n", cpos
.x
, cpos
.y
);
780 r
= SetCaretPos(-1, -1);
781 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
782 r
= GetCaretPos(&cpos
);
783 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
784 ok(cpos
.x
== -1 && cpos
.y
== -1, "Wrong caret position, expected: (-1,-1), got: (%d,%d)\n", cpos
.x
, cpos
.y
);
785 r
= SetCaretPos(w
<< 1, h
<< 1);
786 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
787 r
= GetCaretPos(&cpos
);
788 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
789 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
);
790 r
= SetCaretPos(w
, h
);
791 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
792 r
= GetCaretPos(&cpos
);
793 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
794 ok(cpos
.x
== w
&& cpos
.y
== h
, "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
, h
, cpos
.x
, cpos
.y
);
795 r
= SetCaretPos(w
- 1, h
- 1);
796 ok(1 == r
, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
797 r
= GetCaretPos(&cpos
);
798 ok(1 == r
, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r
);
799 ok(cpos
.x
== (w
- 1) && cpos
.y
== (h
- 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w
- 1, h
- 1, cpos
.x
, cpos
.y
);
802 DestroyWindow (hwndET2
);
803 DestroyWindow (hwndMain
);
806 static void ET2_check_change(void) {
807 char szLocalString
[MAXLEN
];
808 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
809 GetWindowTextA(hwndET2
, szLocalString
, MAXLEN
);
810 if (strcmp(szLocalString
, "foo")==0) {
811 strcpy(szLocalString
, "bar");
812 SendMessageA(hwndET2
, WM_SETTEXT
, 0, (LPARAM
) szLocalString
);
814 /* always leave the cursor at the end. */
815 SendMessageA(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
817 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
819 if (id
==ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
822 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); \
850 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
854 switch (HIWORD(wParam
)) {
856 notifications
.en_maxtext
++;
859 notifications
.en_update
++;
862 notifications
.en_change
++;
867 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
870 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
873 static void test_edit_control_3(void)
879 static const char *str
= "this is a long string.";
880 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
, EM_SETLIMITTEXT
, 5, 0);
974 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
976 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
977 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
978 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
979 test_notify(1, 1, 1);
982 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
983 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
984 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
985 test_notify(1, 0, 1);
989 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
990 hWnd
= CreateWindowExA(0,
994 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
995 hParent
, NULL
, NULL
, NULL
);
999 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1000 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1001 if (len
== lstrlenA(str
)) /* Win 8 */
1002 test_notify(1, 0, 1);
1005 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1006 test_notify(1, 1, 1);
1009 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1011 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1012 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1013 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1014 test_notify(1, 0, 1);
1017 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1018 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1019 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1020 test_notify(0, 0, 0);
1022 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1024 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1026 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
1027 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1028 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1029 test_notify(1, 1, 1);
1032 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1033 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1034 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1035 test_notify(0, 0, 0);
1037 DestroyWindow(hWnd
);
1039 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1040 hWnd
= CreateWindowExA(0,
1043 ES_MULTILINE
| ES_AUTOHSCROLL
,
1044 10, 10, (50 * dpi
) / 96, (50 * dpi
) / 96,
1045 hParent
, NULL
, NULL
, NULL
);
1049 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1050 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1051 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
1052 test_notify(1, 1, 1);
1054 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1056 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
1057 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1058 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
1059 test_notify(1, 0, 1);
1062 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1063 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1064 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1065 test_notify(0, 0, 0);
1067 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1069 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1071 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1072 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1073 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1074 test_notify(1, 1, 1);
1077 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1078 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1079 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1080 test_notify(0, 0, 0);
1082 DestroyWindow(hWnd
);
1084 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1085 hWnd
= CreateWindowExA(0,
1088 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
1090 hParent
, NULL
, NULL
, NULL
);
1094 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1095 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1096 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1097 test_notify(1, 0, 1);
1100 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1101 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1102 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1103 test_notify(0, 0, 0);
1105 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
1107 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
1109 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
1110 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1111 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
1112 test_notify(1, 1, 1);
1115 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
1116 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1117 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
1118 test_notify(0, 0, 0);
1120 DestroyWindow(hWnd
);
1123 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
1125 static void test_edit_control_4(void)
1132 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
1133 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1134 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1135 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1136 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1137 mid
= lo
+ (hi
- lo
) / 2;
1139 for (i
= lo
; i
< mid
; i
++) {
1140 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1141 ok(0 == ret
, "expected 0 got %d\n", ret
);
1143 for (i
= mid
; i
<= hi
; i
++) {
1144 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1145 ok(1 == ret
, "expected 1 got %d\n", ret
);
1147 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1148 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1149 DestroyWindow(hwEdit
);
1151 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1152 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1153 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1154 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1155 mid
= lo
+ (hi
- lo
) / 2;
1157 for (i
= lo
; i
< mid
; i
++) {
1158 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1159 ok(0 == ret
, "expected 0 got %d\n", ret
);
1161 for (i
= mid
; i
<= hi
; i
++) {
1162 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1163 ok(1 == ret
, "expected 1 got %d\n", ret
);
1165 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1166 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1167 DestroyWindow(hwEdit
);
1169 hwEdit
= create_editcontrol(ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1170 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1171 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1172 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1173 mid
= lo
+ (hi
- lo
) / 2;
1175 for (i
= lo
; i
< mid
; i
++) {
1176 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1177 ok(0 == ret
, "expected 0 got %d\n", ret
);
1179 for (i
= mid
; i
<= hi
; i
++) {
1180 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1181 ok(1 == ret
, "expected 1 got %d\n", ret
);
1183 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1184 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1185 DestroyWindow(hwEdit
);
1187 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1188 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1189 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1190 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1191 mid
= lo
+ (hi
- lo
) / 2 +1;
1193 for (i
= lo
; i
< mid
; i
++) {
1194 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1195 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1197 for (i
= mid
; i
<= hi
; i
++) {
1198 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1199 ok(1 == ret
, "expected 1 got %d\n", ret
);
1201 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1202 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1203 DestroyWindow(hwEdit
);
1205 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1206 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1207 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1208 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1209 mid
= lo
+ (hi
- lo
) / 2 +1;
1211 for (i
= lo
; i
< mid
; i
++) {
1212 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1213 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1215 for (i
= mid
; i
<= hi
; i
++) {
1216 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1217 ok(1 == ret
, "expected 1 got %d\n", ret
);
1219 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1220 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1221 DestroyWindow(hwEdit
);
1223 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1224 SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
1225 lo
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 0, 0));
1226 hi
= LOWORD(SendMessageA(hwEdit
, EM_POSFROMCHAR
, 1, 0));
1227 mid
= lo
+ (hi
- lo
) / 2 +1;
1229 for (i
= lo
; i
< mid
; i
++) {
1230 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1231 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
1233 for (i
= mid
; i
<= hi
; i
++) {
1234 ret
= LOWORD(SendMessageA(hwEdit
, EM_CHARFROMPOS
, 0, i
));
1235 ok(1 == ret
, "expected 1 got %d\n", ret
);
1237 ret
= SendMessageA(hwEdit
, EM_POSFROMCHAR
, 2, 0);
1238 ok(-1 == ret
, "expected -1 got %d\n", ret
);
1239 DestroyWindow(hwEdit
);
1242 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1243 * truncates text that doesn't fit.
1245 static void test_edit_control_5(void)
1247 static const char *str
= "test\r\ntest";
1251 RECT rc1
= { 10, 10, 11, 11};
1254 /* first show that a non-child won't do for this test */
1255 hWnd
= CreateWindowExA(0,
1260 NULL
, NULL
, NULL
, NULL
);
1262 /* size of non-child edit control is (much) bigger than requested */
1263 GetWindowRect( hWnd
, &rc
);
1264 ok( rc
.right
- rc
.left
> 20, "size of the window (%d) is smaller than expected\n",
1265 rc
.right
- rc
.left
);
1266 DestroyWindow(hWnd
);
1267 /* so create a parent, and give it edit controls children to test with */
1268 parentWnd
= CreateWindowExA(0,
1269 szEditTextPositionClass
,
1270 "Edit Test", WS_VISIBLE
|
1271 WS_OVERLAPPEDWINDOW
,
1272 CW_USEDEFAULT
, CW_USEDEFAULT
,
1274 NULL
, NULL
, hinst
, NULL
);
1276 ShowWindow( parentWnd
, SW_SHOW
);
1278 hWnd
= CreateWindowExA(0,
1280 str
, WS_VISIBLE
| WS_BORDER
|
1282 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1283 parentWnd
, NULL
, NULL
, NULL
);
1285 GetClientRect( hWnd
, &rc
);
1286 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1287 "Client rectangle not the expected size (%d,%d,%d,%d)\n",
1288 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
1289 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1290 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1291 DestroyWindow(hWnd
);
1293 hWnd
= CreateWindowExA(0,
1296 WS_CHILD
| ES_MULTILINE
,
1297 rc1
.left
, rc1
.top
, rc1
.right
- rc1
.left
, rc1
.bottom
- rc1
.top
,
1298 parentWnd
, NULL
, NULL
, NULL
);
1300 GetClientRect( hWnd
, &rc
);
1301 ok( rc
.right
== rc1
.right
- rc1
.left
&& rc
.bottom
== rc1
.bottom
- rc1
.top
,
1302 "Client rectangle not the expected size (%d,%d,%d,%d)\n",
1303 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
1304 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
1305 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
1306 DestroyWindow(hWnd
);
1307 DestroyWindow(parentWnd
);
1310 /* Test WM_GETTEXT processing
1311 * after destroy messages
1313 static void test_edit_control_6(void)
1315 static const char *str
= "test\r\ntest";
1320 hWnd
= CreateWindowExA(0,
1325 NULL
, NULL
, hinst
, NULL
);
1328 ret
= SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
1329 ok(ret
== TRUE
, "Expected %d, got %d\n", TRUE
, ret
);
1330 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1331 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1332 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1334 ret
= SendMessageA(hWnd
, WM_DESTROY
, 0, 0);
1335 ok(ret
== 0, "Expected 0, got %d\n", ret
);
1336 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1337 ok(ret
== strlen(str
), "Expected %s, got len %d\n", str
, ret
);
1338 ok(!strcmp(buf
, str
), "Expected %s, got %s\n", str
, buf
);
1340 ret
= SendMessageA(hWnd
, WM_NCDESTROY
, 0, 0);
1341 ok(ret
== 0, "Expected 0, got %d\n", ret
);
1342 ret
= SendMessageA(hWnd
, WM_GETTEXT
, MAXLEN
, (LPARAM
)buf
);
1343 ok(ret
== 0, "Expected 0, got len %d\n", ret
);
1344 ok(!strcmp(buf
, ""), "Expected empty string, got %s\n", buf
);
1346 DestroyWindow(hWnd
);
1349 static void test_edit_control_limittext(void)
1354 /* Test default limit for single-line control */
1355 trace("EDIT: buffer limit for single-line\n");
1356 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1357 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1358 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1359 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1360 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1361 ok( r
== 2147483646, "got limit %u (expected 2147483646)\n", r
);
1362 DestroyWindow(hwEdit
);
1364 /* Test default limit for multi-line control */
1365 trace("EDIT: buffer limit for multi-line\n");
1366 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1367 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1368 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
1369 SendMessageA(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
1370 r
= SendMessageA(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
1371 ok( r
== 4294967295U, "got limit %u (expected 4294967295)\n", r
);
1372 DestroyWindow(hwEdit
);
1375 /* Test EM_SCROLL */
1376 static void test_edit_control_scroll(void)
1378 static const char *single_line_str
= "a";
1379 static const char *multiline_str
= "Test\r\nText";
1383 /* Check the return value when EM_SCROLL doesn't scroll
1384 * anything. Should not return true unless any lines were actually
1386 hwEdit
= CreateWindowA(
1389 WS_VSCROLL
| ES_MULTILINE
,
1391 NULL
, NULL
, hinst
, NULL
);
1395 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1396 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1398 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEUP
, 0);
1399 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1401 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEUP
, 0);
1402 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1404 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_LINEDOWN
, 0);
1405 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1407 DestroyWindow (hwEdit
);
1409 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1410 should not cause EM_SCROLL to return a negative value of
1411 scrolled lines that would put us "before" the beginning. */
1412 hwEdit
= CreateWindowA(
1415 WS_VSCROLL
| ES_MULTILINE
,
1417 NULL
, NULL
, hinst
, NULL
);
1420 ret
= SendMessageA(hwEdit
, EM_SCROLL
, SB_PAGEDOWN
, 0);
1421 ok(!ret
, "Returned %x, expected 0.\n", ret
);
1423 DestroyWindow (hwEdit
);
1426 static void test_margins(void)
1429 RECT old_rect
, new_rect
;
1430 INT old_right_margin
;
1431 DWORD old_margins
, new_margins
;
1435 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
1437 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1438 old_right_margin
= HIWORD(old_margins
);
1440 /* Check if setting the margins works */
1442 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
1443 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1444 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1445 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
1447 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
1448 new_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1449 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
1450 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
1452 /* The size of the rectangle must decrease if we increase the margin */
1454 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
1455 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1456 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
1457 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1458 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
1459 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
1460 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
1461 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
1463 /* If we set the margin to same value as the current margin,
1464 the rectangle must not change */
1466 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1467 SetRect(&old_rect
, 1, 1, 99, 99);
1468 SendMessageA(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
1469 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1470 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
1471 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1472 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1474 /* The lParam argument of the WM_SIZE message should be ignored. */
1476 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
1477 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, 0);
1478 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1479 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1480 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MINIMIZED
, 0);
1481 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1482 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1483 SendMessageA(hwEdit
, WM_SIZE
, SIZE_MAXIMIZED
, 0);
1484 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1485 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1486 SendMessageA(hwEdit
, WM_SIZE
, SIZE_RESTORED
, MAKELONG(10, 10));
1487 SendMessageA(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
1488 ok(EqualRect(&old_rect
, &new_rect
), "The border of the rectangle has changed\n");
1490 DestroyWindow (hwEdit
);
1492 memset(&lf
, 0, sizeof(lf
));
1494 lf
.lfWeight
= FW_NORMAL
;
1495 lf
.lfCharSet
= DEFAULT_CHARSET
;
1496 strcpy(lf
.lfFaceName
, "Tahoma");
1498 hfont
= CreateFontIndirectA(&lf
);
1499 ok(hfont
!= NULL
, "got %p\n", hfont
);
1501 /* Empty window rectangle */
1502 hwEdit
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
, NULL
, NULL
, NULL
, NULL
);
1503 ok(hwEdit
!= NULL
, "got %p\n", hwEdit
);
1504 GetClientRect(hwEdit
, &old_rect
);
1505 ok(IsRectEmpty(&old_rect
), "got rect %d,%d-%d,%d\n", old_rect
.left
, old_rect
.top
, old_rect
.right
, old_rect
.bottom
);
1507 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1508 ok(old_margins
== 0, "got %x\n", old_margins
);
1510 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1511 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1512 ok(HIWORD(old_margins
) > 0 && LOWORD(old_margins
) > 0, "got %d, %d\n", HIWORD(old_margins
), LOWORD(old_margins
));
1514 DestroyWindow(hwEdit
);
1516 /* Size is not enough to display a text, but not empty */
1517 hwEdit
= CreateWindowExA(0, "Edit", "A", WS_POPUP
, 0, 0, 2, 2, NULL
, NULL
, NULL
, NULL
);
1518 ok(hwEdit
!= NULL
, "got %p\n", hwEdit
);
1519 GetClientRect(hwEdit
, &old_rect
);
1520 ok(!IsRectEmpty(&old_rect
), "got rect %d,%d-%d,%d\n", old_rect
.left
, old_rect
.top
, old_rect
.right
, old_rect
.bottom
);
1522 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1523 ok(old_margins
== 0, "got %x\n", old_margins
);
1525 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, MAKELPARAM(TRUE
, 0));
1526 old_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1527 ok(old_margins
== 0, "got %d, %d\n", HIWORD(old_margins
), LOWORD(old_margins
));
1529 DeleteObject(hfont
);
1530 DestroyWindow(hwEdit
);
1533 static INT CALLBACK
find_font_proc(const LOGFONTA
*elf
, const TEXTMETRICA
*ntm
, DWORD type
, LPARAM lParam
)
1538 static void test_margins_font_change(void)
1541 DWORD margins
, font_margins
;
1543 HFONT hfont
, hfont2
;
1546 if(EnumFontFamiliesA(hdc
, "Arial", find_font_proc
, 0))
1548 trace("Arial not found - skipping font change margin tests\n");
1554 hwEdit
= create_child_editcontrol(0, 0);
1556 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1558 memset(&lf
, 0, sizeof(lf
));
1559 strcpy(lf
.lfFaceName
, "Arial");
1561 lf
.lfCharSet
= DEFAULT_CHARSET
;
1562 hfont
= CreateFontIndirectA(&lf
);
1564 hfont2
= CreateFontIndirectA(&lf
);
1566 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1567 font_margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1568 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
1569 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
1571 /* With 'small' edit controls, test that the margin doesn't get set */
1572 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1573 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
1574 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1575 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1576 ok(LOWORD(margins
) == 0 || broken(LOWORD(margins
) == LOWORD(font_margins
)), /* win95 */
1577 "got %d\n", LOWORD(margins
));
1578 ok(HIWORD(margins
) == 0 || broken(HIWORD(margins
) == HIWORD(font_margins
)), /* win95 */
1579 "got %d\n", HIWORD(margins
));
1581 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1582 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1583 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1584 ok(LOWORD(margins
) == 1 || broken(LOWORD(margins
) == LOWORD(font_margins
)), /* win95 */
1585 "got %d\n", LOWORD(margins
));
1586 ok(HIWORD(margins
) == 0 || broken(HIWORD(margins
) == HIWORD(font_margins
)), /* win95 */
1587 "got %d\n", HIWORD(margins
));
1589 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1590 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1591 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1592 ok(LOWORD(margins
) == 1 || broken(LOWORD(margins
) == LOWORD(font_margins
)), /* win95 */
1593 "got %d\n", LOWORD(margins
));
1594 ok(HIWORD(margins
) == 1 || broken(HIWORD(margins
) == HIWORD(font_margins
)), /* win95 */
1595 "got %d\n", HIWORD(margins
));
1597 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1598 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1599 ok(LOWORD(margins
) == 1 || broken(LOWORD(margins
) == LOWORD(font_margins
)), /* win95 */
1600 "got %d\n", LOWORD(margins
));
1601 ok(HIWORD(margins
) == 1 || broken(HIWORD(margins
) == HIWORD(font_margins
)), /* win95 */
1602 "got %d\n", HIWORD(margins
));
1604 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1605 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1606 ok(LOWORD(margins
) == 1 || broken(LOWORD(margins
) != 1 && LOWORD(margins
) != LOWORD(font_margins
)), /* win95 */
1607 "got %d\n", LOWORD(margins
));
1608 ok(HIWORD(margins
) == 1 || broken(HIWORD(margins
) != 1 && HIWORD(margins
) != HIWORD(font_margins
)), /* win95 */
1609 "got %d\n", HIWORD(margins
));
1611 /* Above a certain size threshold then the margin is updated */
1612 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
1613 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
1614 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1615 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1616 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1617 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1619 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
1620 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1621 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1622 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1623 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1625 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
1626 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
1627 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1628 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
1629 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1630 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
1631 margins
= SendMessageA(hwEdit
, EM_GETMARGINS
, 0, 0);
1632 ok(LOWORD(margins
) != LOWORD(font_margins
) || broken(LOWORD(margins
) == LOWORD(font_margins
)), /* win98 */
1633 "got %d\n", LOWORD(margins
));
1634 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
1636 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
1638 DeleteObject(hfont2
);
1639 DeleteObject(hfont
);
1640 destroy_child_editcontrol(hwEdit
);
1644 #define edit_pos_ok(exp, got, txt) \
1645 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1647 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1651 set_client_height(hwEdit, set_height); \
1652 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1653 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
1654 edit_pos_ok(test_top, format_rect.top, vertical position); \
1655 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1656 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1659 static void test_text_position_style(DWORD style
)
1662 HFONT font
, oldFont
;
1664 TEXTMETRICA metrics
;
1666 BOOL xb
, single_line
= !(style
& ES_MULTILINE
);
1668 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
1673 /* Get a stock font for which we can determine the metrics */
1674 font
= GetStockObject(SYSTEM_FONT
);
1675 ok (font
!= NULL
, "GetStockObject SYSTEM_FONT failed\n");
1677 ok (dc
!= NULL
, "GetDC() failed\n");
1678 oldFont
= SelectObject(dc
, font
);
1679 xb
= GetTextMetricsA(dc
, &metrics
);
1680 ok (xb
, "GetTextMetrics failed\n");
1681 SelectObject(dc
, oldFont
);
1682 ReleaseDC(NULL
, dc
);
1684 /* Windows' edit control has some bugs in multi-line mode:
1685 * - Sometimes the format rectangle doesn't get updated
1686 * (see workaround in set_client_height())
1687 * - If the height of the control is smaller than the height of a text
1688 * line, the format rectangle is still as high as a text line
1689 * (higher than the client rectangle) and the caret is not shown
1692 /* Edit controls that are in a parent window */
1694 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
1695 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1697 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1698 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1699 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1700 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1701 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1702 destroy_child_editcontrol(hwEdit
);
1704 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
1705 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1707 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1708 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1709 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1710 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1711 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1712 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1713 destroy_child_editcontrol(hwEdit
);
1715 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1716 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1718 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1719 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1720 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1721 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1722 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1723 destroy_child_editcontrol(hwEdit
);
1725 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
1726 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1728 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1729 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1730 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1731 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1732 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1733 destroy_child_editcontrol(hwEdit
);
1736 /* Edit controls that are popup windows */
1738 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
1739 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1741 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
1742 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
1743 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
1744 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
1745 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
1746 DestroyWindow(hwEdit
);
1748 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
1749 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1751 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1752 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1753 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1754 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1755 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1756 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1757 DestroyWindow(hwEdit
);
1759 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
1760 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1762 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1763 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1764 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1765 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1766 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1767 DestroyWindow(hwEdit
);
1769 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
1770 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
) font
, FALSE
);
1772 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1773 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1774 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1775 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1776 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1777 DestroyWindow(hwEdit
);
1780 static void test_text_position(void)
1782 trace("EDIT: Text position (Single line)\n");
1783 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1784 trace("EDIT: Text position (Multi line)\n");
1785 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1788 static void test_espassword(void)
1793 const char* password
= "secret";
1795 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
1796 r
= get_edit_style(hwEdit
);
1797 ok(r
== ES_PASSWORD
, "Wrong style expected ES_PASSWORD got: 0x%x\n", r
);
1799 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
1800 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
1802 /* select all, cut (ctrl-x) */
1803 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1804 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
1805 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1808 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1809 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
1810 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
1812 r
= OpenClipboard(hwEdit
);
1813 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1814 r
= EmptyClipboard();
1815 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1816 r
= CloseClipboard();
1817 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1819 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1820 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1821 r
= SendMessageA(hwEdit
, WM_CHAR
, 3, 0);
1822 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1823 r
= SendMessageA(hwEdit
, WM_CHAR
, 22, 0);
1824 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1828 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1829 ok(r
== 0, "Expected: 0, got: %d\n", r
);
1830 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
1832 DestroyWindow (hwEdit
);
1835 static void test_undo(void)
1841 const char* text
= "undo this";
1843 hwEdit
= create_editcontrol(0, 0);
1844 r
= get_edit_style(hwEdit
);
1845 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1848 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
1849 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1852 cpMin
= cpMax
= 0xdeadbeef;
1853 SendMessageA(hwEdit
, EM_SETSEL
, 0, -1);
1854 r
= SendMessageA(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
1855 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
1856 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
1857 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
1860 r
= SendMessageA(hwEdit
, WM_CHAR
, 24, 0);
1861 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1865 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1866 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1867 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1870 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
1871 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1875 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1876 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
1877 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
1879 /* undo again (ctrl-z) */
1880 r
= SendMessageA(hwEdit
, WM_CHAR
, 26, 0);
1881 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1885 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1886 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
1887 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1889 DestroyWindow (hwEdit
);
1892 static void test_enter(void)
1899 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
1900 r
= get_edit_style(hwEdit
);
1901 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
1904 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
1905 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1907 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
1908 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1912 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
1913 ok(2 == r
, "Expected: %d, got len %d\n", 2, r
);
1914 ok(0 == strcmp(buffer
, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer
);
1916 DestroyWindow (hwEdit
);
1919 hwEdit
= create_editcontrol(0, 0);
1920 r
= get_edit_style(hwEdit
);
1921 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1924 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
1925 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1927 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
1928 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1932 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
1933 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1934 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
1936 DestroyWindow (hwEdit
);
1938 /* single line with ES_WANTRETURN */
1939 hwEdit
= create_editcontrol(ES_WANTRETURN
, 0);
1940 r
= get_edit_style(hwEdit
);
1941 ok(ES_WANTRETURN
== r
, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r
);
1944 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
1945 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1947 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0);
1948 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1952 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
1953 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1954 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
1956 DestroyWindow (hwEdit
);
1959 static void test_tab(void)
1966 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
1967 r
= get_edit_style(hwEdit
);
1968 ok(ES_MULTILINE
== r
, "Wrong style expected ES_MULTILINE got: 0x%x\n", r
);
1971 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
1972 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1974 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
1975 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1979 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
1980 ok(1 == r
, "Expected: %d, got len %d\n", 1, r
);
1981 ok(0 == strcmp(buffer
, "\t"), "expected \"\\t\", got \"%s\"\n", buffer
);
1983 DestroyWindow (hwEdit
);
1986 hwEdit
= create_editcontrol(0, 0);
1987 r
= get_edit_style(hwEdit
);
1988 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1991 r
= SendMessageA(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "");
1992 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1994 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_TAB
, 0);
1995 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
1999 r
= SendMessageA(hwEdit
, WM_GETTEXT
, 16, (LPARAM
) buffer
);
2000 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
2001 ok(0 == strcmp(buffer
, ""), "expected \"\", got \"%s\"\n", buffer
);
2003 DestroyWindow (hwEdit
);
2006 static void test_edit_dialog(void)
2010 /* from bug 11841 */
2011 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 0);
2012 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2013 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 1);
2014 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2015 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 2);
2016 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2018 /* more tests for WM_CHAR */
2019 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 3);
2020 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2021 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 4);
2022 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2023 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 5);
2024 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2026 /* more tests for WM_KEYDOWN + WM_CHAR */
2027 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 6);
2028 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2029 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 7);
2030 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2031 r
= DialogBoxParamA(hinst
, "EDIT_READONLY_DIALOG", NULL
, edit_dialog_proc
, 8);
2032 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2034 /* tests with an editable edit control */
2035 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 0);
2036 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2037 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 1);
2038 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2039 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 2);
2040 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2042 /* tests for WM_CHAR */
2043 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 3);
2044 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2045 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 4);
2046 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2047 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 5);
2048 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2050 /* tests for WM_KEYDOWN + WM_CHAR */
2051 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 6);
2052 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2053 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 7);
2054 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2055 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 8);
2056 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2058 /* multiple tab tests */
2059 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 9);
2060 ok(22 == r
, "Expected %d, got %d\n", 22, r
);
2061 r
= DialogBoxParamA(hinst
, "EDIT_DIALOG", NULL
, edit_dialog_proc
, 10);
2062 ok(33 == r
, "Expected %d, got %d\n", 33, r
);
2065 static void test_multi_edit_dialog(void)
2069 /* test for multiple edit dialogs (bug 12319) */
2070 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 0);
2071 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2072 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 1);
2073 ok(1111 == r
, "Expected %d, got %d\n", 1111, r
);
2074 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 2);
2075 ok(2222 == r
, "Expected %d, got %d\n", 2222, r
);
2076 r
= DialogBoxParamA(hinst
, "MULTI_EDIT_DIALOG", NULL
, multi_edit_dialog_proc
, 3);
2077 ok(11 == r
, "Expected %d, got %d\n", 11, r
);
2080 static void test_wantreturn_edit_dialog(void)
2084 /* tests for WM_KEYDOWN */
2085 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 0);
2086 ok(333 == r
, "Expected %d, got %d\n", 333, r
);
2087 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 1);
2088 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2089 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 2);
2090 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2092 /* tests for WM_CHAR */
2093 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 3);
2094 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2095 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 4);
2096 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2097 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 5);
2098 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2100 /* tests for WM_KEYDOWN + WM_CHAR */
2101 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 6);
2102 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2103 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 7);
2104 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2105 r
= DialogBoxParamA(hinst
, "EDIT_WANTRETURN_DIALOG", NULL
, edit_wantreturn_dialog_proc
, 8);
2106 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2109 static void test_singleline_wantreturn_edit_dialog(void)
2113 /* tests for WM_KEYDOWN */
2114 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2115 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2116 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2117 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2118 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2119 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2121 /* tests for WM_CHAR */
2122 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2123 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2124 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2125 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2126 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2127 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2129 /* tests for WM_KEYDOWN + WM_CHAR */
2130 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2131 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2132 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2133 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2134 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2135 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2137 /* tests for WM_KEYDOWN */
2138 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 0);
2139 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2140 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 1);
2141 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2142 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 2);
2143 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2145 /* tests for WM_CHAR */
2146 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 3);
2147 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2148 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 4);
2149 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2150 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 5);
2151 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2153 /* tests for WM_KEYDOWN + WM_CHAR */
2154 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 6);
2155 ok(222 == r
, "Expected %d, got %d\n", 222, r
);
2156 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 7);
2157 ok(111 == r
, "Expected %d, got %d\n", 111, r
);
2158 r
= DialogBoxParamA(hinst
, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL
, edit_singleline_dialog_proc
, 8);
2159 ok(444 == r
, "Expected %d, got %d\n", 444, r
);
2162 static int child_edit_wmkeydown_num_messages
= 0;
2163 static INT_PTR CALLBACK
child_edit_wmkeydown_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
2172 child_edit_wmkeydown_num_messages
++;
2179 static void test_child_edit_wmkeydown(void)
2181 HWND hwEdit
, hwParent
;
2184 hwEdit
= create_child_editcontrol(0, 0);
2185 hwParent
= GetParent(hwEdit
);
2186 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)child_edit_wmkeydown_proc
);
2187 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2188 ok(1 == r
, "expected 1, got %d\n", r
);
2189 ok(0 == child_edit_wmkeydown_num_messages
, "expected 0, got %d\n", child_edit_wmkeydown_num_messages
);
2190 destroy_child_editcontrol(hwEdit
);
2193 static BOOL got_en_setfocus
= FALSE
;
2194 static BOOL got_wm_capturechanged
= FALSE
;
2195 static LRESULT (CALLBACK
*p_edit_proc
)(HWND
, UINT
, WPARAM
, LPARAM
);
2197 static LRESULT CALLBACK
edit4_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2201 switch (HIWORD(wParam
)) {
2203 got_en_setfocus
= TRUE
;
2207 case WM_CAPTURECHANGED
:
2208 if (hWnd
!= (HWND
)lParam
)
2210 got_wm_capturechanged
= TRUE
;
2215 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
2218 static LRESULT CALLBACK
edit_proc_proxy(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2221 case WM_ENTERIDLE
: {
2224 HWND ctx_menu
= (HWND
)lParam
;
2226 memset(&mbi
, 0, sizeof(mbi
));
2227 mbi
.cbSize
= sizeof(mbi
);
2228 SetLastError(0xdeadbeef);
2229 ret
= pGetMenuBarInfo(ctx_menu
, OBJID_CLIENT
, 0, &mbi
);
2230 ok(ret
|| broken(!ret
&& GetLastError()==ERROR_INVALID_WINDOW_HANDLE
) /* NT */,
2231 "GetMenuBarInfo failed\n");
2234 ok(mbi
.hMenu
!= NULL
, "mbi.hMenu = NULL\n");
2235 ok(!mbi
.hwndMenu
, "mbi.hwndMenu != NULL\n");
2236 ok(mbi
.fBarFocused
, "mbi.fBarFocused = FALSE\n");
2237 ok(mbi
.fFocused
, "mbi.fFocused = FALSE\n");
2240 memset(&mbi
, 0, sizeof(mbi
));
2241 mbi
.cbSize
= sizeof(mbi
);
2242 SetLastError(0xdeadbeef);
2243 ret
= pGetMenuBarInfo(ctx_menu
, OBJID_CLIENT
, 1, &mbi
);
2244 ok(ret
|| broken(!ret
&& GetLastError()==ERROR_INVALID_WINDOW_HANDLE
) /* NT */,
2245 "GetMenuBarInfo failed\n");
2248 ok(mbi
.hMenu
!= NULL
, "mbi.hMenu = NULL\n");
2249 ok(!mbi
.hwndMenu
, "mbi.hwndMenu != NULL\n");
2250 ok(mbi
.fBarFocused
, "mbi.fBarFocused = FALSE\n");
2251 ok(!mbi
.fFocused
, "mbi.fFocused = TRUE\n");
2258 return p_edit_proc(hWnd
, msg
, wParam
, lParam
);
2261 struct context_menu_messages
2263 unsigned int wm_command
, em_setsel
;
2266 static struct context_menu_messages menu_messages
;
2268 static LRESULT CALLBACK
child_edit_menu_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2272 if (wParam
== MSGF_MENU
) {
2273 HWND hwndMenu
= (HWND
)lParam
;
2274 MENUBARINFO mbi
= { sizeof(MENUBARINFO
) };
2275 if (pGetMenuBarInfo(hwndMenu
, OBJID_CLIENT
, 0, &mbi
)) {
2276 MENUITEMINFOA mii
= { sizeof(MENUITEMINFOA
), MIIM_STATE
};
2277 if (GetMenuItemInfoA(mbi
.hMenu
, EM_SETSEL
, FALSE
, &mii
)) {
2278 if (mii
.fState
& MFS_HILITE
) {
2279 PostMessageA(hwnd
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2280 PostMessageA(hwnd
, WM_KEYUP
, VK_RETURN
, 0x1c0001);
2283 PostMessageA(hwnd
, WM_KEYDOWN
, VK_DOWN
, 0x500001);
2284 PostMessageA(hwnd
, WM_KEYUP
, VK_DOWN
, 0x500001);
2291 menu_messages
.wm_command
++;
2294 menu_messages
.em_setsel
++;
2297 return CallWindowProcA(p_edit_proc
, hwnd
, msg
, wParam
, lParam
);
2300 static void test_contextmenu(void)
2302 HWND hwndMain
, hwndEdit
;
2305 hwndMain
= CreateWindowA(szEditTest4Class
, "ET4", WS_OVERLAPPEDWINDOW
|WS_VISIBLE
,
2306 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
2309 hwndEdit
= CreateWindowA("EDIT", NULL
,
2310 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|ES_LEFT
|ES_AUTOHSCROLL
,
2311 0, 0, 150, 50, /* important this not be 0 size. */
2312 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
2316 SetCapture(hwndMain
);
2317 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(10, 10));
2318 ok(got_en_setfocus
, "edit box didn't get focused\n");
2319 ok(got_wm_capturechanged
, "main window capture did not change\n");
2321 if (pGetMenuBarInfo
)
2323 p_edit_proc
= (void*)SetWindowLongPtrA(hwndEdit
, GWLP_WNDPROC
, (ULONG_PTR
)edit_proc_proxy
);
2324 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(10, 10));
2327 DestroyWindow (hwndEdit
);
2329 hwndEdit
= CreateWindowA("EDIT", "Test Text",
2330 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
2332 hwndMain
, NULL
, hinst
, NULL
);
2333 memset(&menu_messages
, 0, sizeof(menu_messages
));
2334 p_edit_proc
= (void*)SetWindowLongPtrA(hwndEdit
, GWLP_WNDPROC
,
2335 (ULONG_PTR
)child_edit_menu_proc
);
2338 SendMessageA(hwndEdit
, WM_SETTEXT
, 0, (LPARAM
)"foo");
2339 SendMessageA(hwndEdit
, WM_CONTEXTMENU
, (WPARAM
)hwndEdit
, MAKEWORD(-1, -1));
2340 while (PeekMessageA(&msg
, hwndEdit
, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
2341 ok(menu_messages
.wm_command
== 0,
2342 "Expected no WM_COMMAND messages, got %d\n", menu_messages
.wm_command
);
2343 ok(menu_messages
.em_setsel
== 1,
2344 "Expected 1 EM_SETSEL message, got %d\n", menu_messages
.em_setsel
);
2346 DestroyWindow (hwndEdit
);
2347 DestroyWindow (hwndMain
);
2350 static BOOL
RegisterWindowClasses (void)
2355 WNDCLASSA text_position
;
2358 test2
.lpfnWndProc
= ET2_WndProc
;
2359 test2
.cbClsExtra
= 0;
2360 test2
.cbWndExtra
= 0;
2361 test2
.hInstance
= hinst
;
2363 test2
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2364 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2365 test2
.lpszMenuName
= NULL
;
2366 test2
.lpszClassName
= szEditTest2Class
;
2367 if (!RegisterClassA(&test2
)) return FALSE
;
2370 test3
.lpfnWndProc
= edit3_wnd_procA
;
2371 test3
.cbClsExtra
= 0;
2372 test3
.cbWndExtra
= 0;
2373 test3
.hInstance
= hinst
;
2375 test3
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
2376 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
2377 test3
.lpszMenuName
= NULL
;
2378 test3
.lpszClassName
= szEditTest3Class
;
2379 if (!RegisterClassA(&test3
)) return FALSE
;
2382 test4
.lpfnWndProc
= edit4_wnd_procA
;
2383 test4
.cbClsExtra
= 0;
2384 test4
.cbWndExtra
= 0;
2385 test4
.hInstance
= hinst
;
2387 test4
.hCursor
= LoadCursorA (NULL
, (LPCSTR
)IDC_ARROW
);
2388 test4
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2389 test4
.lpszMenuName
= NULL
;
2390 test4
.lpszClassName
= szEditTest4Class
;
2391 if (!RegisterClassA(&test4
)) return FALSE
;
2393 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
2394 text_position
.cbClsExtra
= 0;
2395 text_position
.cbWndExtra
= 0;
2396 text_position
.hInstance
= hinst
;
2397 text_position
.hIcon
= NULL
;
2398 text_position
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
2399 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2400 text_position
.lpszMenuName
= NULL
;
2401 text_position
.lpszClassName
= szEditTextPositionClass
;
2402 text_position
.lpfnWndProc
= DefWindowProcA
;
2403 if (!RegisterClassA(&text_position
)) return FALSE
;
2408 static void UnregisterWindowClasses (void)
2410 UnregisterClassA(szEditTest2Class
, hinst
);
2411 UnregisterClassA(szEditTest3Class
, hinst
);
2412 UnregisterClassA(szEditTest4Class
, hinst
);
2413 UnregisterClassA(szEditTextPositionClass
, hinst
);
2416 static void test_fontsize(void)
2423 char szLocalString
[MAXLEN
];
2427 dpi
= GetDeviceCaps(hDC
, LOGPIXELSY
);
2428 ReleaseDC(NULL
, hDC
);
2430 memset(&lf
,0,sizeof(LOGFONTA
));
2431 strcpy(lf
.lfFaceName
,"Arial");
2432 lf
.lfHeight
= -300; /* taller than the edit box */
2434 hfont
= CreateFontIndirectA(&lf
);
2436 trace("EDIT: Oversized font (Multi line)\n");
2437 hwEdit
= CreateWindowA("EDIT", NULL
, ES_MULTILINE
|ES_AUTOHSCROLL
,
2438 0, 0, (150 * dpi
) / 96, (50 * dpi
) / 96, NULL
, NULL
,
2441 SendMessageA(hwEdit
,WM_SETFONT
,(WPARAM
)hfont
,0);
2443 if (winetest_interactive
)
2444 ShowWindow (hwEdit
, SW_SHOW
);
2446 r
= SendMessageA(hwEdit
, WM_CHAR
, 'A', 1);
2447 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2448 r
= SendMessageA(hwEdit
, WM_CHAR
, 'B', 1);
2449 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2450 r
= SendMessageA(hwEdit
, WM_CHAR
, 'C', 1);
2451 ok(1 == r
, "Expected: %d, got: %d\n", 1, r
);
2453 GetWindowTextA(hwEdit
, szLocalString
, MAXLEN
);
2454 ok(strcmp(szLocalString
, "ABC")==0,
2455 "Wrong contents of edit: %s\n", szLocalString
);
2457 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,0,0);
2458 ok(r
!= -1,"EM_POSFROMCHAR failed index 0\n");
2459 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,1,0);
2460 ok(r
!= -1,"EM_POSFROMCHAR failed index 1\n");
2461 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,2,0);
2462 ok(r
!= -1,"EM_POSFROMCHAR failed index 2\n");
2463 r
= SendMessageA(hwEdit
, EM_POSFROMCHAR
,3,0);
2464 ok(r
== -1,"EM_POSFROMCHAR succeeded index 3\n");
2466 DestroyWindow (hwEdit
);
2467 DeleteObject(hfont
);
2470 struct dialog_mode_messages
2472 int wm_getdefid
, wm_close
, wm_command
, wm_nextdlgctl
;
2475 static struct dialog_mode_messages dm_messages
;
2477 static void zero_dm_messages(void)
2479 dm_messages
.wm_command
= 0;
2480 dm_messages
.wm_close
= 0;
2481 dm_messages
.wm_getdefid
= 0;
2482 dm_messages
.wm_nextdlgctl
= 0;
2485 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2486 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2487 "got %d\n", wmcommand, dm_messages.wm_command); \
2488 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2489 "got %d\n", wmclose, dm_messages.wm_close); \
2490 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2491 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2492 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2493 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2495 static LRESULT CALLBACK
dialog_mode_wnd_proc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
2500 dm_messages
.wm_command
++;
2503 dm_messages
.wm_getdefid
++;
2504 return MAKELONG(ID_EDITTESTDBUTTON
, DC_HASDEFID
);
2506 dm_messages
.wm_nextdlgctl
++;
2509 dm_messages
.wm_close
++;
2513 return DefWindowProcA(hwnd
, iMsg
, wParam
, lParam
);
2516 static void test_dialogmode(void)
2518 HWND hwEdit
, hwParent
, hwButton
;
2521 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2523 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2524 ok(1 == r
, "expected 1, got %d\n", r
);
2525 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2526 ok(11 == len
, "expected 11, got %d\n", len
);
2528 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, 0);
2529 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2531 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2532 ok(1 == r
, "expected 1, got %d\n", r
);
2533 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2534 ok(13 == len
, "expected 13, got %d\n", len
);
2536 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
)&msg
);
2537 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2538 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2539 ok(1 == r
, "expected 1, got %d\n", r
);
2540 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2541 ok(13 == len
, "expected 13, got %d\n", len
);
2543 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2544 ok(1 == r
, "expected 1, got %d\n", r
);
2545 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2546 ok(13 == len
, "expected 13, got %d\n", len
);
2548 destroy_child_editcontrol(hwEdit
);
2550 hwEdit
= create_editcontrol(ES_MULTILINE
, 0);
2552 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2553 ok(1 == r
, "expected 1, got %d\n", r
);
2554 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2555 ok(11 == len
, "expected 11, got %d\n", len
);
2558 msg
.message
= WM_KEYDOWN
;
2559 msg
.wParam
= VK_BACK
;
2560 msg
.lParam
= 0xe0001;
2561 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_BACK
, (LPARAM
)&msg
);
2562 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2564 r
= SendMessageA(hwEdit
, WM_CHAR
, VK_RETURN
, 0x1c0001);
2565 ok(1 == r
, "expected 1, got %d\n", r
);
2566 len
= SendMessageA(hwEdit
, WM_GETTEXTLENGTH
, 0, 0);
2567 ok(11 == len
, "expected 11, got %d\n", len
);
2569 DestroyWindow(hwEdit
);
2571 hwEdit
= create_child_editcontrol(0, 0);
2572 hwParent
= GetParent(hwEdit
);
2573 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2576 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2577 ok(1 == r
, "expected 1, got %d\n", r
);
2578 test_dm_messages(0, 0, 0, 0);
2581 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2582 ok(1 == r
, "expected 1, got %d\n", r
);
2583 test_dm_messages(0, 0, 0, 0);
2587 msg
.message
= WM_KEYDOWN
;
2588 msg
.wParam
= VK_TAB
;
2589 msg
.lParam
= 0xf0001;
2590 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_TAB
, (LPARAM
)&msg
);
2591 ok(0x89 == r
, "expected 0x89, got 0x%x\n", r
);
2592 test_dm_messages(0, 0, 0, 0);
2595 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2596 ok(1 == r
, "expected 1, got %d\n", r
);
2597 test_dm_messages(0, 0, 0, 0);
2600 destroy_child_editcontrol(hwEdit
);
2602 hwEdit
= create_child_editcontrol(ES_MULTILINE
, 0);
2603 hwParent
= GetParent(hwEdit
);
2604 SetWindowLongPtrA(hwParent
, GWLP_WNDPROC
, (LONG_PTR
)dialog_mode_wnd_proc
);
2606 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2607 ok(1 == r
, "expected 1, got %d\n", r
);
2608 test_dm_messages(0, 0, 0, 0);
2612 msg
.message
= WM_KEYDOWN
;
2613 msg
.wParam
= VK_ESCAPE
;
2614 msg
.lParam
= 0x10001;
2615 r
= SendMessageA(hwEdit
, WM_GETDLGCODE
, VK_ESCAPE
, (LPARAM
)&msg
);
2616 ok(0x8d == r
, "expected 0x8d, got 0x%x\n", r
);
2617 test_dm_messages(0, 0, 0, 0);
2620 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_ESCAPE
, 0x10001);
2621 ok(1 == r
, "expected 1, got %d\n", r
);
2622 test_dm_messages(0, 0, 0, 0);
2625 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_TAB
, 0xf0001);
2626 ok(1 == r
, "expected 1, got %d\n", r
);
2627 test_dm_messages(0, 0, 0, 1);
2630 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2631 ok(1 == r
, "expected 1, got %d\n", r
);
2632 test_dm_messages(0, 0, 1, 0);
2635 hwButton
= CreateWindowA("BUTTON", "OK", WS_VISIBLE
|WS_CHILD
|BS_PUSHBUTTON
,
2636 100, 100, 50, 20, hwParent
, (HMENU
)ID_EDITTESTDBUTTON
, hinst
, NULL
);
2637 ok(hwButton
!=NULL
, "CreateWindow failed with error code %d\n", GetLastError());
2639 r
= SendMessageA(hwEdit
, WM_KEYDOWN
, VK_RETURN
, 0x1c0001);
2640 ok(1 == r
, "expected 1, got %d\n", r
);
2641 test_dm_messages(0, 0, 1, 1);
2644 DestroyWindow(hwButton
);
2645 destroy_child_editcontrol(hwEdit
);
2648 static void test_EM_GETHANDLE(void)
2650 static const char str0
[] = "untouched";
2651 static const char str1
[] = "1111+1111+1111#";
2652 static const char str2
[] = "2222-2222-2222-2222#";
2653 static const char str3
[] = "3333*3333*3333*3333*3333#";
2663 trace("EDIT: EM_GETHANDLE\n");
2665 /* EM_GETHANDLE is not supported for a single line edit control */
2666 hEdit
= create_editcontrol(WS_BORDER
, 0);
2667 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
2669 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2670 ok(hmem
== NULL
, "got %p (expected NULL)\n", hmem
);
2671 DestroyWindow(hEdit
);
2674 /* EM_GETHANDLE needs a multiline edit control */
2675 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
2676 ok(hEdit
!= NULL
, "got %p (expected != NULL)\n", hEdit
);
2679 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2680 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2681 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
2683 lstrcpyA(current
, str0
);
2684 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2685 ok((r
== lstrlenA(str1
)) && !lstrcmpA(current
, str1
),
2686 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str1
), str1
);
2688 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2689 ok(hmem
!= NULL
, "got %p (expected != NULL)\n", hmem
);
2690 /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
2691 buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
2693 buffer
= LocalLock(hmem
);
2694 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2695 len
= lstrlenA(buffer
);
2696 ok((len
== lstrlenA(str1
)) && !lstrcmpA(buffer
, str1
),
2697 "got %d and \"%s\" (expected %d and \"%s\")\n", len
, buffer
, lstrlenA(str1
), str1
);
2700 /* use LocalAlloc first to get a different handle */
2701 halloc
= LocalAlloc(LMEM_MOVEABLE
, 42);
2702 ok(halloc
!= NULL
, "got %p (expected != NULL)\n", halloc
);
2703 /* prepare our new memory */
2704 buffer
= LocalLock(halloc
);
2705 ok(buffer
!= NULL
, "got %p (expected != NULL)\n", buffer
);
2706 lstrcpyA(buffer
, str2
);
2707 LocalUnlock(halloc
);
2709 /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
2711 /* use LocalAlloc after the LocalFree to likely consume the handle */
2712 hmem2
= LocalAlloc(LMEM_MOVEABLE
, 42);
2713 ok(hmem2
!= NULL
, "got %p (expected != NULL)\n", hmem2
);
2715 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)halloc
, 0);
2717 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2718 ok(len
== lstrlenA(str2
), "got %d (expected %d)\n", len
, lstrlenA(str2
));
2720 lstrcpyA(current
, str0
);
2721 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2722 ok((r
== lstrlenA(str2
)) && !lstrcmpA(current
, str2
),
2723 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str2
), str2
);
2725 /* set a different text */
2726 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str3
);
2727 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2728 ok((r
== 1) && (len
== lstrlenA(str3
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str3
));
2730 lstrcpyA(current
, str0
);
2731 r
= SendMessageA(hEdit
, WM_GETTEXT
, sizeof(current
), (LPARAM
)current
);
2732 ok((r
== lstrlenA(str3
)) && !lstrcmpA(current
, str3
),
2733 "got %d and \"%s\" (expected %d and \"%s\")\n", r
, current
, lstrlenA(str3
), str3
);
2736 DestroyWindow(hEdit
);
2738 /* Some apps have bugs ... */
2739 hEdit
= create_editcontrol(WS_BORDER
| ES_MULTILINE
, 0);
2742 r
= SendMessageA(hEdit
, WM_SETTEXT
, 0, (LPARAM
)str1
);
2743 len
= SendMessageA(hEdit
, WM_GETTEXTLENGTH
, 0, 0);
2744 ok((r
== 1) && (len
== lstrlenA(str1
)), "got %d and %d (expected 1 and %d)\n", r
, len
, lstrlenA(str1
));
2746 /* everything is normal up to EM_GETHANDLE */
2747 hmem
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2748 /* Some messages still work while other messages fail.
2749 After LocalFree the memory handle, messages can crash the app */
2751 /* A buggy editor used EM_GETHANDLE twice */
2752 hmem2
= (HGLOBAL
) SendMessageA(hEdit
, EM_GETHANDLE
, 0, 0);
2753 ok(hmem2
== hmem
, "got %p (expected %p)\n", hmem2
, hmem
);
2755 /* Let the edit control free the memory handle */
2756 SendMessageA(hEdit
, EM_SETHANDLE
, (WPARAM
)hmem2
, 0);
2758 DestroyWindow(hEdit
);
2766 init_function_pointers();
2768 hinst
= GetModuleHandleA(NULL
);
2769 b
= RegisterWindowClasses();
2770 ok (b
, "RegisterWindowClasses failed\n");
2773 test_edit_control_1();
2774 test_edit_control_2();
2775 test_edit_control_3();
2776 test_edit_control_4();
2777 test_edit_control_5();
2778 test_edit_control_6();
2779 test_edit_control_limittext();
2780 test_edit_control_scroll();
2782 test_margins_font_change();
2783 test_text_position();
2789 test_multi_edit_dialog();
2790 test_wantreturn_edit_dialog();
2791 test_singleline_wantreturn_edit_dialog();
2792 test_child_edit_wmkeydown();
2798 win_skip("EndMenu is not available\n");
2800 test_EM_GETHANDLE();
2802 UnregisterWindowClasses();