1 /* Unit test suite for edit control.
3 * Copyright 2004 Vitaliy Margolen
4 * Copyright 2005 C. Scott Ananian
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
28 #define ES_COMBO 0x200
31 #define ID_EDITTEST2 99
35 int en_change
, en_maxtext
, en_update
;
38 static struct edit_notify notifications
;
40 static HINSTANCE hinst
;
42 static const char szEditTest2Class
[] = "EditTest2Class";
43 static const char szEditTest3Class
[] = "EditTest3Class";
44 static const char szEditTextPositionClass
[] = "EditTextPositionWindowClass";
46 static HWND
create_editcontrol (DWORD style
, DWORD exstyle
)
50 handle
= CreateWindowEx(exstyle
,
55 NULL
, NULL
, hinst
, NULL
);
57 if (winetest_interactive
)
58 ShowWindow (handle
, SW_SHOW
);
62 static HWND
create_child_editcontrol (DWORD style
, DWORD exstyle
)
72 assert(AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
));
74 parentWnd
= CreateWindowEx(0,
75 szEditTextPositionClass
,
78 CW_USEDEFAULT
, CW_USEDEFAULT
,
79 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
80 NULL
, NULL
, hinst
, NULL
);
83 editWnd
= CreateWindowEx(exstyle
,
88 parentWnd
, NULL
, hinst
, NULL
);
90 if (winetest_interactive
)
91 ShowWindow (parentWnd
, SW_SHOW
);
95 static void destroy_child_editcontrol (HWND hwndEdit
)
97 if (GetParent(hwndEdit
))
98 DestroyWindow(GetParent(hwndEdit
));
100 trace("Edit control has no parent!\n");
101 DestroyWindow(hwndEdit
);
105 static LONG
get_edit_style (HWND hwnd
)
107 return GetWindowLongA( hwnd
, GWL_STYLE
) & (
109 /* FIXME: not implemented
128 static void set_client_height(HWND Wnd
, unsigned Height
)
130 RECT ClientRect
, WindowRect
;
132 GetWindowRect(Wnd
, &WindowRect
);
133 GetClientRect(Wnd
, &ClientRect
);
134 SetWindowPos(Wnd
, NULL
, 0, 0,
135 WindowRect
.right
- WindowRect
.left
,
136 Height
+ (WindowRect
.bottom
- WindowRect
.top
) -
137 (ClientRect
.bottom
- ClientRect
.top
),
138 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
140 /* Workaround for a bug in Windows' edit control
142 GetWindowRect(Wnd
, &WindowRect
);
143 SetWindowPos(Wnd
, NULL
, 0, 0,
144 WindowRect
.right
- WindowRect
.left
+ 1,
145 WindowRect
.bottom
- WindowRect
.top
+ 1,
146 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
147 SetWindowPos(Wnd
, NULL
, 0, 0,
148 WindowRect
.right
- WindowRect
.left
,
149 WindowRect
.bottom
- WindowRect
.top
,
150 SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
152 GetClientRect(Wnd
, &ClientRect
);
153 ok(ClientRect
.bottom
- ClientRect
.top
== Height
,
154 "The client height should be %ld, but is %ld\n",
155 (long)Height
, (long)(ClientRect
.bottom
- ClientRect
.top
));
158 static void test_edit_control_1(void)
165 msMessage
.message
= WM_KEYDOWN
;
167 trace("EDIT: Single line\n");
168 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
169 r
= get_edit_style(hwEdit
);
170 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
), "Wrong style expected 0xc0 got: 0x%x\n", r
);
171 for (i
=0;i
<65535;i
++)
173 msMessage
.wParam
= i
;
174 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
175 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
176 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
178 DestroyWindow (hwEdit
);
180 trace("EDIT: Single line want returns\n");
181 hwEdit
= create_editcontrol(ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
182 r
= get_edit_style(hwEdit
);
183 ok(r
== (ES_AUTOVSCROLL
| ES_AUTOHSCROLL
| ES_WANTRETURN
), "Wrong style expected 0x10c0 got: 0x%x\n", r
);
184 for (i
=0;i
<65535;i
++)
186 msMessage
.wParam
= i
;
187 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
188 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTARROWS
),
189 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r
);
191 DestroyWindow (hwEdit
);
193 trace("EDIT: Multiline line\n");
194 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
195 r
= get_edit_style(hwEdit
);
196 ok(r
== (ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0xc4 got: 0x%x\n", r
);
197 for (i
=0;i
<65535;i
++)
199 msMessage
.wParam
= i
;
200 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
201 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
202 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
204 DestroyWindow (hwEdit
);
206 trace("EDIT: Multi line want returns\n");
207 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
208 r
= get_edit_style(hwEdit
);
209 ok(r
== (ES_WANTRETURN
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
| ES_MULTILINE
), "Wrong style expected 0x10c4 got: 0x%x\n", r
);
210 for (i
=0;i
<65535;i
++)
212 msMessage
.wParam
= i
;
213 r
= SendMessage(hwEdit
, WM_GETDLGCODE
, 0, (LPARAM
) &msMessage
);
214 ok(r
== (DLGC_WANTCHARS
| DLGC_HASSETSEL
| DLGC_WANTALLKEYS
| DLGC_WANTARROWS
),
215 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r
);
217 DestroyWindow (hwEdit
);
220 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
221 * selection. This test checks that the first 'select all' doesn't generate
222 * an UPDATE message which can escape and (via a handler) change the
223 * selection, which would cause WM_SETTEXT to break. This old bug
224 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
226 static void test_edit_control_2(void)
229 char szLocalString
[MAXLEN
];
231 /* Create main and edit windows. */
232 hwndMain
= CreateWindow(szEditTest2Class
, "ET2", WS_OVERLAPPEDWINDOW
,
233 0, 0, 200, 200, NULL
, NULL
, hinst
, NULL
);
235 if (winetest_interactive
)
236 ShowWindow (hwndMain
, SW_SHOW
);
238 hwndET2
= CreateWindow("EDIT", NULL
,
239 WS_CHILD
|WS_BORDER
|ES_LEFT
|ES_AUTOHSCROLL
,
240 0, 0, 150, 50, /* important this not be 0 size. */
241 hwndMain
, (HMENU
) ID_EDITTEST2
, hinst
, NULL
);
243 if (winetest_interactive
)
244 ShowWindow (hwndET2
, SW_SHOW
);
246 trace("EDIT: SETTEXT atomicity\n");
247 /* Send messages to "type" in the word 'foo'. */
248 SendMessage(hwndET2
, WM_CHAR
, 'f', 1);
249 SendMessage(hwndET2
, WM_CHAR
, 'o', 1);
250 SendMessage(hwndET2
, WM_CHAR
, 'o', 1);
251 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
252 GetWindowText(hwndET2
, szLocalString
, MAXLEN
);
253 ok(lstrcmp(szLocalString
, "bar")==0,
254 "Wrong contents of edit: %s\n", szLocalString
);
257 DestroyWindow (hwndET2
);
258 DestroyWindow (hwndMain
);
261 static void ET2_check_change(void) {
262 char szLocalString
[MAXLEN
];
263 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
264 GetWindowText(hwndET2
, szLocalString
, MAXLEN
);
265 if (lstrcmp(szLocalString
, "foo")==0) {
266 lstrcpy(szLocalString
, "bar");
267 SendMessage(hwndET2
, WM_SETTEXT
, 0, (LPARAM
) szLocalString
);
269 /* always leave the cursor at the end. */
270 SendMessage(hwndET2
, EM_SETSEL
, MAXLEN
- 1, MAXLEN
- 1);
272 static void ET2_OnCommand(HWND hwnd
, int id
, HWND hwndCtl
, UINT codeNotify
)
274 if (id
==ID_EDITTEST2
&& codeNotify
== EN_UPDATE
)
277 static LRESULT CALLBACK
ET2_WndProc(HWND hwnd
, UINT iMsg
, WPARAM wParam
, LPARAM lParam
)
281 ET2_OnCommand(hwnd
, LOWORD(wParam
), (HWND
)lParam
, HIWORD(wParam
));
284 return DefWindowProc(hwnd
, iMsg
, wParam
, lParam
);
287 static void zero_notify(void)
289 notifications
.en_change
= 0;
290 notifications
.en_maxtext
= 0;
291 notifications
.en_update
= 0;
294 #define test_notify(enchange, enmaxtext, enupdate) \
295 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
296 "got %d\n", enchange, notifications.en_change); \
297 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
298 "got %d\n", enmaxtext, notifications.en_maxtext); \
299 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
300 "got %d\n", enupdate, notifications.en_update)
303 static LRESULT CALLBACK
edit3_wnd_procA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
307 switch (HIWORD(wParam
)) {
309 notifications
.en_maxtext
++;
312 notifications
.en_update
++;
315 notifications
.en_change
++;
320 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
323 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
326 static void test_edit_control_3(void)
331 static const char *str
= "this is a long string.";
332 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.";
334 trace("EDIT: Test notifications\n");
336 hParent
= CreateWindowExA(0,
340 CW_USEDEFAULT
, CW_USEDEFAULT
, 10, 10,
341 NULL
, NULL
, NULL
, NULL
);
344 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
345 hWnd
= CreateWindowExA(0,
350 hParent
, NULL
, NULL
, NULL
);
354 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
355 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
356 ok(lstrlenA(str
) > len
, "text should have been truncated\n");
357 test_notify(1, 1, 1);
359 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
361 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
362 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
363 ok(1 == len
, "wrong text length, expected 1, got %d\n", len
);
364 test_notify(1, 0, 1);
367 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
368 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
369 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
370 test_notify(1, 0, 1);
372 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
374 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
376 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
377 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
378 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
379 test_notify(1, 1, 1);
382 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
383 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
384 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
385 test_notify(1, 0, 1);
389 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
390 hWnd
= CreateWindowExA(0,
395 hParent
, NULL
, NULL
, NULL
);
399 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
400 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
401 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
402 test_notify(1, 0, 1);
405 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
406 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
407 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
408 test_notify(1, 0, 1);
410 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
412 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
414 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
415 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
416 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
417 test_notify(1, 1, 1);
420 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
421 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
422 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
423 test_notify(1, 0, 1);
427 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
428 hWnd
= CreateWindowExA(0,
433 hParent
, NULL
, NULL
, NULL
);
437 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
438 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
439 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
440 test_notify(1, 1, 1);
442 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
444 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
445 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
446 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
447 test_notify(1, 0, 1);
450 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
451 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
452 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
453 test_notify(0, 0, 0);
455 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
457 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
459 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str
);
460 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
461 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
462 test_notify(1, 1, 1);
465 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str
);
466 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
467 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
468 test_notify(0, 0, 0);
472 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
473 hWnd
= CreateWindowExA(0,
476 ES_MULTILINE
| ES_AUTOHSCROLL
,
478 hParent
, NULL
, NULL
, NULL
);
482 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
483 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
484 ok(0 == len
, "text should have been truncated, expected 0, got %d\n", len
);
485 test_notify(1, 1, 1);
487 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
489 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)"a");
490 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
491 ok(1 == SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0), "wrong text length, expected 1, got %d\n", len
);
492 test_notify(1, 0, 1);
495 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
496 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
497 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
498 test_notify(0, 0, 0);
500 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
502 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
504 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
505 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
506 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
507 test_notify(1, 1, 1);
510 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
511 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
512 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
513 test_notify(0, 0, 0);
517 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
518 hWnd
= CreateWindowExA(0,
521 ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
,
523 hParent
, NULL
, NULL
, NULL
);
527 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
528 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
529 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
530 test_notify(1, 0, 1);
533 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
534 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
535 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
536 test_notify(0, 0, 0);
538 SendMessageA(hWnd
, EM_SETLIMITTEXT
, 5, 0);
540 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)"");
542 SendMessageA(hWnd
, EM_REPLACESEL
, 0, (LPARAM
)str2
);
543 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
544 ok(5 == len
, "text should have been truncated to limit, expected 5, got %d\n", len
);
545 test_notify(1, 1, 1);
548 SendMessageA(hWnd
, WM_SETTEXT
, 0, (LPARAM
)str2
);
549 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
550 ok(lstrlenA(str2
) == len
, "text shouldn't have been truncated\n");
551 test_notify(0, 0, 0);
556 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
558 static void test_edit_control_4(void)
565 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
566 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
567 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
568 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
569 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
570 mid
= lo
+ (hi
- lo
) / 2;
572 for (i
= lo
; i
< mid
; i
++) {
573 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
574 ok(0 == ret
, "expected 0 got %d\n", ret
);
576 for (i
= mid
; i
<= hi
; i
++) {
577 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
578 ok(1 == ret
, "expected 1 got %d\n", ret
);
580 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
581 ok(-1 == ret
, "expected -1 got %d\n", ret
);
582 DestroyWindow(hwEdit
);
584 hwEdit
= create_editcontrol(ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
585 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
586 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
587 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
588 mid
= lo
+ (hi
- lo
) / 2;
590 for (i
= lo
; i
< mid
; i
++) {
591 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
592 ok(0 == ret
, "expected 0 got %d\n", ret
);
594 for (i
= mid
; i
<= hi
; i
++) {
595 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
596 ok(1 == ret
, "expected 1 got %d\n", ret
);
598 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
599 ok(-1 == ret
, "expected -1 got %d\n", ret
);
600 DestroyWindow(hwEdit
);
602 hwEdit
= create_editcontrol(ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
603 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
604 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
605 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
606 mid
= lo
+ (hi
- lo
) / 2;
608 for (i
= lo
; i
< mid
; i
++) {
609 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
610 ok(0 == ret
, "expected 0 got %d\n", ret
);
612 for (i
= mid
; i
<= hi
; i
++) {
613 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
614 ok(1 == ret
, "expected 1 got %d\n", ret
);
616 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
617 ok(-1 == ret
, "expected -1 got %d\n", ret
);
618 DestroyWindow(hwEdit
);
620 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
621 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
622 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
623 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
624 mid
= lo
+ (hi
- lo
) / 2 +1;
626 for (i
= lo
; i
< mid
; i
++) {
627 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
628 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
630 for (i
= mid
; i
<= hi
; i
++) {
631 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
632 ok(1 == ret
, "expected 1 got %d\n", ret
);
634 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
635 ok(-1 == ret
, "expected -1 got %d\n", ret
);
636 DestroyWindow(hwEdit
);
638 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_RIGHT
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
639 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
640 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
641 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
642 mid
= lo
+ (hi
- lo
) / 2 +1;
644 for (i
= lo
; i
< mid
; i
++) {
645 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
646 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
648 for (i
= mid
; i
<= hi
; i
++) {
649 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
650 ok(1 == ret
, "expected 1 got %d\n", ret
);
652 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
653 ok(-1 == ret
, "expected -1 got %d\n", ret
);
654 DestroyWindow(hwEdit
);
656 hwEdit
= create_editcontrol(ES_MULTILINE
| ES_CENTER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
657 SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) "aa");
658 lo
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 0, 0));
659 hi
= LOWORD(SendMessage(hwEdit
, EM_POSFROMCHAR
, 1, 0));
660 mid
= lo
+ (hi
- lo
) / 2 +1;
662 for (i
= lo
; i
< mid
; i
++) {
663 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
664 ok((0 == ret
|| 1 == ret
/* Vista */), "expected 0 or 1 got %d\n", ret
);
666 for (i
= mid
; i
<= hi
; i
++) {
667 ret
= LOWORD(SendMessage(hwEdit
, EM_CHARFROMPOS
, 0, (LPARAM
) i
));
668 ok(1 == ret
, "expected 1 got %d\n", ret
);
670 ret
= SendMessage(hwEdit
, EM_POSFROMCHAR
, 2, 0);
671 ok(-1 == ret
, "expected -1 got %d\n", ret
);
672 DestroyWindow(hwEdit
);
675 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
676 * truncates text that doesn't fit.
678 static void test_edit_control_5(void)
680 static const char *str
= "test\r\ntest";
684 hWnd
= CreateWindowEx(0,
689 NULL
, NULL
, NULL
, NULL
);
692 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
693 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
696 hWnd
= CreateWindowEx(0,
701 NULL
, NULL
, NULL
, NULL
);
704 len
= SendMessageA(hWnd
, WM_GETTEXTLENGTH
, 0, 0);
705 ok(lstrlenA(str
) == len
, "text shouldn't have been truncated\n");
709 static void test_edit_control_limittext(void)
714 /* Test default limit for single-line control */
715 trace("EDIT: buffer limit for single-line\n");
716 hwEdit
= create_editcontrol(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
717 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
718 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
719 SendMessage(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
720 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
721 /* Win9x+ME: 32766; WinNT: 2147483646UL */
722 ok( (r
== 32766) || (r
== 2147483646UL),
723 "got limit %u (expected 32766 or 2147483646)\n", r
);
724 DestroyWindow(hwEdit
);
726 /* Test default limit for multi-line control */
727 trace("EDIT: buffer limit for multi-line\n");
728 hwEdit
= create_editcontrol(ES_MULTILINE
| WS_VSCROLL
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
729 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
730 ok(r
== 30000, "Incorrect default text limit, expected 30000 got %u\n", r
);
731 SendMessage(hwEdit
, EM_SETLIMITTEXT
, 0, 0);
732 r
= SendMessage(hwEdit
, EM_GETLIMITTEXT
, 0, 0);
733 /* Win9x+ME: 65535; WinNT: 4294967295UL */
734 ok( (r
== 65535) || (r
== 4294967295UL),
735 "got limit %u (expected 65535 or 4294967295)\n", r
);
736 DestroyWindow(hwEdit
);
739 static void test_margins(void)
742 RECT old_rect
, new_rect
;
743 INT old_left_margin
, old_right_margin
;
744 DWORD old_margins
, new_margins
;
746 hwEdit
= create_editcontrol(WS_BORDER
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
, 0);
748 old_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
749 old_left_margin
= LOWORD(old_margins
);
750 old_right_margin
= HIWORD(old_margins
);
752 /* Check if setting the margins works */
754 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
, MAKELONG(10, 0));
755 new_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
756 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
757 ok(HIWORD(new_margins
) == old_right_margin
, "Wrong right margin: %d\n", HIWORD(new_margins
));
759 SendMessage(hwEdit
, EM_SETMARGINS
, EC_RIGHTMARGIN
, MAKELONG(0, 10));
760 new_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
761 ok(LOWORD(new_margins
) == 10, "Wrong left margin: %d\n", LOWORD(new_margins
));
762 ok(HIWORD(new_margins
) == 10, "Wrong right margin: %d\n", HIWORD(new_margins
));
765 /* The size of the rectangle must decrease if we increase the margin */
767 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(5, 5));
768 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
769 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(15, 20));
770 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
771 ok(new_rect
.left
== old_rect
.left
+ 10, "The left border of the rectangle is wrong\n");
772 ok(new_rect
.right
== old_rect
.right
- 15, "The right border of the rectangle is wrong\n");
773 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle must not change\n");
774 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle must not change\n");
777 /* If we set the margin to same value as the current margin,
778 the rectangle must not change */
780 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
784 old_rect
.bottom
= 99;
785 SendMessage(hwEdit
, EM_SETRECT
, 0, (LPARAM
)&old_rect
);
786 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&old_rect
);
787 SendMessage(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(10, 10));
788 SendMessage(hwEdit
, EM_GETRECT
, 0, (LPARAM
)&new_rect
);
789 ok(new_rect
.left
== old_rect
.left
, "The left border of the rectangle has changed\n");
790 ok(new_rect
.right
== old_rect
.right
, "The right border of the rectangle has changed\n");
791 ok(new_rect
.top
== old_rect
.top
, "The top border of the rectangle has changed\n");
792 ok(new_rect
.bottom
== old_rect
.bottom
, "The bottom border of the rectangle has changed\n");
794 DestroyWindow (hwEdit
);
797 static INT CALLBACK
find_font_proc(const LOGFONT
*elf
, const TEXTMETRIC
*ntm
, DWORD type
, LPARAM lParam
)
802 static void test_margins_font_change(void)
805 DWORD margins
, font_margins
;
810 if(EnumFontFamiliesA(hdc
, "Arial", find_font_proc
, 0))
812 trace("Arial not found - skipping font change margin tests\n");
818 hwEdit
= create_child_editcontrol(0, 0);
820 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
822 memset(&lf
, 0, sizeof(lf
));
823 strcpy(lf
.lfFaceName
, "Arial");
825 lf
.lfCharSet
= DEFAULT_CHARSET
;
826 hfont
= CreateFontIndirectA(&lf
);
828 hfont2
= CreateFontIndirectA(&lf
);
830 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
831 font_margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
832 ok(LOWORD(font_margins
) != 0, "got %d\n", LOWORD(font_margins
));
833 ok(HIWORD(font_margins
) != 0, "got %d\n", HIWORD(font_margins
));
835 /* With 'small' edit controls, test that the margin doesn't get set */
836 SetWindowPos(hwEdit
, NULL
, 10, 10, 16, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
837 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(0,0));
838 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
839 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
840 ok(LOWORD(margins
) == 0, "got %d\n", LOWORD(margins
));
841 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
843 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
844 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
845 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
846 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
847 ok(HIWORD(margins
) == 0, "got %d\n", HIWORD(margins
));
849 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
850 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
851 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
852 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
853 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
855 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
856 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
857 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
858 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
859 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
860 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
861 ok(LOWORD(margins
) == 1, "got %d\n", LOWORD(margins
));
862 ok(HIWORD(margins
) == 1, "got %d\n", HIWORD(margins
));
864 /* Above a certain size threshold then the margin is updated */
865 SetWindowPos(hwEdit
, NULL
, 10, 10, 1000, 100, SWP_NOZORDER
| SWP_NOACTIVATE
);
866 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,0));
867 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
868 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
869 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
870 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
872 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(1,1));
873 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont
, 0);
874 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
875 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
876 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
878 SendMessageA(hwEdit
, EM_SETMARGINS
, EC_LEFTMARGIN
| EC_RIGHTMARGIN
, MAKELONG(EC_USEFONTINFO
,EC_USEFONTINFO
));
879 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
880 ok(LOWORD(margins
) == LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
881 ok(HIWORD(margins
) == HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
882 SendMessageA(hwEdit
, WM_SETFONT
, (WPARAM
)hfont2
, 0);
883 margins
= SendMessage(hwEdit
, EM_GETMARGINS
, 0, 0);
884 ok(LOWORD(margins
) != LOWORD(font_margins
), "got %d\n", LOWORD(margins
));
885 ok(HIWORD(margins
) != HIWORD(font_margins
), "got %d\n", HIWORD(margins
));
887 SendMessageA(hwEdit
, WM_SETFONT
, 0, 0);
889 DeleteObject(hfont2
);
891 destroy_child_editcontrol(hwEdit
);
895 #define edit_pos_ok(exp, got, txt) \
896 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
898 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
902 set_client_height(hwEdit, set_height); \
903 SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
904 left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
905 edit_pos_ok(test_top, format_rect.top, vertical position); \
906 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
907 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
910 static void test_text_position_style(DWORD style
)
917 BOOL single_line
= !(style
& ES_MULTILINE
);
919 b
= GetSystemMetrics(SM_CYBORDER
) + 1;
924 /* Get a stock font for which we can determine the metrics */
925 assert(font
= GetStockObject(SYSTEM_FONT
));
926 assert(dc
= GetDC(NULL
));
927 oldFont
= SelectObject(dc
, font
);
928 assert(GetTextMetrics(dc
, &metrics
));
929 SelectObject(dc
, oldFont
);
932 /* Windows' edit control has some bugs in multi-line mode:
933 * - Sometimes the format rectangle doesn't get updated
934 * (see workaround in set_client_height())
935 * - If the height of the control is smaller than the height of a text
936 * line, the format rectangle is still as high as a text line
937 * (higher than the client rectangle) and the caret is not shown
940 /* Edit controls that are in a parent window */
942 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, 0);
943 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
945 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
946 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
947 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
948 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
949 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
950 destroy_child_editcontrol(hwEdit
);
952 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, 0);
953 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
955 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
956 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
957 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
958 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
959 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
960 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
961 destroy_child_editcontrol(hwEdit
);
963 hwEdit
= create_child_editcontrol(style
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
964 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
966 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
967 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
968 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
969 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
970 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
971 destroy_child_editcontrol(hwEdit
);
973 hwEdit
= create_child_editcontrol(style
| WS_BORDER
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
974 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
976 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
977 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
978 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
979 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
980 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
981 destroy_child_editcontrol(hwEdit
);
984 /* Edit controls that are popup windows */
986 hwEdit
= create_editcontrol(style
| WS_POPUP
, 0);
987 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
989 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 0);
990 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 0);
991 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 0);
992 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 0, metrics
.tmHeight
, 0);
993 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 0, metrics
.tmHeight
, 0);
994 DestroyWindow(hwEdit
);
996 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, 0);
997 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
999 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, b
);
1000 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, b
);
1001 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, b
);
1002 check_pos(hwEdit
, metrics
.tmHeight
+ bm
, 0, metrics
.tmHeight
, b
);
1003 check_pos(hwEdit
, metrics
.tmHeight
+ b2
, b
, metrics
.tmHeight
, b
);
1004 check_pos(hwEdit
, metrics
.tmHeight
+ b3
, b
, metrics
.tmHeight
, b
);
1005 DestroyWindow(hwEdit
);
1007 hwEdit
= create_editcontrol(style
| WS_POPUP
, WS_EX_CLIENTEDGE
);
1008 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1010 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1011 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1012 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1013 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1014 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1015 DestroyWindow(hwEdit
);
1017 hwEdit
= create_editcontrol(style
| WS_POPUP
| WS_BORDER
, WS_EX_CLIENTEDGE
);
1018 SendMessage(hwEdit
, WM_SETFONT
, (WPARAM
) font
, (LPARAM
) FALSE
);
1020 check_pos(hwEdit
, metrics
.tmHeight
- 1, 0, metrics
.tmHeight
- 1, 1);
1021 check_pos(hwEdit
, metrics
.tmHeight
, 0, metrics
.tmHeight
, 1);
1022 check_pos(hwEdit
, metrics
.tmHeight
+ 1, 0, metrics
.tmHeight
, 1);
1023 check_pos(hwEdit
, metrics
.tmHeight
+ 2, 1, metrics
.tmHeight
, 1);
1024 check_pos(hwEdit
, metrics
.tmHeight
+ 10, 1, metrics
.tmHeight
, 1);
1025 DestroyWindow(hwEdit
);
1028 static void test_text_position(void)
1030 trace("EDIT: Text position (Single line)\n");
1031 test_text_position_style(ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1032 trace("EDIT: Text position (Multi line)\n");
1033 test_text_position_style(ES_MULTILINE
| ES_AUTOHSCROLL
| ES_AUTOVSCROLL
);
1036 static void test_espassword(void)
1041 const char* password
= "secret";
1043 hwEdit
= create_editcontrol(ES_PASSWORD
, 0);
1044 r
= get_edit_style(hwEdit
);
1045 ok(r
== ES_PASSWORD
, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD
, r
);
1047 r
= SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) password
);
1048 ok(r
== TRUE
, "Expected: %d, got: %d\n", TRUE
, r
);
1050 /* select all, cut (ctrl-x) */
1051 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1052 SendMessage(hwEdit
, WM_CHAR
, 24, 0);
1055 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1056 ok(r
== strlen(password
), "Expected: %s, got len %d\n", password
, r
);
1057 ok(strcmp(buffer
, password
) == 0, "expected %s, got %s\n", password
, buffer
);
1059 r
= OpenClipboard(hwEdit
);
1060 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1061 r
= EmptyClipboard();
1062 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1063 r
= CloseClipboard();
1064 ok(r
== TRUE
, "expected %d, got %d\n", TRUE
, r
);
1066 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1067 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1068 SendMessage(hwEdit
, WM_CHAR
, 3, 0);
1069 SendMessage(hwEdit
, WM_CHAR
, 22, 0);
1073 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1074 ok(r
== 0, "Expected: 0, got: %d\n", r
);
1075 ok(strcmp(buffer
, "") == 0, "expected empty string, got %s\n", buffer
);
1077 DestroyWindow (hwEdit
);
1080 static void test_undo(void)
1086 const char* text
= "undo this";
1088 hwEdit
= create_editcontrol(0, 0);
1089 r
= get_edit_style(hwEdit
);
1090 ok(0 == r
, "Wrong style expected 0x%x got: 0x%x\n", 0, r
);
1093 r
= SendMessage(hwEdit
, WM_SETTEXT
, 0, (LPARAM
) text
);
1094 ok(TRUE
== r
, "Expected: %d, got: %d\n", TRUE
, r
);
1097 cpMin
= cpMax
= 0xdeadbeef;
1098 SendMessage(hwEdit
, EM_SETSEL
, 0, -1);
1099 r
= SendMessage(hwEdit
, EM_GETSEL
, (WPARAM
) &cpMin
, (LPARAM
) &cpMax
);
1100 ok((strlen(text
) << 16) == r
, "Unexpected length %d\n", r
);
1101 ok(0 == cpMin
, "Expected: %d, got %d\n", 0, cpMin
);
1102 ok(9 == cpMax
, "Expected: %d, got %d\n", 9, cpMax
);
1105 r
= SendMessage(hwEdit
, WM_CHAR
, 24, 0);
1106 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1110 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1111 ok(0 == r
, "Expected: %d, got len %d\n", 0, r
);
1112 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1115 r
= SendMessage(hwEdit
, WM_CHAR
, 26, 0);
1116 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1120 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1121 ok(strlen(text
) == r
, "Unexpected length %d\n", r
);
1122 ok(0 == strcmp(buffer
, text
), "expected %s, got %s\n", text
, buffer
);
1124 /* undo again (ctrl-z) */
1125 r
= SendMessage(hwEdit
, WM_CHAR
, 26, 0);
1126 todo_wine
{ ok(1 == r
, "Expected: %d, got: %d\n", 1, r
); }
1130 r
= SendMessage(hwEdit
, WM_GETTEXT
, 1024, (LPARAM
) buffer
);
1131 ok(r
== 0, "Expected: %d, got len %d\n", 0, r
);
1132 ok(0 == strcmp(buffer
, ""), "expected %s, got %s\n", "", buffer
);
1134 DestroyWindow (hwEdit
);
1137 static BOOL
RegisterWindowClasses (void)
1141 WNDCLASSA text_position
;
1144 test2
.lpfnWndProc
= ET2_WndProc
;
1145 test2
.cbClsExtra
= 0;
1146 test2
.cbWndExtra
= 0;
1147 test2
.hInstance
= hinst
;
1149 test2
.hCursor
= LoadCursorA (NULL
, IDC_ARROW
);
1150 test2
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1151 test2
.lpszMenuName
= NULL
;
1152 test2
.lpszClassName
= szEditTest2Class
;
1153 if (!RegisterClassA(&test2
)) return FALSE
;
1156 test3
.lpfnWndProc
= edit3_wnd_procA
;
1157 test3
.cbClsExtra
= 0;
1158 test3
.cbWndExtra
= 0;
1159 test3
.hInstance
= hinst
;
1161 test3
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
1162 test3
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
1163 test3
.lpszMenuName
= NULL
;
1164 test3
.lpszClassName
= szEditTest3Class
;
1165 if (!RegisterClassA(&test3
)) return FALSE
;
1167 text_position
.style
= CS_HREDRAW
| CS_VREDRAW
;
1168 text_position
.cbClsExtra
= 0;
1169 text_position
.cbWndExtra
= 0;
1170 text_position
.hInstance
= hinst
;
1171 text_position
.hIcon
= NULL
;
1172 text_position
.hCursor
= LoadCursorA(NULL
, IDC_ARROW
);
1173 text_position
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
1174 text_position
.lpszMenuName
= NULL
;
1175 text_position
.lpszClassName
= szEditTextPositionClass
;
1176 text_position
.lpfnWndProc
= DefWindowProc
;
1177 if (!RegisterClassA(&text_position
)) return FALSE
;
1182 static void UnregisterWindowClasses (void)
1184 UnregisterClassA(szEditTest2Class
, hinst
);
1185 UnregisterClassA(szEditTest3Class
, hinst
);
1186 UnregisterClassA(szEditTextPositionClass
, hinst
);
1191 hinst
= GetModuleHandleA(NULL
);
1192 assert(RegisterWindowClasses());
1194 test_edit_control_1();
1195 test_edit_control_2();
1196 test_edit_control_3();
1197 test_edit_control_4();
1198 test_edit_control_5();
1199 test_edit_control_limittext();
1201 test_margins_font_change();
1202 test_text_position();
1206 UnregisterWindowClasses();