d3dcompiler: Add argument check in D3DReflect().
[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     HDC hDC;
841     int len, dpi;
842     static const char *str = "this is a long string.";
843     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.";
844
845     hDC = GetDC(NULL);
846     dpi = GetDeviceCaps(hDC, LOGPIXELSY);
847     ReleaseDC(NULL, hDC);
848
849     trace("EDIT: Test notifications\n");
850
851     hParent = CreateWindowExA(0,
852               szEditTest3Class,
853               NULL,
854               0,
855               CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
856               NULL, NULL, NULL, NULL);
857     assert(hParent);
858
859     trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
860     hWnd = CreateWindowExA(0,
861               "EDIT",
862               NULL,
863               0,
864               10, 10, 50, 50,
865               hParent, NULL, NULL, NULL);
866     assert(hWnd);
867
868     zero_notify();
869     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
870     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
871     ok(lstrlenA(str) > len, "text should have been truncated\n");
872     test_notify(1, 1, 1);
873
874     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
875     zero_notify();
876     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
877     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
878     ok(1 == len, "wrong text length, expected 1, got %d\n", len);
879     test_notify(1, 0, 1);
880
881     zero_notify();
882     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
883     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
884     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
885     test_notify(1, 0, 1);
886
887     len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
888     ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
889     ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
890     SendMessage(hParent, WM_SETFOCUS, 0, (LPARAM)hWnd);
891     len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
892     ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
893     ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
894
895     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
896
897     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
898     zero_notify();
899     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
900     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
901     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
902     test_notify(1, 1, 1);
903
904     zero_notify();
905     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
906     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
907     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
908     test_notify(1, 0, 1);
909
910     DestroyWindow(hWnd);
911
912     trace("EDIT: Single line, ES_AUTOHSCROLL\n");
913     hWnd = CreateWindowExA(0,
914               "EDIT",
915               NULL,
916               ES_AUTOHSCROLL,
917               10, 10, 50, 50,
918               hParent, NULL, NULL, NULL);
919     assert(hWnd);
920
921     zero_notify();
922     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
923     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
924     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
925     test_notify(1, 0, 1);
926
927     zero_notify();
928     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
929     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
930     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
931     test_notify(1, 0, 1);
932
933     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
934
935     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
936     zero_notify();
937     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
938     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
939     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
940     test_notify(1, 1, 1);
941
942     zero_notify();
943     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
944     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
945     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
946     test_notify(1, 0, 1);
947
948     DestroyWindow(hWnd);
949
950     trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
951     hWnd = CreateWindowExA(0,
952               "EDIT",
953               NULL,
954               ES_MULTILINE,
955               10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
956               hParent, NULL, NULL, NULL);
957     assert(hWnd);
958
959     zero_notify();
960     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
961     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
962     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
963     test_notify(1, 1, 1);
964
965     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
966     zero_notify();
967     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
968     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
969     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
970     test_notify(1, 0, 1);
971
972     zero_notify();
973     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
974     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
975     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
976     test_notify(0, 0, 0);
977
978     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
979
980     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
981     zero_notify();
982     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
983     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
984     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
985     test_notify(1, 1, 1);
986
987     zero_notify();
988     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
989     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
990     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
991     test_notify(0, 0, 0);
992
993     DestroyWindow(hWnd);
994
995     trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
996     hWnd = CreateWindowExA(0,
997               "EDIT",
998               NULL,
999               ES_MULTILINE | ES_AUTOHSCROLL,
1000               10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1001               hParent, NULL, NULL, NULL);
1002     assert(hWnd);
1003
1004     zero_notify();
1005     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1006     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1007     ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1008     test_notify(1, 1, 1);
1009
1010     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1011     zero_notify();
1012     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
1013     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1014     ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1015     test_notify(1, 0, 1);
1016
1017     zero_notify();
1018     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1019     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1020     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1021     test_notify(0, 0, 0);
1022
1023     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1024
1025     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1026     zero_notify();
1027     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1028     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1029     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1030     test_notify(1, 1, 1);
1031
1032     zero_notify();
1033     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1034     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1035     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1036     test_notify(0, 0, 0);
1037
1038     DestroyWindow(hWnd);
1039
1040     trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1041     hWnd = CreateWindowExA(0,
1042               "EDIT",
1043               NULL,
1044               ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
1045               10, 10, 50, 50,
1046               hParent, NULL, NULL, NULL);
1047     assert(hWnd);
1048
1049     zero_notify();
1050     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1051     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1052     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1053     test_notify(1, 0, 1);
1054
1055     zero_notify();
1056     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1057     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1058     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1059     test_notify(0, 0, 0);
1060
1061     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1062
1063     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1064     zero_notify();
1065     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1066     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1067     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1068     test_notify(1, 1, 1);
1069
1070     zero_notify();
1071     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1072     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1073     ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1074     test_notify(0, 0, 0);
1075
1076     DestroyWindow(hWnd);
1077 }
1078
1079 /* Test EM_CHARFROMPOS and EM_POSFROMCHAR
1080  */
1081 static void test_edit_control_4(void)
1082 {
1083     HWND hwEdit;
1084     int lo, hi, mid;
1085     int ret;
1086     int i;
1087
1088     trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n");
1089     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1090     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1091     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1092     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1093     mid = lo + (hi - lo) / 2;
1094
1095     for (i = lo; i < mid; i++) {
1096        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1097        ok(0 == ret, "expected 0 got %d\n", ret);
1098     }
1099     for (i = mid; i <= hi; i++) {
1100        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1101        ok(1 == ret, "expected 1 got %d\n", ret);
1102     }
1103     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1104     ok(-1 == ret, "expected -1 got %d\n", ret);
1105     DestroyWindow(hwEdit);
1106
1107     hwEdit = create_editcontrol(ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1108     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1109     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1110     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1111     mid = lo + (hi - lo) / 2;
1112
1113     for (i = lo; i < mid; i++) {
1114        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1115        ok(0 == ret, "expected 0 got %d\n", ret);
1116     }
1117     for (i = mid; i <= hi; i++) {
1118        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1119        ok(1 == ret, "expected 1 got %d\n", ret);
1120     }
1121     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1122     ok(-1 == ret, "expected -1 got %d\n", ret);
1123     DestroyWindow(hwEdit);
1124
1125     hwEdit = create_editcontrol(ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1126     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1127     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1128     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1129     mid = lo + (hi - lo) / 2;
1130
1131     for (i = lo; i < mid; i++) {
1132        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1133        ok(0 == ret, "expected 0 got %d\n", ret);
1134     }
1135     for (i = mid; i <= hi; i++) {
1136        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1137        ok(1 == ret, "expected 1 got %d\n", ret);
1138     }
1139     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1140     ok(-1 == ret, "expected -1 got %d\n", ret);
1141     DestroyWindow(hwEdit);
1142
1143     hwEdit = create_editcontrol(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1144     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1145     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1146     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1147     mid = lo + (hi - lo) / 2 +1;
1148
1149     for (i = lo; i < mid; i++) {
1150        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1151        ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1152     }
1153     for (i = mid; i <= hi; i++) {
1154        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1155        ok(1 == ret, "expected 1 got %d\n", ret);
1156     }
1157     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1158     ok(-1 == ret, "expected -1 got %d\n", ret);
1159     DestroyWindow(hwEdit);
1160
1161     hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1162     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1163     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1164     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1165     mid = lo + (hi - lo) / 2 +1;
1166
1167     for (i = lo; i < mid; i++) {
1168        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1169        ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1170     }
1171     for (i = mid; i <= hi; i++) {
1172        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1173        ok(1 == ret, "expected 1 got %d\n", ret);
1174     }
1175     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1176     ok(-1 == ret, "expected -1 got %d\n", ret);
1177     DestroyWindow(hwEdit);
1178
1179     hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1180     SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa");
1181     lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0));
1182     hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0));
1183     mid = lo + (hi - lo) / 2 +1;
1184
1185     for (i = lo; i < mid; i++) {
1186        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1187        ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1188     }
1189     for (i = mid; i <= hi; i++) {
1190        ret = LOWORD(SendMessage(hwEdit, EM_CHARFROMPOS, 0, i));
1191        ok(1 == ret, "expected 1 got %d\n", ret);
1192     }
1193     ret = SendMessage(hwEdit, EM_POSFROMCHAR, 2, 0);
1194     ok(-1 == ret, "expected -1 got %d\n", ret);
1195     DestroyWindow(hwEdit);
1196 }
1197
1198 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1199  * truncates text that doesn't fit.
1200  */
1201 static void test_edit_control_5(void)
1202 {
1203     static const char *str = "test\r\ntest";
1204     HWND parentWnd;
1205     HWND hWnd;
1206     int len;
1207     RECT rc1 = { 10, 10, 11, 11};
1208     RECT rc;
1209
1210     /* first show that a non-child won't do for this test */
1211     hWnd = CreateWindowEx(0,
1212               "EDIT",
1213               str,
1214               0,
1215               10, 10, 1, 1,
1216               NULL, NULL, NULL, NULL);
1217     assert(hWnd);
1218     /* size of non-child edit control is (much) bigger than requested */
1219     GetWindowRect( hWnd, &rc);
1220     ok( rc.right - rc.left > 20, "size of the window (%d) is smaller than expected\n",
1221             rc.right - rc.left);
1222     DestroyWindow(hWnd);
1223     /* so create a parent, and give it edit controls children to test with */
1224     parentWnd = CreateWindowEx(0,
1225                             szEditTextPositionClass,
1226                             "Edit Test", WS_VISIBLE |
1227                             WS_OVERLAPPEDWINDOW,
1228                             CW_USEDEFAULT, CW_USEDEFAULT,
1229                             250, 250,
1230                             NULL, NULL, hinst, NULL);
1231     assert(parentWnd);
1232     ShowWindow( parentWnd, SW_SHOW);
1233     /* single line */
1234     hWnd = CreateWindowEx(0,
1235               "EDIT",
1236               str, WS_VISIBLE | WS_BORDER |
1237               WS_CHILD,
1238               rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1239               parentWnd, NULL, NULL, NULL);
1240     assert(hWnd);
1241     GetClientRect( hWnd, &rc);
1242     ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1243             "Client rectangle not the expected size (%d,%d,%d,%d)\n",
1244             rc.left, rc.top, rc.right, rc.bottom);
1245     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1246     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1247     DestroyWindow(hWnd);
1248     /* multi line */
1249     hWnd = CreateWindowEx(0,
1250               "EDIT",
1251               str,
1252               WS_CHILD | ES_MULTILINE,
1253               rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1254               parentWnd, NULL, NULL, NULL);
1255     assert(hWnd);
1256     GetClientRect( hWnd, &rc);
1257     ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1258             "Client rectangle not the expected size (%d,%d,%d,%d)\n",
1259             rc.left, rc.top, rc.right, rc.bottom);
1260     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1261     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1262     DestroyWindow(hWnd);
1263 }
1264
1265 /* Test WM_GETTEXT processing
1266  * after destroy messages
1267  */
1268 static void test_edit_control_6(void)
1269 {
1270     static const char *str = "test\r\ntest";
1271     char buf[MAXLEN];
1272     LONG ret;
1273     HWND hWnd;
1274
1275     hWnd = CreateWindowEx(0,
1276               "EDIT",
1277               "Test",
1278               0,
1279               10, 10, 1, 1,
1280               NULL, NULL, hinst, NULL);
1281     assert(hWnd);
1282
1283     ret = SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1284     ok(ret == TRUE, "Expected %d, got %d\n", TRUE, ret);
1285     ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1286     ok(ret == lstrlen(str), "Expected %s, got len %d\n", str, ret);
1287     ok(!lstrcmp(buf, str), "Expected %s, got %s\n", str, buf);
1288     buf[0] = 0;
1289     ret = SendMessageA(hWnd, WM_DESTROY, 0, 0);
1290     ok(ret == 0, "Expected 0, got %d\n", ret);
1291     ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1292     ok(ret == lstrlen(str), "Expected %s, got len %d\n", str, ret);
1293     ok(!lstrcmp(buf, str), "Expected %s, got %s\n", str, buf);
1294     buf[0] = 0;
1295     ret = SendMessageA(hWnd, WM_NCDESTROY, 0, 0);
1296     ok(ret == 0, "Expected 0, got %d\n", ret);
1297     ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1298     ok(ret == 0, "Expected 0, got len %d\n", ret);
1299     ok(!lstrcmp(buf, ""), "Expected empty string, got %s\n", buf);
1300
1301     DestroyWindow(hWnd);
1302 }
1303
1304 static void test_edit_control_limittext(void)
1305 {
1306     HWND hwEdit;
1307     DWORD r;
1308
1309     /* Test default limit for single-line control */
1310     trace("EDIT: buffer limit for single-line\n");
1311     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1312     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1313     ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1314     SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
1315     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1316     /* Win9x+ME: 32766; WinNT: 2147483646UL */
1317     ok( (r == 32766) || (r == 2147483646UL),
1318         "got limit %u (expected 32766 or 2147483646)\n", r);
1319     DestroyWindow(hwEdit);
1320
1321     /* Test default limit for multi-line control */
1322     trace("EDIT: buffer limit for multi-line\n");
1323     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1324     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1325     ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1326     SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
1327     r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
1328     /* Win9x+ME: 65535; WinNT: 4294967295UL */
1329     ok( (r == 65535) || (r == 4294967295UL),
1330         "got limit %u (expected 65535 or 4294967295)\n", r);
1331     DestroyWindow(hwEdit);
1332 }
1333
1334 /* Test EM_SCROLL */
1335 static void test_edit_control_scroll(void)
1336 {
1337     static const char *single_line_str = "a";
1338     static const char *multiline_str = "Test\r\nText";
1339     HWND hwEdit;
1340     LONG ret;
1341
1342     /* Check the return value when EM_SCROLL doesn't scroll
1343      * anything. Should not return true unless any lines were actually
1344      * scrolled. */
1345     hwEdit = CreateWindow(
1346               "EDIT",
1347               single_line_str,
1348               WS_VSCROLL | ES_MULTILINE,
1349               1, 1, 100, 100,
1350               NULL, NULL, hinst, NULL);
1351
1352     assert(hwEdit);
1353
1354     ret = SendMessage(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1355     ok(!ret, "Returned %x, expected 0.\n", ret);
1356
1357     ret = SendMessage(hwEdit, EM_SCROLL, SB_PAGEUP, 0);
1358     ok(!ret, "Returned %x, expected 0.\n", ret);
1359
1360     ret = SendMessage(hwEdit, EM_SCROLL, SB_LINEUP, 0);
1361     ok(!ret, "Returned %x, expected 0.\n", ret);
1362
1363     ret = SendMessage(hwEdit, EM_SCROLL, SB_LINEDOWN, 0);
1364     ok(!ret, "Returned %x, expected 0.\n", ret);
1365
1366     DestroyWindow (hwEdit);
1367
1368     /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1369        should not cause EM_SCROLL to return a negative value of
1370        scrolled lines that would put us "before" the beginning. */
1371     hwEdit = CreateWindow(
1372                 "EDIT",
1373                 multiline_str,
1374                 WS_VSCROLL | ES_MULTILINE,
1375                 0, 0, 100, 100,
1376                 NULL, NULL, hinst, NULL);
1377     assert(hwEdit);
1378
1379     ret = SendMessage(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1380     ok(!ret, "Returned %x, expected 0.\n", ret);
1381
1382     DestroyWindow (hwEdit);
1383 }
1384
1385 static void test_margins(void)
1386 {
1387     HWND hwEdit;
1388     RECT old_rect, new_rect;
1389     INT old_right_margin;
1390     DWORD old_margins, new_margins;
1391
1392     hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1393     
1394     old_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1395     old_right_margin = HIWORD(old_margins);
1396     
1397     /* Check if setting the margins works */
1398     
1399     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
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) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
1403     
1404     SendMessage(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
1405     new_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1406     ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1407     ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
1408     
1409     
1410     /* The size of the rectangle must decrease if we increase the margin */
1411     
1412     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
1413     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1414     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
1415     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1416     ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
1417     ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
1418     ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
1419     ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
1420     
1421     
1422     /* If we set the margin to same value as the current margin,
1423        the rectangle must not change */
1424     
1425     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1426     old_rect.left = 1;
1427     old_rect.right = 99;
1428     old_rect.top = 1;
1429     old_rect.bottom = 99;
1430     SendMessage(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);    
1431     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1432     SendMessage(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1433     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1434     ok(new_rect.left == old_rect.left, "The left border of the rectangle has changed\n");
1435     ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n");
1436     ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n");
1437     ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n");
1438
1439     DestroyWindow (hwEdit);
1440 }
1441
1442 static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
1443 {
1444     return 0;
1445 }
1446
1447 static void test_margins_font_change(void)
1448 {
1449     HWND hwEdit;
1450     DWORD margins, font_margins;
1451     LOGFONT lf;
1452     HFONT hfont, hfont2;
1453     HDC hdc = GetDC(0);
1454
1455     if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
1456     {
1457         trace("Arial not found - skipping font change margin tests\n");
1458         ReleaseDC(0, hdc);
1459         return;
1460     }
1461     ReleaseDC(0, hdc);
1462
1463     hwEdit = create_child_editcontrol(0, 0);
1464
1465     SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1466
1467     memset(&lf, 0, sizeof(lf));
1468     strcpy(lf.lfFaceName, "Arial");
1469     lf.lfHeight = 16;
1470     lf.lfCharSet = DEFAULT_CHARSET;
1471     hfont = CreateFontIndirectA(&lf);
1472     lf.lfHeight = 30;
1473     hfont2 = CreateFontIndirectA(&lf);
1474
1475     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1476     font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1477     ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
1478     ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
1479
1480     /* With 'small' edit controls, test that the margin doesn't get set */
1481     SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1482     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
1483     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1484     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1485     ok(LOWORD(margins) == 0 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1486        "got %d\n", LOWORD(margins));
1487     ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1488        "got %d\n", HIWORD(margins));
1489
1490     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1491     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1492     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1493     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1494        "got %d\n", LOWORD(margins));
1495     ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1496        "got %d\n", HIWORD(margins));
1497
1498     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1499     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1500     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1501     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1502        "got %d\n", LOWORD(margins));
1503     ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1504        "got %d\n", HIWORD(margins));
1505
1506     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1507     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1508     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
1509        "got %d\n", LOWORD(margins));
1510     ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
1511        "got %d\n", HIWORD(margins));
1512
1513     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1514     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1515     ok(LOWORD(margins) == 1 || broken(LOWORD(margins) != 1 && LOWORD(margins) != LOWORD(font_margins)), /* win95 */
1516        "got %d\n", LOWORD(margins));
1517     ok(HIWORD(margins) == 1 || broken(HIWORD(margins) != 1 && HIWORD(margins) != HIWORD(font_margins)), /* win95 */
1518        "got %d\n", HIWORD(margins));
1519
1520     /* Above a certain size threshold then the margin is updated */
1521     SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1522     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1523     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1524     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1525     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1526     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1527
1528     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1529     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
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
1534     SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1535     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1536     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1537     ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1538     ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1539     SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1540     margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
1541     ok(LOWORD(margins) != LOWORD(font_margins) || broken(LOWORD(margins) == LOWORD(font_margins)), /* win98 */
1542        "got %d\n", LOWORD(margins));
1543     ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
1544
1545     SendMessageA(hwEdit, WM_SETFONT, 0, 0);
1546     
1547     DeleteObject(hfont2);
1548     DeleteObject(hfont);
1549     destroy_child_editcontrol(hwEdit);
1550
1551 }
1552
1553 #define edit_pos_ok(exp, got, txt) \
1554     ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1555
1556 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1557 do { \
1558     RECT format_rect; \
1559     int left_margin; \
1560     set_client_height(hwEdit, set_height); \
1561     SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1562     left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \
1563     edit_pos_ok(test_top, format_rect.top, vertical position); \
1564     edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1565     edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1566 } while(0)
1567
1568 static void test_text_position_style(DWORD style)
1569 {
1570     HWND hwEdit;
1571     HFONT font, oldFont;
1572     HDC dc;
1573     TEXTMETRIC metrics;
1574     INT b, bm, b2, b3;
1575     BOOL single_line = !(style & ES_MULTILINE);
1576
1577     b = GetSystemMetrics(SM_CYBORDER) + 1;
1578     b2 = 2 * b;
1579     b3 = 3 * b;
1580     bm = b2 - 1;
1581     
1582     /* Get a stock font for which we can determine the metrics */
1583     assert(font = GetStockObject(SYSTEM_FONT));
1584     assert(dc = GetDC(NULL));
1585     oldFont = SelectObject(dc, font);
1586     assert(GetTextMetrics(dc, &metrics));    
1587     SelectObject(dc, oldFont);
1588     ReleaseDC(NULL, dc);
1589     
1590     /* Windows' edit control has some bugs in multi-line mode:
1591      * - Sometimes the format rectangle doesn't get updated
1592      *   (see workaround in set_client_height())
1593      * - If the height of the control is smaller than the height of a text
1594      *   line, the format rectangle is still as high as a text line
1595      *   (higher than the client rectangle) and the caret is not shown
1596      */
1597     
1598     /* Edit controls that are in a parent window */
1599        
1600     hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
1601     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1602     if (single_line)
1603     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
1604     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
1605     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
1606     check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
1607     check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
1608     destroy_child_editcontrol(hwEdit);
1609
1610     hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
1611     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1612     if (single_line)
1613     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
1614     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
1615     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
1616     check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
1617     check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
1618     check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
1619     destroy_child_editcontrol(hwEdit);
1620
1621     hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
1622     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1623     if (single_line)
1624     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1625     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1626     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1627     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1628     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1629     destroy_child_editcontrol(hwEdit);
1630
1631     hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
1632     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1633     if (single_line)
1634     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1635     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1636     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1637     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1638     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1639     destroy_child_editcontrol(hwEdit);
1640
1641
1642     /* Edit controls that are popup windows */
1643     
1644     hwEdit = create_editcontrol(style | WS_POPUP, 0);
1645     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1646     if (single_line)
1647     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 0);
1648     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 0);
1649     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 0);
1650     check_pos(hwEdit, metrics.tmHeight +  2, 0, metrics.tmHeight    , 0);
1651     check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight    , 0);
1652     DestroyWindow(hwEdit);
1653
1654     hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
1655     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1656     if (single_line)
1657     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, b);
1658     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , b);
1659     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , b);
1660     check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight    , b);
1661     check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight    , b);
1662     check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight    , b);
1663     DestroyWindow(hwEdit);
1664
1665     hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
1666     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1667     if (single_line)
1668     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1669     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1670     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1671     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1672     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1673     DestroyWindow(hwEdit);
1674
1675     hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
1676     SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1677     if (single_line)
1678     check_pos(hwEdit, metrics.tmHeight -  1, 0, metrics.tmHeight - 1, 1);
1679     check_pos(hwEdit, metrics.tmHeight     , 0, metrics.tmHeight    , 1);
1680     check_pos(hwEdit, metrics.tmHeight +  1, 0, metrics.tmHeight    , 1);
1681     check_pos(hwEdit, metrics.tmHeight +  2, 1, metrics.tmHeight    , 1);
1682     check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight    , 1);
1683     DestroyWindow(hwEdit);
1684 }
1685
1686 static void test_text_position(void)
1687 {
1688     trace("EDIT: Text position (Single line)\n");
1689     test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1690     trace("EDIT: Text position (Multi line)\n");
1691     test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1692 }
1693
1694 static void test_espassword(void)
1695 {
1696     HWND hwEdit;
1697     LONG r;
1698     char buffer[1024];
1699     const char* password = "secret";
1700
1701     hwEdit = create_editcontrol(ES_PASSWORD, 0);
1702     r = get_edit_style(hwEdit);
1703     ok(r == ES_PASSWORD, "Wrong style expected 0x%x got: 0x%x\n", ES_PASSWORD, r);
1704     /* set text */
1705     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
1706     ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
1707
1708     /* select all, cut (ctrl-x) */
1709     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1710     r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1711     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1712
1713     /* get text */
1714     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1715     ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
1716     ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
1717
1718     r = OpenClipboard(hwEdit);
1719     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1720     r = EmptyClipboard();
1721     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1722     r = CloseClipboard();
1723     ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1724
1725     /* select all, copy (ctrl-c) and paste (ctrl-v) */
1726     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1727     r = SendMessage(hwEdit, WM_CHAR, 3, 0);
1728     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1729     r = SendMessage(hwEdit, WM_CHAR, 22, 0);
1730     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1731
1732     /* get text */
1733     buffer[0] = 0;
1734     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1735     ok(r == 0, "Expected: 0, got: %d\n", r);
1736     ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
1737
1738     DestroyWindow (hwEdit);
1739 }
1740
1741 static void test_undo(void)
1742 {
1743     HWND hwEdit;
1744     LONG r;
1745     DWORD cpMin, cpMax;
1746     char buffer[1024];
1747     const char* text = "undo this";
1748
1749     hwEdit = create_editcontrol(0, 0);
1750     r = get_edit_style(hwEdit);
1751     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1752
1753     /* set text */
1754     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
1755     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1756
1757     /* select all, */
1758     cpMin = cpMax = 0xdeadbeef;
1759     SendMessage(hwEdit, EM_SETSEL, 0, -1);
1760     r = SendMessage(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
1761     ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
1762     ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
1763     ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
1764
1765     /* cut (ctrl-x) */
1766     r = SendMessage(hwEdit, WM_CHAR, 24, 0);
1767     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1768
1769     /* get text */
1770     buffer[0] = 0;
1771     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1772     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1773     ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1774
1775     /* undo (ctrl-z) */
1776     r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1777     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1778
1779     /* get text */
1780     buffer[0] = 0;
1781     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1782     ok(strlen(text) == r, "Unexpected length %d\n", r);
1783     ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
1784
1785     /* undo again (ctrl-z) */
1786     r = SendMessage(hwEdit, WM_CHAR, 26, 0);
1787     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1788
1789     /* get text */
1790     buffer[0] = 0;
1791     r = SendMessage(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1792     ok(r == 0, "Expected: %d, got len %d\n", 0, r);
1793     ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1794
1795     DestroyWindow (hwEdit);
1796 }
1797
1798 static void test_enter(void)
1799 {
1800     HWND hwEdit;
1801     LONG r;
1802     char buffer[16];
1803
1804     /* multiline */
1805     hwEdit = create_editcontrol(ES_MULTILINE, 0);
1806     r = get_edit_style(hwEdit);
1807     ok(ES_MULTILINE == r, "Wrong style expected 0x%x got: 0x%x\n", ES_MULTILINE, r);
1808
1809     /* set text */
1810     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1811     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1812
1813     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1814     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1815
1816     /* get text */
1817     buffer[0] = 0;
1818     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1819     ok(2 == r, "Expected: %d, got len %d\n", 2, r);
1820     ok(0 == strcmp(buffer, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer);
1821
1822     DestroyWindow (hwEdit);
1823
1824     /* single line */
1825     hwEdit = create_editcontrol(0, 0);
1826     r = get_edit_style(hwEdit);
1827     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1828
1829     /* set text */
1830     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1831     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1832
1833     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1834     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1835
1836     /* get text */
1837     buffer[0] = 0;
1838     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1839     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1840     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1841
1842     DestroyWindow (hwEdit);
1843
1844     /* single line with ES_WANTRETURN */
1845     hwEdit = create_editcontrol(ES_WANTRETURN, 0);
1846     r = get_edit_style(hwEdit);
1847     ok(ES_WANTRETURN == r, "Wrong style expected 0x%x got: 0x%x\n", ES_WANTRETURN, r);
1848
1849     /* set text */
1850     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1851     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1852
1853     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0);
1854     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1855
1856     /* get text */
1857     buffer[0] = 0;
1858     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1859     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1860     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1861
1862     DestroyWindow (hwEdit);
1863 }
1864
1865 static void test_tab(void)
1866 {
1867     HWND hwEdit;
1868     LONG r;
1869     char buffer[16];
1870
1871     /* multiline */
1872     hwEdit = create_editcontrol(ES_MULTILINE, 0);
1873     r = get_edit_style(hwEdit);
1874     ok(ES_MULTILINE == r, "Wrong style expected 0x%x got: 0x%x\n", ES_MULTILINE, r);
1875
1876     /* set text */
1877     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1878     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1879
1880     r = SendMessage(hwEdit, WM_CHAR, VK_TAB, 0);
1881     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1882
1883     /* get text */
1884     buffer[0] = 0;
1885     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1886     ok(1 == r, "Expected: %d, got len %d\n", 1, r);
1887     ok(0 == strcmp(buffer, "\t"), "expected \"\\t\", got \"%s\"\n", buffer);
1888
1889     DestroyWindow (hwEdit);
1890
1891     /* single line */
1892     hwEdit = create_editcontrol(0, 0);
1893     r = get_edit_style(hwEdit);
1894     ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1895
1896     /* set text */
1897     r = SendMessage(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
1898     ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1899
1900     r = SendMessage(hwEdit, WM_CHAR, VK_TAB, 0);
1901     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1902
1903     /* get text */
1904     buffer[0] = 0;
1905     r = SendMessage(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
1906     ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1907     ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
1908
1909     DestroyWindow (hwEdit);
1910 }
1911
1912 static void test_edit_dialog(void)
1913 {
1914     int r;
1915
1916     /* from bug 11841 */
1917     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 0);
1918     ok(333 == r, "Expected %d, got %d\n", 333, r);
1919     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 1);
1920     ok(111 == r, "Expected %d, got %d\n", 111, r);
1921     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 2);
1922     ok(444 == r, "Expected %d, got %d\n", 444, r);
1923
1924     /* more tests for WM_CHAR */
1925     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 3);
1926     ok(444 == r, "Expected %d, got %d\n", 444, r);
1927     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 4);
1928     ok(444 == r, "Expected %d, got %d\n", 444, r);
1929     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 5);
1930     ok(444 == r, "Expected %d, got %d\n", 444, r);
1931
1932     /* more tests for WM_KEYDOWN + WM_CHAR */
1933     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 6);
1934     ok(444 == r, "Expected %d, got %d\n", 444, r);
1935     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 7);
1936     ok(444 == r, "Expected %d, got %d\n", 444, r);
1937     r = DialogBoxParam(hinst, "EDIT_READONLY_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 8);
1938     ok(444 == r, "Expected %d, got %d\n", 444, r);
1939
1940     /* tests with an editable edit control */
1941     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 0);
1942     ok(333 == r, "Expected %d, got %d\n", 333, r);
1943     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 1);
1944     ok(111 == r, "Expected %d, got %d\n", 111, r);
1945     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 2);
1946     ok(444 == r, "Expected %d, got %d\n", 444, r);
1947
1948     /* tests for WM_CHAR */
1949     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 3);
1950     ok(444 == r, "Expected %d, got %d\n", 444, r);
1951     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 4);
1952     ok(444 == r, "Expected %d, got %d\n", 444, r);
1953     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 5);
1954     ok(444 == r, "Expected %d, got %d\n", 444, r);
1955
1956     /* tests for WM_KEYDOWN + WM_CHAR */
1957     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 6);
1958     ok(444 == r, "Expected %d, got %d\n", 444, r);
1959     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 7);
1960     ok(444 == r, "Expected %d, got %d\n", 444, r);
1961     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 8);
1962     ok(444 == r, "Expected %d, got %d\n", 444, r);
1963
1964     /* multiple tab tests */
1965     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 9);
1966     ok(22 == r, "Expected %d, got %d\n", 22, r);
1967     r = DialogBoxParam(hinst, "EDIT_DIALOG", NULL, (DLGPROC)edit_dialog_proc, 10);
1968     ok(33 == r, "Expected %d, got %d\n", 33, r);
1969 }
1970
1971 static void test_multi_edit_dialog(void)
1972 {
1973     int r;
1974
1975     /* test for multiple edit dialogs (bug 12319) */
1976     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 0);
1977     ok(2222 == r, "Expected %d, got %d\n", 2222, r);
1978     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 1);
1979     ok(1111 == r, "Expected %d, got %d\n", 1111, r);
1980     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 2);
1981     ok(2222 == r, "Expected %d, got %d\n", 2222, r);
1982     r = DialogBoxParam(hinst, "MULTI_EDIT_DIALOG", NULL, (DLGPROC)multi_edit_dialog_proc, 3);
1983     ok(11 == r, "Expected %d, got %d\n", 11, r);
1984 }
1985
1986 static void test_wantreturn_edit_dialog(void)
1987 {
1988     int r;
1989
1990     /* tests for WM_KEYDOWN */
1991     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 0);
1992     ok(333 == r, "Expected %d, got %d\n", 333, r);
1993     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 1);
1994     ok(444 == r, "Expected %d, got %d\n", 444, r);
1995     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 2);
1996     ok(444 == r, "Expected %d, got %d\n", 444, r);
1997
1998     /* tests for WM_CHAR */
1999     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 3);
2000     ok(444 == r, "Expected %d, got %d\n", 444, r);
2001     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 4);
2002     ok(444 == r, "Expected %d, got %d\n", 444, r);
2003     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 5);
2004     ok(444 == r, "Expected %d, got %d\n", 444, r);
2005
2006     /* tests for WM_KEYDOWN + WM_CHAR */
2007     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 6);
2008     ok(444 == r, "Expected %d, got %d\n", 444, r);
2009     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 7);
2010     ok(444 == r, "Expected %d, got %d\n", 444, r);
2011     r = DialogBoxParam(hinst, "EDIT_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_wantreturn_dialog_proc, 8);
2012     ok(444 == r, "Expected %d, got %d\n", 444, r);
2013 }
2014
2015 static void test_singleline_wantreturn_edit_dialog(void)
2016 {
2017     int r;
2018
2019     /* tests for WM_KEYDOWN */
2020     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 0);
2021     ok(222 == r, "Expected %d, got %d\n", 222, r);
2022     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 1);
2023     ok(111 == r, "Expected %d, got %d\n", 111, r);
2024     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 2);
2025     ok(444 == r, "Expected %d, got %d\n", 444, r);
2026
2027     /* tests for WM_CHAR */
2028     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 3);
2029     ok(444 == r, "Expected %d, got %d\n", 444, r);
2030     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 4);
2031     ok(444 == r, "Expected %d, got %d\n", 444, r);
2032     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 5);
2033     ok(444 == r, "Expected %d, got %d\n", 444, r);
2034
2035     /* tests for WM_KEYDOWN + WM_CHAR */
2036     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 6);
2037     ok(222 == r, "Expected %d, got %d\n", 222, r);
2038     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 7);
2039     ok(111 == r, "Expected %d, got %d\n", 111, r);
2040     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 8);
2041     ok(444 == r, "Expected %d, got %d\n", 444, r);
2042
2043     /* tests for WM_KEYDOWN */
2044     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 0);
2045     ok(222 == r, "Expected %d, got %d\n", 222, r);
2046     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 1);
2047     ok(111 == r, "Expected %d, got %d\n", 111, r);
2048     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 2);
2049     ok(444 == r, "Expected %d, got %d\n", 444, r);
2050
2051     /* tests for WM_CHAR */
2052     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 3);
2053     ok(444 == r, "Expected %d, got %d\n", 444, r);
2054     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 4);
2055     ok(444 == r, "Expected %d, got %d\n", 444, r);
2056     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 5);
2057     ok(444 == r, "Expected %d, got %d\n", 444, r);
2058
2059     /* tests for WM_KEYDOWN + WM_CHAR */
2060     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 6);
2061     ok(222 == r, "Expected %d, got %d\n", 222, r);
2062     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 7);
2063     ok(111 == r, "Expected %d, got %d\n", 111, r);
2064     r = DialogBoxParam(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, (DLGPROC)edit_singleline_dialog_proc, 8);
2065     ok(444 == r, "Expected %d, got %d\n", 444, r);
2066 }
2067
2068 static int child_edit_wmkeydown_num_messages = 0;
2069 static INT_PTR CALLBACK child_edit_wmkeydown_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
2070 {
2071     switch (msg)
2072     {
2073         case WM_DESTROY:
2074         case WM_NCDESTROY:
2075             break;
2076
2077         default:
2078             child_edit_wmkeydown_num_messages++;
2079             break;
2080     }
2081
2082     return FALSE;
2083 }
2084
2085 static void test_child_edit_wmkeydown(void)
2086 {
2087     HWND hwEdit, hwParent;
2088     int r;
2089
2090     hwEdit = create_child_editcontrol(0, 0);
2091     hwParent = GetParent(hwEdit);
2092     SetWindowLongPtr(hwParent, GWLP_WNDPROC, (LONG_PTR)child_edit_wmkeydown_proc);
2093     r = SendMessage(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2094     ok(1 == r, "expected 1, got %d\n", r);
2095     ok(0 == child_edit_wmkeydown_num_messages, "expected 0, got %d\n", child_edit_wmkeydown_num_messages);
2096     destroy_child_editcontrol(hwEdit);
2097 }
2098
2099 static int got_en_setfocus = 0;
2100 static int got_wm_capturechanged = 0;
2101
2102 static LRESULT CALLBACK edit4_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
2103 {
2104     switch (msg) {
2105         case WM_COMMAND:
2106             switch (HIWORD(wParam)) {
2107                 case EN_SETFOCUS:
2108                     got_en_setfocus = 1;
2109                     break;
2110             }
2111             break;
2112         case WM_CAPTURECHANGED:
2113             if (hWnd != (HWND)lParam)
2114             {
2115                 got_wm_capturechanged = 1;
2116                 pEndMenu();
2117             }
2118             break;
2119     }
2120     return DefWindowProcA(hWnd, msg, wParam, lParam);
2121 }
2122
2123 static void test_contextmenu_focus(void)
2124 {
2125     HWND hwndMain, hwndEdit;
2126
2127     hwndMain = CreateWindow(szEditTest4Class, "ET4", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
2128                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
2129     assert(hwndMain);
2130
2131     hwndEdit = CreateWindow("EDIT", NULL,
2132                            WS_CHILD|WS_BORDER|WS_VISIBLE|ES_LEFT|ES_AUTOHSCROLL,
2133                            0, 0, 150, 50, /* important this not be 0 size. */
2134                            hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
2135     assert(hwndEdit);
2136
2137     SetFocus(NULL);
2138
2139     SetCapture(hwndMain);
2140
2141     SendMessage(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(10, 10));
2142
2143     ok(got_en_setfocus, "edit box didn't get focused\n");
2144
2145     ok(got_wm_capturechanged, "main window capture did not change\n");
2146
2147     DestroyWindow (hwndEdit);
2148     DestroyWindow (hwndMain);
2149 }
2150
2151 static BOOL RegisterWindowClasses (void)
2152 {
2153     WNDCLASSA test2;
2154     WNDCLASSA test3;
2155     WNDCLASSA test4;
2156     WNDCLASSA text_position;
2157     
2158     test2.style = 0;
2159     test2.lpfnWndProc = ET2_WndProc;
2160     test2.cbClsExtra = 0;
2161     test2.cbWndExtra = 0;
2162     test2.hInstance = hinst;
2163     test2.hIcon = NULL;
2164     test2.hCursor = LoadCursorA (NULL, IDC_ARROW);
2165     test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2166     test2.lpszMenuName = NULL;
2167     test2.lpszClassName = szEditTest2Class;
2168     if (!RegisterClassA(&test2)) return FALSE;
2169
2170     test3.style = 0;
2171     test3.lpfnWndProc = edit3_wnd_procA;
2172     test3.cbClsExtra = 0;
2173     test3.cbWndExtra = 0;
2174     test3.hInstance = hinst;
2175     test3.hIcon = 0;
2176     test3.hCursor = LoadCursorA(0, IDC_ARROW);
2177     test3.hbrBackground = GetStockObject(WHITE_BRUSH);
2178     test3.lpszMenuName = NULL;
2179     test3.lpszClassName = szEditTest3Class;
2180     if (!RegisterClassA(&test3)) return FALSE;
2181     
2182     test4.style = 0;
2183     test4.lpfnWndProc = edit4_wnd_procA;
2184     test4.cbClsExtra = 0;
2185     test4.cbWndExtra = 0;
2186     test4.hInstance = hinst;
2187     test4.hIcon = NULL;
2188     test4.hCursor = LoadCursorA (NULL, IDC_ARROW);
2189     test4.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2190     test4.lpszMenuName = NULL;
2191     test4.lpszClassName = szEditTest4Class;
2192     if (!RegisterClassA(&test4)) return FALSE;
2193
2194     text_position.style = CS_HREDRAW | CS_VREDRAW;
2195     text_position.cbClsExtra = 0;
2196     text_position.cbWndExtra = 0;
2197     text_position.hInstance = hinst;
2198     text_position.hIcon = NULL;
2199     text_position.hCursor = LoadCursorA(NULL, IDC_ARROW);
2200     text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2201     text_position.lpszMenuName = NULL;
2202     text_position.lpszClassName = szEditTextPositionClass;
2203     text_position.lpfnWndProc = DefWindowProc;
2204     if (!RegisterClassA(&text_position)) return FALSE;
2205
2206     return TRUE;
2207 }
2208
2209 static void UnregisterWindowClasses (void)
2210 {
2211     UnregisterClassA(szEditTest2Class, hinst);
2212     UnregisterClassA(szEditTest3Class, hinst);
2213     UnregisterClassA(szEditTest4Class, hinst);
2214     UnregisterClassA(szEditTextPositionClass, hinst);
2215 }
2216
2217 static void test_fontsize(void)
2218 {
2219     HWND hwEdit;
2220     HFONT hfont;
2221     HDC hDC;
2222     LOGFONT lf;
2223     LONG r;
2224     char szLocalString[MAXLEN];
2225     int dpi;
2226
2227     hDC = GetDC(NULL);
2228     dpi = GetDeviceCaps(hDC, LOGPIXELSY);
2229     ReleaseDC(NULL, hDC);
2230
2231     memset(&lf,0,sizeof(LOGFONTA));
2232     strcpy(lf.lfFaceName,"Arial");
2233     lf.lfHeight = -300; /* taller than the edit box */
2234     lf.lfWeight = 500;
2235     hfont = CreateFontIndirect(&lf);
2236
2237     trace("EDIT: Oversized font (Multi line)\n");
2238     hwEdit= CreateWindow("EDIT", NULL, ES_MULTILINE|ES_AUTOHSCROLL,
2239                            0, 0, (150 * dpi) / 96, (50 * dpi) / 96, NULL, NULL,
2240                            hinst, NULL);
2241
2242     SendMessage(hwEdit,WM_SETFONT,(WPARAM)hfont,0);
2243
2244     if (winetest_interactive)
2245         ShowWindow (hwEdit, SW_SHOW);
2246
2247     r = SendMessage(hwEdit, WM_CHAR, 'A', 1);
2248     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2249     r = SendMessage(hwEdit, WM_CHAR, 'B', 1);
2250     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2251     r = SendMessage(hwEdit, WM_CHAR, 'C', 1);
2252     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2253
2254     GetWindowText(hwEdit, szLocalString, MAXLEN);
2255     ok(lstrcmp(szLocalString, "ABC")==0,
2256        "Wrong contents of edit: %s\n", szLocalString);
2257
2258     r = SendMessage(hwEdit, EM_POSFROMCHAR,0,0);
2259     ok(r != -1,"EM_POSFROMCHAR failed index 0\n");
2260     r = SendMessage(hwEdit, EM_POSFROMCHAR,1,0);
2261     ok(r != -1,"EM_POSFROMCHAR failed index 1\n");
2262     r = SendMessage(hwEdit, EM_POSFROMCHAR,2,0);
2263     ok(r != -1,"EM_POSFROMCHAR failed index 2\n");
2264     r = SendMessage(hwEdit, EM_POSFROMCHAR,3,0);
2265     ok(r == -1,"EM_POSFROMCHAR succeeded index 3\n");
2266
2267     DestroyWindow (hwEdit);
2268     DeleteObject(hfont);
2269 }
2270
2271 struct dialog_mode_messages
2272 {
2273     int wm_getdefid, wm_close, wm_command, wm_nextdlgctl;
2274 };
2275
2276 static struct dialog_mode_messages dm_messages;
2277
2278 static void zero_dm_messages(void)
2279 {
2280     dm_messages.wm_command      = 0;
2281     dm_messages.wm_close        = 0;
2282     dm_messages.wm_getdefid     = 0;
2283     dm_messages.wm_nextdlgctl   = 0;
2284 }
2285
2286 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2287     ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2288     "got %d\n", wmcommand, dm_messages.wm_command); \
2289     ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2290     "got %d\n", wmclose, dm_messages.wm_close); \
2291     ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2292     "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2293     ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2294     "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2295
2296 static LRESULT CALLBACK dialog_mode_wnd_proc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
2297 {
2298     switch (iMsg)
2299     {
2300         case WM_COMMAND:
2301             dm_messages.wm_command++;
2302             break;
2303         case DM_GETDEFID:
2304             dm_messages.wm_getdefid++;
2305             return MAKELONG(ID_EDITTESTDBUTTON, DC_HASDEFID);
2306         case WM_NEXTDLGCTL:
2307             dm_messages.wm_nextdlgctl++;
2308             break;
2309         case WM_CLOSE:
2310             dm_messages.wm_close++;
2311             break;
2312     }
2313
2314     return DefWindowProc(hwnd, iMsg, wParam, lParam);
2315 }
2316
2317 static void test_dialogmode(void)
2318 {
2319     HWND hwEdit, hwParent, hwButton;
2320     MSG msg= {0};
2321     int len, r;
2322     hwEdit = create_child_editcontrol(ES_MULTILINE, 0);
2323
2324     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2325     ok(1 == r, "expected 1, got %d\n", r);
2326     len = SendMessage(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2327     ok(11 == len, "expected 11, got %d\n", len);
2328
2329     r = SendMessage(hwEdit, WM_GETDLGCODE, 0, 0);
2330     ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2331
2332     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2333     ok(1 == r, "expected 1, got %d\n", r);
2334     len = SendMessage(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2335     ok(13 == len, "expected 13, got %d\n", len);
2336
2337     r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM)&msg);
2338     ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2339     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2340     ok(1 == r, "expected 1, got %d\n", r);
2341     len = SendMessage(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2342     ok(13 == len, "expected 13, got %d\n", len);
2343
2344     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2345     ok(1 == r, "expected 1, got %d\n", r);
2346     len = SendMessage(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2347     ok(13 == len, "expected 13, got %d\n", len);
2348
2349     destroy_child_editcontrol(hwEdit);
2350
2351     hwEdit = create_editcontrol(ES_MULTILINE, 0);
2352
2353     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2354     ok(1 == r, "expected 1, got %d\n", r);
2355     len = SendMessage(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2356     ok(11 == len, "expected 11, got %d\n", len);
2357
2358     msg.hwnd = hwEdit;
2359     msg.message = WM_KEYDOWN;
2360     msg.wParam = VK_BACK;
2361     msg.lParam = 0xe0001;
2362     r = SendMessage(hwEdit, WM_GETDLGCODE, VK_BACK, (LPARAM)&msg);
2363     ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2364
2365     r = SendMessage(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2366     ok(1 == r, "expected 1, got %d\n", r);
2367     len = SendMessage(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2368     ok(11 == len, "expected 11, got %d\n", len);
2369
2370     DestroyWindow(hwEdit);
2371
2372     hwEdit = create_child_editcontrol(0, 0);
2373     hwParent = GetParent(hwEdit);
2374     SetWindowLongPtr(hwParent, GWLP_WNDPROC, (LONG_PTR)dialog_mode_wnd_proc);
2375
2376     zero_dm_messages();
2377     r = SendMessage(hwEdit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
2378     ok(1 == r, "expected 1, got %d\n", r);
2379     test_dm_messages(0, 0, 0, 0);
2380     zero_dm_messages();
2381
2382     r = SendMessage(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2383     ok(1 == r, "expected 1, got %d\n", r);
2384     test_dm_messages(0, 0, 0, 0);
2385     zero_dm_messages();
2386
2387     msg.hwnd = hwEdit;
2388     msg.message = WM_KEYDOWN;
2389     msg.wParam = VK_TAB;
2390     msg.lParam = 0xf0001;
2391     r = SendMessage(hwEdit, WM_GETDLGCODE, VK_TAB, (LPARAM)&msg);
2392     ok(0x89 == r, "expected 0x89, got 0x%x\n", r);
2393     test_dm_messages(0, 0, 0, 0);
2394     zero_dm_messages();
2395
2396     r = SendMessage(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2397     ok(1 == r, "expected 1, got %d\n", r);
2398     test_dm_messages(0, 0, 0, 0);
2399     zero_dm_messages();
2400
2401     destroy_child_editcontrol(hwEdit);
2402
2403     hwEdit = create_child_editcontrol(ES_MULTILINE, 0);
2404     hwParent = GetParent(hwEdit);
2405     SetWindowLongPtr(hwParent, GWLP_WNDPROC, (LONG_PTR)dialog_mode_wnd_proc);
2406
2407     r = SendMessage(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2408     ok(1 == r, "expected 1, got %d\n", r);
2409     test_dm_messages(0, 0, 0, 0);
2410     zero_dm_messages();
2411
2412     msg.hwnd = hwEdit;
2413     msg.message = WM_KEYDOWN;
2414     msg.wParam = VK_ESCAPE;
2415     msg.lParam = 0x10001;
2416     r = SendMessage(hwEdit, WM_GETDLGCODE, VK_ESCAPE, (LPARAM)&msg);
2417     ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2418     test_dm_messages(0, 0, 0, 0);
2419     zero_dm_messages();
2420
2421     r = SendMessage(hwEdit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
2422     ok(1 == r, "expected 1, got %d\n", r);
2423     test_dm_messages(0, 0, 0, 0);
2424     zero_dm_messages();
2425
2426     r = SendMessage(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2427     ok(1 == r, "expected 1, got %d\n", r);
2428     test_dm_messages(0, 0, 0, 1);
2429     zero_dm_messages();
2430
2431     r = SendMessage(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2432     ok(1 == r, "expected 1, got %d\n", r);
2433     test_dm_messages(0, 0, 1, 0);
2434     zero_dm_messages();
2435
2436     hwButton = CreateWindow("BUTTON", "OK", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
2437         100, 100, 50, 20, hwParent, (HMENU)ID_EDITTESTDBUTTON, hinst, NULL);
2438     ok(hwButton!=NULL, "CreateWindow failed with error code %d\n", GetLastError());
2439
2440     r = SendMessage(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2441     ok(1 == r, "expected 1, got %d\n", r);
2442     test_dm_messages(0, 0, 1, 1);
2443     zero_dm_messages();
2444
2445     DestroyWindow(hwButton);
2446     destroy_child_editcontrol(hwEdit);
2447 }
2448
2449 START_TEST(edit)
2450 {
2451     init_function_pointers();
2452
2453     hinst = GetModuleHandleA(NULL);
2454     assert(RegisterWindowClasses());
2455
2456     test_edit_control_1();
2457     test_edit_control_2();
2458     test_edit_control_3();
2459     test_edit_control_4();
2460     test_edit_control_5();
2461     test_edit_control_6();
2462     test_edit_control_limittext();
2463     test_edit_control_scroll();
2464     test_margins();
2465     test_margins_font_change();
2466     test_text_position();
2467     test_espassword();
2468     test_undo();
2469     test_enter();
2470     test_tab();
2471     test_edit_dialog();
2472     test_multi_edit_dialog();
2473     test_wantreturn_edit_dialog();
2474     test_singleline_wantreturn_edit_dialog();
2475     test_child_edit_wmkeydown();
2476     test_fontsize();
2477     test_dialogmode();
2478     if (pEndMenu)
2479         test_contextmenu_focus();
2480     else
2481         win_skip("EndMenu is not available\n");
2482
2483     UnregisterWindowClasses();
2484 }