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