~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/user32/tests/edit.c

Version: ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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_EDITTEST2 99
 32 #define MAXLEN 200
 33 
 34 struct edit_notify {
 35     int en_change, en_maxtext, en_update;
 36 };
 37 
 38 static struct edit_notify notifications;
 39 
 40 static INT_PTR CALLBACK multi_edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
 41 {
 42     static int num_ok_commands = 0;
 43     switch (msg)
 44     {
 45         case WM_INITDIALOG:
 46         {
 47             HWND hedit = GetDlgItem(hdlg, 1000);
 48             SetFocus(hedit);
 49             switch (lparam)
 50             {
 51                 /* test cases related to bug 12319 */
 52                 case 0:
 53                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
 54                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
 55                     break;
 56                 case 1:
 57                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
 58                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
 59                     break;
 60                 case 2:
 61                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
 62                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
 63                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
 64                     break;
 65 
 66                 /* test cases for pressing enter */
 67                 case 3:
 68                     num_ok_commands = 0;
 69                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
 70                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
 71                     break;
 72 
 73                 default:
 74                     break;
 75             }
 76             break;
 77         }
 78 
 79         case WM_COMMAND:
 80             if (HIWORD(wparam) != BN_CLICKED)
 81                 break;
 82 
 83             switch (LOWORD(wparam))
 84             {
 85                 case IDOK:
 86                     num_ok_commands++;
 87                     break;
 88 
 89                 default:
 90                     break;
 91             }
 92             break;
 93 
 94         case WM_USER:
 95         {
 96             HWND hfocus = GetFocus();
 97             HWND hedit = GetDlgItem(hdlg, 1000);
 98             HWND hedit2 = GetDlgItem(hdlg, 1001);
 99             HWND hedit3 = GetDlgItem(hdlg, 1002);
100 
101             if (wparam != 0xdeadbeef)
102                 break;
103 
104             switch (lparam)
105             {
106                 case 0:
107                     if (hfocus == hedit)
108                         EndDialog(hdlg, 1111);
109                     else if (hfocus == hedit2)
110                         EndDialog(hdlg, 2222);
111                     else if (hfocus == hedit3)
112                         EndDialog(hdlg, 3333);
113                     else
114                         EndDialog(hdlg, 4444);
115                     break;
116                 case 1:
117                     if ((hfocus == hedit) && (num_ok_commands == 0))
118                         EndDialog(hdlg, 11);
119                     else
120                         EndDialog(hdlg, 22);
121                     break;
122                 default:
123                     EndDialog(hdlg, 5555);
124             }
125             break;
126         }
127 
128         case WM_CLOSE:
129             EndDialog(hdlg, 333);
130             break;
131 
132         default:
133             break;
134     }
135 
136     return FALSE;
137 }
138 
139 static INT_PTR CALLBACK edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
140 {
141     switch (msg)
142     {
143         case WM_INITDIALOG:
144         {
145             HWND hedit = GetDlgItem(hdlg, 1000);
146             SetFocus(hedit);
147             switch (lparam)
148             {
149                 /* from bug 11841 */
150                 case 0:
151                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
152                     break;
153                 case 1:
154                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
155                     break;
156                 case 2:
157                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
158                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
159                     break;
160 
161                 /* more test cases for WM_CHAR */
162                 case 3:
163                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
164                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
165                     break;
166                 case 4:
167                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
168                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
169                     break;
170                 case 5:
171                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
172                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
173                     break;
174 
175                 /* more test cases for WM_KEYDOWN + WM_CHAR */
176                 case 6:
177                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
178                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
179                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
180                     break;
181                 case 7:
182                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
183                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
184                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
185                     break;
186                 case 8:
187                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
188                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
189                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
190                     break;
191 
192                 /* multiple tab tests */
193                 case 9:
194                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
195                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
196                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 2);
197                     break;
198                 case 10:
199                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
200                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
201                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
202                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 2);
203                     break;
204 
205                 default:
206                     break;
207             }
208             break;
209         }
210 
211         case WM_COMMAND:
212             if (HIWORD(wparam) != BN_CLICKED)
213                 break;
214 
215             switch (LOWORD(wparam))
216             {
217                 case IDOK:
218                     EndDialog(hdlg, 111);
219                     break;
220 
221                 case IDCANCEL:
222                     EndDialog(hdlg, 222);
223                     break;
224 
225                 default:
226                     break;
227             }
228             break;
229 
230         case WM_USER:
231         {
232             int len;
233             HWND hok = GetDlgItem(hdlg, IDOK);
234             HWND hcancel = GetDlgItem(hdlg, IDCANCEL);
235             HWND hedit = GetDlgItem(hdlg, 1000);
236             HWND hfocus = GetFocus();
237 
238             if (wparam != 0xdeadbeef)
239                 break;
240 
241             switch (lparam)
242             {
243                 case 0:
244                     len = SendMessage(hedit, WM_GETTEXTLENGTH, 0, 0);
245                     if (len == 0)
246                         EndDialog(hdlg, 444);
247                     else
248                         EndDialog(hdlg, 555);
249                     break;
250 
251                 case 1:
252                     len = SendMessage(hedit, WM_GETTEXTLENGTH, 0, 0);
253                     if ((hfocus == hok) && len == 0)
254                         EndDialog(hdlg, 444);
255                     else
256                         EndDialog(hdlg, 555);
257                     break;
258 
259                 case 2:
260                     if (hfocus == hok)
261                         EndDialog(hdlg, 11);
262                     else if (hfocus == hcancel)
263                         EndDialog(hdlg, 22);
264                     else if (hfocus == hedit)
265                         EndDialog(hdlg, 33);
266                     else
267                         EndDialog(hdlg, 44);
268                     break;
269 
270                 default:
271                     EndDialog(hdlg, 555);
272             }
273             break;
274         }
275 
276         case WM_CLOSE:
277             EndDialog(hdlg, 333);
278             break;
279 
280         default:
281             break;
282     }
283 
284     return FALSE;
285 }
286 
287 static INT_PTR CALLBACK edit_singleline_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
288 {
289     switch (msg)
290     {
291         case WM_INITDIALOG:
292         {
293             HWND hedit = GetDlgItem(hdlg, 1000);
294             SetFocus(hedit);
295             switch (lparam)
296             {
297                 /* test cases for WM_KEYDOWN */
298                 case 0:
299                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
300                     break;
301                 case 1:
302                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
303                     break;
304                 case 2:
305                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
306                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
307                     break;
308 
309                 /* test cases for WM_CHAR */
310                 case 3:
311                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
312                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
313                     break;
314                 case 4:
315                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
316                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
317                     break;
318                 case 5:
319                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
320                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
321                     break;
322 
323                 /* test cases for WM_KEYDOWN + WM_CHAR */
324                 case 6:
325                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
326                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
327                     break;
328                 case 7:
329                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
330                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
331                     break;
332                 case 8:
333                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
334                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
335                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
336                     break;
337 
338                 default:
339                     break;
340             }
341             break;
342         }
343 
344         case WM_COMMAND:
345             if (HIWORD(wparam) != BN_CLICKED)
346                 break;
347 
348             switch (LOWORD(wparam))
349             {
350                 case IDOK:
351                     EndDialog(hdlg, 111);
352                     break;
353 
354                 case IDCANCEL:
355                     EndDialog(hdlg, 222);
356                     break;
357 
358                 default:
359                     break;
360             }
361             break;
362 
363         case WM_USER:
364         {
365             HWND hok = GetDlgItem(hdlg, IDOK);
366             HWND hedit = GetDlgItem(hdlg, 1000);
367             HWND hfocus = GetFocus();
368             int len = SendMessage(hedit, WM_GETTEXTLENGTH, 0, 0);
369 
370             if (wparam != 0xdeadbeef)
371                 break;
372 
373             switch (lparam)
374             {
375                 case 0:
376                     if ((hfocus == hedit) && len == 0)
377                         EndDialog(hdlg, 444);
378                     else
379                         EndDialog(hdlg, 555);
380                     break;
381 
382                 case 1:
383                     if ((hfocus == hok) && len == 0)
384                         EndDialog(hdlg, 444);
385                     else
386                         EndDialog(hdlg, 555);
387                     break;
388 
389                 default:
390                     EndDialog(hdlg, 55);
391             }
392             break;
393         }
394 
395         case WM_CLOSE:
396             EndDialog(hdlg, 333);
397             break;
398 
399         default:
400             break;
401     }
402 
403     return FALSE;
404 }
405 
406 static INT_PTR CALLBACK edit_wantreturn_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
407 {
408     switch (msg)
409     {
410         case WM_INITDIALOG:
411         {
412             HWND hedit = GetDlgItem(hdlg, 1000);
413             SetFocus(hedit);
414             switch (lparam)
415             {
416                 /* test cases for WM_KEYDOWN */
417                 case 0:
418                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
419                     break;
420                 case 1:
421                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
422                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
423                     break;
424                 case 2:
425                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
426                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
427                     break;
428 
429                 /* test cases for WM_CHAR */
430                 case 3:
431                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
432                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
433                     break;
434                 case 4:
435                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
436                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 2);
437                     break;
438                 case 5:
439                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
440                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
441                     break;
442 
443                 /* test cases for WM_KEYDOWN + WM_CHAR */
444                 case 6:
445                     PostMessage(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
446                     PostMessage(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
447                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 0);
448                     break;
449                 case 7:
450                     PostMessage(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
451                     PostMessage(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
452                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 2);
453                     break;
454                 case 8:
455                     PostMessage(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
456                     PostMessage(hedit, WM_CHAR, VK_TAB, 0xf0001);
457                     PostMessage(hdlg, WM_USER, 0xdeadbeef, 1);
458                     break;
459 
460                 default:
461                     break;
462             }
463             break;
464         }
465 
466         case WM_COMMAND:
467             if (HIWORD(wparam) != BN_CLICKED)
468                 break;
469 
470             switch (LOWORD(wparam))
471             {
472                 case IDOK:
473                     EndDialog(hdlg, 111);
474                     break;
475 
476                 case IDCANCEL:
477                     EndDialog(hdlg, 222);
478                     break;
479 
480                 default:
481                     break;
482             }
483             break;
484 
485         case WM_USER:
486         {
487             HWND hok = GetDlgItem(hdlg, IDOK);
488             HWND hedit = GetDlgItem(hdlg, 1000);
489             HWND hfocus = GetFocus();
490             int len = SendMessage(hedit, WM_GETTEXTLENGTH, 0, 0);
491 
492             if (wparam != 0xdeadbeef)
493                 break;
494 
495             switch (lparam)
496             {
497                 case 0:
498                     if ((hfocus == hedit) && len == 0)
499                         EndDialog(hdlg, 444);
500                     else
501                         EndDialog(hdlg, 555);
502                     break;
503 
504                 case 1:
505                     if ((hfocus == hok) && len == 0)
506                         EndDialog(hdlg, 444);
507                     else
508                         EndDialog(hdlg, 555);
509                     break;
510 
511                 case 2:
512                     if ((hfocus == hedit) && len == 2)
513                         EndDialog(hdlg, 444);
514                     else
515                         EndDialog(hdlg, 555);
516                     break;
517 
518                 default:
519                     EndDialog(hdlg, 55);
520             }
521             break;
522         }
523 
524         case WM_CLOSE:
525             EndDialog(hdlg, 333);
526             break;
527 
528         default:
529             break;
530     }
531 
532     return FALSE;
533 }
534 
535 static HINSTANCE hinst;
536 static HWND hwndET2;
537 static const char szEditTest2Class[] = "EditTest2Class";
538 static const char szEditTest3Class[] = "EditTest3Class";
539 static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
540 
541 static HWND create_editcontrol (DWORD style, DWORD exstyle)
542 {
543     HWND handle;
544 
545     handle = CreateWindowEx(exstyle,
546                           "EDIT",
547                           "Test Text",
548                           style,
549                           10, 10, 300, 300,
550                           NULL, NULL, hinst, NULL);
551     assert (handle);
552     if (winetest_interactive)
553         ShowWindow (handle, SW_SHOW);
554     return handle;
555 }
556 
557 static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
558 {
559     HWND parentWnd;
560     HWND editWnd;
561     RECT rect;
562     
563     rect.left = 0;
564     rect.top = 0;
565     rect.right = 300;
566     rect.bottom = 300;
567     assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
568     
569     parentWnd = CreateWindowEx(0,
570                             szEditTextPositionClass,
571                             "Edit Test",
572                             WS_OVERLAPPEDWINDOW,
573                             CW_USEDEFAULT, CW_USEDEFAULT,
574                             rect.right - rect.left, rect.bottom - rect.top,
575                             NULL, NULL, hinst, NULL);
576     assert(parentWnd);
577 
578     editWnd = CreateWindowEx(exstyle,
579                             "EDIT",
580                             "Test Text",
581                             WS_CHILD | style,
582                             0, 0, 300, 300,
583                             parentWnd, NULL, hinst, NULL);
584     assert(editWnd);
585     if (winetest_interactive)
586         ShowWindow (parentWnd, SW_SHOW);
587     return editWnd;
588 }
589 
590 static void destroy_child_editcontrol (HWND hwndEdit)
591 {
592     if (GetParent(hwndEdit))
593         DestroyWindow(GetParent(hwndEdit));
594     else {
595         trace("Edit control has no parent!\n");
596         DestroyWindow(hwndEdit);
597     }
598 }
599 
600 static LONG get_edit_style (HWND hwnd)
601 {
602     return GetWindowLongA( hwnd, GWL_STYLE ) & (
603         ES_LEFT |
604 /* FIXME: not implemented
605         ES_CENTER |
606         ES_RIGHT |
607         ES_OEMCONVERT |
608 */
609         ES_MULTILINE |
610         ES_UPPERCASE |
611         ES_LOWERCASE |
612         ES_PASSWORD |
613         ES_AUTOVSCROLL |
614         ES_AUTOHSCROLL |
615         ES_NOHIDESEL |
616         ES_COMBO |
617         ES_READONLY |
618         ES_WANTRETURN |
619         ES_NUMBER
620         );
621 }
622 
623 static void set_client_height(HWND Wnd, unsigned Height)
624 {
625     RECT ClientRect, WindowRect;
626 
627     GetWindowRect(Wnd, &WindowRect);
628     GetClientRect(Wnd, &ClientRect);
629     SetWindowPos(Wnd, NULL, 0, 0,
630                  WindowRect.right - WindowRect.left,
631                  Height + (WindowRect.bottom - WindowRect.top) -
632                  (ClientRect.bottom - ClientRect.top),
633                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
634 
635     /* Workaround for a bug in Windows' edit control
636        (multi-line mode) */
637     GetWindowRect(Wnd, &WindowRect);             
638     SetWindowPos(Wnd, NULL, 0, 0,
639                  WindowRect.right - WindowRect.left + 1,
640                  WindowRect.bottom - WindowRect.top + 1,
641                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
642     SetWindowPos(Wnd, NULL, 0, 0,
643                  WindowRect.right - WindowRect.left,
644                  WindowRect.bottom - WindowRect.top,
645                  SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
646 
647     GetClientRect(Wnd, &ClientRect);
648     ok(ClientRect.bottom - ClientRect.top == Height,
649         "The client height should be %ld, but is %ld\n",
650         (long)Height, (long)(ClientRect.bottom - ClientRect.top));
651 }
652 
653 static void test_edit_control_1(void)
654 {
655     HWND hwEdit;
656     MSG msMessage;
657     int i;
658     LONG r;
659 
660     msMessage.message = WM_KEYDOWN;
661 
662     trace("EDIT: Single line\n");
663     hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
664     r = get_edit_style(hwEdit);
665     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%x\n", r);
666     for (i=0;i<65535;i++)
667     {
668         msMessage.wParam = i;
669         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
670         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
671             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
672     }
673     DestroyWindow (hwEdit);
674 
675     trace("EDIT: Single line want returns\n");
676     hwEdit = create_editcontrol(ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
677     r = get_edit_style(hwEdit);
678     ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%x\n", r);
679     for (i=0;i<65535;i++)
680     {
681         msMessage.wParam = i;
682         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
683         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
684             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
685     }
686     DestroyWindow (hwEdit);
687 
688     trace("EDIT: Multiline line\n");
689     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
690     r = get_edit_style(hwEdit);
691     ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%x\n", r);
692     for (i=0;i<65535;i++)
693     {
694         msMessage.wParam = i;
695         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
696         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
697             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
698     }
699     DestroyWindow (hwEdit);
700 
701     trace("EDIT: Multi line want returns\n");
702     hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
703     r = get_edit_style(hwEdit);
704     ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%x\n", r);
705     for (i=0;i<65535;i++)
706     {
707         msMessage.wParam = i;
708         r = SendMessage(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
709         ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
710             "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
711     }
712     DestroyWindow (hwEdit);
713 }
714 
715 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
716  * selection.  This test checks that the first 'select all' doesn't generate
717  * an UPDATE message which can escape and (via a handler) change the
718  * selection, which would cause WM_SETTEXT to break.  This old bug
719  * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
720  */
721 static void test_edit_control_2(void)
722 {
723     HWND hwndMain;
724     char szLocalString[MAXLEN];
725     LONG r;
726 
727     /* Create main and edit windows. */
728     hwndMain = CreateWindow(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW,
729                             0, 0, 200, 200, NULL, NULL, hinst, NULL);
730     assert(hwndMain);
731     if (winetest_interactive)
732         ShowWindow (hwndMain, SW_SHOW);
733 
734     hwndET2 = CreateWindow("EDIT", NULL,
735                            WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
736                            0, 0, 150, 50, /* important this not be 0 size. */
737                            hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
738     assert(hwndET2);
739     if (winetest_interactive)
740         ShowWindow (hwndET2, SW_SHOW);
741 
742     trace("EDIT: SETTEXT atomicity\n");
743     /* Send messages to "type" in the word 'foo'. */
744     r = SendMessage(hwndET2, WM_CHAR, 'f', 1);
745     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
746     r = SendMessage(hwndET2, WM_CHAR, 'o', 1);
747     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
748     r = SendMessage(hwndET2, WM_CHAR, 'o', 1);
749     ok(1 == r, "Expected: %d, got: %d\n", 1, r);
750     /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
751     GetWindowText(hwndET2, szLocalString, MAXLEN);
752     ok(lstrcmp(szLocalString, "bar")==0,
753        "Wrong contents of edit: %s\n", szLocalString);
754 
755     /* OK, done! */
756     DestroyWindow (hwndET2);
757     DestroyWindow (hwndMain);
758 }
759 
760 static void ET2_check_change(void) {
761    char szLocalString[MAXLEN];
762    /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
763    GetWindowText(hwndET2, szLocalString, MAXLEN);
764    if (lstrcmp(szLocalString, "foo")==0) {
765        lstrcpy(szLocalString, "bar");
766        SendMessage(hwndET2, WM_SETTEXT, 0, (LPARAM) szLocalString);
767    }
768    /* always leave the cursor at the end. */
769    SendMessage(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
770 }
771 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
772 {
773     if (id==ID_EDITTEST2 && codeNotify == EN_UPDATE)
774         ET2_check_change();
775 }
776 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
777 {
778     switch (iMsg) {
779     case WM_COMMAND:
780         ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
781         break;
782     }
783     return DefWindowProc(hwnd, iMsg, wParam, lParam);
784 }
785 
786 static void zero_notify(void)
787 {
788     notifications.en_change = 0;
789     notifications.en_maxtext = 0;
790     notifications.en_update = 0;
791 }
792 
793 #define test_notify(enchange, enmaxtext, enupdate) \
794     ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
795     "got %d\n", enchange, notifications.en_change); \
796     ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
797     "got %d\n", enmaxtext, notifications.en_maxtext); \
798     ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
799     "got %d\n", enupdate, notifications.en_update)
800 
801 
802 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
803 {
804     switch (msg) {
805         case WM_COMMAND:
806             switch (HIWORD(wParam)) {
807                 case EN_MAXTEXT:
808                     notifications.en_maxtext++;
809                     break;
810                 case EN_UPDATE:
811                     notifications.en_update++;
812                     break;
813                 case EN_CHANGE:
814                     notifications.en_change++;
815                     break;
816             }
817             break;
818     }
819     return DefWindowProcA(hWnd, msg, wParam, lParam);
820 }
821 
822 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response
823  * to these messages.
824  */
825 static void test_edit_control_3(void)
826 {
827     HWND hWnd;
828     HWND hParent;
829     int len;
830     static const char *str = "this is a long string.";
831     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.";
832 
833     trace("EDIT: Test notifications\n");
834 
835     hParent = CreateWindowExA(0,
836               szEditTest3Class,
837               NULL,
838               0,
839               CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
840               NULL, NULL, NULL, NULL);
841     assert(hParent);
842 
843     trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
844     hWnd = CreateWindowExA(0,
845               "EDIT",
846               NULL,
847               0,
848               10, 10, 50, 50,
849               hParent, NULL, NULL, NULL);
850     assert(hWnd);
851 
852     zero_notify();
853     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
854     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
855     ok(lstrlenA(str) > len, "text should have been truncated\n");
856     test_notify(1, 1, 1);
857 
858     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
859     zero_notify();
860     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
861     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
862     ok(1 == len, "wrong text length, expected 1, got %d\n", len);
863     test_notify(1, 0, 1);
864 
865     zero_notify();
866     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
867     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
868     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
869     test_notify(1, 0, 1);
870 
871     SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
872 
873     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
874     zero_notify();
875     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
876     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
877     ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
878     test_notify(1, 1, 1);
879 
880     zero_notify();
881     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
882     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
883     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
884     test_notify(1, 0, 1);
885 
886     DestroyWindow(hWnd);
887 
888     trace("EDIT: Single line, ES_AUTOHSCROLL\n");
889     hWnd = CreateWindowExA(0,
890               "EDIT",
891               NULL,
892               ES_AUTOHSCROLL,
893               10, 10, 50, 50,
894               hParent, NULL, NULL, NULL);
895     assert(hWnd);
896 
897     zero_notify();
898     SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
899     len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
900     ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
901     test_notify(1, 0, 1);
902 
903     zero_notify();
904     SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
905     len = SendMessageA(hWnd,