user32/tests: Fix the edit margins tests on Win9x.
[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 %ld, but is %ld\n",
650         (long)Height, (long)(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 hWnd;
1181     int len;
1182
1183     hWnd = CreateWindowEx(0,
1184               "EDIT",
1185               str,
1186               0,
1187               10, 10, 1, 1,
1188               NULL, NULL, NULL, NULL);
1189     assert(hWnd);
1190
1191     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1192     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1193     DestroyWindow(hWnd);
1194
1195     hWnd = CreateWindowEx(0,
1196               "EDIT",
1197               str,
1198               ES_MULTILINE,
1199               10, 10, 1, 1,
1200               NULL, NULL, NULL, NULL);
1201     assert(hWnd);
1202
1203     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1204     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1205     DestroyWindow(hWnd);
1206 }
1207
1208 static void test_edit_control_limittext(void)
1209 {
1210     HWND hwEdit;
1211     DWORD r;
1212
1213     /* Test default limit for single-line control */
1214     trace("EDIT: buffer limit for single-line\n");
1215     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1216     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1217     ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1218     SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
1219     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1220     /* Win9x+ME: 32766; WinNT: 2147483646UL */
1221     ok( (r == 32766) || (r == 2147483646UL),
1222         "got limit %u (expected 32766 or 2147483646)\n", r);
1223     DestroyWindow(hwEdit);
1224
1225     /* Test default limit for multi-line control */
1226     trace("EDIT: buffer limit for multi-line\n");
1227     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1228     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1229     ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1230     SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
1231     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1232     /* Win9x+ME: 65535; WinNT: 4294967295UL */
1233     ok( (r == 65535) || (r == 4294967295UL),
1234         "got limit %u (expected 65535 or 4294967295)\n", r);
1235     DestroyWindow(hwEdit);
1236 }
1237
1238 static void test_margins(void)
1239 {
1240     HWND hwEdit;
1241     RECT old_rect, new_rect;
1242     INT old_left_margin, old_right_margin;
1243     DWORD old_margins, new_margins;
1244
1245     hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1246     
1247     old_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1248     old_left_margin = LOWORD(old_margins);
1249     old_right_margin = HIWORD(old_margins);
1250     
1251     /* Check if setting the margins works */
1252     
1253     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
1254     new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1255     ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1256     ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
1257     
1258     SendMessage(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
1259     new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1260     ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1261     ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
1262     
1263     
1264     /* The size of the rectangle must decrease if we increase the margin */
1265     
1266     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
1267     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1268     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
1269     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1270     ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
1271     ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
1272     ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
1273     ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
1274     
1275     
1276     /* If we set the margin to same value as the current margin,
1277        the rectangle must not change */
1278     
1279     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1280     old_rect.left = 1;
1281     old_rect.right = 99;
1282     old_rect.top = 1;
1283     old_rect.bottom = 99;
1284     SendMessage(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);    
1285     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1286     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1287     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1288     ok(new_rect.left == old_rect.left, "The left border of the rectangle has changed\n");
1289     ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n");
1290     ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n");
1291     ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n");
1292
1293     DestroyWindow (hwEdit);
1294 }
1295
1296 static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
1297 {
1298     return 0;
1299 }
1300
1301 static void test_margins_font_change(void)
1302 {
1303     HWND hwEdit;
1304     DWORD margins, font_margins;
1305     LOGFONT lf;
1306     HFONT hfont, hfont2;
1307     HDC hdc = GetDC(0);
1308
1309     if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
1310     {
1311         trace("Arial not found - skipping font change margin tests\n");
1312         ReleaseDC(0, hdc);
1313         return;
1314     }
1315     ReleaseDC(0, hdc);
1316
1317     hwEdit = create_child_editcontrol(0, 0);
1318
1319     SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1320
1321     memset(&lf, 0, sizeof(lf));
1322     strcpy(lf.lfFaceName, "Arial");
1323     lf.lfHeight = 16;
1324     lf.lfCharSet = DEFAULT_CHARSET;
1325     hfont = CreateFontIndirectA(&lf);
1326     lf.lfHeight = 30;
1327     hfont2 = CreateFontIndirectA(&lf);
1328
1329     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1330     font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1331     ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
1332     ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
1333
1334     /* With 'small' edit controls, test that the margin doesn't get set */
1335     SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1336     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
1337     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1338     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1339     ok(LOWORD(margins) == 0 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1340        "got %d\n", LOWORD(margins));
1341     ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1342        "got %d\n", HIWORD(margins));
1343
1344     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1345     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1346     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1347     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1348        "got %d\n", LOWORD(margins));
1349     ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1350        "got %d\n", HIWORD(margins));
1351
1352     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1353     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1354     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1355     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1356        "got %d\n", LOWORD(margins));
1357     ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1358        "got %d\n", HIWORD(margins));
1359
1360     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1361     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1362     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1363        "got %d\n", LOWORD(margins));
1364     ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1365        "got %d\n", HIWORD(margins));
1366
1367     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1368     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1369     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) != 1 && LOWORD(margins) != LOWORD(font_margins)), /* win95 */
1370        "got %d\n", LOWORD(margins));
1371     ok(HIWORD(margins) == 1 || broken(HIWORD(margins) != 1 && HIWORD(margins) != HIWORD(font_margins)), /* win95 */
1372        "got %d\n", HIWORD(margins));
1373
1374     /* Above a certain size threshold then the margin is updated */
1375     SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1376     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1377     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1378     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1379     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1380     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1381
1382     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1383     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1384     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1385     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1386     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1387
1388     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1389     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1390     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1391     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1392     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1393     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1394     ok(LOWORD(margins) != LOWORD(font_margins) || broken(LOWORD(margins) == LOWORD(font_margins)), /* win98 */
1395        "got %d\n", LOWORD(margins));
1396     ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1397
1398     SendMessageA(hwEdit, WM_SETFONT, 0, 0);
1399     
1400     DeleteObject(hfont2);
1401     DeleteObject(hfont);
1402     destroy_child_editcontrol(hwEdit);
1403
1404 }
1405
1406 #define edit_pos_ok(exp, got, txt) \
1407     ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1408
1409 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1410 do { \
1411     RECT format_rect; \
1412     int left_margin; \
1413     set_client_height(hwEdit, set_height); \
1414     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1415     left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
1416     edit_pos_ok(test_top, format_rect.top, vertical position); \
1417     edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1418     edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1419 } while(0)
1420
1421 static void test_text_position_style(DWORD style)
1422 {
1423     HWND hwEdit;
1424     HFONT font, oldFont;
1425     HDC dc;
1426     TEXTMETRIC metrics;
1427     INT b, bm, b2, b3;
1428     BOOL single_line = !(style & ES_MULTILINE);
1429
1430     b = GetSystemMetrics(SM_CYBORDER) + 1;
1431     b2 = 2 * b;
1432     b3 = 3 * b;
1433     bm = b2 - 1;
1434     
1435     /* Get a stock font for which we can determine the metrics */
1436     assert(font = GetStockObject(SYSTEM_FONT));
1437     assert(dc = GetDC(NULL));
1438     oldFont = SelectObject(dc, font);
1439     assert(GetTextMetrics(dc, &metrics));    
1440     SelectObject(dc, oldFont);
1441     ReleaseDC(NULL, dc);
1442     
1443     /* Windows' edit control has some bugs in multi-line mode:
1444      * - Sometimes the format rectangle doesn't get updated
1445      *   (see workaround in set_client_height())
1446      * - If the height of the control is smaller than the height of a text
1447      *   line, the format rectangle is still as high as a text line
1448      *   (higher than the client rectangle) and the caret is not shown
1449      */
1450     
1451     /* Edit controls that are in a parent window */
1452        
1453     hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
1454     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1455     if (single_line)
1456     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
1457     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
1458     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
1459     check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
1460     check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
1461     destroy_child_editcontrol(hwEdit);
1462
1463     hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
1464     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1465     if (single_line)
1466     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
1467     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
1468     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
1469     check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
1470     check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
1471     check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
1472     destroy_child_editcontrol(hwEdit);
1473
1474     hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
1475     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1476     if (single_line)
1477     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1478     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1479     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1480     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1481     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1482     destroy_child_editcontrol(hwEdit);
1483
1484     hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
1485     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1486     if (single_line)
1487     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1488     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1489     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1490     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1491     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1492     destroy_child_editcontrol(hwEdit);
1493
1494
1495     /* Edit controls that are popup windows */
1496     
1497     hwEdit = create_editcontrol(style | WS_POPUP, 0);
1498     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1499     if (single_line)
1500     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
1501     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
1502     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
1503     check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
1504     check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
1505     DestroyWindow(hwEdit);
1506
1507     hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
1508     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1509     if (single_line)
1510     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
1511     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
1512     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
1513     check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
1514     check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
1515     check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
1516     DestroyWindow(hwEdit);
1517
1518     hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
1519     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1520     if (single_line)
1521     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1522     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1523     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1524     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1525     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1526     DestroyWindow(hwEdit);
1527
1528     hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
1529     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1530     if (single_line)
1531     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1532     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1533     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1534     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1535     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1536     DestroyWindow(hwEdit);
1537 }
1538
1539 static void test_text_position(void)
1540 {
1541     trace("EDIT: Text position (Single line)\n");
1542     test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1543     trace("EDIT: Text position (Multi line)\n");
1544     test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1545 }
1546
1547 static void test_espassword(void)
1548 {
1549     HWND hwEdit;
1550     LONG r;
1551     char buffer[1024];
1552     const char* password = "secret";
1553
1554     hwEdit = create_editcontrol(ES_PASSWORD, 0);
1555     r = get_edit_style(hwEdit);
1556     ok(r == ES_PASSWORD, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD, r);
1557     /* set text */
1558     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
1559     ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
1560
1561     /* select all, cut (ctrl-x) */
1562     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1563     r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1564     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1565
1566     /* get text */
1567     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1568     ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
1569     ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
1570
1571     r = OpenClipboard(hwEdit);
1572     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1573     r = EmptyClipboard();
1574     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1575     r = CloseClipboard();
1576     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1577
1578     /* select all, copy (ctrl-c) and paste (ctrl-v) */
1579     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1580     r = SendMessage(hwEdit, WM_CHAR, 3, 0);
1581     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1582     r = SendMessage(hwEdit, WM_CHAR, 22, 0);
1583     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1584
1585     /* get text */
1586     buffer[0] = 0;
1587     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1588     ok(r == 0, "Expected: 0, got: %d\n", r);
1589     ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
1590
1591     DestroyWindow (hwEdit);
1592 }
1593
1594 static void test_undo(void)
1595 {
1596     HWND hwEdit;
1597     LONG r;
1598     DWORD cpMin, cpMax;
1599     char buffer[1024];
1600     const char* text = "undo this";
1601
1602     hwEdit = create_editcontrol(0, 0);
1603     r = get_edit_style(hwEdit);
1604     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1605
1606     /* set text */
1607     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
1608     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1609
1610     /* select all, */
1611     cpMin = cpMax = 0xdeadbeef;
1612     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1613     r = SendMessage(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
1614     ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
1615     ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
1616     ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
1617
1618     /* cut (ctrl-x) */
1619     r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1620     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1621
1622     /* get text */
1623     buffer[0] = 0;
1624     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1625     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1626     ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1627
1628     /* undo (ctrl-z) */
1629     r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1630     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1631
1632     /* get text */
1633     buffer[0] = 0;
1634     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1635     ok(strlen(text) == r, "Unexpected length %d\n", r);
1636     ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
1637
1638     /* undo again (ctrl-z) */
1639     r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1640     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1641
1642     /* get text */
1643     buffer[0] = 0;
1644     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1645     ok(r == 0, "Expected: %d, got len %d\n", 0, r);
1646     ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1647
1648     DestroyWindow (hwEdit);
1649 }
1650
1651 static void test_enter(void)
1652 {
1653     HWND hwEdit;
1654     LONG r;
1655     char buffer[16];
1656
1657     /* multiline */
1658     hwEdit = create_editcontrol(ES_MULTILINE, 0);
1659     r = get_edit_style(hwEdit);
1660     ok(ES_MULTILINE == r, "Wrong style expected 0x%x got: 0x%x\n", ES_MULTILINE, r);
1661
1662     /* set text */
1663     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1664     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1665
1666     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1667     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1668
1669     /* get text */
1670     buffer[0] = 0;
1671     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1672     ok(2 == r, "Expected: %d, got len %d\n", 2, r);
1673     ok(0 == strcmp(buffer, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer);
1674
1675     DestroyWindow (hwEdit);
1676
1677     /* single line */
1678     hwEdit = create_editcontrol(0, 0);
1679     r = get_edit_style(hwEdit);
1680     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1681
1682     /* set text */
1683     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1684     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1685
1686     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1687     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1688
1689     /* get text */
1690     buffer[0] = 0;
1691     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1692     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1693     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1694
1695     DestroyWindow (hwEdit);
1696
1697     /* single line with ES_WANTRETURN */
1698     hwEdit = create_editcontrol(ES_WANTRETURN, 0);
1699     r = get_edit_style(hwEdit);
1700     ok(ES_WANTRETURN == r, "Wrong style expected 0x%x got: 0x%x\n", ES_WANTRETURN, r);
1701
1702     /* set text */
1703     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1704     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1705
1706     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1707     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1708
1709     /* get text */
1710     buffer[0] = 0;
1711     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1712     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1713     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1714
1715     DestroyWindow (hwEdit);
1716 }
1717
1718 static void test_tab(void)
1719 {
1720     HWND hwEdit;
1721     LONG r;
1722     char buffer[16];
1723
1724     /* multiline */
1725     hwEdit = create_editcontrol(ES_MULTILINE, 0);
1726     r = get_edit_style(hwEdit);
1727     ok(ES_MULTILINE == r, "Wrong style expected 0x%x got: 0x%x\n", ES_MULTILINE, r);
1728
1729     /* set text */
1730     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1731     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1732
1733     r = SendMessage(hwEdit, WM_CHAR, VK_TAB, 0);
1734     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1735
1736     /* get text */
1737     buffer[0] = 0;
1738     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1739     ok(1 == r, "Expected: %d, got len %d\n", 1, r);
1740     ok(0 == strcmp(buffer, "\t"), "expected \"\\t\", got \"%s\"\n", buffer);
1741
1742     DestroyWindow (hwEdit);
1743
1744     /* single line */
1745     hwEdit = create_editcontrol(0, 0);
1746     r = get_edit_style(hwEdit);
1747     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1748
1749     /* set text */
1750     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1751     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1752
1753     r = SendMessage(hwEdit, WM_CHAR, VK_TAB, 0);
1754     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1755
1756     /* get text */
1757     buffer[0] = 0;
1758     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1759     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1760     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1761
1762     DestroyWindow (hwEdit);
1763 }
1764
1765 static void test_edit_dialog(void)
1766 {
1767     int r;
1768
1769     /* from bug 11841 */
1770     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 0);
1771     ok(333 == r, "Expected %d, got %d\n", 333, r);
1772     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 1);
1773     ok(111 == r, "Expected %d, got %d\n", 111, r);
1774     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 2);
1775     ok(444 == r, "Expected %d, got %d\n", 444, r);
1776
1777     /* more tests for WM_CHAR */
1778     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 3);
1779     ok(444 == r, "Expected %d, got %d\n", 444, r);
1780     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 4);
1781     ok(444 == r, "Expected %d, got %d\n", 444, r);
1782     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 5);
1783     ok(444 == r, "Expected %d, got %d\n", 444, r);
1784
1785     /* more tests for WM_KEYDOWN + WM_CHAR */
1786     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 6);
1787     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1788     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 7);
1789     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1790     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 8);
1791     ok(444 == r, "Expected %d, got %d\n", 444, r);
1792
1793     /* tests with an editable edit control */
1794     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 0);
1795     ok(333 == r, "Expected %d, got %d\n", 333, r);
1796     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 1);
1797     ok(111 == r, "Expected %d, got %d\n", 111, r);
1798     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 2);
1799     ok(444 == r, "Expected %d, got %d\n", 444, r);
1800
1801     /* tests for WM_CHAR */
1802     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 3);
1803     ok(444 == r, "Expected %d, got %d\n", 444, r);
1804     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 4);
1805     ok(444 == r, "Expected %d, got %d\n", 444, r);
1806     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 5);
1807     ok(444 == r, "Expected %d, got %d\n", 444, r);
1808
1809     /* tests for WM_KEYDOWN + WM_CHAR */
1810     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 6);
1811     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1812     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 7);
1813     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1814     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 8);
1815     ok(444 == r, "Expected %d, got %d\n", 444, r);
1816
1817     /* multiple tab tests */
1818     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 9);
1819     ok(22 == r, "Expected %d, got %d\n", 22, r);
1820     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 10);
1821     ok(33 == r, "Expected %d, got %d\n", 33, r);
1822 }
1823
1824 static void test_multi_edit_dialog(void)
1825 {
1826     int r;
1827
1828     /* test for multiple edit dialogs (bug 12319) */
1829     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 0);
1830     ok(2222 == r, "Expected %d, got %d\n", 2222, r);
1831     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 1);
1832     ok(1111 == r, "Expected %d, got %d\n", 1111, r);
1833     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 2);
1834     ok(2222 == r, "Expected %d, got %d\n", 2222, r);
1835     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 3);
1836     ok(11 == r, "Expected %d, got %d\n", 11, r);
1837 }
1838
1839 static void test_wantreturn_edit_dialog(void)
1840 {
1841     int r;
1842
1843     /* tests for WM_KEYDOWN */
1844     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 0);
1845     ok(333 == r, "Expected %d, got %d\n", 333, r);
1846     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 1);
1847     ok(444 == r, "Expected %d, got %d\n", 444, r);
1848     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 2);
1849     ok(444 == r, "Expected %d, got %d\n", 444, r);
1850
1851     /* tests for WM_CHAR */
1852     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 3);
1853     ok(444 == r, "Expected %d, got %d\n", 444, r);
1854     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 4);
1855     ok(444 == r, "Expected %d, got %d\n", 444, r);
1856     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 5);
1857     ok(444 == r, "Expected %d, got %d\n", 444, r);
1858
1859     /* tests for WM_KEYDOWN + WM_CHAR */
1860     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 6);
1861     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1862     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 7);
1863     ok(444 == r, "Expected %d, got %d\n", 444, r);
1864     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 8);
1865     ok(444 == r, "Expected %d, got %d\n", 444, r);
1866 }
1867
1868 static void test_singleline_wantreturn_edit_dialog(void)
1869 {
1870     int r;
1871
1872     /* tests for WM_KEYDOWN */
1873     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 0);
1874     ok(222 == r, "Expected %d, got %d\n", 222, r);
1875     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 1);
1876     ok(111 == r, "Expected %d, got %d\n", 111, r);
1877     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 2);
1878     ok(444 == r, "Expected %d, got %d\n", 444, r);
1879
1880     /* tests for WM_CHAR */
1881     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 3);
1882     ok(444 == r, "Expected %d, got %d\n", 444, r);
1883     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 4);
1884     ok(444 == r, "Expected %d, got %d\n", 444, r);
1885     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 5);
1886     ok(444 == r, "Expected %d, got %d\n", 444, r);
1887
1888     /* tests for WM_KEYDOWN + WM_CHAR */
1889     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 6);
1890     ok(222 == r, "Expected %d, got %d\n", 222, r);
1891     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 7);
1892     ok(111 == r, "Expected %d, got %d\n", 111, r);
1893     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 8);
1894     ok(444 == r, "Expected %d, got %d\n", 444, r);
1895
1896     /* tests for WM_KEYDOWN */
1897     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 0);
1898     ok(222 == r, "Expected %d, got %d\n", 222, r);
1899     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 1);
1900     ok(111 == r, "Expected %d, got %d\n", 111, r);
1901     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 2);
1902     ok(444 == r, "Expected %d, got %d\n", 444, r);
1903
1904     /* tests for WM_CHAR */
1905     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 3);
1906     ok(444 == r, "Expected %d, got %d\n", 444, r);
1907     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 4);
1908     ok(444 == r, "Expected %d, got %d\n", 444, r);
1909     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 5);
1910     ok(444 == r, "Expected %d, got %d\n", 444, r);
1911
1912     /* tests for WM_KEYDOWN + WM_CHAR */
1913     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 6);
1914     ok(222 == r, "Expected %d, got %d\n", 222, r);
1915     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 7);
1916     ok(111 == r, "Expected %d, got %d\n", 111, r);
1917     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 8);
1918     ok(444 == r, "Expected %d, got %d\n", 444, r);
1919 }
1920
1921 static int child_edit_wmkeydown_num_messages = 0;
1922 static INT_PTR CALLBACK child_edit_wmkeydown_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
1923 {
1924     switch (msg)
1925     {
1926         case WM_DESTROY:
1927         case WM_NCDESTROY:
1928             break;
1929
1930         default:
1931             child_edit_wmkeydown_num_messages++;
1932             break;
1933     }
1934
1935     return FALSE;
1936 }
1937
1938 static void test_child_edit_wmkeydown(void)
1939 {
1940     HWND hwEdit, hwParent;
1941     int r;
1942
1943     hwEdit = create_child_editcontrol(0, 0);
1944     hwParent = GetParent(hwEdit);
1945     SetWindowLongPtr(hwParent, GWLP_WNDPROC, (LONG_PTR)child_edit_wmkeydown_proc);
1946     r = SendMessage(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
1947     ok(1 == r, "expected 1, got %d\n", r);
1948     ok(0 == child_edit_wmkeydown_num_messages, "expected 0, got %d\n", child_edit_wmkeydown_num_messages);
1949     destroy_child_editcontrol(hwEdit);
1950 }
1951
1952 static BOOL RegisterWindowClasses (void)
1953 {
1954     WNDCLASSA test2;
1955     WNDCLASSA test3;
1956     WNDCLASSA text_position;
1957     
1958     test2.style = 0;
1959     test2.lpfnWndProc = ET2_WndProc;
1960     test2.cbClsExtra = 0;
1961     test2.cbWndExtra = 0;
1962     test2.hInstance = hinst;
1963     test2.hIcon = NULL;
1964     test2.hCursor = LoadCursorA (NULL, IDC_ARROW);
1965     test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1966     test2.lpszMenuName = NULL;
1967     test2.lpszClassName = szEditTest2Class;
1968     if (!RegisterClassA(&test2)) return FALSE;
1969
1970     test3.style = 0;
1971     test3.lpfnWndProc = edit3_wnd_procA;
1972     test3.cbClsExtra = 0;
1973     test3.cbWndExtra = 0;
1974     test3.hInstance = hinst;
1975     test3.hIcon = 0;
1976     test3.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1977     test3.hbrBackground = GetStockObject(WHITE_BRUSH);
1978     test3.lpszMenuName = NULL;
1979     test3.lpszClassName = szEditTest3Class;
1980     if (!RegisterClassA(&test3)) return FALSE;
1981
1982     text_position.style = CS_HREDRAW | CS_VREDRAW;
1983     text_position.cbClsExtra = 0;
1984     text_position.cbWndExtra = 0;
1985     text_position.hInstance = hinst;
1986     text_position.hIcon = NULL;
1987     text_position.hCursor = LoadCursorA(NULL, IDC_ARROW);
1988     text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1989     text_position.lpszMenuName = NULL;
1990     text_position.lpszClassName = szEditTextPositionClass;
1991     text_position.lpfnWndProc = DefWindowProc;
1992     if (!RegisterClassA(&text_position)) return FALSE;
1993
1994     return TRUE;
1995 }
1996
1997 static void UnregisterWindowClasses (void)
1998 {
1999     UnregisterClassA(szEditTest2Class, hinst);
2000     UnregisterClassA(szEditTest3Class, hinst);
2001     UnregisterClassA(szEditTextPositionClass, hinst);
2002 }
2003
2004 void test_fontsize(void)
2005 {
2006     HWND hwEdit;
2007     HFONT hfont;
2008     LOGFONT lf;
2009     LONG r;
2010     char szLocalString[MAXLEN];
2011
2012     memset(&lf,0,sizeof(LOGFONTA));
2013     strcpy(lf.lfFaceName,"Arial");
2014     lf.lfHeight = -300; /* taller than the edit box */
2015     lf.lfWeight = 500;
2016     hfont = CreateFontIndirect(&lf);
2017
2018     trace("EDIT: Oversized font (Multi line)\n");
2019     hwEdit= CreateWindow("EDIT", NULL, ES_MULTILINE|ES_AUTOHSCROLL,
2020                            0, 0, 150, 50, NULL, NULL, hinst, NULL);
2021
2022     SendMessage(hwEdit,WM_SETFONT,(WPARAM)hfont,0);
2023
2024     if (winetest_interactive)
2025         ShowWindow (hwEdit, SW_SHOW);
2026
2027     r = SendMessage(hwEdit, WM_CHAR, 'A', 1);
2028     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2029     r = SendMessage(hwEdit, WM_CHAR, 'B', 1);
2030     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2031     r = SendMessage(hwEdit, WM_CHAR, 'C', 1);
2032     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2033
2034     GetWindowText(hwEdit, szLocalString, MAXLEN);
2035     ok(lstrcmp(szLocalString, "ABC")==0,
2036        "Wrong contents of edit: %s\n", szLocalString);
2037
2038     r = SendMessage(hwEdit, EM_POSFROMCHAR,0,0);
2039     ok(r != -1,"EM_POSFROMCHAR failed index 0\n");
2040     r = SendMessage(hwEdit, EM_POSFROMCHAR,1,0);
2041     ok(r != -1,"EM_POSFROMCHAR failed index 1\n");
2042     r = SendMessage(hwEdit, EM_POSFROMCHAR,2,0);
2043     ok(r != -1,"EM_POSFROMCHAR failed index 2\n");
2044     r = SendMessage(hwEdit, EM_POSFROMCHAR,3,0);
2045     ok(r == -1,"EM_POSFROMCHAR succeeded index 3\n");
2046
2047     DestroyWindow (hwEdit);
2048     DeleteObject(hfont);
2049 }
2050
2051 START_TEST(edit)
2052 {
2053     hinst = GetModuleHandleA(NULL);
2054     assert(RegisterWindowClasses());
2055
2056     test_edit_control_1();
2057     test_edit_control_2();
2058     test_edit_control_3();
2059     test_edit_control_4();
2060     test_edit_control_5();
2061     test_edit_control_limittext();
2062     test_margins();
2063     test_margins_font_change();
2064     test_text_position();
2065     test_espassword();
2066     test_undo();
2067     test_enter();
2068     test_tab();
2069     test_edit_dialog();
2070     test_multi_edit_dialog();
2071     test_wantreturn_edit_dialog();
2072     test_singleline_wantreturn_edit_dialog();
2073     test_child_edit_wmkeydown();
2074     test_fontsize();
2075
2076     UnregisterWindowClasses();
2077 }