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