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