user32: Fix WM_CHAR return value for edit controls.
[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                     /* needed so the test does not wait for user input */
304                     PostMessage(hdlg, WM_USER, 0xfeedbeef, 0);
305                     break;
306                 case 2:
307                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
308                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
309                     break;
310
311                 /* test cases for WM_CHAR */
312                 case 3:
313                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
314                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
315                     break;
316                 case 4:
317                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
318                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
319                     break;
320                 case 5:
321                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
322                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
323                     break;
324
325                 /* test cases for WM_KEYDOWN + WM_CHAR */
326                 case 6:
327                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
328                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
329                     break;
330                 case 7:
331                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
332                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
333                     /* needed so the test does not wait for user input */
334                     PostMessage(hdlg, WM_USER, 0xfeedbeef, 0);
335                     break;
336                 case 8:
337                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
338                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
339                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
340                     break;
341
342                 default:
343                     break;
344             }
345             break;
346         }
347
348         case WM_COMMAND:
349             if (HIWORD(wparam) != BN_CLICKED)
350                 break;
351
352             switch (LOWORD(wparam))
353             {
354                 case IDOK:
355                     EndDialog(hdlg, 111);
356                     break;
357
358                 case IDCANCEL:
359                     EndDialog(hdlg, 222);
360                     break;
361
362                 default:
363                     break;
364             }
365             break;
366
367         case WM_USER:
368         {
369             HWND hok = GetDlgItem(hdlg, IDOK);
370             HWND hedit = GetDlgItem(hdlg, 1000);
371             HWND hfocus = GetFocus();
372             int len = SendMessage(hedit, WM_GETTEXTLENGTH, 0, 0);
373
374             if (wparam == 0xfeedbeef)
375             {
376                 EndDialog(hdlg, 66);
377                 break;
378             }
379             if (wparam != 0xdeadbeef)
380                 break;
381
382             switch (lparam)
383             {
384                 case 0:
385                     if ((hfocus == hedit) && len == 0)
386                         EndDialog(hdlg, 444);
387                     else
388                         EndDialog(hdlg, 555);
389                     break;
390
391                 case 1:
392                     if ((hfocus == hok) && len == 0)
393                         EndDialog(hdlg, 444);
394                     else
395                         EndDialog(hdlg, 555);
396                     break;
397
398                 default:
399                     EndDialog(hdlg, 55);
400             }
401             break;
402         }
403
404         case WM_CLOSE:
405             EndDialog(hdlg, 333);
406             break;
407
408         default:
409             break;
410     }
411
412     return FALSE;
413 }
414
415 static INT_PTR CALLBACK edit_wantreturn_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
416 {
417     switch (msg)
418     {
419         case WM_INITDIALOG:
420         {
421             HWND hedit = GetDlgItem(hdlg, 1000);
422             SetFocus(hedit);
423             switch (lparam)
424             {
425                 /* test cases for WM_KEYDOWN */
426                 case 0:
427                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
428                     break;
429                 case 1:
430                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
431                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
432                     break;
433                 case 2:
434                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
435                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
436                     break;
437
438                 /* test cases for WM_CHAR */
439                 case 3:
440                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
441                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
442                     break;
443                 case 4:
444                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
445                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 2);
446                     break;
447                 case 5:
448                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
449                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
450                     break;
451
452                 /* test cases for WM_KEYDOWN + WM_CHAR */
453                 case 6:
454                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
455                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
456                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
457                     break;
458                 case 7:
459                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
460                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
461                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 2);
462                     break;
463                 case 8:
464                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
465                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
466                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
467                     break;
468
469                 default:
470                     break;
471             }
472             break;
473         }
474
475         case WM_COMMAND:
476             if (HIWORD(wparam) != BN_CLICKED)
477                 break;
478
479             switch (LOWORD(wparam))
480             {
481                 case IDOK:
482                     EndDialog(hdlg, 111);
483                     break;
484
485                 case IDCANCEL:
486                     EndDialog(hdlg, 222);
487                     break;
488
489                 default:
490                     break;
491             }
492             break;
493
494         case WM_USER:
495         {
496             HWND hok = GetDlgItem(hdlg, IDOK);
497             HWND hedit = GetDlgItem(hdlg, 1000);
498             HWND hfocus = GetFocus();
499             int len = SendMessage(hedit, WM_GETTEXTLENGTH, 0, 0);
500
501             if (wparam != 0xdeadbeef)
502                 break;
503
504             switch (lparam)
505             {
506                 case 0:
507                     if ((hfocus == hedit) && len == 0)
508                         EndDialog(hdlg, 444);
509                     else
510                         EndDialog(hdlg, 555);
511                     break;
512
513                 case 1:
514                     if ((hfocus == hok) && len == 0)
515                         EndDialog(hdlg, 444);
516                     else
517                         EndDialog(hdlg, 555);
518                     break;
519
520                 case 2:
521                     if ((hfocus == hedit) && len == 2)
522                         EndDialog(hdlg, 444);
523                     else
524                         EndDialog(hdlg, 555);
525                     break;
526
527                 default:
528                     EndDialog(hdlg, 55);
529             }
530             break;
531         }
532
533         case WM_CLOSE:
534             EndDialog(hdlg, 333);
535             break;
536
537         default:
538             break;
539     }
540
541     return FALSE;
542 }
543
544 static HINSTANCE hinst;
545 static HWND hwndET2;
546 static const char szEditTest2Class[] = "EditTest2Class";
547 static const char szEditTest3Class[] = "EditTest3Class";
548 static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
549
550 static HWND create_editcontrol (DWORD style, DWORD exstyle)
551 {
552     HWND handle;
553
554     handle = CreateWindowEx(exstyle,
555                           "EDIT",
556                           "Test Text",
557                           style,
558                           10, 10, 300, 300,
559                           NULL, NULL, hinst, NULL);
560     assert (handle);
561     if (winetest_interactive)
562         ShowWindow (handle, SW_SHOW);
563     return handle;
564 }
565
566 static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
567 {
568     HWND parentWnd;
569     HWND editWnd;
570     RECT rect;
571     
572     rect.left = 0;
573     rect.top = 0;
574     rect.right = 300;
575     rect.bottom = 300;
576     assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
577     
578     parentWnd = CreateWindowEx(0,
579                             szEditTextPositionClass,
580                             "Edit Test",
581                             WS_OVERLAPPEDWINDOW,
582                             CW_USEDEFAULT, CW_USEDEFAULT,
583                             rect.right - rect.left, rect.bottom - rect.top,
584                             NULL, NULL, hinst, NULL);
585     assert(parentWnd);
586
587     editWnd = CreateWindowEx(exstyle,
588                             "EDIT",
589                             "Test Text",
590                             WS_CHILD | style,
591                             0, 0, 300, 300,
592                             parentWnd, NULL, hinst, NULL);
593     assert(editWnd);
594     if (winetest_interactive)
595         ShowWindow (parentWnd, SW_SHOW);
596     return editWnd;
597 }
598
599 static void destroy_child_editcontrol (HWND hwndEdit)
600 {
601     if (GetParent(hwndEdit))
602         DestroyWindow(GetParent(hwndEdit));
603     else {
604         trace("Edit control has no parent!\n");
605         DestroyWindow(hwndEdit);
606     }
607 }
608
609 static LONG get_edit_style (HWND hwnd)
610 {
611     return GetWindowLongA( hwnd, GWL_STYLE ) & (
612         ES_LEFT |
613 /* FIXME: not implemented
614         ES_CENTER |
615         ES_RIGHT |
616         ES_OEMCONVERT |
617 */
618         ES_MULTILINE |
619         ES_UPPERCASE |
620         ES_LOWERCASE |
621         ES_PASSWORD |
622         ES_AUTOVSCROLL |
623         ES_AUTOHSCROLL |
624         ES_NOHIDESEL |
625         ES_COMBO |
626         ES_READONLY |
627         ES_WANTRETURN |
628         ES_NUMBER
629         );
630 }
631
632 static void set_client_height(HWND Wnd, unsigned Height)
633 {
634     RECT ClientRect, WindowRect;
635
636     GetWindowRect(Wnd, &WindowRect);
637     GetClientRect(Wnd, &ClientRect);
638     SetWindowPos(Wnd, NULL, 0, 0,
639                  WindowRect.right - WindowRect.left,
640                  Height + (WindowRect.bottom - WindowRect.top) -
641                  (ClientRect.bottom - ClientRect.top),
642                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
643
644     /* Workaround for a bug in Windows' edit control
645        (multi-line mode) */
646     GetWindowRect(Wnd, &WindowRect);             
647     SetWindowPos(Wnd, NULL, 0, 0,
648                  WindowRect.right - WindowRect.left + 1,
649                  WindowRect.bottom - WindowRect.top + 1,
650                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
651     SetWindowPos(Wnd, NULL, 0, 0,
652                  WindowRect.right - WindowRect.left,
653                  WindowRect.bottom - WindowRect.top,
654                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
655
656     GetClientRect(Wnd, &ClientRect);
657     ok(ClientRect.bottom - ClientRect.top == Height,
658         "The client height should be %ld, but is %ld\n",
659         (long)Height, (long)(ClientRect.bottom - ClientRect.top));
660 }
661
662 static void test_edit_control_1(void)
663 {
664     HWND hwEdit;
665     MSG msMessage;
666     int i;
667     LONG r;
668
669     msMessage.message = WM_KEYDOWN;
670
671     trace("EDIT: Single line\n");
672     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
673     r = get_edit_style(hwEdit);
674     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%x\n", r);
675     for (i=0;i<65535;i++)
676     {
677         msMessage.wParam = i;
678         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
679         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
680             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
681     }
682     DestroyWindow (hwEdit);
683
684     trace("EDIT: Single line want returns\n");
685     hwEdit = create_editcontrol(ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
686     r = get_edit_style(hwEdit);
687     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%x\n", r);
688     for (i=0;i<65535;i++)
689     {
690         msMessage.wParam = i;
691         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
692         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
693             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
694     }
695     DestroyWindow (hwEdit);
696
697     trace("EDIT: Multiline line\n");
698     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
699     r = get_edit_style(hwEdit);
700     ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%x\n", r);
701     for (i=0;i<65535;i++)
702     {
703         msMessage.wParam = i;
704         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
705         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
706             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
707     }
708     DestroyWindow (hwEdit);
709
710     trace("EDIT: Multi line want returns\n");
711     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
712     r = get_edit_style(hwEdit);
713     ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%x\n", r);
714     for (i=0;i<65535;i++)
715     {
716         msMessage.wParam = i;
717         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
718         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
719             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
720     }
721     DestroyWindow (hwEdit);
722 }
723
724 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
725  * selection.  This test checks that the first 'select all' doesn't generate
726  * an UPDATE message which can escape and (via a handler) change the
727  * selection, which would cause WM_SETTEXT to break.  This old bug
728  * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
729  */
730 static void test_edit_control_2(void)
731 {
732     HWND hwndMain;
733     char szLocalString[MAXLEN];
734     LONG r;
735
736     /* Create main and edit windows. */
737     hwndMain = CreateWindow(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW,
738                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
739     assert(hwndMain);
740     if (winetest_interactive)
741         ShowWindow (hwndMain, SW_SHOW);
742
743     hwndET2 = CreateWindow("EDIT", NULL,
744                            WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
745                            0, 0, 150, 50, /* important this not be 0 size. */
746                            hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
747     assert(hwndET2);
748     if (winetest_interactive)
749         ShowWindow (hwndET2, SW_SHOW);
750
751     trace("EDIT: SETTEXT atomicity\n");
752     /* Send messages to "type" in the word 'foo'. */
753     r = SendMessage(hwndET2, WM_CHAR, 'f', 1);
754     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
755     r = SendMessage(hwndET2, WM_CHAR, 'o', 1);
756     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
757     r = SendMessage(hwndET2, WM_CHAR, 'o', 1);
758     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
759     /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
760     GetWindowText(hwndET2, szLocalString, MAXLEN);
761     ok(lstrcmp(szLocalString, "bar")==0,
762        "Wrong contents of edit: %s\n", szLocalString);
763
764     /* OK, done! */
765     DestroyWindow (hwndET2);
766     DestroyWindow (hwndMain);
767 }
768
769 static void ET2_check_change(void) {
770    char szLocalString[MAXLEN];
771    /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
772    GetWindowText(hwndET2, szLocalString, MAXLEN);
773    if (lstrcmp(szLocalString, "foo")==0) {
774        lstrcpy(szLocalString, "bar");
775        SendMessage(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
776    }
777    /* always leave the cursor at the end. */
778    SendMessage(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
779 }
780 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
781 {
782     if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
783         ET2_check_change();
784 }
785 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
786 {
787     switch (iMsg) {
788     case WM_COMMAND:
789         ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
790         break;
791     }
792     return DefWindowProc(hwnd, iMsg, wParam, lParam);
793 }
794
795 static void zero_notify(void)
796 {
797     notifications.en_change = 0;
798     notifications.en_maxtext = 0;
799     notifications.en_update = 0;
800 }
801
802 #define test_notify(enchange, enmaxtext, enupdate) \
803     ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
804     "got %d\n", enchange, notifications.en_change); \
805     ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
806     "got %d\n", enmaxtext, notifications.en_maxtext); \
807     ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
808     "got %d\n", enupdate, notifications.en_update)
809
810
811 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
812 {
813     switch (msg) {
814         case WM_COMMAND:
815             switch (HIWORD(wParam)) {
816                 case EN_MAXTEXT:
817                     notifications.en_maxtext++;
818                     break;
819                 case EN_UPDATE:
820                     notifications.en_update++;
821                     break;
822                 case EN_CHANGE:
823                     notifications.en_change++;
824                     break;
825             }
826             break;
827     }
828     return DefWindowProcA(hWnd, msg, wParam, lParam);
829 }
830
831 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
832  * to these messages.
833  */
834 static void test_edit_control_3(void)
835 {
836     HWND hWnd;
837     HWND hParent;
838     int len;
839     static const char *str = "this is a long string.";
840     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.";
841
842     trace("EDIT: Test notifications\n");
843
844     hParent = CreateWindowExA(0,
845               szEditTest3Class,
846               NULL,
847               0,
848               CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
849               NULL, NULL, NULL, NULL);
850     assert(hParent);
851
852     trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
853     hWnd = CreateWindowExA(0,
854               "EDIT",
855               NULL,
856               0,
857               10, 10, 50, 50,
858               hParent, NULL, NULL, NULL);
859     assert(hWnd);
860
861     zero_notify();
862     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
863     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
864     ok(lstrlenA(str) > len, "text should have been truncated\n");
865     test_notify(1, 1, 1);
866
867     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
868     zero_notify();
869     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
870     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
871     ok(1 == len, "wrong text length, expected 1, got %d\n", len);
872     test_notify(1, 0, 1);
873
874     zero_notify();
875     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
876     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
877     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
878     test_notify(1, 0, 1);
879
880     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
881
882     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
883     zero_notify();
884     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
885     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
886     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
887     test_notify(1, 1, 1);
888
889     zero_notify();
890     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
891     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
892     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
893     test_notify(1, 0, 1);
894
895     DestroyWindow(hWnd);
896
897     trace("EDIT: Single line, ES_AUTOHSCROLL\n");
898     hWnd = CreateWindowExA(0,
899               "EDIT",
900               NULL,
901               ES_AUTOHSCROLL,
902               10, 10, 50, 50,
903               hParent, NULL, NULL, NULL);
904     assert(hWnd);
905
906     zero_notify();
907     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
908     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
909     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
910     test_notify(1, 0, 1);
911
912     zero_notify();
913     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
914     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
915     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
916     test_notify(1, 0, 1);
917
918     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
919
920     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
921     zero_notify();
922     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
923     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
924     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
925     test_notify(1, 1, 1);
926
927     zero_notify();
928     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
929     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
930     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
931     test_notify(1, 0, 1);
932
933     DestroyWindow(hWnd);
934
935     trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
936     hWnd = CreateWindowExA(0,
937               "EDIT",
938               NULL,
939               ES_MULTILINE,
940               10, 10, 50, 50,
941               hParent, NULL, NULL, NULL);
942     assert(hWnd);
943
944     zero_notify();
945     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
946     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
947     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
948     test_notify(1, 1, 1);
949
950     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
951     zero_notify();
952     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
953     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
954     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
955     test_notify(1, 0, 1);
956
957     zero_notify();
958     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
959     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
960     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
961     test_notify(0, 0, 0);
962
963     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
964
965     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
966     zero_notify();
967     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
968     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
969     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
970     test_notify(1, 1, 1);
971
972     zero_notify();
973     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
974     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
975     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
976     test_notify(0, 0, 0);
977
978     DestroyWindow(hWnd);
979
980     trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
981     hWnd = CreateWindowExA(0,
982               "EDIT",
983               NULL,
984               ES_MULTILINE | ES_AUTOHSCROLL,
985               10, 10, 50, 50,
986               hParent, NULL, NULL, NULL);
987     assert(hWnd);
988
989     zero_notify();
990     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
991     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
992     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
993     test_notify(1, 1, 1);
994
995     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
996     zero_notify();
997     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
998     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
999     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1000     test_notify(1, 0, 1);
1001
1002     zero_notify();
1003     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1004     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1005     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1006     test_notify(0, 0, 0);
1007
1008     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1009
1010     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1011     zero_notify();
1012     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1013     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1014     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1015     test_notify(1, 1, 1);
1016
1017     zero_notify();
1018     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1019     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1020     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1021     test_notify(0, 0, 0);
1022
1023     DestroyWindow(hWnd);
1024
1025     trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1026     hWnd = CreateWindowExA(0,
1027               "EDIT",
1028               NULL,
1029               ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
1030               10, 10, 50, 50,
1031               hParent, NULL, NULL, NULL);
1032     assert(hWnd);
1033
1034     zero_notify();
1035     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1036     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1037     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1038     test_notify(1, 0, 1);
1039
1040     zero_notify();
1041     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1042     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1043     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1044     test_notify(0, 0, 0);
1045
1046     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1047
1048     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1049     zero_notify();
1050     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1051     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1052     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1053     test_notify(1, 1, 1);
1054
1055     zero_notify();
1056     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1057     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1058     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1059     test_notify(0, 0, 0);
1060
1061     DestroyWindow(hWnd);
1062 }
1063
1064 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
1065  */
1066 static void test_edit_control_4(void)
1067 {
1068     HWND hwEdit;
1069     int lo, hi, mid;
1070     int ret;
1071     int i;
1072
1073     trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
1074     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1075     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1076     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1077     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1078     mid = lo + (hi - lo) / 2;
1079
1080     for (i = lo; i < mid; i++) {
1081        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1082        ok(0 == ret, "expected 0 got %d\n", ret);
1083     }
1084     for (i = mid; i <= hi; i++) {
1085        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1086        ok(1 == ret, "expected 1 got %d\n", ret);
1087     }
1088     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1089     ok(-1 == ret, "expected -1 got %d\n", ret);
1090     DestroyWindow(hwEdit);
1091
1092     hwEdit = create_editcontrol(ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1093     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1094     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1095     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1096     mid = lo + (hi - lo) / 2;
1097
1098     for (i = lo; i < mid; i++) {
1099        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1100        ok(0 == ret, "expected 0 got %d\n", ret);
1101     }
1102     for (i = mid; i <= hi; i++) {
1103        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1104        ok(1 == ret, "expected 1 got %d\n", ret);
1105     }
1106     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1107     ok(-1 == ret, "expected -1 got %d\n", ret);
1108     DestroyWindow(hwEdit);
1109
1110     hwEdit = create_editcontrol(ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1111     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1112     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1113     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1114     mid = lo + (hi - lo) / 2;
1115
1116     for (i = lo; i < mid; i++) {
1117        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1118        ok(0 == ret, "expected 0 got %d\n", ret);
1119     }
1120     for (i = mid; i <= hi; i++) {
1121        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1122        ok(1 == ret, "expected 1 got %d\n", ret);
1123     }
1124     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1125     ok(-1 == ret, "expected -1 got %d\n", ret);
1126     DestroyWindow(hwEdit);
1127
1128     hwEdit = create_editcontrol(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1129     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1130     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1131     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1132     mid = lo + (hi - lo) / 2 +1;
1133
1134     for (i = lo; i < mid; i++) {
1135        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1136        ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1137     }
1138     for (i = mid; i <= hi; i++) {
1139        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1140        ok(1 == ret, "expected 1 got %d\n", ret);
1141     }
1142     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1143     ok(-1 == ret, "expected -1 got %d\n", ret);
1144     DestroyWindow(hwEdit);
1145
1146     hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1147     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1148     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1149     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1150     mid = lo + (hi - lo) / 2 +1;
1151
1152     for (i = lo; i < mid; i++) {
1153        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1154        ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1155     }
1156     for (i = mid; i <= hi; i++) {
1157        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1158        ok(1 == ret, "expected 1 got %d\n", ret);
1159     }
1160     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1161     ok(-1 == ret, "expected -1 got %d\n", ret);
1162     DestroyWindow(hwEdit);
1163
1164     hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1165     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1166     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1167     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1168     mid = lo + (hi - lo) / 2 +1;
1169
1170     for (i = lo; i < mid; i++) {
1171        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1172        ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1173     }
1174     for (i = mid; i <= hi; i++) {
1175        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, (LPARAM) i));
1176        ok(1 == ret, "expected 1 got %d\n", ret);
1177     }
1178     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1179     ok(-1 == ret, "expected -1 got %d\n", ret);
1180     DestroyWindow(hwEdit);
1181 }
1182
1183 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1184  * truncates text that doesn't fit.
1185  */
1186 static void test_edit_control_5(void)
1187 {
1188     static const char *str = "test\r\ntest";
1189     HWND hWnd;
1190     int len;
1191
1192     hWnd = CreateWindowEx(0,
1193               "EDIT",
1194               str,
1195               0,
1196               10, 10, 1, 1,
1197               NULL, NULL, NULL, NULL);
1198     assert(hWnd);
1199
1200     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1201     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1202     DestroyWindow(hWnd);
1203
1204     hWnd = CreateWindowEx(0,
1205               "EDIT",
1206               str,
1207               ES_MULTILINE,
1208               10, 10, 1, 1,
1209               NULL, NULL, NULL, NULL);
1210     assert(hWnd);
1211
1212     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1213     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1214     DestroyWindow(hWnd);
1215 }
1216
1217 static void test_edit_control_limittext(void)
1218 {
1219     HWND hwEdit;
1220     DWORD r;
1221
1222     /* Test default limit for single-line control */
1223     trace("EDIT: buffer limit for single-line\n");
1224     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1225     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1226     ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1227     SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
1228     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1229     /* Win9x+ME: 32766; WinNT: 2147483646UL */
1230     ok( (r == 32766) || (r == 2147483646UL),
1231         "got limit %u (expected 32766 or 2147483646)\n", r);
1232     DestroyWindow(hwEdit);
1233
1234     /* Test default limit for multi-line control */
1235     trace("EDIT: buffer limit for multi-line\n");
1236     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1237     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1238     ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1239     SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
1240     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1241     /* Win9x+ME: 65535; WinNT: 4294967295UL */
1242     ok( (r == 65535) || (r == 4294967295UL),
1243         "got limit %u (expected 65535 or 4294967295)\n", r);
1244     DestroyWindow(hwEdit);
1245 }
1246
1247 static void test_margins(void)
1248 {
1249     HWND hwEdit;
1250     RECT old_rect, new_rect;
1251     INT old_left_margin, old_right_margin;
1252     DWORD old_margins, new_margins;
1253
1254     hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1255     
1256     old_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1257     old_left_margin = LOWORD(old_margins);
1258     old_right_margin = HIWORD(old_margins);
1259     
1260     /* Check if setting the margins works */
1261     
1262     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
1263     new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1264     ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1265     ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
1266     
1267     SendMessage(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
1268     new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1269     ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1270     ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
1271     
1272     
1273     /* The size of the rectangle must decrease if we increase the margin */
1274     
1275     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
1276     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1277     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
1278     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1279     ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
1280     ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
1281     ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
1282     ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
1283     
1284     
1285     /* If we set the margin to same value as the current margin,
1286        the rectangle must not change */
1287     
1288     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1289     old_rect.left = 1;
1290     old_rect.right = 99;
1291     old_rect.top = 1;
1292     old_rect.bottom = 99;
1293     SendMessage(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);    
1294     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1295     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1296     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1297     ok(new_rect.left == old_rect.left, "The left border of the rectangle has changed\n");
1298     ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n");
1299     ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n");
1300     ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n");
1301
1302     DestroyWindow (hwEdit);
1303 }
1304
1305 static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
1306 {
1307     return 0;
1308 }
1309
1310 static void test_margins_font_change(void)
1311 {
1312     HWND hwEdit;
1313     DWORD margins, font_margins;
1314     LOGFONT lf;
1315     HFONT hfont, hfont2;
1316     HDC hdc = GetDC(0);
1317
1318     if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
1319     {
1320         trace("Arial not found - skipping font change margin tests\n");
1321         ReleaseDC(0, hdc);
1322         return;
1323     }
1324     ReleaseDC(0, hdc);
1325
1326     hwEdit = create_child_editcontrol(0, 0);
1327
1328     SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1329
1330     memset(&lf, 0, sizeof(lf));
1331     strcpy(lf.lfFaceName, "Arial");
1332     lf.lfHeight = 16;
1333     lf.lfCharSet = DEFAULT_CHARSET;
1334     hfont = CreateFontIndirectA(&lf);
1335     lf.lfHeight = 30;
1336     hfont2 = CreateFontIndirectA(&lf);
1337
1338     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1339     font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1340     ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
1341     ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
1342
1343     /* With 'small' edit controls, test that the margin doesn't get set */
1344     SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1345     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
1346     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1347     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1348     ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins));
1349     ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
1350  
1351     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1352     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1353     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1354     ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1355     ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));  
1356
1357     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1358     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1359     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1360     ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1361     ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));  
1362
1363     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1364     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1365     ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1366     ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); 
1367     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1368     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1369     ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1370     ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); 
1371  
1372     /* Above a certain size threshold then the margin is updated */
1373     SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1374     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1375     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1376     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1377     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1378     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1379
1380     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1381     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1382     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1383     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1384     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1385
1386     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1387     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1388     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1389     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1390     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1391     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1392     ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins));
1393     ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1394
1395     SendMessageA(hwEdit, WM_SETFONT, 0, 0);
1396     
1397     DeleteObject(hfont2);
1398     DeleteObject(hfont);
1399     destroy_child_editcontrol(hwEdit);
1400
1401 }
1402
1403 #define edit_pos_ok(exp, got, txt) \
1404     ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1405
1406 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1407 do { \
1408     RECT format_rect; \
1409     int left_margin; \
1410     set_client_height(hwEdit, set_height); \
1411     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1412     left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
1413     edit_pos_ok(test_top, format_rect.top, vertical position); \
1414     edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1415     edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1416 } while(0)
1417
1418 static void test_text_position_style(DWORD style)
1419 {
1420     HWND hwEdit;
1421     HFONT font, oldFont;
1422     HDC dc;
1423     TEXTMETRIC metrics;
1424     INT b, bm, b2, b3;
1425     BOOL single_line = !(style & ES_MULTILINE);
1426
1427     b = GetSystemMetrics(SM_CYBORDER) + 1;
1428     b2 = 2 * b;
1429     b3 = 3 * b;
1430     bm = b2 - 1;
1431     
1432     /* Get a stock font for which we can determine the metrics */
1433     assert(font = GetStockObject(SYSTEM_FONT));
1434     assert(dc = GetDC(NULL));
1435     oldFont = SelectObject(dc, font);
1436     assert(GetTextMetrics(dc, &metrics));    
1437     SelectObject(dc, oldFont);
1438     ReleaseDC(NULL, dc);
1439     
1440     /* Windows' edit control has some bugs in multi-line mode:
1441      * - Sometimes the format rectangle doesn't get updated
1442      *   (see workaround in set_client_height())
1443      * - If the height of the control is smaller than the height of a text
1444      *   line, the format rectangle is still as high as a text line
1445      *   (higher than the client rectangle) and the caret is not shown
1446      */
1447     
1448     /* Edit controls that are in a parent window */
1449        
1450     hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
1451     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1452     if (single_line)
1453     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
1454     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
1455     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
1456     check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
1457     check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
1458     destroy_child_editcontrol(hwEdit);
1459
1460     hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
1461     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1462     if (single_line)
1463     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
1464     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
1465     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
1466     check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
1467     check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
1468     check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
1469     destroy_child_editcontrol(hwEdit);
1470
1471     hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
1472     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1473     if (single_line)
1474     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1475     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1476     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1477     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1478     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1479     destroy_child_editcontrol(hwEdit);
1480
1481     hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
1482     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1483     if (single_line)
1484     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1485     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1486     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1487     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1488     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1489     destroy_child_editcontrol(hwEdit);
1490
1491
1492     /* Edit controls that are popup windows */
1493     
1494     hwEdit = create_editcontrol(style | WS_POPUP, 0);
1495     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1496     if (single_line)
1497     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
1498     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
1499     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
1500     check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
1501     check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
1502     DestroyWindow(hwEdit);
1503
1504     hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
1505     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1506     if (single_line)
1507     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
1508     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
1509     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
1510     check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
1511     check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
1512     check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
1513     DestroyWindow(hwEdit);
1514
1515     hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
1516     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1517     if (single_line)
1518     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1519     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1520     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1521     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1522     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1523     DestroyWindow(hwEdit);
1524
1525     hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
1526     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE);
1527     if (single_line)
1528     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1529     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1530     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1531     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1532     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1533     DestroyWindow(hwEdit);
1534 }
1535
1536 static void test_text_position(void)
1537 {
1538     trace("EDIT: Text position (Single line)\n");
1539     test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1540     trace("EDIT: Text position (Multi line)\n");
1541     test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1542 }
1543
1544 static void test_espassword(void)
1545 {
1546     HWND hwEdit;
1547     LONG r;
1548     char buffer[1024];
1549     const char* password = "secret";
1550
1551     hwEdit = create_editcontrol(ES_PASSWORD, 0);
1552     r = get_edit_style(hwEdit);
1553     ok(r == ES_PASSWORD, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD, r);
1554     /* set text */
1555     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
1556     ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
1557
1558     /* select all, cut (ctrl-x) */
1559     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1560     r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1561     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1562
1563     /* get text */
1564     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1565     ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
1566     ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
1567
1568     r = OpenClipboard(hwEdit);
1569     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1570     r = EmptyClipboard();
1571     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1572     r = CloseClipboard();
1573     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1574
1575     /* select all, copy (ctrl-c) and paste (ctrl-v) */
1576     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1577     r = SendMessage(hwEdit, WM_CHAR, 3, 0);
1578     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1579     r = SendMessage(hwEdit, WM_CHAR, 22, 0);
1580     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1581
1582     /* get text */
1583     buffer[0] = 0;
1584     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1585     ok(r == 0, "Expected: 0, got: %d\n", r);
1586     ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
1587
1588     DestroyWindow (hwEdit);
1589 }
1590
1591 static void test_undo(void)
1592 {
1593     HWND hwEdit;
1594     LONG r;
1595     DWORD cpMin, cpMax;
1596     char buffer[1024];
1597     const char* text = "undo this";
1598
1599     hwEdit = create_editcontrol(0, 0);
1600     r = get_edit_style(hwEdit);
1601     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1602
1603     /* set text */
1604     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
1605     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1606
1607     /* select all, */
1608     cpMin = cpMax = 0xdeadbeef;
1609     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1610     r = SendMessage(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
1611     ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
1612     ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
1613     ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
1614
1615     /* cut (ctrl-x) */
1616     r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1617     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1618
1619     /* get text */
1620     buffer[0] = 0;
1621     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1622     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1623     ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1624
1625     /* undo (ctrl-z) */
1626     r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1627     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1628
1629     /* get text */
1630     buffer[0] = 0;
1631     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1632     ok(strlen(text) == r, "Unexpected length %d\n", r);
1633     ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
1634
1635     /* undo again (ctrl-z) */
1636     r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1637     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1638
1639     /* get text */
1640     buffer[0] = 0;
1641     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1642     ok(r == 0, "Expected: %d, got len %d\n", 0, r);
1643     ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1644
1645     DestroyWindow (hwEdit);
1646 }
1647
1648 static void test_enter(void)
1649 {
1650     HWND hwEdit;
1651     LONG r;
1652     char buffer[16];
1653
1654     /* multiline */
1655     hwEdit = create_editcontrol(ES_MULTILINE, 0);
1656     r = get_edit_style(hwEdit);
1657     ok(ES_MULTILINE == r, "Wrong style expected 0x%x got: 0x%x\n", ES_MULTILINE, r);
1658
1659     /* set text */
1660     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1661     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1662
1663     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1664     todo_wine ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1665
1666     /* get text */
1667     buffer[0] = 0;
1668     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1669     todo_wine {
1670     ok(2 == r, "Expected: %d, got len %d\n", 2, r);
1671     ok(0 == strcmp(buffer, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer);
1672     }
1673
1674     DestroyWindow (hwEdit);
1675
1676     /* single line */
1677     hwEdit = create_editcontrol(0, 0);
1678     r = get_edit_style(hwEdit);
1679     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1680
1681     /* set text */
1682     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1683     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1684
1685     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1686     todo_wine ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1687
1688     /* get text */
1689     buffer[0] = 0;
1690     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1691     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1692     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1693
1694     DestroyWindow (hwEdit);
1695
1696     /* single line with ES_WANTRETURN */
1697     hwEdit = create_editcontrol(ES_WANTRETURN, 0);
1698     r = get_edit_style(hwEdit);
1699     ok(ES_WANTRETURN == r, "Wrong style expected 0x%x got: 0x%x\n", ES_WANTRETURN, r);
1700
1701     /* set text */
1702     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1703     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1704
1705     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1706     todo_wine ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1707
1708     /* get text */
1709     buffer[0] = 0;
1710     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1711     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1712     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1713
1714     DestroyWindow (hwEdit);
1715 }
1716
1717 static void test_tab(void)
1718 {
1719     HWND hwEdit;
1720     LONG r;
1721     char buffer[16];
1722
1723     /* multiline */
1724     hwEdit = create_editcontrol(ES_MULTILINE, 0);
1725     r = get_edit_style(hwEdit);
1726     ok(ES_MULTILINE == r, "Wrong style expected 0x%x got: 0x%x\n", ES_MULTILINE, r);
1727
1728     /* set text */
1729     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1730     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1731
1732     r = SendMessage(hwEdit, WM_CHAR, VK_TAB, 0);
1733     todo_wine ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1734
1735     /* get text */
1736     buffer[0] = 0;
1737     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1738     todo_wine {
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
1743     DestroyWindow (hwEdit);
1744
1745     /* single line */
1746     hwEdit = create_editcontrol(0, 0);
1747     r = get_edit_style(hwEdit);
1748     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1749
1750     /* set text */
1751     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1752     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1753
1754     r = SendMessage(hwEdit, WM_CHAR, VK_TAB, 0);
1755     todo_wine ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1756
1757     /* get text */
1758     buffer[0] = 0;
1759     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1760     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1761     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1762
1763     DestroyWindow (hwEdit);
1764 }
1765
1766 static void test_edit_dialog(void)
1767 {
1768     int r;
1769
1770     /* from bug 11841 */
1771     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 0);
1772     ok(333 == r, "Expected %d, got %d\n", 333, r);
1773     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 1);
1774     ok(111 == r, "Expected %d, got %d\n", 111, r);
1775     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 2);
1776     ok(444 == r, "Expected %d, got %d\n", 444, r);
1777
1778     /* more tests for WM_CHAR */
1779     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 3);
1780     ok(444 == r, "Expected %d, got %d\n", 444, r);
1781     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 4);
1782     ok(444 == r, "Expected %d, got %d\n", 444, r);
1783     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 5);
1784     ok(444 == r, "Expected %d, got %d\n", 444, r);
1785
1786     /* more tests for WM_KEYDOWN + WM_CHAR */
1787     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 6);
1788     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1789     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 7);
1790     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1791     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 8);
1792     ok(444 == r, "Expected %d, got %d\n", 444, r);
1793
1794     /* tests with an editable edit control */
1795     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 0);
1796     ok(333 == r, "Expected %d, got %d\n", 333, r);
1797     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 1);
1798     ok(111 == r, "Expected %d, got %d\n", 111, r);
1799     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 2);
1800     ok(444 == r, "Expected %d, got %d\n", 444, r);
1801
1802     /* tests for WM_CHAR */
1803     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 3);
1804     ok(444 == r, "Expected %d, got %d\n", 444, r);
1805     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 4);
1806     ok(444 == r, "Expected %d, got %d\n", 444, r);
1807     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 5);
1808     ok(444 == r, "Expected %d, got %d\n", 444, r);
1809
1810     /* tests for WM_KEYDOWN + WM_CHAR */
1811     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 6);
1812     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1813     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 7);
1814     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1815     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 8);
1816     ok(444 == r, "Expected %d, got %d\n", 444, r);
1817
1818     /* multiple tab tests */
1819     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 9);
1820     ok(22 == r, "Expected %d, got %d\n", 22, r);
1821     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 10);
1822     ok(33 == r, "Expected %d, got %d\n", 33, r);
1823 }
1824
1825 static void test_multi_edit_dialog(void)
1826 {
1827     int r;
1828
1829     /* test for multiple edit dialogs (bug 12319) */
1830     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 0);
1831     ok(2222 == r, "Expected %d, got %d\n", 2222, r);
1832     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 1);
1833     ok(1111 == r, "Expected %d, got %d\n", 1111, r);
1834     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 2);
1835     ok(2222 == r, "Expected %d, got %d\n", 2222, r);
1836     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 3);
1837     ok(11 == r, "Expected %d, got %d\n", 11, r);
1838 }
1839
1840 static void test_wantreturn_edit_dialog(void)
1841 {
1842     int r;
1843
1844     /* tests for WM_KEYDOWN */
1845     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 0);
1846     ok(333 == r, "Expected %d, got %d\n", 333, r);
1847     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 1);
1848     ok(444 == r, "Expected %d, got %d\n", 444, r);
1849     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 2);
1850     ok(444 == r, "Expected %d, got %d\n", 444, r);
1851
1852     /* tests for WM_CHAR */
1853     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 3);
1854     ok(444 == r, "Expected %d, got %d\n", 444, r);
1855     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 4);
1856     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1857     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 5);
1858     ok(444 == r, "Expected %d, got %d\n", 444, r);
1859
1860     /* tests for WM_KEYDOWN + WM_CHAR */
1861     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 6);
1862     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1863     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 7);
1864     todo_wine ok(444 == r, "Expected %d, got %d\n", 444, r);
1865     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 8);
1866     ok(444 == r, "Expected %d, got %d\n", 444, r);
1867 }
1868
1869 static void test_singleline_wantreturn_edit_dialog(void)
1870 {
1871     int r;
1872
1873     /* tests for WM_KEYDOWN */
1874     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 0);
1875     todo_wine ok(222 == r, "Expected %d, got %d\n", 222, r);
1876     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 1);
1877     ok(111 == r, "Expected %d, got %d\n", 111, r);
1878     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 2);
1879     ok(444 == r, "Expected %d, got %d\n", 444, r);
1880
1881     /* tests for WM_CHAR */
1882     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 3);
1883     ok(444 == r, "Expected %d, got %d\n", 444, r);
1884     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 4);
1885     ok(444 == r, "Expected %d, got %d\n", 444, r);
1886     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 5);
1887     ok(444 == r, "Expected %d, got %d\n", 444, r);
1888
1889     /* tests for WM_KEYDOWN + WM_CHAR */
1890     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 6);
1891     todo_wine ok(222 == r, "Expected %d, got %d\n", 222, r);
1892     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 7);
1893     ok(111 == r, "Expected %d, got %d\n", 111, r);
1894     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 8);
1895     ok(444 == r, "Expected %d, got %d\n", 444, r);
1896
1897     /* tests for WM_KEYDOWN */
1898     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 0);
1899     todo_wine ok(222 == r, "Expected %d, got %d\n", 222, r);
1900     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 1);
1901     todo_wine ok(111 == r, "Expected %d, got %d\n", 111, r);
1902     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 2);
1903     ok(444 == r, "Expected %d, got %d\n", 444, r);
1904
1905     /* tests for WM_CHAR */
1906     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 3);
1907     ok(444 == r, "Expected %d, got %d\n", 444, r);
1908     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 4);
1909     ok(444 == r, "Expected %d, got %d\n", 444, r);
1910     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 5);
1911     ok(444 == r, "Expected %d, got %d\n", 444, r);
1912
1913     /* tests for WM_KEYDOWN + WM_CHAR */
1914     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 6);
1915     todo_wine ok(222 == r, "Expected %d, got %d\n", 222, r);
1916     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 7);
1917     todo_wine ok(111 == r, "Expected %d, got %d\n", 111, r);
1918     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 8);
1919     ok(444 == r, "Expected %d, got %d\n", 444, r);
1920 }
1921
1922 static BOOL RegisterWindowClasses (void)
1923 {
1924     WNDCLASSA test2;
1925     WNDCLASSA test3;
1926     WNDCLASSA text_position;
1927     
1928     test2.style = 0;
1929     test2.lpfnWndProc = ET2_WndProc;
1930     test2.cbClsExtra = 0;
1931     test2.cbWndExtra = 0;
1932     test2.hInstance = hinst;
1933     test2.hIcon = NULL;
1934     test2.hCursor = LoadCursorA (NULL, IDC_ARROW);
1935     test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1936     test2.lpszMenuName = NULL;
1937     test2.lpszClassName = szEditTest2Class;
1938     if (!RegisterClassA(&test2)) return FALSE;
1939
1940     test3.style = 0;
1941     test3.lpfnWndProc = edit3_wnd_procA;
1942     test3.cbClsExtra = 0;
1943     test3.cbWndExtra = 0;
1944     test3.hInstance = hinst;
1945     test3.hIcon = 0;
1946     test3.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1947     test3.hbrBackground = GetStockObject(WHITE_BRUSH);
1948     test3.lpszMenuName = NULL;
1949     test3.lpszClassName = szEditTest3Class;
1950     if (!RegisterClassA(&test3)) return FALSE;
1951
1952     text_position.style = CS_HREDRAW | CS_VREDRAW;
1953     text_position.cbClsExtra = 0;
1954     text_position.cbWndExtra = 0;
1955     text_position.hInstance = hinst;
1956     text_position.hIcon = NULL;
1957     text_position.hCursor = LoadCursorA(NULL, IDC_ARROW);
1958     text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1959     text_position.lpszMenuName = NULL;
1960     text_position.lpszClassName = szEditTextPositionClass;
1961     text_position.lpfnWndProc = DefWindowProc;
1962     if (!RegisterClassA(&text_position)) return FALSE;
1963
1964     return TRUE;
1965 }
1966
1967 static void UnregisterWindowClasses (void)
1968 {
1969     UnregisterClassA(szEditTest2Class, hinst);
1970     UnregisterClassA(szEditTest3Class, hinst);
1971     UnregisterClassA(szEditTextPositionClass, hinst);
1972 }
1973
1974 START_TEST(edit)
1975 {
1976     hinst = GetModuleHandleA(NULL);
1977     assert(RegisterWindowClasses());
1978
1979     test_edit_control_1();
1980     test_edit_control_2();
1981     test_edit_control_3();
1982     test_edit_control_4();
1983     test_edit_control_5();
1984     test_edit_control_limittext();
1985     test_margins();
1986     test_margins_font_change();
1987     test_text_position();
1988     test_espassword();
1989     test_undo();
1990     test_enter();
1991     test_tab();
1992     test_edit_dialog();
1993     test_multi_edit_dialog();
1994     test_wantreturn_edit_dialog();
1995     test_singleline_wantreturn_edit_dialog();
1996
1997     UnregisterWindowClasses();
1998 }