ReactOS 0.4.16-dev-125-g798ea90
edit.c
Go to the documentation of this file.
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 <windows.h>
22#include <commctrl.h>
23
24#include "wine/test.h"
25#include "v6util.h"
26#include "msg.h"
27
28#ifndef ES_COMBO
29#define ES_COMBO 0x200
30#endif
31
32#define ID_EDITTESTDBUTTON 0x123
33#define ID_EDITTEST2 99
34#define MAXLEN 200
35
37{
40};
41
43{
46};
47
49
52};
53
55
57{
58 static int num_ok_commands = 0;
59 switch (msg)
60 {
61 case WM_INITDIALOG:
62 {
63 HWND hedit = GetDlgItem(hdlg, 1000);
64 SetFocus(hedit);
65 switch (lparam)
66 {
67 /* test cases related to bug 12319 */
68 case 0:
69 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
70 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
71 break;
72 case 1:
73 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
74 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
75 break;
76 case 2:
77 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
78 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
79 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
80 break;
81
82 /* test cases for pressing enter */
83 case 3:
84 num_ok_commands = 0;
85 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
86 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
87 break;
88
89 default:
90 break;
91 }
92 break;
93 }
94
95 case WM_COMMAND:
96 if (HIWORD(wparam) != BN_CLICKED)
97 break;
98
99 switch (LOWORD(wparam))
100 {
101 case IDOK:
102 num_ok_commands++;
103 break;
104
105 default:
106 break;
107 }
108 break;
109
110 case WM_USER:
111 {
112 HWND hfocus = GetFocus();
113 HWND hedit = GetDlgItem(hdlg, 1000);
114 HWND hedit2 = GetDlgItem(hdlg, 1001);
115 HWND hedit3 = GetDlgItem(hdlg, 1002);
116
117 if (wparam != 0xdeadbeef)
118 break;
119
120 switch (lparam)
121 {
122 case 0:
123 if (hfocus == hedit)
124 EndDialog(hdlg, 1111);
125 else if (hfocus == hedit2)
126 EndDialog(hdlg, 2222);
127 else if (hfocus == hedit3)
128 EndDialog(hdlg, 3333);
129 else
130 EndDialog(hdlg, 4444);
131 break;
132 case 1:
133 if ((hfocus == hedit) && (num_ok_commands == 0))
134 EndDialog(hdlg, 11);
135 else
136 EndDialog(hdlg, 22);
137 break;
138 default:
139 EndDialog(hdlg, 5555);
140 }
141 break;
142 }
143
144 case WM_CLOSE:
145 EndDialog(hdlg, 333);
146 break;
147
148 default:
149 break;
150 }
151
152 return FALSE;
153}
154
156{
157 switch (msg)
158 {
159 case WM_INITDIALOG:
160 {
161 HWND hedit = GetDlgItem(hdlg, 1000);
162 SetFocus(hedit);
163 switch (lparam)
164 {
165 /* from bug 11841 */
166 case 0:
167 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
168 break;
169 case 1:
170 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
171 break;
172 case 2:
173 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
174 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
175 break;
176
177 /* more test cases for WM_CHAR */
178 case 3:
179 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
180 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
181 break;
182 case 4:
183 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
184 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
185 break;
186 case 5:
187 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
188 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
189 break;
190
191 /* more test cases for WM_KEYDOWN + WM_CHAR */
192 case 6:
193 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
194 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
195 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
196 break;
197 case 7:
198 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
199 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
200 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
201 break;
202 case 8:
203 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
204 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
205 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
206 break;
207
208 /* multiple tab tests */
209 case 9:
210 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
211 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
212 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
213 break;
214 case 10:
215 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
216 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
217 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
218 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
219 break;
220
221 default:
222 break;
223 }
224 break;
225 }
226
227 case WM_COMMAND:
228 if (HIWORD(wparam) != BN_CLICKED)
229 break;
230
231 switch (LOWORD(wparam))
232 {
233 case IDOK:
234 EndDialog(hdlg, 111);
235 break;
236
237 case IDCANCEL:
238 EndDialog(hdlg, 222);
239 break;
240
241 default:
242 break;
243 }
244 break;
245
246 case WM_USER:
247 {
248 int len;
249 HWND hok = GetDlgItem(hdlg, IDOK);
250 HWND hcancel = GetDlgItem(hdlg, IDCANCEL);
251 HWND hedit = GetDlgItem(hdlg, 1000);
252 HWND hfocus = GetFocus();
253
254 if (wparam != 0xdeadbeef)
255 break;
256
257 switch (lparam)
258 {
259 case 0:
260 len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
261 if (len == 0)
262 EndDialog(hdlg, 444);
263 else
264 EndDialog(hdlg, 555);
265 break;
266
267 case 1:
268 len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
269 if ((hfocus == hok) && len == 0)
270 EndDialog(hdlg, 444);
271 else
272 EndDialog(hdlg, 555);
273 break;
274
275 case 2:
276 if (hfocus == hok)
277 EndDialog(hdlg, 11);
278 else if (hfocus == hcancel)
279 EndDialog(hdlg, 22);
280 else if (hfocus == hedit)
281 EndDialog(hdlg, 33);
282 else
283 EndDialog(hdlg, 44);
284 break;
285
286 default:
287 EndDialog(hdlg, 555);
288 }
289 break;
290 }
291
292 case WM_CLOSE:
293 EndDialog(hdlg, 333);
294 break;
295
296 default:
297 break;
298 }
299
300 return FALSE;
301}
302
304{
305 switch (msg)
306 {
307 case WM_INITDIALOG:
308 {
309 HWND hedit = GetDlgItem(hdlg, 1000);
310 SetFocus(hedit);
311 switch (lparam)
312 {
313 /* test cases for WM_KEYDOWN */
314 case 0:
315 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
316 break;
317 case 1:
318 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
319 break;
320 case 2:
321 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
322 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
323 break;
324
325 /* test cases for WM_CHAR */
326 case 3:
327 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
328 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
329 break;
330 case 4:
331 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
332 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
333 break;
334 case 5:
335 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
336 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
337 break;
338
339 /* test cases for WM_KEYDOWN + WM_CHAR */
340 case 6:
341 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
342 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
343 break;
344 case 7:
345 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
346 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
347 break;
348 case 8:
349 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
350 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
351 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
352 break;
353
354 default:
355 break;
356 }
357 break;
358 }
359
360 case WM_COMMAND:
361 if (HIWORD(wparam) != BN_CLICKED)
362 break;
363
364 switch (LOWORD(wparam))
365 {
366 case IDOK:
367 EndDialog(hdlg, 111);
368 break;
369
370 case IDCANCEL:
371 EndDialog(hdlg, 222);
372 break;
373
374 default:
375 break;
376 }
377 break;
378
379 case WM_USER:
380 {
381 HWND hok = GetDlgItem(hdlg, IDOK);
382 HWND hedit = GetDlgItem(hdlg, 1000);
383 HWND hfocus = GetFocus();
384 int len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
385
386 if (wparam != 0xdeadbeef)
387 break;
388
389 switch (lparam)
390 {
391 case 0:
392 if ((hfocus == hedit) && len == 0)
393 EndDialog(hdlg, 444);
394 else
395 EndDialog(hdlg, 555);
396 break;
397
398 case 1:
399 if ((hfocus == hok) && len == 0)
400 EndDialog(hdlg, 444);
401 else
402 EndDialog(hdlg, 555);
403 break;
404
405 default:
406 EndDialog(hdlg, 55);
407 }
408 break;
409 }
410
411 case WM_CLOSE:
412 EndDialog(hdlg, 333);
413 break;
414
415 default:
416 break;
417 }
418
419 return FALSE;
420}
421
423{
424 switch (msg)
425 {
426 case WM_INITDIALOG:
427 {
428 HWND hedit = GetDlgItem(hdlg, 1000);
429 SetFocus(hedit);
430 switch (lparam)
431 {
432 /* test cases for WM_KEYDOWN */
433 case 0:
434 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
435 break;
436 case 1:
437 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
438 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
439 break;
440 case 2:
441 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
442 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
443 break;
444
445 /* test cases for WM_CHAR */
446 case 3:
447 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
448 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
449 break;
450 case 4:
451 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
452 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
453 break;
454 case 5:
455 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
456 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
457 break;
458
459 /* test cases for WM_KEYDOWN + WM_CHAR */
460 case 6:
461 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
462 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
463 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
464 break;
465 case 7:
466 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
467 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
468 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
469 break;
470 case 8:
471 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
472 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
473 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
474 break;
475
476 default:
477 break;
478 }
479 break;
480 }
481
482 case WM_COMMAND:
483 if (HIWORD(wparam) != BN_CLICKED)
484 break;
485
486 switch (LOWORD(wparam))
487 {
488 case IDOK:
489 EndDialog(hdlg, 111);
490 break;
491
492 case IDCANCEL:
493 EndDialog(hdlg, 222);
494 break;
495
496 default:
497 break;
498 }
499 break;
500
501 case WM_USER:
502 {
503 HWND hok = GetDlgItem(hdlg, IDOK);
504 HWND hedit = GetDlgItem(hdlg, 1000);
505 HWND hfocus = GetFocus();
506 int len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
507
508 if (wparam != 0xdeadbeef)
509 break;
510
511 switch (lparam)
512 {
513 case 0:
514 if ((hfocus == hedit) && len == 0)
515 EndDialog(hdlg, 444);
516 else
517 EndDialog(hdlg, 555);
518 break;
519
520 case 1:
521 if ((hfocus == hok) && len == 0)
522 EndDialog(hdlg, 444);
523 else
524 EndDialog(hdlg, 555);
525 break;
526
527 case 2:
528 if ((hfocus == hedit) && len == 2)
529 EndDialog(hdlg, 444);
530 else
531 EndDialog(hdlg, 555);
532 break;
533
534 default:
535 EndDialog(hdlg, 55);
536 }
537 break;
538 }
539
540 case WM_CLOSE:
541 EndDialog(hdlg, 333);
542 break;
543
544 default:
545 break;
546 }
547
548 return FALSE;
549}
550
553static const char szEditTest2Class[] = "EditTest2Class";
554static const char szEditTest3Class[] = "EditTest3Class";
555static const char szEditTest4Class[] = "EditTest4Class";
556static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
557
559{
560 HWND handle;
561
562 handle = CreateWindowExA(exstyle, WC_EDITA, "Text Text", style, 10, 10, 300, 300,
563 NULL, NULL, hinst, NULL);
564 ok (handle != NULL, "CreateWindow EDIT Control failed\n");
565
568 return handle;
569}
570
572{
573 static const WCHAR testtextW[] = {'T','e','s','t',' ','t','e','x','t',0};
574 HWND handle;
575
576 handle = CreateWindowExW(exstyle, WC_EDITW, testtextW, style, 10, 10, 300, 300,
577 NULL, NULL, hinst, NULL);
578 ok(handle != NULL, "Failed to create Edit control.\n");
579 return handle;
580}
581
583{
584 HWND parentWnd;
585 HWND editWnd;
586 RECT rect;
587 BOOL b;
588 SetRect(&rect, 0, 0, 300, 300);
590 ok(b, "AdjustWindowRect failed\n");
591
592 parentWnd = CreateWindowExA(0,
594 "Edit Test",
597 rect.right - rect.left, rect.bottom - rect.top,
598 NULL, NULL, hinst, NULL);
599 ok (parentWnd != NULL, "CreateWindow EDIT Test failed\n");
600
601 editWnd = CreateWindowExA(exstyle,
602 "EDIT",
603 "Test Text",
604 WS_CHILD | style,
605 0, 0, 300, 300,
606 parentWnd, NULL, hinst, NULL);
607 ok (editWnd != NULL, "CreateWindow EDIT Test Text failed\n");
609 ShowWindow (parentWnd, SW_SHOW);
610 return editWnd;
611}
612
614{
615 if (GetParent(hwndEdit))
617 else {
618 trace("Edit control has no parent!\n");
620 }
621}
622
624{
625 return GetWindowLongA( hwnd, GWL_STYLE ) & (
626 ES_LEFT |
627/* FIXME: not implemented
628 ES_CENTER |
629 ES_RIGHT |
630 ES_OEMCONVERT |
631*/
639 ES_COMBO |
643 );
644}
645
646static void set_client_height(HWND Wnd, unsigned Height)
647{
648 RECT ClientRect, WindowRect;
649
650 GetWindowRect(Wnd, &WindowRect);
651 GetClientRect(Wnd, &ClientRect);
652 SetWindowPos(Wnd, NULL, 0, 0,
653 WindowRect.right - WindowRect.left,
654 Height + (WindowRect.bottom - WindowRect.top) -
655 (ClientRect.bottom - ClientRect.top),
657
658 /* Workaround for a bug in Windows' edit control
659 (multi-line mode) */
660 GetWindowRect(Wnd, &WindowRect);
661 SetWindowPos(Wnd, NULL, 0, 0,
662 WindowRect.right - WindowRect.left + 1,
663 WindowRect.bottom - WindowRect.top + 1,
665 SetWindowPos(Wnd, NULL, 0, 0,
666 WindowRect.right - WindowRect.left,
667 WindowRect.bottom - WindowRect.top,
669
670 GetClientRect(Wnd, &ClientRect);
671 ok(ClientRect.bottom - ClientRect.top == Height,
672 "The client height should be %d, but is %d\n",
673 Height, ClientRect.bottom - ClientRect.top);
674}
675
676static void test_edit_control_1(void)
677{
678 HWND hwEdit;
679 MSG msMessage;
680 int i;
681 LONG r;
682
683 msMessage.message = WM_KEYDOWN;
684
685 trace("EDIT: Single line\n");
687 r = get_edit_style(hwEdit);
688 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%x\n", r);
689 for (i = 0; i < 65535; i++)
690 {
691 msMessage.wParam = i;
692 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
694 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
695 }
696 DestroyWindow(hwEdit);
697
698 trace("EDIT: Single line want returns\n");
700 r = get_edit_style(hwEdit);
701 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%x\n", r);
702 for (i = 0; i < 65535; i++)
703 {
704 msMessage.wParam = i;
705 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
707 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
708 }
709 DestroyWindow(hwEdit);
710
711 trace("EDIT: Multiline line\n");
713 r = get_edit_style(hwEdit);
714 ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%x\n", r);
715 for (i = 0; i < 65535; i++)
716 {
717 msMessage.wParam = i;
718 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
720 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
721 }
722 DestroyWindow(hwEdit);
723
724 trace("EDIT: Multi line want returns\n");
726 r = get_edit_style(hwEdit);
727 ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%x\n", r);
728 for (i = 0; i < 65535; i++)
729 {
730 msMessage.wParam = i;
731 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
733 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
734 }
735 DestroyWindow(hwEdit);
736}
737
738/* WM_SETTEXT is implemented by selecting all text, and then replacing the
739 * selection. This test checks that the first 'select all' doesn't generate
740 * an UPDATE message which can escape and (via a handler) change the
741 * selection, which would cause WM_SETTEXT to break. This old bug
742 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
743 */
744static void test_edit_control_2(void)
745{
746 HWND hwndMain, phwnd;
747 char szLocalString[MAXLEN];
748 LONG r, w = 150, h = 50;
749 POINT cpos;
750
751 /* Create main and edit windows. */
753 0, 0, 200, 200, NULL, NULL, hinst, NULL);
754 ok(hwndMain != NULL, "Failed to create control parent.\n");
757
759 0, 0, w, h, /* important this not be 0 size. */
761 ok(hwndET2 != NULL, "Failed to create Edit control.\n");
764
765 trace("EDIT: SETTEXT atomicity\n");
766 /* Send messages to "type" in the word 'foo'. */
767 r = SendMessageA(hwndET2, WM_CHAR, 'f', 1);
768 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
769 r = SendMessageA(hwndET2, WM_CHAR, 'o', 1);
770 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
771 r = SendMessageA(hwndET2, WM_CHAR, 'o', 1);
772 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
773 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
774 GetWindowTextA(hwndET2, szLocalString, MAXLEN);
775 ok(strcmp(szLocalString, "bar")==0,
776 "Wrong contents of edit: %s\n", szLocalString);
777
778 /* try setting the caret before it's visible */
779 r = SetCaretPos(0, 0);
780 todo_wine ok(0 == r, "SetCaretPos succeeded unexpectedly, expected: 0, got: %d\n", r);
781 phwnd = SetFocus(hwndET2);
782 ok(phwnd != NULL, "SetFocus failed unexpectedly, expected non-zero, got NULL\n");
783 r = SetCaretPos(0, 0);
784 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
785 r = GetCaretPos(&cpos);
786 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
787 ok(cpos.x == 0 && cpos.y == 0, "Wrong caret position, expected: (0,0), got: (%d,%d)\n", cpos.x, cpos.y);
788 r = SetCaretPos(-1, -1);
789 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
790 r = GetCaretPos(&cpos);
791 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
792 ok(cpos.x == -1 && cpos.y == -1, "Wrong caret position, expected: (-1,-1), got: (%d,%d)\n", cpos.x, cpos.y);
793 r = SetCaretPos(w << 1, h << 1);
794 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
795 r = GetCaretPos(&cpos);
796 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
797 ok(cpos.x == (w << 1) && cpos.y == (h << 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w << 1, h << 1, cpos.x, cpos.y);
798 r = SetCaretPos(w, h);
799 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
800 r = GetCaretPos(&cpos);
801 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
802 ok(cpos.x == w && cpos.y == h, "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w, h, cpos.x, cpos.y);
803 r = SetCaretPos(w - 1, h - 1);
804 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
805 r = GetCaretPos(&cpos);
806 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
807 ok(cpos.x == (w - 1) && cpos.y == (h - 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w - 1, h - 1, cpos.x, cpos.y);
808
811}
812
813static void ET2_check_change(void)
814{
815 char szLocalString[MAXLEN];
816 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
817 GetWindowTextA(hwndET2, szLocalString, MAXLEN);
818 if (!strcmp(szLocalString, "foo"))
819 {
820 strcpy(szLocalString, "bar");
821 SendMessageA(hwndET2, WM_SETTEXT, 0, (LPARAM)szLocalString);
822 }
823 /* always leave the cursor at the end. */
825}
826
827static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
828{
829 if (id == ID_EDITTEST2 && codeNotify == EN_UPDATE)
831}
832
834{
835 switch (iMsg)
836 {
837 case WM_COMMAND:
839 break;
840 }
841 return DefWindowProcA(hwnd, iMsg, wParam, lParam);
842}
843
844static void zero_notify(void)
845{
846 notifications.en_change = 0;
847 notifications.en_maxtext = 0;
848 notifications.en_update = 0;
849}
850
851#define test_notify(enchange, enmaxtext, enupdate) \
852do { \
853 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
854 "got %d\n", enchange, notifications.en_change); \
855 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
856 "got %d\n", enmaxtext, notifications.en_maxtext); \
857 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
858 "got %d\n", enupdate, notifications.en_update); \
859} while(0)
860
862{
863 switch (msg)
864 {
865 case WM_COMMAND:
866 switch (HIWORD(wParam))
867 {
868 case EN_MAXTEXT:
869 notifications.en_maxtext++;
870 break;
871 case EN_UPDATE:
872 notifications.en_update++;
873 break;
874 case EN_CHANGE:
875 notifications.en_change++;
876 break;
877 }
878 break;
879 }
881}
882
884{
885 static LONG defwndproc_counter = 0;
886 struct message msg = { 0 };
887 LRESULT ret;
888
889 msg.message = message;
890 msg.flags = sent|wparam|id;
891 if (defwndproc_counter) msg.flags |= defwinproc;
892 msg.wParam = wParam;
893 msg.id = PARENT_ID;
894
895 if (message != WM_IME_SETCONTEXT &&
897 message != WM_GETICON &&
900 message != WM_PAINT &&
902 message < 0xc000)
903 {
905 }
906
907 defwndproc_counter++;
909 defwndproc_counter--;
910
911 return ret;
912}
913
915{
917 static LONG defwndproc_counter = 0;
918 struct message msg = { 0 };
919 LRESULT ret;
920
921 msg.message = message;
922 msg.flags = sent|wparam|id;
923 if (defwndproc_counter) msg.flags |= defwinproc;
924 msg.wParam = wParam;
925 msg.id = EDIT_ID;
926
927 if (message != WM_IME_SETCONTEXT &&
929 {
931 }
932
933 defwndproc_counter++;
936 else
938 defwndproc_counter--;
939
940 return ret;
941}
942
943/* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response
944 * to these messages.
945 */
946static void test_edit_control_3(void)
947{
948 static const char *str = "this is a long string.";
949 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.";
950 HWND hWnd, hParent;
951 int len, dpi;
952 HDC hDC;
953
954 hDC = GetDC(NULL);
957
958 trace("EDIT: Test notifications\n");
959
960 hParent = CreateWindowExA(0,
962 NULL,
963 0,
965 NULL, NULL, NULL, NULL);
966 ok(hParent != NULL, "Failed to create control parent.\n");
967
968 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
969 hWnd = CreateWindowExA(0, WC_EDITA, NULL, 0, 10, 10, 50, 50, hParent, NULL, NULL, NULL);
970 ok(hWnd != NULL, "Failed to create Edit control.\n");
971
972 zero_notify();
975 if (len == lstrlenA(str)) /* Win 8 */
976 test_notify(1, 0, 1);
977 else
978 test_notify(1, 1, 1);
979
981 zero_notify();
984 ok(1 == len, "wrong text length, expected 1, got %d\n", len);
985 test_notify(1, 0, 1);
986
987 zero_notify();
990 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
991 test_notify(1, 0, 1);
992
993 len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
994 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
995 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
996 SendMessageA(hParent, WM_SETFOCUS, 0, (LPARAM)hWnd);
997 len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
998 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
999 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
1000
1002
1004 zero_notify();
1007 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1008 test_notify(1, 1, 1);
1009
1010 zero_notify();
1013 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1014 test_notify(1, 0, 1);
1015
1017
1018 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
1019 hWnd = CreateWindowExA(0, WC_EDITA, NULL, ES_AUTOHSCROLL, 10, 10, 50, 50, hParent, NULL, NULL, NULL);
1020 ok(hWnd != NULL, "Failed to create Edit control.\n");
1021
1022 zero_notify();
1025 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1026 test_notify(1, 0, 1);
1027
1028 zero_notify();
1031 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1032 test_notify(1, 0, 1);
1033
1035 zero_notify();
1038 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1039 test_notify(1, 0, 1);
1040
1041 zero_notify();
1042 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1044 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1045 test_notify(1, 0, 1);
1046
1048
1050 zero_notify();
1053 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1054 test_notify(1, 1, 1);
1055
1056 zero_notify();
1059 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1060 test_notify(1, 0, 1);
1061
1063
1064 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1066 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1067 hParent, NULL, NULL, NULL);
1068 ok(hWnd != NULL, "Failed to create Edit control.\n");
1069
1070 zero_notify();
1073 if (len == lstrlenA(str)) /* Win 8 */
1074 test_notify(1, 0, 1);
1075 else
1076 {
1077 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1078 test_notify(1, 1, 1);
1079 }
1080
1082 zero_notify();
1085 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1086 test_notify(1, 0, 1);
1087
1088 zero_notify();
1091 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1092 test_notify(0, 0, 0);
1093
1095
1097 zero_notify();
1100 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1101 test_notify(1, 1, 1);
1102
1103 zero_notify();
1106 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1107 test_notify(0, 0, 0);
1108
1110
1111 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1113 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1114 hParent, NULL, NULL, NULL);
1115 ok(hWnd != NULL, "Failed to create Edit control.\n");
1116
1117 zero_notify();
1120 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1121 test_notify(1, 1, 1);
1122
1124 zero_notify();
1127 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1128 test_notify(1, 0, 1);
1129
1130 zero_notify();
1131 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1133 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1134 test_notify(0, 0, 0);
1135
1137
1139 zero_notify();
1142 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1143 test_notify(1, 1, 1);
1144
1145 zero_notify();
1146 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1148 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1149 test_notify(0, 0, 0);
1150
1152
1153 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1155 10, 10, 50, 50, hParent, NULL, NULL, NULL);
1156 ok(hWnd != NULL, "Failed to create Edit control.\n");
1157
1158 zero_notify();
1161 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1162 test_notify(1, 0, 1);
1163
1164 zero_notify();
1165 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1167 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1168 test_notify(0, 0, 0);
1169
1171
1173 zero_notify();
1176 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1177 test_notify(1, 1, 1);
1178
1179 zero_notify();
1180 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1182 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1183 test_notify(0, 0, 0);
1184
1186}
1187
1188static void test_char_from_pos(void)
1189{
1190 int lo, hi, mid, ret, i;
1191 HWND hwEdit;
1192 HDC dc;
1193 SIZE size;
1194
1196 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1197 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1198 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1199 mid = lo + (hi - lo) / 2;
1200
1201 for (i = lo; i < mid; i++)
1202 {
1203 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1204 ok(0 == ret, "expected 0 got %d\n", ret);
1205 }
1206
1207 for (i = mid; i <= hi; i++)
1208 {
1209 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1210 ok(1 == ret, "expected 1 got %d\n", ret);
1211 }
1212
1213 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1214 ok(-1 == ret, "expected -1 got %d\n", ret);
1215 DestroyWindow(hwEdit);
1216
1218 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1219 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1220 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1221 mid = lo + (hi - lo) / 2;
1222
1223 for (i = lo; i < mid; i++)
1224 {
1225 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1226 ok(0 == ret, "expected 0 got %d\n", ret);
1227 }
1228
1229 for (i = mid; i <= hi; i++)
1230 {
1231 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1232 ok(1 == ret, "expected 1 got %d\n", ret);
1233 }
1234
1235 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1236 ok(-1 == ret, "expected -1 got %d\n", ret);
1237 DestroyWindow(hwEdit);
1238
1240 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1241 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1242 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1243 mid = lo + (hi - lo) / 2;
1244
1245 for (i = lo; i < mid; i++)
1246 {
1247 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1248 ok(0 == ret, "expected 0 got %d\n", ret);
1249 }
1250
1251 for (i = mid; i <= hi; i++)
1252 {
1253 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1254 ok(1 == ret, "expected 1 got %d\n", ret);
1255 }
1256
1257 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1258 ok(-1 == ret, "expected -1 got %d\n", ret);
1259 DestroyWindow(hwEdit);
1260
1262 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1263 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1264 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1265 mid = lo + (hi - lo) / 2 + 1;
1266
1267 for (i = lo; i < mid; i++)
1268 {
1269 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1270 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1271 }
1272
1273 for (i = mid; i <= hi; i++)
1274 {
1275 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1276 ok(1 == ret, "expected 1 got %d\n", ret);
1277 }
1278
1279 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1280 ok(-1 == ret, "expected -1 got %d\n", ret);
1281 DestroyWindow(hwEdit);
1282
1284 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1285 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1286 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1287 mid = lo + (hi - lo) / 2 + 1;
1288
1289 for (i = lo; i < mid; i++)
1290 {
1291 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1292 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1293 }
1294
1295 for (i = mid; i <= hi; i++)
1296 {
1297 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1298 ok(1 == ret, "expected 1 got %d\n", ret);
1299 }
1300
1301 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1302 ok(-1 == ret, "expected -1 got %d\n", ret);
1303 DestroyWindow(hwEdit);
1304
1306 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1307 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1308 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1309 mid = lo + (hi - lo) / 2 + 1;
1310
1311 for (i = lo; i < mid; i++)
1312 {
1313 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1314 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1315 }
1316
1317 for (i = mid; i <= hi; i++)
1318 {
1319 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1320 ok(1 == ret, "expected 1 got %d\n", ret);
1321 }
1322
1323 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1324 ok(-1 == ret, "expected -1 got %d\n", ret);
1325 DestroyWindow(hwEdit);
1326
1327 /* Scrolled to the right with partially visible line, position on next line. */
1329
1330 dc = GetDC(hwEdit);
1331 GetTextExtentPoint32A(dc, "w", 1, &size);
1332 ReleaseDC(hwEdit, dc);
1333
1334 SetWindowPos(hwEdit, NULL, 0, 0, size.cx * 15, size.cy * 5, SWP_NOMOVE | SWP_NOZORDER);
1335 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"wwwwwwwwwwwwwwwwwwww\r\n\r\n");
1336 SendMessageA(hwEdit, EM_SETSEL, 40, 40);
1337
1338 lo = (short)SendMessageA(hwEdit, EM_POSFROMCHAR, 22, 0);
1339 ret = (short)SendMessageA(hwEdit, EM_POSFROMCHAR, 20, 0);
1340 ret -= 20 * size.cx; /* Calculate expected position, 20 characters back. */
1341 ok(ret == lo, "Unexpected position %d vs %d.\n", lo, ret);
1342
1343 DestroyWindow(hwEdit);
1344}
1345
1346/* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1347 * truncates text that doesn't fit.
1348 */
1349static void test_edit_control_5(void)
1350{
1351 static const char *str = "test\r\ntest";
1352 HWND parentWnd;
1353 HWND hWnd;
1354 int len;
1355 RECT rc1 = { 10, 10, 11, 11};
1356 RECT rc;
1357
1358 /* first show that a non-child won't do for this test */
1359 hWnd = CreateWindowExA(0, WC_EDITA, str, 0, 10, 10, 1, 1, NULL, NULL, NULL, NULL);
1360 ok(hWnd != NULL, "Failed to create Edit control.\n");
1361
1362 /* size of non-child edit control is (much) bigger than requested */
1363 GetWindowRect( hWnd, &rc);
1364 ok( rc.right - rc.left > 20, "size of the window (%d) is smaller than expected\n",
1365 rc.right - rc.left);
1367 /* so create a parent, and give it edit controls children to test with */
1368 parentWnd = CreateWindowExA(0,
1370 "Edit Test", WS_VISIBLE |
1373 250, 250,
1374 NULL, NULL, hinst, NULL);
1375 ok(parentWnd != NULL, "Failed to create control parent.\n");
1376 ShowWindow( parentWnd, SW_SHOW);
1377 /* single line */
1379 rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1380 parentWnd, NULL, NULL, NULL);
1381 ok(hWnd != NULL, "Failed to create Edit control.\n");
1382 GetClientRect( hWnd, &rc);
1383 ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1384 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc ));
1386 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1388 /* multi line */
1390 rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1391 parentWnd, NULL, NULL, NULL);
1392 ok(hWnd != NULL, "Failed to create Edit control.\n");
1393 GetClientRect( hWnd, &rc);
1394 ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1395 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc ));
1397 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1399 DestroyWindow(parentWnd);
1400}
1401
1402/* Test WM_GETTEXT processing
1403 * after destroy messages
1404 */
1405static void test_edit_control_6(void)
1406{
1407 static const char *str = "test\r\ntest";
1408 char buf[MAXLEN];
1409 HWND hWnd;
1410 LONG ret;
1411
1412 hWnd = CreateWindowExA(0, "EDIT", "Test", 0, 10, 10, 1, 1, NULL, NULL, hinst, NULL);
1413 ok(hWnd != NULL, "Failed to create edit control.\n");
1414
1416 ok(ret == TRUE, "Expected %d, got %d\n", TRUE, ret);
1418 ok(ret == strlen(str), "Expected %s, got len %d\n", str, ret);
1419 ok(!strcmp(buf, str), "Expected %s, got %s\n", str, buf);
1420
1421 buf[0] = 0;
1422 ret = SendMessageA(hWnd, WM_DESTROY, 0, 0);
1424 ok(ret == 1, "Unexpected return value %d\n", ret);
1426 ok(ret == strlen(str), "Expected %s, got len %d\n", str, ret);
1427 ok(!strcmp(buf, str), "Expected %s, got %s\n", str, buf);
1428
1429 buf[0] = 0;
1431 ok(ret == 0, "Expected 0, got %d\n", ret);
1433todo_wine {
1434 ok(ret == strlen("Test"), "Unexpected text length %d\n", ret);
1435 ok(!strcmp(buf, "Test"), "Unexpected text %s\n", buf);
1436}
1438}
1439
1441{
1442 HWND hwEdit;
1443 DWORD r;
1444
1445 /* Test default limit for single-line control */
1446 trace("EDIT: buffer limit for single-line\n");
1448 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1449 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1450 SendMessageA(hwEdit, EM_SETLIMITTEXT, 0, 0);
1451 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1452 ok( r == 2147483646, "got limit %u (expected 2147483646)\n", r);
1453 DestroyWindow(hwEdit);
1454
1455 /* Test default limit for multi-line control */
1456 trace("EDIT: buffer limit for multi-line\n");
1458 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1459 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1460 SendMessageA(hwEdit, EM_SETLIMITTEXT, 0, 0);
1461 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1462 ok( r == 4294967295U, "got limit %u (expected 4294967295)\n", r);
1463 DestroyWindow(hwEdit);
1464}
1465
1466/* Test EM_SCROLL */
1468{
1469 static const char *single_line_str = "a";
1470 static const char *multiline_str = "Test\r\nText";
1471 HWND hwEdit;
1472 LONG ret;
1473
1474 /* Check the return value when EM_SCROLL doesn't scroll
1475 * anything. Should not return true unless any lines were actually
1476 * scrolled. */
1477 hwEdit = CreateWindowA(WC_EDITA, single_line_str, WS_VSCROLL | ES_MULTILINE,
1478 1, 1, 100, 100, NULL, NULL, hinst, NULL);
1479 ok(hwEdit != NULL, "Failed to create Edit control.\n");
1480
1481 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1482 ok(!ret, "Returned %x, expected 0.\n", ret);
1483
1484 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEUP, 0);
1485 ok(!ret, "Returned %x, expected 0.\n", ret);
1486
1487 ret = SendMessageA(hwEdit, EM_SCROLL, SB_LINEUP, 0);
1488 ok(!ret, "Returned %x, expected 0.\n", ret);
1489
1490 ret = SendMessageA(hwEdit, EM_SCROLL, SB_LINEDOWN, 0);
1491 ok(!ret, "Returned %x, expected 0.\n", ret);
1492
1493 DestroyWindow (hwEdit);
1494
1495 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1496 should not cause EM_SCROLL to return a negative value of
1497 scrolled lines that would put us "before" the beginning. */
1498 hwEdit = CreateWindowA(WC_EDITA, multiline_str, WS_VSCROLL | ES_MULTILINE,
1499 0, 0, 100, 100, NULL, NULL, hinst, NULL);
1500 ok(hwEdit != NULL, "Failed to create Edit control.\n");
1501
1502 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1503 ok(!ret, "Returned %x, expected 0.\n", ret);
1504
1505 DestroyWindow (hwEdit);
1506}
1507
1509{
1512
1513 switch (GdiGetCodePage(dc)) {
1514 case 932: case 936: case 949: case 950: case 1361:
1515 return TRUE;
1516 default:
1517 return (GetTextCharsetInfo(dc, &fs, 0) != DEFAULT_CHARSET &&
1518 (fs.fsCsb[0] & FS_DBCS_MASK));
1519 }
1520}
1521
1523{
1524 HWND hwnd;
1525 HDC hdc;
1527 SIZE size;
1528 LOGFONTA lf;
1529 HFONT hfont;
1530 RECT rect;
1531 INT margins, threshold, expect, empty_expect;
1532 const UINT small_margins = MAKELONG(1, 5);
1533
1534 memset(&lf, 0, sizeof(lf));
1535 lf.lfHeight = -11;
1536 lf.lfWeight = FW_NORMAL;
1537 lf.lfCharSet = charset;
1538 strcpy(lf.lfFaceName, "Tahoma");
1539
1541 ok(hfont != NULL, "got %p\n", hfont);
1542
1543 /* Big window rectangle */
1544 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 5000, 1000, NULL, NULL, NULL, NULL);
1545 ok(hwnd != NULL, "got %p\n", hwnd);
1547 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1548
1549 hdc = GetDC(hwnd);
1551 size.cx = GdiGetCharDimensions( hdc, &tm, &size.cy );
1552 if ((charset != tm.tmCharSet && charset != DEFAULT_CHARSET) ||
1553 !(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR))) {
1554 skip("%s for charset %d isn't available\n", lf.lfFaceName, charset);
1556 ReleaseDC(hwnd, hdc);
1559 return;
1560 }
1561 expect = MAKELONG(size.cx / 2, size.cx / 2);
1563 ReleaseDC(hwnd, hdc);
1564
1566 ok(margins == 0, "got %x\n", margins);
1571
1572 threshold = HIWORD(expect) + LOWORD(expect) + size.cx * 2;
1573 empty_expect = threshold > 80 ? small_margins : expect;
1574
1575 /* Size below the threshold, margins remain unchanged */
1576 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, threshold - 1, 100, NULL, NULL, NULL, NULL);
1577 ok(hwnd != NULL, "got %p\n", hwnd);
1579 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1580
1582 ok(margins == 0, "got %x\n", margins);
1583
1588 ok(margins == small_margins, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1590
1591 /* Size at the threshold, margins become non-zero */
1592 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, threshold, 100, NULL, NULL, NULL, NULL);
1593 ok(hwnd != NULL, "got %p\n", hwnd);
1595 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1596
1598 ok(margins == 0, "got %x\n", margins);
1599
1604 ok(margins == expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1606
1607 /* Empty rect */
1608 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1609 ok(hwnd != NULL, "got %p\n", hwnd);
1611 ok(IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1612
1614 ok(margins == 0, "got %x\n", margins);
1615
1620 ok(margins == empty_expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1622
1624}
1625
1627{
1628 INT margin;
1629 if (side_bearing < 0)
1630 margin = min(-side_bearing, width/2);
1631 else
1632 margin = 0;
1633 return margin;
1634}
1635
1637{
1638 ABC abc[256];
1639 SHORT left, right;
1640 UINT i;
1641
1642 if (!GetCharABCWidthsW(hdc, 0, 255, abc))
1643 return 0;
1644
1645 left = right = 0;
1646 for (i = 0; i < ARRAY_SIZE(abc); i++) {
1647 if (-abc[i].abcA > right) right = -abc[i].abcA;
1648 if (-abc[i].abcC > left) left = -abc[i].abcC;
1649 }
1650 return MAKELONG(left, right);
1651}
1652
1653static void test_margins_default(const char* facename, UINT charset)
1654{
1655 HWND hwnd;
1656 HDC hdc;
1658 SIZE size;
1659 BOOL cjk;
1660 LOGFONTA lf;
1661 HFONT hfont;
1662 RECT rect;
1663 INT margins, expect, font_expect;
1664 const UINT small_margins = MAKELONG(1, 5);
1665 const WCHAR EditW[] = {'E','d','i','t',0}, strW[] = {'W',0};
1666 struct char_width_info {
1667 INT lsb, rsb, unknown;
1668 } info;
1670 BOOL (WINAPI *pGetCharWidthInfo)(HDC, struct char_width_info *);
1671
1672 hgdi32 = GetModuleHandleA("gdi32.dll");
1673 pGetCharWidthInfo = (void *)GetProcAddress(hgdi32, "GetCharWidthInfo");
1674
1675 memset(&lf, 0, sizeof(lf));
1676 lf.lfHeight = -11;
1677 lf.lfWeight = FW_NORMAL;
1678 lf.lfCharSet = charset;
1679 strcpy(lf.lfFaceName, facename);
1680
1682 ok(hfont != NULL, "got %p\n", hfont);
1683
1684 /* Unicode version */
1685 hwnd = CreateWindowExW(0, EditW, strW, WS_POPUP, 0, 0, 5000, 1000, NULL, NULL, NULL, NULL);
1686 ok(hwnd != NULL, "got %p\n", hwnd);
1688 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1689
1690 hdc = GetDC(hwnd);
1692 size.cx = GdiGetCharDimensions( hdc, &tm, &size.cy );
1693 if ((charset != tm.tmCharSet && charset != DEFAULT_CHARSET) ||
1694 !(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR))) {
1695 skip("%s for charset %d isn't available\n", lf.lfFaceName, charset);
1697 ReleaseDC(hwnd, hdc);
1700 return;
1701 }
1702 cjk = is_cjk(hdc);
1703 if (cjk && pGetCharWidthInfo && pGetCharWidthInfo(hdc, &info)) {
1704 short left, right;
1705
1709
1710 font_expect = get_cjk_font_margins(hdc);
1711 if (!font_expect)
1712 /* In this case, margins aren't updated */
1713 font_expect = small_margins;
1714 }
1715 else
1716 font_expect = expect = MAKELONG(size.cx / 2, size.cx / 2);
1717
1719 ReleaseDC(hwnd, hdc);
1720
1722 ok(margins == 0, "got %x\n", margins);
1726 ok(margins == font_expect, "%s:%d: got %d, %d\n", facename, charset, HIWORD(margins), LOWORD(margins));
1730 ok(margins == expect, "%s:%d: expected %d, %d, got %d, %d\n", facename, charset, HIWORD(expect), LOWORD(expect), HIWORD(margins), LOWORD(margins));
1732
1733 /* ANSI version */
1734 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 5000, 1000, NULL, NULL, NULL, NULL);
1735 ok(hwnd != NULL, "got %p\n", hwnd);
1737 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1738
1740 ok(margins == 0, "got %x\n", margins);
1744 ok(margins == font_expect, "%s:%d: got %d, %d\n", facename, charset, HIWORD(margins), LOWORD(margins));
1748 ok(margins == expect, "%s:%d: expected %d, %d, got %d, %d\n", facename, charset, HIWORD(expect), LOWORD(expect), HIWORD(margins), LOWORD(margins));
1750
1752}
1753
1755{
1756 return 0;
1757}
1758
1759static BOOL is_font_installed(const char*name)
1760{
1761 HDC hdc = GetDC(NULL);
1762 BOOL ret = FALSE;
1763
1765 ret = TRUE;
1766
1767 ReleaseDC(NULL, hdc);
1768 return ret;
1769}
1770
1771static void test_margins(void)
1772{
1773 DWORD old_margins, new_margins;
1774 RECT old_rect, new_rect;
1775 INT old_right_margin;
1776 HWND hwEdit;
1777
1779
1780 old_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1781 old_right_margin = HIWORD(old_margins);
1782
1783 /* Check if setting the margins works */
1784
1786 new_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1787 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1788 ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
1789
1791 new_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1792 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1793 ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
1794
1795 /* The size of the rectangle must decrease if we increase the margin */
1796
1798 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1800 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1801 ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
1802 ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
1803 ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
1804 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
1805
1806 /* If we set the margin to same value as the current margin,
1807 the rectangle must not change */
1808
1810 SetRect(&old_rect, 1, 1, 99, 99);
1811 SendMessageA(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);
1812 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1814 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1815 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1816
1817 /* The lParam argument of the WM_SIZE message should be ignored. */
1818
1819 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1820 SendMessageA(hwEdit, WM_SIZE, SIZE_RESTORED, 0);
1821 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1822 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1823 SendMessageA(hwEdit, WM_SIZE, SIZE_MINIMIZED, 0);
1824 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1825 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1826 SendMessageA(hwEdit, WM_SIZE, SIZE_MAXIMIZED, 0);
1827 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1828 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1829 SendMessageA(hwEdit, WM_SIZE, SIZE_RESTORED, MAKELONG(10, 10));
1830 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1831 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1832
1833 DestroyWindow (hwEdit);
1834
1837
1841 /* Don't test JOHAB_CHARSET. Treated as CJK by Win 8,
1842 but not by < Win 8 and Win 10. */
1843
1845
1848
1851
1852 if (is_font_installed("MS PGothic")) {
1854 test_margins_default("MS PGothic", GREEK_CHARSET);
1855 }
1856 else
1857 skip("MS PGothic is not available, skipping some margin tests\n");
1858
1859 if (is_font_installed("Ume P Gothic")) {
1860 test_margins_default("Ume P Gothic", SHIFTJIS_CHARSET);
1861 test_margins_default("Ume P Gothic", GREEK_CHARSET);
1862 }
1863 else
1864 skip("Ume P Gothic is not available, skipping some margin tests\n");
1865
1866 if (is_font_installed("SimSun")) {
1869 }
1870 else
1871 skip("SimSun is not available, skipping some margin tests\n");
1872}
1873
1875{
1876 DWORD margins, font_margins;
1877 HFONT hfont, hfont2;
1878 HWND hwEdit;
1879 LOGFONTA lf;
1880
1881 if (!is_font_installed("Arial"))
1882 {
1883 skip("Arial not found - skipping font change margin tests\n");
1884 return;
1885 }
1886
1887 hwEdit = create_child_editcontrol(0, 0);
1888
1889 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1890
1891 memset(&lf, 0, sizeof(lf));
1892 strcpy(lf.lfFaceName, "Arial");
1893 lf.lfHeight = 16;
1894 lf.lfCharSet = GREEK_CHARSET; /* to avoid associated charset feature */
1896 lf.lfHeight = 30;
1897 hfont2 = CreateFontIndirectA(&lf);
1898
1899 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1900 font_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1901 ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
1902 ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
1903
1904 /* With 'small' edit controls, test that the margin doesn't get set */
1905 SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1907 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1908 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1909 ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins));
1910 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
1911
1913 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1914 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1915 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1916 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
1917
1919 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1920 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1921 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1922 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
1923
1925 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1926 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1927 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
1928
1929 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1930 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1931 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1932 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
1933
1934 /* Above a certain size threshold then the margin is updated */
1935 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1937 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1938 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1939 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1940 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1941
1943 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1944 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1945 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1946 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1947
1949 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1950 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1951 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1952 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1953 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1954 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1955 ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins));
1956 ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins));
1957
1958 SendMessageA(hwEdit, WM_SETFONT, 0, 0);
1959
1960 DeleteObject(hfont2);
1963
1964}
1965
1966#define edit_pos_ok(exp, got, txt) \
1967 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1968
1969#define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1970do { \
1971 RECT format_rect; \
1972 int left_margin; \
1973 set_client_height(hwEdit, set_height); \
1974 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1975 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
1976 edit_pos_ok(test_top, format_rect.top, vertical position); \
1977 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1978 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1979} while(0)
1980
1982{
1983 HWND hwEdit;
1984 HFONT font, oldFont;
1985 HDC dc;
1987 INT b, bm, b2, b3;
1988 BOOL xb, single_line = !(style & ES_MULTILINE);
1989
1991 b2 = 2 * b;
1992 b3 = 3 * b;
1993 bm = b2 - 1;
1994
1995 /* Get a stock font for which we can determine the metrics */
1997 ok (font != NULL, "GetStockObject SYSTEM_FONT failed\n");
1998 dc = GetDC(NULL);
1999 ok (dc != NULL, "GetDC() failed\n");
2000 oldFont = SelectObject(dc, font);
2001 xb = GetTextMetricsA(dc, &metrics);
2002 ok (xb, "GetTextMetrics failed\n");
2003 SelectObject(dc, oldFont);
2004 ReleaseDC(NULL, dc);
2005
2006 /* Windows' edit control has some bugs in multi-line mode:
2007 * - Sometimes the format rectangle doesn't get updated
2008 * (see workaround in set_client_height())
2009 * - If the height of the control is smaller than the height of a text
2010 * line, the format rectangle is still as high as a text line
2011 * (higher than the client rectangle) and the caret is not shown
2012 */
2013
2014 /* Edit controls that are in a parent window */
2015
2018 if (single_line)
2019 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
2020 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
2021 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
2022 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
2023 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
2025
2028 if (single_line)
2029 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
2030 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
2031 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
2032 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
2033 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
2034 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
2036
2039 if (single_line)
2040 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
2041 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
2042 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
2043 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
2044 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
2046
2049 if (single_line)
2050 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
2051 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
2052 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
2053 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
2054 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
2056
2057
2058 /* Edit controls that are popup windows */
2059
2060 hwEdit = create_editcontrol(style | WS_POPUP, 0);
2062 if (single_line)
2063 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
2064 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
2065 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
2066 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
2067 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
2068 DestroyWindow(hwEdit);
2069
2070 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
2072 if (single_line)
2073 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
2074 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
2075 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
2076 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
2077 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
2078 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
2079 DestroyWindow(hwEdit);
2080
2083 if (single_line)
2084 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
2085 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
2086 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
2087 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
2088 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
2089 DestroyWindow(hwEdit);
2090
2093 if (single_line)
2094 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
2095 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
2096 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
2097 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
2098 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
2099 DestroyWindow(hwEdit);
2100}
2101
2102static void test_text_position(void)
2103{
2104 trace("EDIT: Text position (Single line)\n");
2106 trace("EDIT: Text position (Multi line)\n");
2108}
2109
2110static void test_espassword(void)
2111{
2112 HWND hwEdit;
2113 LONG r;
2114 char buffer[1024];
2115 const char* password = "secret";
2116
2117 hwEdit = create_editcontrol(ES_PASSWORD, 0);
2118 r = get_edit_style(hwEdit);
2119 ok(r == ES_PASSWORD, "Wrong style expected ES_PASSWORD got: 0x%x\n", r);
2120 /* set text */
2121 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
2122 ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
2123
2124 /* select all, cut (ctrl-x) */
2125 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
2126 r = SendMessageA(hwEdit, WM_CHAR, 24, 0);
2127 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2128
2129 /* get text */
2130 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
2131 ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
2132 ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
2133
2134 r = OpenClipboard(hwEdit);
2135 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2136 r = EmptyClipboard();
2137 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2138 r = CloseClipboard();
2139 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2140
2141 /* select all, copy (ctrl-c) and paste (ctrl-v) */
2142 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
2143 r = SendMessageA(hwEdit, WM_CHAR, 3, 0);
2144 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2145 r = SendMessageA(hwEdit, WM_CHAR, 22, 0);
2146 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2147
2148 /* get text */
2149 buffer[0] = 0;
2150 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
2151 ok(r == 0, "Expected: 0, got: %d\n", r);
2152 ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
2153
2154 DestroyWindow(hwEdit);
2155}
2156
2157static void test_undo(void)
2158{
2159 HWND hwEdit;
2160 LONG r;
2161 DWORD cpMin, cpMax;
2162 char buffer[1024];
2163 const char* text = "undo this";
2164
2165 hwEdit = create_editcontrol(0, 0);
2166 r = get_edit_style(hwEdit);
2167 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2168
2169 /* set text */
2170 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
2171 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2172
2173 /* select all, */
2174 cpMin = cpMax = 0xdeadbeef;
2175 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
2176 r = SendMessageA(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
2177 ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
2178 ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
2179 ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
2180
2181 /* cut (ctrl-x) */
2182 r = SendMessageA(hwEdit, WM_CHAR, 24, 0);
2183 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2184
2185 /* get text */
2186 buffer[0] = 0;
2187 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
2188 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2189 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
2190
2191 /* undo (ctrl-z) */
2192 r = SendMessageA(hwEdit, WM_CHAR, 26, 0);
2193 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2194
2195 /* get text */
2196 buffer[0] = 0;
2197 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
2198 ok(strlen(text) == r, "Unexpected length %d\n", r);
2199 ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
2200
2201 /* undo again (ctrl-z) */
2202 r = SendMessageA(hwEdit, WM_CHAR, 26, 0);
2203 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2204
2205 /* get text */
2206 buffer[0] = 0;
2207 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
2208 ok(r == 0, "Expected: %d, got len %d\n", 0, r);
2209 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
2210
2211 DestroyWindow(hwEdit);
2212}
2213
2214static void test_enter(void)
2215{
2216 char buffer[16];
2217 HWND hwEdit;
2218 LONG r;
2219
2220 /* multiline */
2221 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2222 r = get_edit_style(hwEdit);
2223 ok(ES_MULTILINE == r, "Wrong style expected ES_MULTILINE got: 0x%x\n", r);
2224
2225 /* set text */
2226 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2227 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2228
2229 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2230 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2231
2232 /* get text */
2233 buffer[0] = 0;
2234 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2235 ok(2 == r, "Expected: %d, got len %d\n", 2, r);
2236 ok(0 == strcmp(buffer, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer);
2237
2238 DestroyWindow (hwEdit);
2239
2240 /* single line */
2241 hwEdit = create_editcontrol(0, 0);
2242 r = get_edit_style(hwEdit);
2243 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2244
2245 /* set text */
2246 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2247 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2248
2249 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2250 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2251
2252 /* get text */
2253 buffer[0] = 0;
2254 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2255 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2256 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2257
2258 DestroyWindow(hwEdit);
2259
2260 /* single line with ES_WANTRETURN */
2261 hwEdit = create_editcontrol(ES_WANTRETURN, 0);
2262 r = get_edit_style(hwEdit);
2263 ok(ES_WANTRETURN == r, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r);
2264
2265 /* set text */
2266 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2267 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2268
2269 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2270 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2271
2272 /* get text */
2273 buffer[0] = 0;
2274 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2275 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2276 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2277
2278 DestroyWindow(hwEdit);
2279}
2280
2281static void test_tab(void)
2282{
2283 char buffer[16];
2284 HWND hwEdit;
2285 LONG r;
2286
2287 /* multiline */
2288 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2289 r = get_edit_style(hwEdit);
2290 ok(ES_MULTILINE == r, "Wrong style expected ES_MULTILINE got: 0x%x\n", r);
2291
2292 /* set text */
2293 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2294 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2295
2296 r = SendMessageA(hwEdit, WM_CHAR, VK_TAB, 0);
2297 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2298
2299 /* get text */
2300 buffer[0] = 0;
2301 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2302 ok(1 == r, "Expected: %d, got len %d\n", 1, r);
2303 ok(0 == strcmp(buffer, "\t"), "expected \"\\t\", got \"%s\"\n", buffer);
2304
2305 DestroyWindow(hwEdit);
2306
2307 /* single line */
2308 hwEdit = create_editcontrol(0, 0);
2309 r = get_edit_style(hwEdit);
2310 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2311
2312 /* set text */
2313 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2314 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2315
2316 r = SendMessageA(hwEdit, WM_CHAR, VK_TAB, 0);
2317 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2318
2319 /* get text */
2320 buffer[0] = 0;
2321 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2322 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2323 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2324
2325 DestroyWindow(hwEdit);
2326}
2327
2328static void test_edit_dialog(void)
2329{
2330 int r;
2331
2332 /* from bug 11841 */
2333 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 0);
2334 ok(333 == r, "Expected %d, got %d\n", 333, r);
2335 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 1);
2336 ok(111 == r, "Expected %d, got %d\n", 111, r);
2337 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 2);
2338 ok(444 == r, "Expected %d, got %d\n", 444, r);
2339
2340 /* more tests for WM_CHAR */
2341 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 3);
2342 ok(444 == r, "Expected %d, got %d\n", 444, r);
2343 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 4);
2344 ok(444 == r, "Expected %d, got %d\n", 444, r);
2345 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 5);
2346 ok(444 == r, "Expected %d, got %d\n", 444, r);
2347
2348 /* more tests for WM_KEYDOWN + WM_CHAR */
2349 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 6);
2350 ok(444 == r, "Expected %d, got %d\n", 444, r);
2351 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 7);
2352 ok(444 == r, "Expected %d, got %d\n", 444, r);
2353 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 8);
2354 ok(444 == r, "Expected %d, got %d\n", 444, r);
2355
2356 /* tests with an editable edit control */
2357 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 0);
2358 ok(333 == r, "Expected %d, got %d\n", 333, r);
2359 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 1);
2360 ok(111 == r, "Expected %d, got %d\n", 111, r);
2361 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 2);
2362 ok(444 == r, "Expected %d, got %d\n", 444, r);
2363
2364 /* tests for WM_CHAR */
2365 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 3);
2366 ok(444 == r, "Expected %d, got %d\n", 444, r);
2367 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 4);
2368 ok(444 == r, "Expected %d, got %d\n", 444, r);
2369 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 5);
2370 ok(444 == r, "Expected %d, got %d\n", 444, r);
2371
2372 /* tests for WM_KEYDOWN + WM_CHAR */
2373 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 6);
2374 ok(444 == r, "Expected %d, got %d\n", 444, r);
2375 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 7);
2376 ok(444 == r, "Expected %d, got %d\n", 444, r);
2377 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 8);
2378 ok(444 == r, "Expected %d, got %d\n", 444, r);
2379
2380 /* multiple tab tests */
2381 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 9);
2382 ok(22 == r, "Expected %d, got %d\n", 22, r);
2383 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 10);
2384 ok(33 == r, "Expected %d, got %d\n", 33, r);
2385}
2386
2387static void test_multi_edit_dialog(void)
2388{
2389 int r;
2390
2391 /* test for multiple edit dialogs (bug 12319) */
2392 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 0);
2393 ok(2222 == r, "Expected %d, got %d\n", 2222, r);
2394 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 1);
2395 ok(1111 == r, "Expected %d, got %d\n", 1111, r);
2396 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 2);
2397 ok(2222 == r, "Expected %d, got %d\n", 2222, r);
2398 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 3);
2399 ok(11 == r, "Expected %d, got %d\n", 11, r);
2400}
2401
2403{
2404 int r;
2405
2406 /* tests for WM_KEYDOWN */
2407 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 0);
2408 ok(333 == r, "Expected %d, got %d\n", 333, r);
2409 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 1);
2410 ok(444 == r, "Expected %d, got %d\n", 444, r);
2411 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 2);
2412 ok(444 == r, "Expected %d, got %d\n", 444, r);
2413
2414 /* tests for WM_CHAR */
2415 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 3);
2416 ok(444 == r, "Expected %d, got %d\n", 444, r);
2417 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 4);
2418 ok(444 == r, "Expected %d, got %d\n", 444, r);
2419 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 5);
2420 ok(444 == r, "Expected %d, got %d\n", 444, r);
2421
2422 /* tests for WM_KEYDOWN + WM_CHAR */
2423 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 6);
2424 ok(444 == r, "Expected %d, got %d\n", 444, r);
2425 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 7);
2426 ok(444 == r, "Expected %d, got %d\n", 444, r);
2427 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 8);
2428 ok(444 == r, "Expected %d, got %d\n", 444, r);
2429}
2430
2432{
2433 int r;
2434
2435 /* tests for WM_KEYDOWN */
2436 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 0);
2437 ok(222 == r, "Expected %d, got %d\n", 222, r);
2438 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 1);
2439 ok(111 == r, "Expected %d, got %d\n", 111, r);
2440 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 2);
2441 ok(444 == r, "Expected %d, got %d\n", 444, r);
2442
2443 /* tests for WM_CHAR */
2444 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 3);
2445 ok(444 == r, "Expected %d, got %d\n", 444, r);
2446 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 4);
2447 ok(444 == r, "Expected %d, got %d\n", 444, r);
2448 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 5);
2449 ok(444 == r, "Expected %d, got %d\n", 444, r);
2450
2451 /* tests for WM_KEYDOWN + WM_CHAR */
2452 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 6);
2453 ok(222 == r, "Expected %d, got %d\n", 222, r);
2454 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 7);
2455 ok(111 == r, "Expected %d, got %d\n", 111, r);
2456 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 8);
2457 ok(444 == r, "Expected %d, got %d\n", 444, r);
2458
2459 /* tests for WM_KEYDOWN */
2460 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 0);
2461 ok(222 == r, "Expected %d, got %d\n", 222, r);
2462 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 1);
2463 ok(111 == r, "Expected %d, got %d\n", 111, r);
2464 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 2);
2465 ok(444 == r, "Expected %d, got %d\n", 444, r);
2466
2467 /* tests for WM_CHAR */
2468 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 3);
2469 ok(444 == r, "Expected %d, got %d\n", 444, r);
2470 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 4);
2471 ok(444 == r, "Expected %d, got %d\n", 444, r);
2472 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 5);
2473 ok(444 == r, "Expected %d, got %d\n", 444, r);
2474
2475 /* tests for WM_KEYDOWN + WM_CHAR */
2476 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 6);
2477 ok(222 == r, "Expected %d, got %d\n", 222, r);
2478 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 7);
2479 ok(111 == r, "Expected %d, got %d\n", 111, r);
2480 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 8);
2481 ok(444 == r, "Expected %d, got %d\n", 444, r);
2482}
2483
2486{
2487 switch (msg)
2488 {
2489 case WM_DESTROY:
2490 case WM_NCDESTROY:
2491 break;
2492
2493 default:
2495 break;
2496 }
2497
2498 return FALSE;
2499}
2500
2502{
2503 HWND hwEdit, hwParent;
2504 int r;
2505
2506 hwEdit = create_child_editcontrol(0, 0);
2507 hwParent = GetParent(hwEdit);
2509 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2510 ok(1 == r, "expected 1, got %d\n", r);
2513}
2514
2517static LRESULT (CALLBACK *p_edit_proc)(HWND, UINT, WPARAM, LPARAM);
2518
2520{
2521 switch (msg) {
2522 case WM_COMMAND:
2523 switch (HIWORD(wParam))
2524 {
2525 case EN_SETFOCUS:
2527 break;
2528 }
2529 break;
2530 case WM_CAPTURECHANGED:
2531 if (hWnd != (HWND)lParam)
2532 {
2534 EndMenu();
2535 }
2536 break;
2537 }
2538 return DefWindowProcA(hWnd, msg, wParam, lParam);
2539}
2540
2542{
2543 unsigned int wm_command, em_setsel;
2544};
2545
2547
2549{
2550 switch (msg)
2551 {
2552 case WM_ENTERIDLE:
2553 if (wParam == MSGF_MENU)
2554 {
2555 HWND hwndMenu = (HWND)lParam;
2556 MENUBARINFO mbi = { sizeof(mbi) };
2557 if (GetMenuBarInfo(hwndMenu, OBJID_CLIENT, 0, &mbi))
2558 {
2559 MENUITEMINFOA mii = { sizeof(MENUITEMINFOA), MIIM_STATE };
2560 if (GetMenuItemInfoA(mbi.hMenu, EM_SETSEL, FALSE, &mii))
2561 {
2562 if (mii.fState & MFS_HILITE)
2563 {
2565 PostMessageA(hwnd, WM_KEYUP, VK_RETURN, 0x1c0001);
2566 }
2567 else
2568 {
2569 PostMessageA(hwnd, WM_KEYDOWN, VK_DOWN, 0x500001);
2570 PostMessageA(hwnd, WM_KEYUP, VK_DOWN, 0x500001);
2571 }
2572 }
2573 }
2574 }
2575 break;
2576 case WM_COMMAND:
2577 menu_messages.wm_command++;
2578 break;
2579 case EM_SETSEL:
2580 menu_messages.em_setsel++;
2581 break;
2582 }
2583 return CallWindowProcA(p_edit_proc, hwnd, msg, wParam, lParam);
2584}
2585
2586static void test_contextmenu(void)
2587{
2589 MSG msg;
2590
2592 0, 0, 200, 200, NULL, NULL, hinst, NULL);
2593 ok(hwndMain != NULL, "Failed to create control parent.\n");
2594
2596 0, 0, 150, 50, /* important this not be 0 size. */
2598 ok(hwndEdit != NULL, "Failed to create Edit control.\n");
2599
2600 SetFocus(NULL);
2603 ok(got_en_setfocus, "edit box didn't get focused\n");
2604 ok(got_wm_capturechanged, "main window capture did not change\n");
2605
2607
2608 hwndEdit = CreateWindowA("EDIT", "Test Text",
2610 0, 0, 100, 100,
2611 hwndMain, NULL, hinst, NULL);
2612 memset(&menu_messages, 0, sizeof(menu_messages));
2613 p_edit_proc = (void*)SetWindowLongPtrA(hwndEdit, GWLP_WNDPROC,
2615
2620 ok(menu_messages.wm_command == 0,
2621 "Expected no WM_COMMAND messages, got %d\n", menu_messages.wm_command);
2622 ok(menu_messages.em_setsel == 1,
2623 "Expected 1 EM_SETSEL message, got %d\n", menu_messages.em_setsel);
2624
2627}
2628
2630{
2634 WNDCLASSA text_position;
2635 WNDCLASSA wc;
2636
2637 test2.style = 0;
2638 test2.lpfnWndProc = ET2_WndProc;
2639 test2.cbClsExtra = 0;
2640 test2.cbWndExtra = 0;
2641 test2.hInstance = hinst;
2642 test2.hIcon = NULL;
2643 test2.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
2644 test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2645 test2.lpszMenuName = NULL;
2646 test2.lpszClassName = szEditTest2Class;
2647 if (!RegisterClassA(&test2)) return FALSE;
2648
2649 test3.style = 0;
2650 test3.lpfnWndProc = edit3_wnd_procA;
2651 test3.cbClsExtra = 0;
2652 test3.cbWndExtra = 0;
2653 test3.hInstance = hinst;
2654 test3.hIcon = 0;
2655 test3.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
2656 test3.hbrBackground = GetStockObject(WHITE_BRUSH);
2657 test3.lpszMenuName = NULL;
2658 test3.lpszClassName = szEditTest3Class;
2659 if (!RegisterClassA(&test3)) return FALSE;
2660
2661 test4.style = 0;
2662 test4.lpfnWndProc = edit4_wnd_procA;
2663 test4.cbClsExtra = 0;
2664 test4.cbWndExtra = 0;
2665 test4.hInstance = hinst;
2666 test4.hIcon = NULL;
2667 test4.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
2668 test4.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2669 test4.lpszMenuName = NULL;
2670 test4.lpszClassName = szEditTest4Class;
2671 if (!RegisterClassA(&test4)) return FALSE;
2672
2673 text_position.style = CS_HREDRAW | CS_VREDRAW;
2674 text_position.cbClsExtra = 0;
2675 text_position.cbWndExtra = 0;
2676 text_position.hInstance = hinst;
2677 text_position.hIcon = NULL;
2678 text_position.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
2679 text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2680 text_position.lpszMenuName = NULL;
2681 text_position.lpszClassName = szEditTextPositionClass;
2682 text_position.lpfnWndProc = DefWindowProcA;
2683 if (!RegisterClassA(&text_position)) return FALSE;
2684
2685 memset(&wc, 0, sizeof(wc));
2688 wc.lpszClassName = "ParentWnd";
2689 if (!RegisterClassA(&wc)) return FALSE;
2690
2691 return TRUE;
2692}
2693
2694static void UnregisterWindowClasses (void)
2695{
2700}
2701
2702static void test_fontsize(void)
2703{
2704 HWND hwEdit;
2705 HFONT hfont;
2706 HDC hDC;
2707 LOGFONTA lf;
2708 LONG r;
2709 char szLocalString[MAXLEN];
2710 int dpi;
2711
2712 hDC = GetDC(NULL);
2714 ReleaseDC(NULL, hDC);
2715
2716 memset(&lf,0,sizeof(LOGFONTA));
2717 strcpy(lf.lfFaceName,"Arial");
2718 lf.lfHeight = -300; /* taller than the edit box */
2719 lf.lfWeight = 500;
2721
2722 trace("EDIT: Oversized font (Multi line)\n");
2724 0, 0, (150 * dpi) / 96, (50 * dpi) / 96, NULL, NULL,
2725 hinst, NULL);
2726
2728
2730 ShowWindow (hwEdit, SW_SHOW);
2731
2732 r = SendMessageA(hwEdit, WM_CHAR, 'A', 1);
2733 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2734 r = SendMessageA(hwEdit, WM_CHAR, 'B', 1);
2735 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2736 r = SendMessageA(hwEdit, WM_CHAR, 'C', 1);
2737 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2738
2739 GetWindowTextA(hwEdit, szLocalString, MAXLEN);
2740 ok(strcmp(szLocalString, "ABC")==0,
2741 "Wrong contents of edit: %s\n", szLocalString);
2742
2743 r = SendMessageA(hwEdit, EM_POSFROMCHAR,0,0);
2744 ok(r != -1,"EM_POSFROMCHAR failed index 0\n");
2745 r = SendMessageA(hwEdit, EM_POSFROMCHAR,1,0);
2746 ok(r != -1,"EM_POSFROMCHAR failed index 1\n");
2747 r = SendMessageA(hwEdit, EM_POSFROMCHAR,2,0);
2748 ok(r != -1,"EM_POSFROMCHAR failed index 2\n");
2749 r = SendMessageA(hwEdit, EM_POSFROMCHAR,3,0);
2750 ok(r == -1,"EM_POSFROMCHAR succeeded index 3\n");
2751
2752 DestroyWindow (hwEdit);
2754}
2755
2757{
2759};
2760
2762
2763static void zero_dm_messages(void)
2764{
2765 dm_messages.wm_command = 0;
2766 dm_messages.wm_close = 0;
2767 dm_messages.wm_getdefid = 0;
2768 dm_messages.wm_nextdlgctl = 0;
2769}
2770
2771#define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2772 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2773 "got %d\n", wmcommand, dm_messages.wm_command); \
2774 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2775 "got %d\n", wmclose, dm_messages.wm_close); \
2776 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2777 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2778 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2779 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2780
2782{
2783 switch (iMsg)
2784 {
2785 case WM_COMMAND:
2786 dm_messages.wm_command++;
2787 break;
2788 case DM_GETDEFID:
2789 dm_messages.wm_getdefid++;
2791 case WM_NEXTDLGCTL:
2792 dm_messages.wm_nextdlgctl++;
2793 break;
2794 case WM_CLOSE:
2795 dm_messages.wm_close++;
2796 break;
2797 }
2798
2799 return DefWindowProcA(hwnd, iMsg, wParam, lParam);
2800}
2801
2802static void test_dialogmode(void)
2803{
2804 HWND hwEdit, hwParent, hwButton;
2805 MSG msg= {0};
2806 int len, r;
2808
2809 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2810 ok(1 == r, "expected 1, got %d\n", r);
2811 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2812 ok(11 == len, "expected 11, got %d\n", len);
2813
2814 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, 0);
2815 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2816
2817 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2818 ok(1 == r, "expected 1, got %d\n", r);
2819 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2820 ok(13 == len, "expected 13, got %d\n", len);
2821
2822 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM)&msg);
2823 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2824 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2825 ok(1 == r, "expected 1, got %d\n", r);
2826 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2827 ok(13 == len, "expected 13, got %d\n", len);
2828
2829 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2830 ok(1 == r, "expected 1, got %d\n", r);
2831 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2832 ok(13 == len, "expected 13, got %d\n", len);
2833
2835
2836 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2837
2838 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2839 ok(1 == r, "expected 1, got %d\n", r);
2840 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2841 ok(11 == len, "expected 11, got %d\n", len);
2842
2843 msg.hwnd = hwEdit;
2844 msg.message = WM_KEYDOWN;
2845 msg.wParam = VK_BACK;
2846 msg.lParam = 0xe0001;
2848 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2849
2850 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2851 ok(1 == r, "expected 1, got %d\n", r);
2852 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2853 ok(11 == len, "expected 11, got %d\n", len);
2854
2855 DestroyWindow(hwEdit);
2856
2857 hwEdit = create_child_editcontrol(0, 0);
2858 hwParent = GetParent(hwEdit);
2860
2862 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
2863 ok(1 == r, "expected 1, got %d\n", r);
2864 test_dm_messages(0, 0, 0, 0);
2866
2867 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2868 ok(1 == r, "expected 1, got %d\n", r);
2869 test_dm_messages(0, 0, 0, 0);
2871
2872 msg.hwnd = hwEdit;
2873 msg.message = WM_KEYDOWN;
2874 msg.wParam = VK_TAB;
2875 msg.lParam = 0xf0001;
2877 ok(0x89 == r, "expected 0x89, got 0x%x\n", r);
2878 test_dm_messages(0, 0, 0, 0);
2880
2881 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2882 ok(1 == r, "expected 1, got %d\n", r);
2883 test_dm_messages(0, 0, 0, 0);
2885
2887
2889 hwParent = GetParent(hwEdit);
2891
2892 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2893 ok(1 == r, "expected 1, got %d\n", r);
2894 test_dm_messages(0, 0, 0, 0);
2896
2897 msg.hwnd = hwEdit;
2898 msg.message = WM_KEYDOWN;
2899 msg.wParam = VK_ESCAPE;
2900 msg.lParam = 0x10001;
2902 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2903 test_dm_messages(0, 0, 0, 0);
2905
2906 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
2907 ok(1 == r, "expected 1, got %d\n", r);
2908 test_dm_messages(0, 0, 0, 0);
2910
2911 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2912 ok(1 == r, "expected 1, got %d\n", r);
2913 test_dm_messages(0, 0, 0, 1);
2915
2916 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2917 ok(1 == r, "expected 1, got %d\n", r);
2918 test_dm_messages(0, 0, 1, 0);
2920
2921 hwButton = CreateWindowA("BUTTON", "OK", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
2922 100, 100, 50, 20, hwParent, (HMENU)ID_EDITTESTDBUTTON, hinst, NULL);
2923 ok(hwButton!=NULL, "CreateWindow failed with error code %d\n", GetLastError());
2924
2925 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2926 ok(1 == r, "expected 1, got %d\n", r);
2927 test_dm_messages(0, 0, 1, 1);
2929
2930 DestroyWindow(hwButton);
2932}
2933
2934static void test_EM_GETHANDLE(void)
2935{
2936 static const WCHAR str1W[] = {'1','1','1','1','+','1','1','1','1','+','1','1','1','1','#',0};
2937 static const WCHAR str2W[] = {'2','2','2','2','-','2','2','2','2','-','2','2','2','2','-','2','2','2','2','#',0};
2938 static const char str0[] = "untouched";
2939 static const char str1[] = "1111+1111+1111#";
2940 static const char str1_1[] = "2111+1111+1111#";
2941 static const char str2[] = "2222-2222-2222-2222#";
2942 static const char str3[] = "3333*3333*3333*3333*3333#";
2943 CHAR current[42];
2944 HWND hEdit;
2945 HLOCAL hmem;
2946 HLOCAL hmem2;
2947 HLOCAL halloc;
2948 WCHAR *buffer;
2949 int len;
2950 int r;
2951
2952 trace("EDIT: EM_GETHANDLE\n");
2953
2954 /* EM_GETHANDLE is not supported for a single line edit control */
2956 ok(hEdit != NULL, "got %p (expected != NULL)\n", hEdit);
2957
2958 hmem = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
2959 ok(hmem == NULL, "got %p (expected NULL)\n", hmem);
2961
2962 /* EM_GETHANDLE needs a multiline edit control */
2964 ok(hEdit != NULL, "got %p (expected != NULL)\n", hEdit);
2965
2966 /* set some text */
2967 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
2969 ok((r == 1) && (len == lstrlenA(str1)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str1));
2970
2971 lstrcpyA(current, str0);
2973 ok((r == lstrlenA(str1)) && !lstrcmpA(current, str1),
2974 "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1), str1);
2975
2976 hmem = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
2977 ok(hmem != NULL, "got %p (expected != NULL)\n", hmem);
2978 /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
2979 buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
2980
2981 buffer = LocalLock(hmem);
2982 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
2983 len = lstrlenW(buffer);
2984 ok(len == lstrlenW(str1W) && !lstrcmpW(buffer, str1W), "Unexpected buffer contents %s, length %d.\n",
2986 LocalUnlock(hmem);
2987
2988 /* See if WM_GETTEXTLENGTH/WM_GETTEXT still work. */
2990 ok(len == lstrlenA(str1), "Unexpected text length %d.\n", len);
2991
2992 lstrcpyA(current, str0);
2994 ok((r == lstrlenA(str1)) && !lstrcmpA(current, str1),
2995 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1), str1);
2996
2997 /* Application altered buffer contents, see if WM_GETTEXTLENGTH/WM_GETTEXT pick that up. */
2998 buffer = LocalLock(hmem);
2999 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
3000 buffer[0] = '2';
3001 LocalUnlock(hmem);
3002
3004 ok(len == lstrlenA(str1_1), "Unexpected text length %d.\n", len);
3005
3006 lstrcpyA(current, str0);
3008 ok(r == lstrlenA(str1_1) && !lstrcmpA(current, str1_1),
3009 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1_1), str1_1);
3010
3011 /* See if WM_SETTEXT/EM_REPLACESEL work. */
3012 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
3013 ok(r, "Failed to set text.\n");
3014
3015 buffer = LocalLock(hmem);
3016 ok(buffer != NULL && buffer[0] == '1', "Unexpected buffer contents\n");
3017 LocalUnlock(hmem);
3018
3019 r = SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)str1_1);
3020 ok(r, "Failed to replace selection.\n");
3021
3022 buffer = LocalLock(hmem);
3023 ok(buffer != NULL && buffer[0] == '2', "Unexpected buffer contents\n");
3024 LocalUnlock(hmem);
3025
3026 /* use LocalAlloc first to get a different handle */
3027 halloc = LocalAlloc(LMEM_MOVEABLE, 42);
3028 ok(halloc != NULL, "got %p (expected != NULL)\n", halloc);
3029 /* prepare our new memory */
3030 buffer = LocalLock(halloc);
3031 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
3032 lstrcpyW(buffer, str2W);
3033 LocalUnlock(halloc);
3034
3035 /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
3036 LocalFree(hmem);
3037 /* use LocalAlloc after the LocalFree to likely consume the handle */
3038 hmem2 = LocalAlloc(LMEM_MOVEABLE, 42);
3039 ok(hmem2 != NULL, "got %p (expected != NULL)\n", hmem2);
3040
3041 SendMessageA(hEdit, EM_SETHANDLE, (WPARAM)halloc, 0);
3042
3044 ok(len == lstrlenA(str2), "got %d (expected %d)\n", len, lstrlenA(str2));
3045
3046 lstrcpyA(current, str0);
3048 ok(r == lstrlenA(str2) && !lstrcmpA(current, str2),
3049 "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str2), str2);
3050
3051 /* set a different text */
3052 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str3);
3054 ok((r == 1) && (len == lstrlenA(str3)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str3));
3055
3056 lstrcpyA(current, str0);
3058 ok((r == lstrlenA(str3)) && !lstrcmpA(current, str3),
3059 "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str3), str3);
3060
3061 LocalFree(hmem2);
3063
3064 /* Some apps have bugs ... */
3066
3067 /* set some text */
3068 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
3070 ok((r == 1) && (len == lstrlenA(str1)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str1));
3071
3072 /* everything is normal up to EM_GETHANDLE */
3073 hmem = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
3074 /* Some messages still work while other messages fail.
3075 After LocalFree the memory handle, messages can crash the app */
3076
3077 /* A buggy editor used EM_GETHANDLE twice */
3078 hmem2 = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
3079 ok(hmem2 == hmem, "got %p (expected %p)\n", hmem2, hmem);
3080
3081 /* Let the edit control free the memory handle */
3083
3085}
3086