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