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