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