Remove unnecessary executable bits
[reactos.git] / modules / rostests / winetests / user32 / edit.c
1 /* Unit test suite for edit control.
2 *
3 * Copyright 2004 Vitaliy Margolen
4 * Copyright 2005 C. Scott Ananian
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <assert.h>
22 #include <windows.h>
23 #include <commctrl.h>
24
25 #include "wine/test.h"
26
27 #ifndef ES_COMBO
28 #define ES_COMBO 0x200
29 #endif
30
31 #define ID_EDITTESTDBUTTON 0x123
32 #define ID_EDITTEST2 99
33 #define MAXLEN 200
34
35 struct edit_notify {
36 int en_change, en_maxtext, en_update;
37 };
38
39 static struct edit_notify notifications;
40
41 static INT_PTR CALLBACK multi_edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
42 {
43 static int num_ok_commands = 0;
44 switch (msg)
45 {
46 case WM_INITDIALOG:
47 {
48 HWND hedit = GetDlgItem(hdlg, 1000);
49 SetFocus(hedit);
50 switch (lparam)
51 {
52 /* test cases related to bug 12319 */
53 case 0:
54 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
55 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
56 break;
57 case 1:
58 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
59 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
60 break;
61 case 2:
62 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
63 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
64 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
65 break;
66
67 /* test cases for pressing enter */
68 case 3:
69 num_ok_commands = 0;
70 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
71 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
72 break;
73
74 default:
75 break;
76 }
77 break;
78 }
79
80 case WM_COMMAND:
81 if (HIWORD(wparam) != BN_CLICKED)
82 break;
83
84 switch (LOWORD(wparam))
85 {
86 case IDOK:
87 num_ok_commands++;
88 break;
89
90 default:
91 break;
92 }
93 break;
94
95 case WM_USER:
96 {
97 HWND hfocus = GetFocus();
98 HWND hedit = GetDlgItem(hdlg, 1000);
99 HWND hedit2 = GetDlgItem(hdlg, 1001);
100 HWND hedit3 = GetDlgItem(hdlg, 1002);
101
102 if (wparam != 0xdeadbeef)
103 break;
104
105 switch (lparam)
106 {
107 case 0:
108 if (hfocus == hedit)
109 EndDialog(hdlg, 1111);
110 else if (hfocus == hedit2)
111 EndDialog(hdlg, 2222);
112 else if (hfocus == hedit3)
113 EndDialog(hdlg, 3333);
114 else
115 EndDialog(hdlg, 4444);
116 break;
117 case 1:
118 if ((hfocus == hedit) && (num_ok_commands == 0))
119 EndDialog(hdlg, 11);
120 else
121 EndDialog(hdlg, 22);
122 break;
123 default:
124 EndDialog(hdlg, 5555);
125 }
126 break;
127 }
128
129 case WM_CLOSE:
130 EndDialog(hdlg, 333);
131 break;
132
133 default:
134 break;
135 }
136
137 return FALSE;
138 }
139
140 static INT_PTR CALLBACK edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
141 {
142 switch (msg)
143 {
144 case WM_INITDIALOG:
145 {
146 HWND hedit = GetDlgItem(hdlg, 1000);
147 SetFocus(hedit);
148 switch (lparam)
149 {
150 /* from bug 11841 */
151 case 0:
152 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
153 break;
154 case 1:
155 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
156 break;
157 case 2:
158 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
159 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
160 break;
161
162 /* more test cases for WM_CHAR */
163 case 3:
164 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
165 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
166 break;
167 case 4:
168 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
169 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
170 break;
171 case 5:
172 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
173 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
174 break;
175
176 /* more test cases for WM_KEYDOWN + WM_CHAR */
177 case 6:
178 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
179 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
180 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
181 break;
182 case 7:
183 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
184 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
185 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
186 break;
187 case 8:
188 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
189 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
190 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
191 break;
192
193 /* multiple tab tests */
194 case 9:
195 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
196 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
197 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
198 break;
199 case 10:
200 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
201 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
202 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
203 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
204 break;
205
206 default:
207 break;
208 }
209 break;
210 }
211
212 case WM_COMMAND:
213 if (HIWORD(wparam) != BN_CLICKED)
214 break;
215
216 switch (LOWORD(wparam))
217 {
218 case IDOK:
219 EndDialog(hdlg, 111);
220 break;
221
222 case IDCANCEL:
223 EndDialog(hdlg, 222);
224 break;
225
226 default:
227 break;
228 }
229 break;
230
231 case WM_USER:
232 {
233 int len;
234 HWND hok = GetDlgItem(hdlg, IDOK);
235 HWND hcancel = GetDlgItem(hdlg, IDCANCEL);
236 HWND hedit = GetDlgItem(hdlg, 1000);
237 HWND hfocus = GetFocus();
238
239 if (wparam != 0xdeadbeef)
240 break;
241
242 switch (lparam)
243 {
244 case 0:
245 len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
246 if (len == 0)
247 EndDialog(hdlg, 444);
248 else
249 EndDialog(hdlg, 555);
250 break;
251
252 case 1:
253 len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
254 if ((hfocus == hok) && len == 0)
255 EndDialog(hdlg, 444);
256 else
257 EndDialog(hdlg, 555);
258 break;
259
260 case 2:
261 if (hfocus == hok)
262 EndDialog(hdlg, 11);
263 else if (hfocus == hcancel)
264 EndDialog(hdlg, 22);
265 else if (hfocus == hedit)
266 EndDialog(hdlg, 33);
267 else
268 EndDialog(hdlg, 44);
269 break;
270
271 default:
272 EndDialog(hdlg, 555);
273 }
274 break;
275 }
276
277 case WM_CLOSE:
278 EndDialog(hdlg, 333);
279 break;
280
281 default:
282 break;
283 }
284
285 return FALSE;
286 }
287
288 static INT_PTR CALLBACK edit_singleline_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
289 {
290 switch (msg)
291 {
292 case WM_INITDIALOG:
293 {
294 HWND hedit = GetDlgItem(hdlg, 1000);
295 SetFocus(hedit);
296 switch (lparam)
297 {
298 /* test cases for WM_KEYDOWN */
299 case 0:
300 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
301 break;
302 case 1:
303 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
304 break;
305 case 2:
306 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
307 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
308 break;
309
310 /* test cases for WM_CHAR */
311 case 3:
312 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
313 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
314 break;
315 case 4:
316 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
317 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
318 break;
319 case 5:
320 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
321 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
322 break;
323
324 /* test cases for WM_KEYDOWN + WM_CHAR */
325 case 6:
326 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
327 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
328 break;
329 case 7:
330 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
331 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
332 break;
333 case 8:
334 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
335 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
336 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
337 break;
338
339 default:
340 break;
341 }
342 break;
343 }
344
345 case WM_COMMAND:
346 if (HIWORD(wparam) != BN_CLICKED)
347 break;
348
349 switch (LOWORD(wparam))
350 {
351 case IDOK:
352 EndDialog(hdlg, 111);
353 break;
354
355 case IDCANCEL:
356 EndDialog(hdlg, 222);
357 break;
358
359 default:
360 break;
361 }
362 break;
363
364 case WM_USER:
365 {
366 HWND hok = GetDlgItem(hdlg, IDOK);
367 HWND hedit = GetDlgItem(hdlg, 1000);
368 HWND hfocus = GetFocus();
369 int len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
370
371 if (wparam != 0xdeadbeef)
372 break;
373
374 switch (lparam)
375 {
376 case 0:
377 if ((hfocus == hedit) && len == 0)
378 EndDialog(hdlg, 444);
379 else
380 EndDialog(hdlg, 555);
381 break;
382
383 case 1:
384 if ((hfocus == hok) && len == 0)
385 EndDialog(hdlg, 444);
386 else
387 EndDialog(hdlg, 555);
388 break;
389
390 default:
391 EndDialog(hdlg, 55);
392 }
393 break;
394 }
395
396 case WM_CLOSE:
397 EndDialog(hdlg, 333);
398 break;
399
400 default:
401 break;
402 }
403
404 return FALSE;
405 }
406
407 static INT_PTR CALLBACK edit_wantreturn_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
408 {
409 switch (msg)
410 {
411 case WM_INITDIALOG:
412 {
413 HWND hedit = GetDlgItem(hdlg, 1000);
414 SetFocus(hedit);
415 switch (lparam)
416 {
417 /* test cases for WM_KEYDOWN */
418 case 0:
419 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
420 break;
421 case 1:
422 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
423 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
424 break;
425 case 2:
426 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
427 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
428 break;
429
430 /* test cases for WM_CHAR */
431 case 3:
432 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
433 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
434 break;
435 case 4:
436 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
437 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
438 break;
439 case 5:
440 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
441 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
442 break;
443
444 /* test cases for WM_KEYDOWN + WM_CHAR */
445 case 6:
446 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
447 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
448 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
449 break;
450 case 7:
451 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
452 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
453 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
454 break;
455 case 8:
456 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
457 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
458 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
459 break;
460
461 default:
462 break;
463 }
464 break;
465 }
466
467 case WM_COMMAND:
468 if (HIWORD(wparam) != BN_CLICKED)
469 break;
470
471 switch (LOWORD(wparam))
472 {
473 case IDOK:
474 EndDialog(hdlg, 111);
475 break;
476
477 case IDCANCEL:
478 EndDialog(hdlg, 222);
479 break;
480
481 default:
482 break;
483 }
484 break;
485
486 case WM_USER:
487 {
488 HWND hok = GetDlgItem(hdlg, IDOK);
489 HWND hedit = GetDlgItem(hdlg, 1000);
490 HWND hfocus = GetFocus();
491 int len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
492
493 if (wparam != 0xdeadbeef)
494 break;
495
496 switch (lparam)
497 {
498 case 0:
499 if ((hfocus == hedit) && len == 0)
500 EndDialog(hdlg, 444);
501 else
502 EndDialog(hdlg, 555);
503 break;
504
505 case 1:
506 if ((hfocus == hok) && len == 0)
507 EndDialog(hdlg, 444);
508 else
509 EndDialog(hdlg, 555);
510 break;
511
512 case 2:
513 if ((hfocus == hedit) && len == 2)
514 EndDialog(hdlg, 444);
515 else
516 EndDialog(hdlg, 555);
517 break;
518
519 default:
520 EndDialog(hdlg, 55);
521 }
522 break;
523 }
524
525 case WM_CLOSE:
526 EndDialog(hdlg, 333);
527 break;
528
529 default:
530 break;
531 }
532
533 return FALSE;
534 }
535
536 static HINSTANCE hinst;
537 static HWND hwndET2;
538 static const char szEditTest2Class[] = "EditTest2Class";
539 static const char szEditTest3Class[] = "EditTest3Class";
540 static const char szEditTest4Class[] = "EditTest4Class";
541 static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
542
543 static HWND create_editcontrol (DWORD style, DWORD exstyle)
544 {
545 HWND handle;
546
547 handle = CreateWindowExA(exstyle,
548 "EDIT",
549 "Test Text",
550 style,
551 10, 10, 300, 300,
552 NULL, NULL, hinst, NULL);
553 ok (handle != NULL, "CreateWindow EDIT Control failed\n");
554 assert (handle);
555 if (winetest_interactive)
556 ShowWindow (handle, SW_SHOW);
557 return handle;
558 }
559
560 static HWND create_editcontrolW(DWORD style, DWORD exstyle)
561 {
562 static const WCHAR testtextW[] = {'T','e','s','t',' ','t','e','x','t',0};
563 static const WCHAR editW[] = {'E','d','i','t',0};
564 HWND handle;
565
566 handle = CreateWindowExW(exstyle, editW, testtextW, style, 10, 10, 300, 300,
567 NULL, NULL, hinst, NULL);
568 ok(handle != NULL, "Failed to create Edit control.\n");
569 return handle;
570 }
571
572 static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
573 {
574 HWND parentWnd;
575 HWND editWnd;
576 RECT rect;
577 BOOL b;
578 SetRect(&rect, 0, 0, 300, 300);
579 b = AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
580 ok(b, "AdjustWindowRect failed\n");
581
582 parentWnd = CreateWindowExA(0,
583 szEditTextPositionClass,
584 "Edit Test",
585 WS_OVERLAPPEDWINDOW,
586 CW_USEDEFAULT, CW_USEDEFAULT,
587 rect.right - rect.left, rect.bottom - rect.top,
588 NULL, NULL, hinst, NULL);
589 ok (parentWnd != NULL, "CreateWindow EDIT Test failed\n");
590 assert(parentWnd);
591
592 editWnd = CreateWindowExA(exstyle,
593 "EDIT",
594 "Test Text",
595 WS_CHILD | style,
596 0, 0, 300, 300,
597 parentWnd, NULL, hinst, NULL);
598 ok (editWnd != NULL, "CreateWindow EDIT Test Text failed\n");
599 assert(editWnd);
600 if (winetest_interactive)
601 ShowWindow (parentWnd, SW_SHOW);
602 return editWnd;
603 }
604
605 static void destroy_child_editcontrol (HWND hwndEdit)
606 {
607 if (GetParent(hwndEdit))
608 DestroyWindow(GetParent(hwndEdit));
609 else {
610 trace("Edit control has no parent!\n");
611 DestroyWindow(hwndEdit);
612 }
613 }
614
615 static LONG get_edit_style (HWND hwnd)
616 {
617 return GetWindowLongA( hwnd, GWL_STYLE ) & (
618 ES_LEFT |
619 /* FIXME: not implemented
620 ES_CENTER |
621 ES_RIGHT |
622 ES_OEMCONVERT |
623 */
624 ES_MULTILINE |
625 ES_UPPERCASE |
626 ES_LOWERCASE |
627 ES_PASSWORD |
628 ES_AUTOVSCROLL |
629 ES_AUTOHSCROLL |
630 ES_NOHIDESEL |
631 ES_COMBO |
632 ES_READONLY |
633 ES_WANTRETURN |
634 ES_NUMBER
635 );
636 }
637
638 static void set_client_height(HWND Wnd, unsigned Height)
639 {
640 RECT ClientRect, WindowRect;
641
642 GetWindowRect(Wnd, &WindowRect);
643 GetClientRect(Wnd, &ClientRect);
644 SetWindowPos(Wnd, NULL, 0, 0,
645 WindowRect.right - WindowRect.left,
646 Height + (WindowRect.bottom - WindowRect.top) -
647 (ClientRect.bottom - ClientRect.top),
648 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
649
650 /* Workaround for a bug in Windows' edit control
651 (multi-line mode) */
652 GetWindowRect(Wnd, &WindowRect);
653 SetWindowPos(Wnd, NULL, 0, 0,
654 WindowRect.right - WindowRect.left + 1,
655 WindowRect.bottom - WindowRect.top + 1,
656 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
657 SetWindowPos(Wnd, NULL, 0, 0,
658 WindowRect.right - WindowRect.left,
659 WindowRect.bottom - WindowRect.top,
660 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
661
662 GetClientRect(Wnd, &ClientRect);
663 ok(ClientRect.bottom - ClientRect.top == Height,
664 "The client height should be %d, but is %d\n",
665 Height, ClientRect.bottom - ClientRect.top);
666 }
667
668 static void test_edit_control_1(void)
669 {
670 HWND hwEdit;
671 MSG msMessage;
672 int i;
673 LONG r;
674
675 msMessage.message = WM_KEYDOWN;
676
677 trace("EDIT: Single line\n");
678 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
679 r = get_edit_style(hwEdit);
680 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%x\n", r);
681 for (i=0;i<65535;i++)
682 {
683 msMessage.wParam = i;
684 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
685 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
686 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
687 }
688 DestroyWindow (hwEdit);
689
690 trace("EDIT: Single line want returns\n");
691 hwEdit = create_editcontrol(ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
692 r = get_edit_style(hwEdit);
693 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%x\n", r);
694 for (i=0;i<65535;i++)
695 {
696 msMessage.wParam = i;
697 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
698 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
699 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
700 }
701 DestroyWindow (hwEdit);
702
703 trace("EDIT: Multiline line\n");
704 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
705 r = get_edit_style(hwEdit);
706 ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%x\n", r);
707 for (i=0;i<65535;i++)
708 {
709 msMessage.wParam = i;
710 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
711 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
712 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
713 }
714 DestroyWindow (hwEdit);
715
716 trace("EDIT: Multi line want returns\n");
717 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
718 r = get_edit_style(hwEdit);
719 ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%x\n", r);
720 for (i=0;i<65535;i++)
721 {
722 msMessage.wParam = i;
723 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
724 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
725 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
726 }
727 DestroyWindow (hwEdit);
728 }
729
730 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
731 * selection. This test checks that the first 'select all' doesn't generate
732 * an UPDATE message which can escape and (via a handler) change the
733 * selection, which would cause WM_SETTEXT to break. This old bug
734 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
735 */
736 static void test_edit_control_2(void)
737 {
738 HWND hwndMain, phwnd;
739 char szLocalString[MAXLEN];
740 LONG r, w = 150, h = 50;
741 POINT cpos;
742
743 /* Create main and edit windows. */
744 hwndMain = CreateWindowA(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW,
745 0, 0, 200, 200, NULL, NULL, hinst, NULL);
746 assert(hwndMain);
747 if (winetest_interactive)
748 ShowWindow (hwndMain, SW_SHOW);
749
750 hwndET2 = CreateWindowA("EDIT", NULL,
751 WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
752 0, 0, w, h, /* important this not be 0 size. */
753 hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
754 assert(hwndET2);
755 if (winetest_interactive)
756 ShowWindow (hwndET2, SW_SHOW);
757
758 trace("EDIT: SETTEXT atomicity\n");
759 /* Send messages to "type" in the word 'foo'. */
760 r = SendMessageA(hwndET2, WM_CHAR, 'f', 1);
761 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
762 r = SendMessageA(hwndET2, WM_CHAR, 'o', 1);
763 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
764 r = SendMessageA(hwndET2, WM_CHAR, 'o', 1);
765 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
766 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
767 GetWindowTextA(hwndET2, szLocalString, MAXLEN);
768 ok(strcmp(szLocalString, "bar")==0,
769 "Wrong contents of edit: %s\n", szLocalString);
770
771 /* try setting the caret before it's visible */
772 r = SetCaretPos(0, 0);
773 todo_wine ok(0 == r, "SetCaretPos succeeded unexpectedly, expected: 0, got: %d\n", r);
774 phwnd = SetFocus(hwndET2);
775 ok(phwnd != NULL, "SetFocus failed unexpectedly, expected non-zero, got NULL\n");
776 r = SetCaretPos(0, 0);
777 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
778 r = GetCaretPos(&cpos);
779 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
780 ok(cpos.x == 0 && cpos.y == 0, "Wrong caret position, expected: (0,0), got: (%d,%d)\n", cpos.x, cpos.y);
781 r = SetCaretPos(-1, -1);
782 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
783 r = GetCaretPos(&cpos);
784 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
785 ok(cpos.x == -1 && cpos.y == -1, "Wrong caret position, expected: (-1,-1), got: (%d,%d)\n", cpos.x, cpos.y);
786 r = SetCaretPos(w << 1, h << 1);
787 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
788 r = GetCaretPos(&cpos);
789 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
790 ok(cpos.x == (w << 1) && cpos.y == (h << 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w << 1, h << 1, cpos.x, cpos.y);
791 r = SetCaretPos(w, h);
792 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
793 r = GetCaretPos(&cpos);
794 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
795 ok(cpos.x == w && cpos.y == h, "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w, h, cpos.x, cpos.y);
796 r = SetCaretPos(w - 1, h - 1);
797 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
798 r = GetCaretPos(&cpos);
799 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
800 ok(cpos.x == (w - 1) && cpos.y == (h - 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w - 1, h - 1, cpos.x, cpos.y);
801
802 /* OK, done! */
803 DestroyWindow (hwndET2);
804 DestroyWindow (hwndMain);
805 }
806
807 static void ET2_check_change(void) {
808 char szLocalString[MAXLEN];
809 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
810 GetWindowTextA(hwndET2, szLocalString, MAXLEN);
811 if (strcmp(szLocalString, "foo")==0) {
812 strcpy(szLocalString, "bar");
813 SendMessageA(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
814 }
815 /* always leave the cursor at the end. */
816 SendMessageA(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
817 }
818 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
819 {
820 if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
821 ET2_check_change();
822 }
823 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
824 {
825 switch (iMsg) {
826 case WM_COMMAND:
827 ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
828 break;
829 }
830 return DefWindowProcA(hwnd, iMsg, wParam, lParam);
831 }
832
833 static void zero_notify(void)
834 {
835 notifications.en_change = 0;
836 notifications.en_maxtext = 0;
837 notifications.en_update = 0;
838 }
839
840 #define test_notify(enchange, enmaxtext, enupdate) \
841 do { \
842 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
843 "got %d\n", enchange, notifications.en_change); \
844 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
845 "got %d\n", enmaxtext, notifications.en_maxtext); \
846 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
847 "got %d\n", enupdate, notifications.en_update); \
848 } while(0)
849
850
851 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
852 {
853 switch (msg) {
854 case WM_COMMAND:
855 switch (HIWORD(wParam)) {
856 case EN_MAXTEXT:
857 notifications.en_maxtext++;
858 break;
859 case EN_UPDATE:
860 notifications.en_update++;
861 break;
862 case EN_CHANGE:
863 notifications.en_change++;
864 break;
865 }
866 break;
867 }
868 return DefWindowProcA(hWnd, msg, wParam, lParam);
869 }
870
871 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response
872 * to these messages.
873 */
874 static void test_edit_control_3(void)
875 {
876 HWND hWnd;
877 HWND hParent;
878 HDC hDC;
879 int len, dpi;
880 static const char *str = "this is a long string.";
881 static const char *str2 = "this is a long string.\r\nthis is a long string.\r\nthis is a long string.\r\nthis is a long string.";
882
883 hDC = GetDC(NULL);
884 dpi = GetDeviceCaps(hDC, LOGPIXELSY);
885 ReleaseDC(NULL, hDC);
886
887 trace("EDIT: Test notifications\n");
888
889 hParent = CreateWindowExA(0,
890 szEditTest3Class,
891 NULL,
892 0,
893 CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
894 NULL, NULL, NULL, NULL);
895 assert(hParent);
896
897 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
898 hWnd = CreateWindowExA(0,
899 "EDIT",
900 NULL,
901 0,
902 10, 10, 50, 50,
903 hParent, NULL, NULL, NULL);
904 assert(hWnd);
905
906 zero_notify();
907 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
908 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
909 if (len == lstrlenA(str)) /* Win 8 */
910 test_notify(1, 0, 1);
911 else
912 test_notify(1, 1, 1);
913
914 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
915 zero_notify();
916 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
917 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
918 ok(1 == len, "wrong text length, expected 1, got %d\n", len);
919 test_notify(1, 0, 1);
920
921 zero_notify();
922 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
923 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
924 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
925 test_notify(1, 0, 1);
926
927 len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
928 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
929 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
930 SendMessageA(hParent, WM_SETFOCUS, 0, (LPARAM)hWnd);
931 len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
932 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
933 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
934
935 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
936
937 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
938 zero_notify();
939 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
940 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
941 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
942 test_notify(1, 1, 1);
943
944 zero_notify();
945 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
946 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
947 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
948 test_notify(1, 0, 1);
949
950 DestroyWindow(hWnd);
951
952 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
953 hWnd = CreateWindowExA(0,
954 "EDIT",
955 NULL,
956 ES_AUTOHSCROLL,
957 10, 10, 50, 50,
958 hParent, NULL, NULL, NULL);
959 assert(hWnd);
960
961 zero_notify();
962 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
963 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
964 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
965 test_notify(1, 0, 1);
966
967 zero_notify();
968 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
969 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
970 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
971 test_notify(1, 0, 1);
972
973 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
974 zero_notify();
975 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
976 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
977 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
978 test_notify(1, 0, 1);
979
980 zero_notify();
981 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
982 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
983 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
984 test_notify(1, 0, 1);
985
986 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
987
988 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
989 zero_notify();
990 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
991 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
992 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
993 test_notify(1, 1, 1);
994
995 zero_notify();
996 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
997 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
998 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
999 test_notify(1, 0, 1);
1000
1001 DestroyWindow(hWnd);
1002
1003 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1004 hWnd = CreateWindowExA(0,
1005 "EDIT",
1006 NULL,
1007 ES_MULTILINE,
1008 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1009 hParent, NULL, NULL, NULL);
1010 assert(hWnd);
1011
1012 zero_notify();
1013 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
1014 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1015 if (len == lstrlenA(str)) /* Win 8 */
1016 test_notify(1, 0, 1);
1017 else
1018 {
1019 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1020 test_notify(1, 1, 1);
1021 }
1022
1023 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1024 zero_notify();
1025 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
1026 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1027 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1028 test_notify(1, 0, 1);
1029
1030 zero_notify();
1031 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1032 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1033 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1034 test_notify(0, 0, 0);
1035
1036 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1037
1038 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1039 zero_notify();
1040 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
1041 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1042 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1043 test_notify(1, 1, 1);
1044
1045 zero_notify();
1046 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1047 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1048 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1049 test_notify(0, 0, 0);
1050
1051 DestroyWindow(hWnd);
1052
1053 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1054 hWnd = CreateWindowExA(0,
1055 "EDIT",
1056 NULL,
1057 ES_MULTILINE | ES_AUTOHSCROLL,
1058 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1059 hParent, NULL, NULL, NULL);
1060 assert(hWnd);
1061
1062 zero_notify();
1063 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1064 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1065 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1066 test_notify(1, 1, 1);
1067
1068 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1069 zero_notify();
1070 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
1071 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1072 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1073 test_notify(1, 0, 1);
1074
1075 zero_notify();
1076 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1077 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1078 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1079 test_notify(0, 0, 0);
1080
1081 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1082
1083 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1084 zero_notify();
1085 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1086 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1087 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1088 test_notify(1, 1, 1);
1089
1090 zero_notify();
1091 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1092 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1093 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1094 test_notify(0, 0, 0);
1095
1096 DestroyWindow(hWnd);
1097
1098 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1099 hWnd = CreateWindowExA(0,
1100 "EDIT",
1101 NULL,
1102 ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
1103 10, 10, 50, 50,
1104 hParent, NULL, NULL, NULL);
1105 assert(hWnd);
1106
1107 zero_notify();
1108 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1109 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1110 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1111 test_notify(1, 0, 1);
1112
1113 zero_notify();
1114 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1115 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1116 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1117 test_notify(0, 0, 0);
1118
1119 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1120
1121 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1122 zero_notify();
1123 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1124 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1125 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1126 test_notify(1, 1, 1);
1127
1128 zero_notify();
1129 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1130 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1131 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1132 test_notify(0, 0, 0);
1133
1134 DestroyWindow(hWnd);
1135 }
1136
1137 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
1138 */
1139 static void test_edit_control_4(void)
1140 {
1141 HWND hwEdit;
1142 int lo, hi, mid;
1143 int ret;
1144 int i;
1145
1146 trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
1147 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1148 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1149 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1150 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1151 mid = lo + (hi - lo) / 2;
1152
1153 for (i = lo; i < mid; i++) {
1154 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1155 ok(0 == ret, "expected 0 got %d\n", ret);
1156 }
1157 for (i = mid; i <= hi; i++) {
1158 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1159 ok(1 == ret, "expected 1 got %d\n", ret);
1160 }
1161 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1162 ok(-1 == ret, "expected -1 got %d\n", ret);
1163 DestroyWindow(hwEdit);
1164
1165 hwEdit = create_editcontrol(ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1166 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1167 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1168 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1169 mid = lo + (hi - lo) / 2;
1170
1171 for (i = lo; i < mid; i++) {
1172 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1173 ok(0 == ret, "expected 0 got %d\n", ret);
1174 }
1175 for (i = mid; i <= hi; i++) {
1176 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1177 ok(1 == ret, "expected 1 got %d\n", ret);
1178 }
1179 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1180 ok(-1 == ret, "expected -1 got %d\n", ret);
1181 DestroyWindow(hwEdit);
1182
1183 hwEdit = create_editcontrol(ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1184 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1185 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1186 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1187 mid = lo + (hi - lo) / 2;
1188
1189 for (i = lo; i < mid; i++) {
1190 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1191 ok(0 == ret, "expected 0 got %d\n", ret);
1192 }
1193 for (i = mid; i <= hi; i++) {
1194 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1195 ok(1 == ret, "expected 1 got %d\n", ret);
1196 }
1197 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1198 ok(-1 == ret, "expected -1 got %d\n", ret);
1199 DestroyWindow(hwEdit);
1200
1201 hwEdit = create_editcontrol(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1202 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1203 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1204 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1205 mid = lo + (hi - lo) / 2 +1;
1206
1207 for (i = lo; i < mid; i++) {
1208 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1209 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1210 }
1211 for (i = mid; i <= hi; i++) {
1212 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1213 ok(1 == ret, "expected 1 got %d\n", ret);
1214 }
1215 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1216 ok(-1 == ret, "expected -1 got %d\n", ret);
1217 DestroyWindow(hwEdit);
1218
1219 hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1220 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1221 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1222 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1223 mid = lo + (hi - lo) / 2 +1;
1224
1225 for (i = lo; i < mid; i++) {
1226 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1227 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1228 }
1229 for (i = mid; i <= hi; i++) {
1230 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1231 ok(1 == ret, "expected 1 got %d\n", ret);
1232 }
1233 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1234 ok(-1 == ret, "expected -1 got %d\n", ret);
1235 DestroyWindow(hwEdit);
1236
1237 hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1238 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1239 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1240 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1241 mid = lo + (hi - lo) / 2 +1;
1242
1243 for (i = lo; i < mid; i++) {
1244 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1245 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1246 }
1247 for (i = mid; i <= hi; i++) {
1248 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1249 ok(1 == ret, "expected 1 got %d\n", ret);
1250 }
1251 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1252 ok(-1 == ret, "expected -1 got %d\n", ret);
1253 DestroyWindow(hwEdit);
1254 }
1255
1256 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1257 * truncates text that doesn't fit.
1258 */
1259 static void test_edit_control_5(void)
1260 {
1261 static const char *str = "test\r\ntest";
1262 HWND parentWnd;
1263 HWND hWnd;
1264 int len;
1265 RECT rc1 = { 10, 10, 11, 11};
1266 RECT rc;
1267
1268 /* first show that a non-child won't do for this test */
1269 hWnd = CreateWindowExA(0,
1270 "EDIT",
1271 str,
1272 0,
1273 10, 10, 1, 1,
1274 NULL, NULL, NULL, NULL);
1275 assert(hWnd);
1276 /* size of non-child edit control is (much) bigger than requested */
1277 GetWindowRect( hWnd, &rc);
1278 ok( rc.right - rc.left > 20, "size of the window (%d) is smaller than expected\n",
1279 rc.right - rc.left);
1280 DestroyWindow(hWnd);
1281 /* so create a parent, and give it edit controls children to test with */
1282 parentWnd = CreateWindowExA(0,
1283 szEditTextPositionClass,
1284 "Edit Test", WS_VISIBLE |
1285 WS_OVERLAPPEDWINDOW,
1286 CW_USEDEFAULT, CW_USEDEFAULT,
1287 250, 250,
1288 NULL, NULL, hinst, NULL);
1289 assert(parentWnd);
1290 ShowWindow( parentWnd, SW_SHOW);
1291 /* single line */
1292 hWnd = CreateWindowExA(0,
1293 "EDIT",
1294 str, WS_VISIBLE | WS_BORDER |
1295 WS_CHILD,
1296 rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1297 parentWnd, NULL, NULL, NULL);
1298 assert(hWnd);
1299 GetClientRect( hWnd, &rc);
1300 ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1301 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc ));
1302 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1303 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1304 DestroyWindow(hWnd);
1305 /* multi line */
1306 hWnd = CreateWindowExA(0,
1307 "EDIT",
1308 str,
1309 WS_CHILD | ES_MULTILINE,
1310 rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1311 parentWnd, NULL, NULL, NULL);
1312 assert(hWnd);
1313 GetClientRect( hWnd, &rc);
1314 ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1315 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc ));
1316 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1317 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1318 DestroyWindow(hWnd);
1319 DestroyWindow(parentWnd);
1320 }
1321
1322 /* Test WM_GETTEXT processing
1323 * after destroy messages
1324 */
1325 static void test_edit_control_6(void)
1326 {
1327 static const char *str = "test\r\ntest";
1328 char buf[MAXLEN];
1329 LONG ret;
1330 HWND hWnd;
1331
1332 hWnd = CreateWindowExA(0,
1333 "EDIT",
1334 "Test",
1335 0,
1336 10, 10, 1, 1,
1337 NULL, NULL, hinst, NULL);
1338 assert(hWnd);
1339
1340 ret = SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1341 ok(ret == TRUE, "Expected %d, got %d\n", TRUE, ret);
1342 ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1343 ok(ret == strlen(str), "Expected %s, got len %d\n", str, ret);
1344 ok(!strcmp(buf, str), "Expected %s, got %s\n", str, buf);
1345 buf[0] = 0;
1346 ret = SendMessageA(hWnd, WM_DESTROY, 0, 0);
1347 ok(ret == 0, "Expected 0, got %d\n", ret);
1348 ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1349 ok(ret == strlen(str), "Expected %s, got len %d\n", str, ret);
1350 ok(!strcmp(buf, str), "Expected %s, got %s\n", str, buf);
1351 buf[0] = 0;
1352 ret = SendMessageA(hWnd, WM_NCDESTROY, 0, 0);
1353 ok(ret == 0, "Expected 0, got %d\n", ret);
1354 ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1355 ok(ret == 0, "Expected 0, got len %d\n", ret);
1356 ok(!strcmp(buf, ""), "Expected empty string, got %s\n", buf);
1357
1358 DestroyWindow(hWnd);
1359 }
1360
1361 static void test_edit_control_limittext(void)
1362 {
1363 HWND hwEdit;
1364 DWORD r;
1365
1366 /* Test default limit for single-line control */
1367 trace("EDIT: buffer limit for single-line\n");
1368 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1369 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1370 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1371 SendMessageA(hwEdit, EM_SETLIMITTEXT, 0, 0);
1372 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1373 ok( r == 2147483646, "got limit %u (expected 2147483646)\n", r);
1374 DestroyWindow(hwEdit);
1375
1376 /* Test default limit for multi-line control */
1377 trace("EDIT: buffer limit for multi-line\n");
1378 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1379 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1380 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1381 SendMessageA(hwEdit, EM_SETLIMITTEXT, 0, 0);
1382 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1383 ok( r == 4294967295U, "got limit %u (expected 4294967295)\n", r);
1384 DestroyWindow(hwEdit);
1385 }
1386
1387 /* Test EM_SCROLL */
1388 static void test_edit_control_scroll(void)
1389 {
1390 static const char *single_line_str = "a";
1391 static const char *multiline_str = "Test\r\nText";
1392 HWND hwEdit;
1393 LONG ret;
1394
1395 /* Check the return value when EM_SCROLL doesn't scroll
1396 * anything. Should not return true unless any lines were actually
1397 * scrolled. */
1398 hwEdit = CreateWindowA(
1399 "EDIT",
1400 single_line_str,
1401 WS_VSCROLL | ES_MULTILINE,
1402 1, 1, 100, 100,
1403 NULL, NULL, hinst, NULL);
1404
1405 assert(hwEdit);
1406
1407 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1408 ok(!ret, "Returned %x, expected 0.\n", ret);
1409
1410 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEUP, 0);
1411 ok(!ret, "Returned %x, expected 0.\n", ret);
1412
1413 ret = SendMessageA(hwEdit, EM_SCROLL, SB_LINEUP, 0);
1414 ok(!ret, "Returned %x, expected 0.\n", ret);
1415
1416 ret = SendMessageA(hwEdit, EM_SCROLL, SB_LINEDOWN, 0);
1417 ok(!ret, "Returned %x, expected 0.\n", ret);
1418
1419 DestroyWindow (hwEdit);
1420
1421 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1422 should not cause EM_SCROLL to return a negative value of
1423 scrolled lines that would put us "before" the beginning. */
1424 hwEdit = CreateWindowA(
1425 "EDIT",
1426 multiline_str,
1427 WS_VSCROLL | ES_MULTILINE,
1428 0, 0, 100, 100,
1429 NULL, NULL, hinst, NULL);
1430 assert(hwEdit);
1431
1432 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1433 ok(!ret, "Returned %x, expected 0.\n", ret);
1434
1435 DestroyWindow (hwEdit);
1436 }
1437
1438 static void test_margins_usefontinfo(UINT charset)
1439 {
1440 HWND hwnd;
1441 HDC hdc;
1442 SIZE size;
1443 BOOL cjk = FALSE;
1444 LOGFONTA lf;
1445 HFONT hfont;
1446 RECT rect;
1447 INT margins, threshold, expect, empty_expect, small_expect;
1448
1449 memset(&lf, 0, sizeof(lf));
1450 lf.lfHeight = -11;
1451 lf.lfWeight = FW_NORMAL;
1452 lf.lfCharSet = charset;
1453 strcpy(lf.lfFaceName, "Tahoma");
1454
1455 hfont = CreateFontIndirectA(&lf);
1456 ok(hfont != NULL, "got %p\n", hfont);
1457
1458 /* Big window rectangle */
1459 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 5000, 1000, NULL, NULL, NULL, NULL);
1460 ok(hwnd != NULL, "got %p\n", hwnd);
1461 GetClientRect(hwnd, &rect);
1462 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1463
1464 hdc = GetDC(hwnd);
1465 hfont = SelectObject(hdc, hfont);
1466 size.cx = GdiGetCharDimensions( hdc, NULL, &size.cy );
1467 expect = MAKELONG(size.cx / 2, size.cx / 2);
1468 small_expect = 0;
1469 empty_expect = size.cx >= 28 ? small_expect : expect;
1470
1471 charset = GetTextCharset(hdc);
1472 switch (charset)
1473 {
1474 case SHIFTJIS_CHARSET:
1475 case HANGUL_CHARSET:
1476 case GB2312_CHARSET:
1477 case CHINESEBIG5_CHARSET:
1478 cjk = TRUE;
1479 }
1480
1481 hfont = SelectObject(hdc, hfont);
1482 ReleaseDC(hwnd, hdc);
1483
1484 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1485 ok(margins == 0, "got %x\n", margins);
1486 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1487 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1488 if (!cjk)
1489 ok(margins == expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1490 else
1491 {
1492 ok(HIWORD(margins) > 0 && LOWORD(margins) > 0, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1493 expect = empty_expect = small_expect = margins;
1494 }
1495 DestroyWindow(hwnd);
1496
1497 threshold = (size.cx / 2 + size.cx) * 2;
1498
1499 /* Size below which non-cjk margins are zero */
1500 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, threshold - 1, 100, NULL, NULL, NULL, NULL);
1501 ok(hwnd != NULL, "got %p\n", hwnd);
1502 GetClientRect(hwnd, &rect);
1503 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1504
1505 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1506 ok(margins == 0, "got %x\n", margins);
1507
1508 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1509 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1510 ok(margins == small_expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1511 DestroyWindow(hwnd);
1512
1513 /* Size at which non-cjk margins become non-zero */
1514 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, threshold, 100, NULL, NULL, NULL, NULL);
1515 ok(hwnd != NULL, "got %p\n", hwnd);
1516 GetClientRect(hwnd, &rect);
1517 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1518
1519 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1520 ok(margins == 0, "got %x\n", margins);
1521
1522 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1523 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1524 ok(margins == expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1525 DestroyWindow(hwnd);
1526
1527 /* Empty rect */
1528 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1529 ok(hwnd != NULL, "got %p\n", hwnd);
1530 GetClientRect(hwnd, &rect);
1531 ok(IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1532
1533 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1534 ok(margins == 0, "got %x\n", margins);
1535
1536 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1537 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1538 ok(margins == empty_expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1539 DestroyWindow(hwnd);
1540
1541 DeleteObject(hfont);
1542 }
1543
1544 static void test_margins(void)
1545 {
1546 HWND hwEdit;
1547 RECT old_rect, new_rect;
1548 INT old_right_margin;
1549 DWORD old_margins, new_margins;
1550
1551 hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1552
1553 old_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1554 old_right_margin = HIWORD(old_margins);
1555
1556 /* Check if setting the margins works */
1557
1558 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
1559 new_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1560 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1561 ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
1562
1563 SendMessageA(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
1564 new_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1565 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1566 ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
1567
1568 /* The size of the rectangle must decrease if we increase the margin */
1569
1570 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
1571 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1572 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
1573 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1574 ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
1575 ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
1576 ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
1577 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
1578
1579 /* If we set the margin to same value as the current margin,
1580 the rectangle must not change */
1581
1582 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1583 SetRect(&old_rect, 1, 1, 99, 99);
1584 SendMessageA(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);
1585 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1586 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1587 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1588 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1589
1590 /* The lParam argument of the WM_SIZE message should be ignored. */
1591
1592 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1593 SendMessageA(hwEdit, WM_SIZE, SIZE_RESTORED, 0);
1594 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1595 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1596 SendMessageA(hwEdit, WM_SIZE, SIZE_MINIMIZED, 0);
1597 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1598 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1599 SendMessageA(hwEdit, WM_SIZE, SIZE_MAXIMIZED, 0);
1600 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1601 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1602 SendMessageA(hwEdit, WM_SIZE, SIZE_RESTORED, MAKELONG(10, 10));
1603 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1604 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1605
1606 DestroyWindow (hwEdit);
1607
1608 test_margins_usefontinfo(ANSI_CHARSET);
1609 test_margins_usefontinfo(EASTEUROPE_CHARSET);
1610
1611 test_margins_usefontinfo(SHIFTJIS_CHARSET);
1612 test_margins_usefontinfo(HANGUL_CHARSET);
1613 test_margins_usefontinfo(CHINESEBIG5_CHARSET);
1614 /* Don't test JOHAB_CHARSET. Treated as CJK by Win 8,
1615 but not by < Win 8 and Win 10. */
1616
1617 test_margins_usefontinfo(DEFAULT_CHARSET);
1618 }
1619
1620 static INT CALLBACK find_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
1621 {
1622 return 0;
1623 }
1624
1625 static void test_margins_font_change(void)
1626 {
1627 HWND hwEdit;
1628 DWORD margins, font_margins;
1629 LOGFONTA lf;
1630 HFONT hfont, hfont2;
1631 HDC hdc = GetDC(0);
1632
1633 if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
1634 {
1635 trace("Arial not found - skipping font change margin tests\n");
1636 ReleaseDC(0, hdc);
1637 return;
1638 }
1639 ReleaseDC(0, hdc);
1640
1641 hwEdit = create_child_editcontrol(0, 0);
1642
1643 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1644
1645 memset(&lf, 0, sizeof(lf));
1646 strcpy(lf.lfFaceName, "Arial");
1647 lf.lfHeight = 16;
1648 lf.lfCharSet = DEFAULT_CHARSET;
1649 hfont = CreateFontIndirectA(&lf);
1650 lf.lfHeight = 30;
1651 hfont2 = CreateFontIndirectA(&lf);
1652
1653 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1654 font_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1655 ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
1656 ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
1657
1658 /* With 'small' edit controls, test that the margin doesn't get set */
1659 SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1660 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
1661 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1662 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1663 ok(LOWORD(margins) == 0 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1664 "got %d\n", LOWORD(margins));
1665 ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1666 "got %d\n", HIWORD(margins));
1667
1668 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1669 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1670 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1671 ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1672 "got %d\n", LOWORD(margins));
1673 ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1674 "got %d\n", HIWORD(margins));
1675
1676 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1677 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1678 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1679 ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1680 "got %d\n", LOWORD(margins));
1681 ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1682 "got %d\n", HIWORD(margins));
1683
1684 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1685 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1686 ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1687 "got %d\n", LOWORD(margins));
1688 ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1689 "got %d\n", HIWORD(margins));
1690
1691 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1692 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1693 ok(LOWORD(margins) == 1 || broken(LOWORD(margins) != 1 && LOWORD(margins) != LOWORD(font_margins)), /* win95 */
1694 "got %d\n", LOWORD(margins));
1695 ok(HIWORD(margins) == 1 || broken(HIWORD(margins) != 1 && HIWORD(margins) != HIWORD(font_margins)), /* win95 */
1696 "got %d\n", HIWORD(margins));
1697
1698 /* Above a certain size threshold then the margin is updated */
1699 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1700 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1701 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1702 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1703 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1704 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1705
1706 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1707 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1708 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1709 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1710 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1711
1712 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1713 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1714 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1715 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1716 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1717 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1718 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1719 ok(LOWORD(margins) != LOWORD(font_margins) || broken(LOWORD(margins) == LOWORD(font_margins)), /* win98 */
1720 "got %d\n", LOWORD(margins));
1721 ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins));
1722
1723 SendMessageA(hwEdit, WM_SETFONT, 0, 0);
1724
1725 DeleteObject(hfont2);
1726 DeleteObject(hfont);
1727 destroy_child_editcontrol(hwEdit);
1728
1729 }
1730
1731 #define edit_pos_ok(exp, got, txt) \
1732 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1733
1734 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1735 do { \
1736 RECT format_rect; \
1737 int left_margin; \
1738 set_client_height(hwEdit, set_height); \
1739 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1740 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
1741 edit_pos_ok(test_top, format_rect.top, vertical position); \
1742 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1743 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1744 } while(0)
1745
1746 static void test_text_position_style(DWORD style)
1747 {
1748 HWND hwEdit;
1749 HFONT font, oldFont;
1750 HDC dc;
1751 TEXTMETRICA metrics;
1752 INT b, bm, b2, b3;
1753 BOOL xb, single_line = !(style & ES_MULTILINE);
1754
1755 b = GetSystemMetrics(SM_CYBORDER) + 1;
1756 b2 = 2 * b;
1757 b3 = 3 * b;
1758 bm = b2 - 1;
1759
1760 /* Get a stock font for which we can determine the metrics */
1761 font = GetStockObject(SYSTEM_FONT);
1762 ok (font != NULL, "GetStockObject SYSTEM_FONT failed\n");
1763 dc = GetDC(NULL);
1764 ok (dc != NULL, "GetDC() failed\n");
1765 oldFont = SelectObject(dc, font);
1766 xb = GetTextMetricsA(dc, &metrics);
1767 ok (xb, "GetTextMetrics failed\n");
1768 SelectObject(dc, oldFont);
1769 ReleaseDC(NULL, dc);
1770
1771 /* Windows' edit control has some bugs in multi-line mode:
1772 * - Sometimes the format rectangle doesn't get updated
1773 * (see workaround in set_client_height())
1774 * - If the height of the control is smaller than the height of a text
1775 * line, the format rectangle is still as high as a text line
1776 * (higher than the client rectangle) and the caret is not shown
1777 */
1778
1779 /* Edit controls that are in a parent window */
1780
1781 hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
1782 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1783 if (single_line)
1784 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
1785 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
1786 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
1787 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
1788 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
1789 destroy_child_editcontrol(hwEdit);
1790
1791 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
1792 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1793 if (single_line)
1794 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
1795 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
1796 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
1797 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
1798 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
1799 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
1800 destroy_child_editcontrol(hwEdit);
1801
1802 hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
1803 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1804 if (single_line)
1805 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1806 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1807 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1808 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1809 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1810 destroy_child_editcontrol(hwEdit);
1811
1812 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
1813 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1814 if (single_line)
1815 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1816 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1817 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1818 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1819 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1820 destroy_child_editcontrol(hwEdit);
1821
1822
1823 /* Edit controls that are popup windows */
1824
1825 hwEdit = create_editcontrol(style | WS_POPUP, 0);
1826 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1827 if (single_line)
1828 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
1829 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
1830 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
1831 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
1832 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
1833 DestroyWindow(hwEdit);
1834
1835 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
1836 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1837 if (single_line)
1838 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
1839 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
1840 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
1841 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
1842 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
1843 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
1844 DestroyWindow(hwEdit);
1845
1846 hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
1847 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1848 if (single_line)
1849 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1850 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1851 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1852 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1853 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1854 DestroyWindow(hwEdit);
1855
1856 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
1857 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1858 if (single_line)
1859 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1860 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1861 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1862 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1863 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1864 DestroyWindow(hwEdit);
1865 }
1866
1867 static void test_text_position(void)
1868 {
1869 trace("EDIT: Text position (Single line)\n");
1870 test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1871 trace("EDIT: Text position (Multi line)\n");
1872 test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1873 }
1874
1875 static void test_espassword(void)
1876 {
1877 HWND hwEdit;
1878 LONG r;
1879 char buffer[1024];
1880 const char* password = "secret";
1881
1882 hwEdit = create_editcontrol(ES_PASSWORD, 0);
1883 r = get_edit_style(hwEdit);
1884 ok(r == ES_PASSWORD, "Wrong style expected ES_PASSWORD got: 0x%x\n", r);
1885 /* set text */
1886 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
1887 ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
1888
1889 /* select all, cut (ctrl-x) */
1890 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
1891 r = SendMessageA(hwEdit, WM_CHAR, 24, 0);
1892 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1893
1894 /* get text */
1895 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1896 ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
1897 ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
1898
1899 r = OpenClipboard(hwEdit);
1900 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1901 r = EmptyClipboard();
1902 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1903 r = CloseClipboard();
1904 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1905
1906 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1907 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
1908 r = SendMessageA(hwEdit, WM_CHAR, 3, 0);
1909 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1910 r = SendMessageA(hwEdit, WM_CHAR, 22, 0);
1911 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1912
1913 /* get text */
1914 buffer[0] = 0;
1915 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1916 ok(r == 0, "Expected: 0, got: %d\n", r);
1917 ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
1918
1919 DestroyWindow (hwEdit);
1920 }
1921
1922 static void test_undo(void)
1923 {
1924 HWND hwEdit;
1925 LONG r;
1926 DWORD cpMin, cpMax;
1927 char buffer[1024];
1928 const char* text = "undo this";
1929
1930 hwEdit = create_editcontrol(0, 0);
1931 r = get_edit_style(hwEdit);
1932 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1933
1934 /* set text */
1935 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
1936 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1937
1938 /* select all, */
1939 cpMin = cpMax = 0xdeadbeef;
1940 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
1941 r = SendMessageA(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
1942 ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
1943 ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
1944 ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
1945
1946 /* cut (ctrl-x) */
1947 r = SendMessageA(hwEdit, WM_CHAR, 24, 0);
1948 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1949
1950 /* get text */
1951 buffer[0] = 0;
1952 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1953 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1954 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1955
1956 /* undo (ctrl-z) */
1957 r = SendMessageA(hwEdit, WM_CHAR, 26, 0);
1958 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1959
1960 /* get text */
1961 buffer[0] = 0;
1962 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1963 ok(strlen(text) == r, "Unexpected length %d\n", r);
1964 ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
1965
1966 /* undo again (ctrl-z) */
1967 r = SendMessageA(hwEdit, WM_CHAR, 26, 0);
1968 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1969
1970 /* get text */
1971 buffer[0] = 0;
1972 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1973 ok(r == 0, "Expected: %d, got len %d\n", 0, r);
1974 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1975
1976 DestroyWindow (hwEdit);
1977 }
1978
1979 static void test_enter(void)
1980 {
1981 HWND hwEdit;
1982 LONG r;
1983 char buffer[16];
1984
1985 /* multiline */
1986 hwEdit = create_editcontrol(ES_MULTILINE, 0);
1987 r = get_edit_style(hwEdit);
1988 ok(ES_MULTILINE == r, "Wrong style expected ES_MULTILINE got: 0x%x\n", r);
1989
1990 /* set text */
1991 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1992 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1993
1994 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
1995 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1996
1997 /* get text */
1998 buffer[0] = 0;
1999 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2000 ok(2 == r, "Expected: %d, got len %d\n", 2, r);
2001 ok(0 == strcmp(buffer, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer);
2002
2003 DestroyWindow (hwEdit);
2004
2005 /* single line */
2006 hwEdit = create_editcontrol(0, 0);
2007 r = get_edit_style(hwEdit);
2008 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2009
2010 /* set text */
2011 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2012 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2013
2014 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2015 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2016
2017 /* get text */
2018 buffer[0] = 0;
2019 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2020 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2021 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2022
2023 DestroyWindow (hwEdit);
2024
2025 /* single line with ES_WANTRETURN */
2026 hwEdit = create_editcontrol(ES_WANTRETURN, 0);
2027 r = get_edit_style(hwEdit);
2028 ok(ES_WANTRETURN == r, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r);
2029
2030 /* set text */
2031 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2032 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2033
2034 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2035 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2036
2037 /* get text */
2038 buffer[0] = 0;
2039 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2040 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2041 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2042
2043 DestroyWindow (hwEdit);
2044 }
2045
2046 static void test_tab(void)
2047 {
2048 HWND hwEdit;
2049 LONG r;
2050 char buffer[16];
2051
2052 /* multiline */
2053 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2054 r = get_edit_style(hwEdit);
2055 ok(ES_MULTILINE == r, "Wrong style expected ES_MULTILINE got: 0x%x\n", r);
2056
2057 /* set text */
2058 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2059 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2060
2061 r = SendMessageA(hwEdit, WM_CHAR, VK_TAB, 0);
2062 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2063
2064 /* get text */
2065 buffer[0] = 0;
2066 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2067 ok(1 == r, "Expected: %d, got len %d\n", 1, r);
2068 ok(0 == strcmp(buffer, "\t"), "expected \"\\t\", got \"%s\"\n", buffer);
2069
2070 DestroyWindow (hwEdit);
2071
2072 /* single line */
2073 hwEdit = create_editcontrol(0, 0);
2074 r = get_edit_style(hwEdit);
2075 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2076
2077 /* set text */
2078 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2079 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2080
2081 r = SendMessageA(hwEdit, WM_CHAR, VK_TAB, 0);
2082 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2083
2084 /* get text */
2085 buffer[0] = 0;
2086 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2087 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2088 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2089
2090 DestroyWindow (hwEdit);
2091 }
2092
2093 static void test_edit_dialog(void)
2094 {
2095 int r;
2096
2097 /* from bug 11841 */
2098 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 0);
2099 ok(333 == r, "Expected %d, got %d\n", 333, r);
2100 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 1);
2101 ok(111 == r, "Expected %d, got %d\n", 111, r);
2102 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 2);
2103 ok(444 == r, "Expected %d, got %d\n", 444, r);
2104
2105 /* more tests for WM_CHAR */
2106 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 3);
2107 ok(444 == r, "Expected %d, got %d\n", 444, r);
2108 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 4);
2109 ok(444 == r, "Expected %d, got %d\n", 444, r);
2110 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 5);
2111 ok(444 == r, "Expected %d, got %d\n", 444, r);
2112
2113 /* more tests for WM_KEYDOWN + WM_CHAR */
2114 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 6);
2115 ok(444 == r, "Expected %d, got %d\n", 444, r);
2116 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 7);
2117 ok(444 == r, "Expected %d, got %d\n", 444, r);
2118 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 8);
2119 ok(444 == r, "Expected %d, got %d\n", 444, r);
2120
2121 /* tests with an editable edit control */
2122 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 0);
2123 ok(333 == r, "Expected %d, got %d\n", 333, r);
2124 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 1);
2125 ok(111 == r, "Expected %d, got %d\n", 111, r);
2126 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 2);
2127 ok(444 == r, "Expected %d, got %d\n", 444, r);
2128
2129 /* tests for WM_CHAR */
2130 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 3);
2131 ok(444 == r, "Expected %d, got %d\n", 444, r);
2132 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 4);
2133 ok(444 == r, "Expected %d, got %d\n", 444, r);
2134 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 5);
2135 ok(444 == r, "Expected %d, got %d\n", 444, r);
2136
2137 /* tests for WM_KEYDOWN + WM_CHAR */
2138 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 6);
2139 ok(444 == r, "Expected %d, got %d\n", 444, r);
2140 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 7);
2141 ok(444 == r, "Expected %d, got %d\n", 444, r);
2142 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 8);
2143 ok(444 == r, "Expected %d, got %d\n", 444, r);
2144
2145 /* multiple tab tests */
2146 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 9);
2147 ok(22 == r, "Expected %d, got %d\n", 22, r);
2148 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 10);
2149 ok(33 == r, "Expected %d, got %d\n", 33, r);
2150 }
2151
2152 static void test_multi_edit_dialog(void)
2153 {
2154 int r;
2155
2156 /* test for multiple edit dialogs (bug 12319) */
2157 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 0);
2158 ok(2222 == r, "Expected %d, got %d\n", 2222, r);
2159 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 1);
2160 ok(1111 == r, "Expected %d, got %d\n", 1111, r);
2161 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 2);
2162 ok(2222 == r, "Expected %d, got %d\n", 2222, r);
2163 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 3);
2164 ok(11 == r, "Expected %d, got %d\n", 11, r);
2165 }
2166
2167 static void test_wantreturn_edit_dialog(void)
2168 {
2169 int r;
2170
2171 /* tests for WM_KEYDOWN */
2172 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 0);
2173 ok(333 == r, "Expected %d, got %d\n", 333, r);
2174 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 1);
2175 ok(444 == r, "Expected %d, got %d\n", 444, r);
2176 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 2);
2177 ok(444 == r, "Expected %d, got %d\n", 444, r);
2178
2179 /* tests for WM_CHAR */
2180 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 3);
2181 ok(444 == r, "Expected %d, got %d\n", 444, r);
2182 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 4);
2183 ok(444 == r, "Expected %d, got %d\n", 444, r);
2184 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 5);
2185 ok(444 == r, "Expected %d, got %d\n", 444, r);
2186
2187 /* tests for WM_KEYDOWN + WM_CHAR */
2188 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 6);
2189 ok(444 == r, "Expected %d, got %d\n", 444, r);
2190 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 7);
2191 ok(444 == r, "Expected %d, got %d\n", 444, r);
2192 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 8);
2193 ok(444 == r, "Expected %d, got %d\n", 444, r);
2194 }
2195
2196 static void test_singleline_wantreturn_edit_dialog(void)
2197 {
2198 int r;
2199
2200 /* tests for WM_KEYDOWN */
2201 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 0);
2202 ok(222 == r, "Expected %d, got %d\n", 222, r);
2203 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 1);
2204 ok(111 == r, "Expected %d, got %d\n", 111, r);
2205 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 2);
2206 ok(444 == r, "Expected %d, got %d\n", 444, r);
2207
2208 /* tests for WM_CHAR */
2209 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 3);
2210 ok(444 == r, "Expected %d, got %d\n", 444, r);
2211 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 4);
2212 ok(444 == r, "Expected %d, got %d\n", 444, r);
2213 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 5);
2214 ok(444 == r, "Expected %d, got %d\n", 444, r);
2215
2216 /* tests for WM_KEYDOWN + WM_CHAR */
2217 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 6);
2218 ok(222 == r, "Expected %d, got %d\n", 222, r);
2219 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 7);
2220 ok(111 == r, "Expected %d, got %d\n", 111, r);
2221 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 8);
2222 ok(444 == r, "Expected %d, got %d\n", 444, r);
2223
2224 /* tests for WM_KEYDOWN */
2225 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 0);
2226 ok(222 == r, "Expected %d, got %d\n", 222, r);
2227 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 1);
2228 ok(111 == r, "Expected %d, got %d\n", 111, r);
2229 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 2);
2230 ok(444 == r, "Expected %d, got %d\n", 444, r);
2231
2232 /* tests for WM_CHAR */
2233 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 3);
2234 ok(444 == r, "Expected %d, got %d\n", 444, r);
2235 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 4);
2236 ok(444 == r, "Expected %d, got %d\n", 444, r);
2237 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 5);
2238 ok(444 == r, "Expected %d, got %d\n", 444, r);
2239
2240 /* tests for WM_KEYDOWN + WM_CHAR */
2241 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 6);
2242 ok(222 == r, "Expected %d, got %d\n", 222, r);
2243 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 7);
2244 ok(111 == r, "Expected %d, got %d\n", 111, r);
2245 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 8);
2246 ok(444 == r, "Expected %d, got %d\n", 444, r);
2247 }
2248
2249 static int child_edit_wmkeydown_num_messages = 0;
2250 static INT_PTR CALLBACK child_edit_wmkeydown_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
2251 {
2252 switch (msg)
2253 {
2254 case WM_DESTROY:
2255 case WM_NCDESTROY:
2256 break;
2257
2258 default:
2259 child_edit_wmkeydown_num_messages++;
2260 break;
2261 }
2262
2263 return FALSE;
2264 }
2265
2266 static void test_child_edit_wmkeydown(void)
2267 {
2268 HWND hwEdit, hwParent;
2269 int r;
2270
2271 hwEdit = create_child_editcontrol(0, 0);
2272 hwParent = GetParent(hwEdit);
2273 SetWindowLongPtrA(hwParent, GWLP_WNDPROC, (LONG_PTR)child_edit_wmkeydown_proc);
2274 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2275 ok(1 == r, "expected 1, got %d\n", r);
2276 ok(0 == child_edit_wmkeydown_num_messages, "expected 0, got %d\n", child_edit_wmkeydown_num_messages);
2277 destroy_child_editcontrol(hwEdit);
2278 }
2279
2280 static BOOL got_en_setfocus = FALSE;
2281 static BOOL got_wm_capturechanged = FALSE;
2282 static LRESULT (CALLBACK *p_edit_proc)(HWND, UINT, WPARAM, LPARAM);
2283
2284 static LRESULT CALLBACK edit4_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
2285 {
2286 switch (msg) {
2287 case WM_COMMAND:
2288 switch (HIWORD(wParam)) {
2289 case EN_SETFOCUS:
2290 got_en_setfocus = TRUE;
2291 break;
2292 }
2293 break;
2294 case WM_CAPTURECHANGED:
2295 if (hWnd != (HWND)lParam)
2296 {
2297 got_wm_capturechanged = TRUE;
2298 EndMenu();
2299 }
2300 break;
2301 }
2302 return DefWindowProcA(hWnd, msg, wParam, lParam);
2303 }
2304
2305 static LRESULT CALLBACK edit_proc_proxy(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
2306 {
2307 switch (msg) {
2308 case WM_ENTERIDLE: {
2309 MENUBARINFO mbi;
2310 BOOL ret;
2311 HWND ctx_menu = (HWND)lParam;
2312
2313 memset(&mbi, 0, sizeof(mbi));
2314 mbi.cbSize = sizeof(mbi);
2315 SetLastError(0xdeadbeef);
2316 ret = GetMenuBarInfo(ctx_menu, OBJID_CLIENT, 0, &mbi);
2317 ok(ret, "GetMenuBarInfo failed\n");
2318 if (ret)
2319 {
2320 ok(mbi.hMenu != NULL, "mbi.hMenu = NULL\n");
2321 ok(!mbi.hwndMenu, "mbi.hwndMenu != NULL\n");
2322 ok(mbi.fBarFocused, "mbi.fBarFocused = FALSE\n");
2323 ok(mbi.fFocused, "mbi.fFocused = FALSE\n");
2324 }
2325
2326 memset(&mbi, 0, sizeof(mbi));
2327 mbi.cbSize = sizeof(mbi);
2328 SetLastError(0xdeadbeef);
2329 ret = GetMenuBarInfo(ctx_menu, OBJID_CLIENT, 1, &mbi);
2330 ok(ret, "GetMenuBarInfo failed\n");
2331 if (ret)
2332 {
2333 ok(mbi.hMenu != NULL, "mbi.hMenu = NULL\n");
2334 ok(!mbi.hwndMenu, "mbi.hwndMenu != NULL\n");
2335 ok(mbi.fBarFocused, "mbi.fBarFocused = FALSE\n");
2336 ok(!mbi.fFocused, "mbi.fFocused = TRUE\n");
2337 }
2338
2339 EndMenu();
2340 break;
2341 }
2342 }
2343 return p_edit_proc(hWnd, msg, wParam, lParam);
2344 }
2345
2346 struct context_menu_messages
2347 {
2348 unsigned int wm_command, em_setsel;
2349 };
2350
2351 static struct context_menu_messages menu_messages;
2352
2353 static LRESULT CALLBACK child_edit_menu_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2354 {
2355 switch (msg) {
2356 case WM_ENTERIDLE:
2357 if (wParam == MSGF_MENU) {
2358 HWND hwndMenu = (HWND)lParam;
2359 MENUBARINFO mbi = { sizeof(MENUBARINFO) };
2360 if (GetMenuBarInfo(hwndMenu, OBJID_CLIENT, 0, &mbi)) {
2361 MENUITEMINFOA mii = { sizeof(MENUITEMINFOA), MIIM_STATE };
2362 if (GetMenuItemInfoA(mbi.hMenu, EM_SETSEL, FALSE, &mii)) {
2363 if (mii.fState & MFS_HILITE) {
2364 PostMessageA(hwnd, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2365 PostMessageA(hwnd, WM_KEYUP, VK_RETURN, 0x1c0001);
2366 }
2367 else {
2368 PostMessageA(hwnd, WM_KEYDOWN, VK_DOWN, 0x500001);
2369 PostMessageA(hwnd, WM_KEYUP, VK_DOWN, 0x500001);
2370 }
2371 }
2372 }
2373 }
2374 break;
2375 case WM_COMMAND:
2376 menu_messages.wm_command++;
2377 break;
2378 case EM_SETSEL:
2379 menu_messages.em_setsel++;
2380 break;
2381 }
2382 return CallWindowProcA(p_edit_proc, hwnd, msg, wParam, lParam);
2383 }
2384
2385 static void test_contextmenu(void)
2386 {
2387 HWND hwndMain, hwndEdit;
2388 MSG msg;
2389
2390 hwndMain = CreateWindowA(szEditTest4Class, "ET4", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
2391 0, 0, 200, 200, NULL, NULL, hinst, NULL);
2392 assert(hwndMain);
2393
2394 hwndEdit = CreateWindowA("EDIT", NULL,
2395 WS_CHILD|WS_BORDER|WS_VISIBLE|ES_LEFT|ES_AUTOHSCROLL,
2396 0, 0, 150, 50, /* important this not be 0 size. */
2397 hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
2398 assert(hwndEdit);
2399
2400 SetFocus(NULL);
2401 SetCapture(hwndMain);
2402 SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(10, 10));
2403 ok(got_en_setfocus, "edit box didn't get focused\n");
2404 ok(got_wm_capturechanged, "main window capture did not change\n");
2405
2406 p_edit_proc = (void*)SetWindowLongPtrA(hwndEdit, GWLP_WNDPROC, (ULONG_PTR)edit_proc_proxy);
2407 SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(10, 10));
2408
2409 DestroyWindow (hwndEdit);
2410
2411 hwndEdit = CreateWindowA("EDIT", "Test Text",
2412 WS_CHILD | WS_BORDER | WS_VISIBLE,
2413 0, 0, 100, 100,
2414 hwndMain, NULL, hinst, NULL);
2415 memset(&menu_messages, 0, sizeof(menu_messages));
2416 p_edit_proc = (void*)SetWindowLongPtrA(hwndEdit, GWLP_WNDPROC,
2417 (ULONG_PTR)child_edit_menu_proc);
2418
2419 SetFocus(hwndEdit);
2420 SendMessageA(hwndEdit, WM_SETTEXT, 0, (LPARAM)"foo");
2421 SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(-1, -1));
2422 while (PeekMessageA(&msg, hwndEdit, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
2423 ok(menu_messages.wm_command == 0,
2424 "Expected no WM_COMMAND messages, got %d\n", menu_messages.wm_command);
2425 ok(menu_messages.em_setsel == 1,
2426 "Expected 1 EM_SETSEL message, got %d\n", menu_messages.em_setsel);
2427
2428 DestroyWindow (hwndEdit);
2429 DestroyWindow (hwndMain);
2430 }
2431
2432 static BOOL RegisterWindowClasses (void)
2433 {
2434 WNDCLASSA test2;
2435 WNDCLASSA test3;
2436 WNDCLASSA test4;
2437 WNDCLASSA text_position;
2438
2439 test2.style = 0;
2440 test2.lpfnWndProc = ET2_WndProc;
2441 test2.cbClsExtra = 0;
2442 test2.cbWndExtra = 0;
2443 test2.hInstance = hinst;
2444 test2.hIcon = NULL;
2445 test2.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
2446 test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2447 test2.lpszMenuName = NULL;
2448 test2.lpszClassName = szEditTest2Class;
2449 if (!RegisterClassA(&test2)) return FALSE;
2450
2451 test3.style = 0;
2452 test3.lpfnWndProc = edit3_wnd_procA;
2453 test3.cbClsExtra = 0;
2454 test3.cbWndExtra = 0;
2455 test3.hInstance = hinst;
2456 test3.hIcon = 0;
2457 test3.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
2458 test3.hbrBackground = GetStockObject(WHITE_BRUSH);
2459 test3.lpszMenuName = NULL;
2460 test3.lpszClassName = szEditTest3Class;
2461 if (!RegisterClassA(&test3)) return FALSE;
2462
2463 test4.style = 0;
2464 test4.lpfnWndProc = edit4_wnd_procA;
2465 test4.cbClsExtra = 0;
2466 test4.cbWndExtra = 0;
2467 test4.hInstance = hinst;
2468 test4.hIcon = NULL;
2469 test4.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
2470 test4.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2471 test4.lpszMenuName = NULL;
2472 test4.lpszClassName = szEditTest4Class;
2473 if (!RegisterClassA(&test4)) return FALSE;
2474
2475 text_position.style = CS_HREDRAW | CS_VREDRAW;
2476 text_position.cbClsExtra = 0;
2477 text_position.cbWndExtra = 0;
2478 text_position.hInstance = hinst;
2479 text_position.hIcon = NULL;
2480 text_position.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
2481 text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2482 text_position.lpszMenuName = NULL;
2483 text_position.lpszClassName = szEditTextPositionClass;
2484 text_position.lpfnWndProc = DefWindowProcA;
2485 if (!RegisterClassA(&text_position)) return FALSE;
2486
2487 return TRUE;
2488 }
2489
2490 static void UnregisterWindowClasses (void)
2491 {
2492 UnregisterClassA(szEditTest2Class, hinst);
2493 UnregisterClassA(szEditTest3Class, hinst);
2494 UnregisterClassA(szEditTest4Class, hinst);
2495 UnregisterClassA(szEditTextPositionClass, hinst);
2496 }
2497
2498 static void test_fontsize(void)
2499 {
2500 HWND hwEdit;
2501 HFONT hfont;
2502 HDC hDC;
2503 LOGFONTA lf;
2504 LONG r;
2505 char szLocalString[MAXLEN];
2506 int dpi;
2507
2508 hDC = GetDC(NULL);
2509 dpi = GetDeviceCaps(hDC, LOGPIXELSY);
2510 ReleaseDC(NULL, hDC);
2511
2512 memset(&lf,0,sizeof(LOGFONTA));
2513 strcpy(lf.lfFaceName,"Arial");
2514 lf.lfHeight = -300; /* taller than the edit box */
2515 lf.lfWeight = 500;
2516 hfont = CreateFontIndirectA(&lf);
2517
2518 trace("EDIT: Oversized font (Multi line)\n");
2519 hwEdit= CreateWindowA("EDIT", NULL, ES_MULTILINE|ES_AUTOHSCROLL,
2520 0, 0, (150 * dpi) / 96, (50 * dpi) / 96, NULL, NULL,
2521 hinst, NULL);
2522
2523 SendMessageA(hwEdit,WM_SETFONT,(WPARAM)hfont,0);
2524
2525 if (winetest_interactive)
2526 ShowWindow (hwEdit, SW_SHOW);
2527
2528 r = SendMessageA(hwEdit, WM_CHAR, 'A', 1);
2529 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2530 r = SendMessageA(hwEdit, WM_CHAR, 'B', 1);
2531 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2532 r = SendMessageA(hwEdit, WM_CHAR, 'C', 1);
2533 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2534
2535 GetWindowTextA(hwEdit, szLocalString, MAXLEN);
2536 ok(strcmp(szLocalString, "ABC")==0,
2537 "Wrong contents of edit: %s\n", szLocalString);
2538
2539 r = SendMessageA(hwEdit, EM_POSFROMCHAR,0,0);
2540 ok(r != -1,"EM_POSFROMCHAR failed index 0\n");
2541 r = SendMessageA(hwEdit, EM_POSFROMCHAR,1,0);
2542 ok(r != -1,"EM_POSFROMCHAR failed index 1\n");
2543 r = SendMessageA(hwEdit, EM_POSFROMCHAR,2,0);
2544 ok(r != -1,"EM_POSFROMCHAR failed index 2\n");
2545 r = SendMessageA(hwEdit, EM_POSFROMCHAR,3,0);
2546 ok(r == -1,"EM_POSFROMCHAR succeeded index 3\n");
2547
2548 DestroyWindow (hwEdit);
2549 DeleteObject(hfont);
2550 }
2551
2552 struct dialog_mode_messages
2553 {
2554 int wm_getdefid, wm_close, wm_command, wm_nextdlgctl;
2555 };
2556
2557 static struct dialog_mode_messages dm_messages;
2558
2559 static void zero_dm_messages(void)
2560 {
2561 dm_messages.wm_command = 0;
2562 dm_messages.wm_close = 0;
2563 dm_messages.wm_getdefid = 0;
2564 dm_messages.wm_nextdlgctl = 0;
2565 }
2566
2567 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2568 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2569 "got %d\n", wmcommand, dm_messages.wm_command); \
2570 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2571 "got %d\n", wmclose, dm_messages.wm_close); \
2572 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2573 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2574 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2575 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2576
2577 static LRESULT CALLBACK dialog_mode_wnd_proc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
2578 {
2579 switch (iMsg)
2580 {
2581 case WM_COMMAND:
2582 dm_messages.wm_command++;
2583 break;
2584 case DM_GETDEFID:
2585 dm_messages.wm_getdefid++;
2586 return MAKELONG(ID_EDITTESTDBUTTON, DC_HASDEFID);
2587 case WM_NEXTDLGCTL:
2588 dm_messages.wm_nextdlgctl++;
2589 break;
2590 case WM_CLOSE:
2591 dm_messages.wm_close++;
2592 break;
2593 }
2594
2595 return DefWindowProcA(hwnd, iMsg, wParam, lParam);
2596 }
2597
2598 static void test_dialogmode(void)
2599 {
2600 HWND hwEdit, hwParent, hwButton;
2601 MSG msg= {0};
2602 int len, r;
2603 hwEdit = create_child_editcontrol(ES_MULTILINE, 0);
2604
2605 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2606 ok(1 == r, "expected 1, got %d\n", r);
2607 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2608 ok(11 == len, "expected 11, got %d\n", len);
2609
2610 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, 0);
2611 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2612
2613 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2614 ok(1 == r, "expected 1, got %d\n", r);
2615 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2616 ok(13 == len, "expected 13, got %d\n", len);
2617
2618 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM)&msg);
2619 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2620 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2621 ok(1 == r, "expected 1, got %d\n", r);
2622 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2623 ok(13 == len, "expected 13, got %d\n", len);
2624
2625 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2626 ok(1 == r, "expected 1, got %d\n", r);
2627 len = SendMessageA(hwEdit