comctl32/tests: Add EM_GETLINE test.
[wine.git] / dlls / comctl32 / tests / edit.c
blob77116837df3ee87a386aed4695c1d5794f39f3c9
1 /* Unit test suite for edit control.
3 * Copyright 2004 Vitaliy Margolen
4 * Copyright 2005 C. Scott Ananian
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.
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.
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
21 #include <assert.h>
22 #include <windows.h>
23 #include <commctrl.h>
25 #include "wine/test.h"
26 #include "v6util.h"
28 #ifndef ES_COMBO
29 #define ES_COMBO 0x200
30 #endif
32 #define ID_EDITTESTDBUTTON 0x123
33 #define ID_EDITTEST2 99
34 #define MAXLEN 200
36 struct edit_notify {
37 int en_change, en_maxtext, en_update;
40 static struct edit_notify notifications;
42 static INT_PTR CALLBACK multi_edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
44 static int num_ok_commands = 0;
45 switch (msg)
47 case WM_INITDIALOG:
49 HWND hedit = GetDlgItem(hdlg, 1000);
50 SetFocus(hedit);
51 switch (lparam)
53 /* test cases related to bug 12319 */
54 case 0:
55 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
56 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
57 break;
58 case 1:
59 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
60 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
61 break;
62 case 2:
63 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
64 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
65 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
66 break;
68 /* test cases for pressing enter */
69 case 3:
70 num_ok_commands = 0;
71 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
72 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
73 break;
75 default:
76 break;
78 break;
81 case WM_COMMAND:
82 if (HIWORD(wparam) != BN_CLICKED)
83 break;
85 switch (LOWORD(wparam))
87 case IDOK:
88 num_ok_commands++;
89 break;
91 default:
92 break;
94 break;
96 case WM_USER:
98 HWND hfocus = GetFocus();
99 HWND hedit = GetDlgItem(hdlg, 1000);
100 HWND hedit2 = GetDlgItem(hdlg, 1001);
101 HWND hedit3 = GetDlgItem(hdlg, 1002);
103 if (wparam != 0xdeadbeef)
104 break;
106 switch (lparam)
108 case 0:
109 if (hfocus == hedit)
110 EndDialog(hdlg, 1111);
111 else if (hfocus == hedit2)
112 EndDialog(hdlg, 2222);
113 else if (hfocus == hedit3)
114 EndDialog(hdlg, 3333);
115 else
116 EndDialog(hdlg, 4444);
117 break;
118 case 1:
119 if ((hfocus == hedit) && (num_ok_commands == 0))
120 EndDialog(hdlg, 11);
121 else
122 EndDialog(hdlg, 22);
123 break;
124 default:
125 EndDialog(hdlg, 5555);
127 break;
130 case WM_CLOSE:
131 EndDialog(hdlg, 333);
132 break;
134 default:
135 break;
138 return FALSE;
141 static INT_PTR CALLBACK edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
143 switch (msg)
145 case WM_INITDIALOG:
147 HWND hedit = GetDlgItem(hdlg, 1000);
148 SetFocus(hedit);
149 switch (lparam)
151 /* from bug 11841 */
152 case 0:
153 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
154 break;
155 case 1:
156 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
157 break;
158 case 2:
159 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
160 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
161 break;
163 /* more test cases for WM_CHAR */
164 case 3:
165 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
166 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
167 break;
168 case 4:
169 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
170 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
171 break;
172 case 5:
173 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
174 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
175 break;
177 /* more test cases for WM_KEYDOWN + WM_CHAR */
178 case 6:
179 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
180 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
181 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
182 break;
183 case 7:
184 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
185 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
186 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
187 break;
188 case 8:
189 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
190 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
191 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
192 break;
194 /* multiple tab tests */
195 case 9:
196 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
197 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
198 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
199 break;
200 case 10:
201 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
202 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
203 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
204 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
205 break;
207 default:
208 break;
210 break;
213 case WM_COMMAND:
214 if (HIWORD(wparam) != BN_CLICKED)
215 break;
217 switch (LOWORD(wparam))
219 case IDOK:
220 EndDialog(hdlg, 111);
221 break;
223 case IDCANCEL:
224 EndDialog(hdlg, 222);
225 break;
227 default:
228 break;
230 break;
232 case WM_USER:
234 int len;
235 HWND hok = GetDlgItem(hdlg, IDOK);
236 HWND hcancel = GetDlgItem(hdlg, IDCANCEL);
237 HWND hedit = GetDlgItem(hdlg, 1000);
238 HWND hfocus = GetFocus();
240 if (wparam != 0xdeadbeef)
241 break;
243 switch (lparam)
245 case 0:
246 len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
247 if (len == 0)
248 EndDialog(hdlg, 444);
249 else
250 EndDialog(hdlg, 555);
251 break;
253 case 1:
254 len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
255 if ((hfocus == hok) && len == 0)
256 EndDialog(hdlg, 444);
257 else
258 EndDialog(hdlg, 555);
259 break;
261 case 2:
262 if (hfocus == hok)
263 EndDialog(hdlg, 11);
264 else if (hfocus == hcancel)
265 EndDialog(hdlg, 22);
266 else if (hfocus == hedit)
267 EndDialog(hdlg, 33);
268 else
269 EndDialog(hdlg, 44);
270 break;
272 default:
273 EndDialog(hdlg, 555);
275 break;
278 case WM_CLOSE:
279 EndDialog(hdlg, 333);
280 break;
282 default:
283 break;
286 return FALSE;
289 static INT_PTR CALLBACK edit_singleline_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
291 switch (msg)
293 case WM_INITDIALOG:
295 HWND hedit = GetDlgItem(hdlg, 1000);
296 SetFocus(hedit);
297 switch (lparam)
299 /* test cases for WM_KEYDOWN */
300 case 0:
301 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
302 break;
303 case 1:
304 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
305 break;
306 case 2:
307 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
308 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
309 break;
311 /* test cases for WM_CHAR */
312 case 3:
313 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
314 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
315 break;
316 case 4:
317 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
318 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
319 break;
320 case 5:
321 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
322 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
323 break;
325 /* test cases for WM_KEYDOWN + WM_CHAR */
326 case 6:
327 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
328 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
329 break;
330 case 7:
331 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
332 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
333 break;
334 case 8:
335 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
336 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
337 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
338 break;
340 default:
341 break;
343 break;
346 case WM_COMMAND:
347 if (HIWORD(wparam) != BN_CLICKED)
348 break;
350 switch (LOWORD(wparam))
352 case IDOK:
353 EndDialog(hdlg, 111);
354 break;
356 case IDCANCEL:
357 EndDialog(hdlg, 222);
358 break;
360 default:
361 break;
363 break;
365 case WM_USER:
367 HWND hok = GetDlgItem(hdlg, IDOK);
368 HWND hedit = GetDlgItem(hdlg, 1000);
369 HWND hfocus = GetFocus();
370 int len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
372 if (wparam != 0xdeadbeef)
373 break;
375 switch (lparam)
377 case 0:
378 if ((hfocus == hedit) && len == 0)
379 EndDialog(hdlg, 444);
380 else
381 EndDialog(hdlg, 555);
382 break;
384 case 1:
385 if ((hfocus == hok) && len == 0)
386 EndDialog(hdlg, 444);
387 else
388 EndDialog(hdlg, 555);
389 break;
391 default:
392 EndDialog(hdlg, 55);
394 break;
397 case WM_CLOSE:
398 EndDialog(hdlg, 333);
399 break;
401 default:
402 break;
405 return FALSE;
408 static INT_PTR CALLBACK edit_wantreturn_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
410 switch (msg)
412 case WM_INITDIALOG:
414 HWND hedit = GetDlgItem(hdlg, 1000);
415 SetFocus(hedit);
416 switch (lparam)
418 /* test cases for WM_KEYDOWN */
419 case 0:
420 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
421 break;
422 case 1:
423 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
424 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
425 break;
426 case 2:
427 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
428 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
429 break;
431 /* test cases for WM_CHAR */
432 case 3:
433 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
434 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
435 break;
436 case 4:
437 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
438 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
439 break;
440 case 5:
441 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
442 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
443 break;
445 /* test cases for WM_KEYDOWN + WM_CHAR */
446 case 6:
447 PostMessageA(hedit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
448 PostMessageA(hedit, WM_CHAR, VK_ESCAPE, 0x10001);
449 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 0);
450 break;
451 case 7:
452 PostMessageA(hedit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
453 PostMessageA(hedit, WM_CHAR, VK_RETURN, 0x1c0001);
454 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 2);
455 break;
456 case 8:
457 PostMessageA(hedit, WM_KEYDOWN, VK_TAB, 0xf0001);
458 PostMessageA(hedit, WM_CHAR, VK_TAB, 0xf0001);
459 PostMessageA(hdlg, WM_USER, 0xdeadbeef, 1);
460 break;
462 default:
463 break;
465 break;
468 case WM_COMMAND:
469 if (HIWORD(wparam) != BN_CLICKED)
470 break;
472 switch (LOWORD(wparam))
474 case IDOK:
475 EndDialog(hdlg, 111);
476 break;
478 case IDCANCEL:
479 EndDialog(hdlg, 222);
480 break;
482 default:
483 break;
485 break;
487 case WM_USER:
489 HWND hok = GetDlgItem(hdlg, IDOK);
490 HWND hedit = GetDlgItem(hdlg, 1000);
491 HWND hfocus = GetFocus();
492 int len = SendMessageA(hedit, WM_GETTEXTLENGTH, 0, 0);
494 if (wparam != 0xdeadbeef)
495 break;
497 switch (lparam)
499 case 0:
500 if ((hfocus == hedit) && len == 0)
501 EndDialog(hdlg, 444);
502 else
503 EndDialog(hdlg, 555);
504 break;
506 case 1:
507 if ((hfocus == hok) && len == 0)
508 EndDialog(hdlg, 444);
509 else
510 EndDialog(hdlg, 555);
511 break;
513 case 2:
514 if ((hfocus == hedit) && len == 2)
515 EndDialog(hdlg, 444);
516 else
517 EndDialog(hdlg, 555);
518 break;
520 default:
521 EndDialog(hdlg, 55);
523 break;
526 case WM_CLOSE:
527 EndDialog(hdlg, 333);
528 break;
530 default:
531 break;
534 return FALSE;
537 static HINSTANCE hinst;
538 static HWND hwndET2;
539 static const char szEditTest2Class[] = "EditTest2Class";
540 static const char szEditTest3Class[] = "EditTest3Class";
541 static const char szEditTest4Class[] = "EditTest4Class";
542 static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
544 static HWND create_editcontrol (DWORD style, DWORD exstyle)
546 HWND handle;
548 handle = CreateWindowExA(exstyle,
549 "EDIT",
550 "Test Text",
551 style,
552 10, 10, 300, 300,
553 NULL, NULL, hinst, NULL);
554 ok (handle != NULL, "CreateWindow EDIT Control failed\n");
555 assert (handle);
556 if (winetest_interactive)
557 ShowWindow (handle, SW_SHOW);
558 return handle;
561 static HWND create_editcontrolW(DWORD style, DWORD exstyle)
563 static const WCHAR testtextW[] = {'T','e','s','t',' ','t','e','x','t',0};
564 HWND handle;
566 handle = CreateWindowExW(exstyle, WC_EDITW, testtextW, style, 10, 10, 300, 300,
567 NULL, NULL, hinst, NULL);
568 ok(handle != NULL, "Failed to create Edit control.\n");
569 return handle;
572 static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
574 HWND parentWnd;
575 HWND editWnd;
576 RECT rect;
577 BOOL b;
578 SetRect(&rect, 0, 0, 300, 300);
579 b = AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
580 ok(b, "AdjustWindowRect failed\n");
582 parentWnd = CreateWindowExA(0,
583 szEditTextPositionClass,
584 "Edit Test",
585 WS_OVERLAPPEDWINDOW,
586 CW_USEDEFAULT, CW_USEDEFAULT,
587 rect.right - rect.left, rect.bottom - rect.top,
588 NULL, NULL, hinst, NULL);
589 ok (parentWnd != NULL, "CreateWindow EDIT Test failed\n");
590 assert(parentWnd);
592 editWnd = CreateWindowExA(exstyle,
593 "EDIT",
594 "Test Text",
595 WS_CHILD | style,
596 0, 0, 300, 300,
597 parentWnd, NULL, hinst, NULL);
598 ok (editWnd != NULL, "CreateWindow EDIT Test Text failed\n");
599 assert(editWnd);
600 if (winetest_interactive)
601 ShowWindow (parentWnd, SW_SHOW);
602 return editWnd;
605 static void destroy_child_editcontrol (HWND hwndEdit)
607 if (GetParent(hwndEdit))
608 DestroyWindow(GetParent(hwndEdit));
609 else {
610 trace("Edit control has no parent!\n");
611 DestroyWindow(hwndEdit);
615 static LONG get_edit_style (HWND hwnd)
617 return GetWindowLongA( hwnd, GWL_STYLE ) & (
618 ES_LEFT |
619 /* FIXME: not implemented
620 ES_CENTER |
621 ES_RIGHT |
622 ES_OEMCONVERT |
624 ES_MULTILINE |
625 ES_UPPERCASE |
626 ES_LOWERCASE |
627 ES_PASSWORD |
628 ES_AUTOVSCROLL |
629 ES_AUTOHSCROLL |
630 ES_NOHIDESEL |
631 ES_COMBO |
632 ES_READONLY |
633 ES_WANTRETURN |
634 ES_NUMBER
638 static void set_client_height(HWND Wnd, unsigned Height)
640 RECT ClientRect, WindowRect;
642 GetWindowRect(Wnd, &WindowRect);
643 GetClientRect(Wnd, &ClientRect);
644 SetWindowPos(Wnd, NULL, 0, 0,
645 WindowRect.right - WindowRect.left,
646 Height + (WindowRect.bottom - WindowRect.top) -
647 (ClientRect.bottom - ClientRect.top),
648 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
650 /* Workaround for a bug in Windows' edit control
651 (multi-line mode) */
652 GetWindowRect(Wnd, &WindowRect);
653 SetWindowPos(Wnd, NULL, 0, 0,
654 WindowRect.right - WindowRect.left + 1,
655 WindowRect.bottom - WindowRect.top + 1,
656 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
657 SetWindowPos(Wnd, NULL, 0, 0,
658 WindowRect.right - WindowRect.left,
659 WindowRect.bottom - WindowRect.top,
660 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
662 GetClientRect(Wnd, &ClientRect);
663 ok(ClientRect.bottom - ClientRect.top == Height,
664 "The client height should be %d, but is %d\n",
665 Height, ClientRect.bottom - ClientRect.top);
668 static void test_edit_control_1(void)
670 HWND hwEdit;
671 MSG msMessage;
672 int i;
673 LONG r;
675 msMessage.message = WM_KEYDOWN;
677 trace("EDIT: Single line\n");
678 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
679 r = get_edit_style(hwEdit);
680 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%x\n", r);
681 for (i = 0; i < 65535; i++)
683 msMessage.wParam = i;
684 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
685 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
686 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
688 DestroyWindow(hwEdit);
690 trace("EDIT: Single line want returns\n");
691 hwEdit = create_editcontrol(ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
692 r = get_edit_style(hwEdit);
693 ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%x\n", r);
694 for (i = 0; i < 65535; i++)
696 msMessage.wParam = i;
697 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
698 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS),
699 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTARROWS got %x\n", r);
701 DestroyWindow(hwEdit);
703 trace("EDIT: Multiline line\n");
704 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
705 r = get_edit_style(hwEdit);
706 ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%x\n", r);
707 for (i = 0; i < 65535; i++)
709 msMessage.wParam = i;
710 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
711 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
712 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
714 DestroyWindow(hwEdit);
716 trace("EDIT: Multi line want returns\n");
717 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
718 r = get_edit_style(hwEdit);
719 ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%x\n", r);
720 for (i = 0; i < 65535; i++)
722 msMessage.wParam = i;
723 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM) &msMessage);
724 ok(r == (DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS),
725 "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %x\n", r);
727 DestroyWindow(hwEdit);
730 /* WM_SETTEXT is implemented by selecting all text, and then replacing the
731 * selection. This test checks that the first 'select all' doesn't generate
732 * an UPDATE message which can escape and (via a handler) change the
733 * selection, which would cause WM_SETTEXT to break. This old bug
734 * was fixed 18-Mar-2005; we check here to ensure it doesn't regress.
736 static void test_edit_control_2(void)
738 HWND hwndMain, phwnd;
739 char szLocalString[MAXLEN];
740 LONG r, w = 150, h = 50;
741 POINT cpos;
743 /* Create main and edit windows. */
744 hwndMain = CreateWindowA(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW,
745 0, 0, 200, 200, NULL, NULL, hinst, NULL);
746 assert(hwndMain);
747 if (winetest_interactive)
748 ShowWindow (hwndMain, SW_SHOW);
750 hwndET2 = CreateWindowA("EDIT", NULL,
751 WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,
752 0, 0, w, h, /* important this not be 0 size. */
753 hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
754 assert(hwndET2);
755 if (winetest_interactive)
756 ShowWindow (hwndET2, SW_SHOW);
758 trace("EDIT: SETTEXT atomicity\n");
759 /* Send messages to "type" in the word 'foo'. */
760 r = SendMessageA(hwndET2, WM_CHAR, 'f', 1);
761 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
762 r = SendMessageA(hwndET2, WM_CHAR, 'o', 1);
763 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
764 r = SendMessageA(hwndET2, WM_CHAR, 'o', 1);
765 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
766 /* 'foo' should have been changed to 'bar' by the UPDATE handler. */
767 GetWindowTextA(hwndET2, szLocalString, MAXLEN);
768 ok(strcmp(szLocalString, "bar")==0,
769 "Wrong contents of edit: %s\n", szLocalString);
771 /* try setting the caret before it's visible */
772 r = SetCaretPos(0, 0);
773 todo_wine ok(0 == r, "SetCaretPos succeeded unexpectedly, expected: 0, got: %d\n", r);
774 phwnd = SetFocus(hwndET2);
775 ok(phwnd != NULL, "SetFocus failed unexpectedly, expected non-zero, got NULL\n");
776 r = SetCaretPos(0, 0);
777 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
778 r = GetCaretPos(&cpos);
779 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
780 ok(cpos.x == 0 && cpos.y == 0, "Wrong caret position, expected: (0,0), got: (%d,%d)\n", cpos.x, cpos.y);
781 r = SetCaretPos(-1, -1);
782 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
783 r = GetCaretPos(&cpos);
784 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
785 ok(cpos.x == -1 && cpos.y == -1, "Wrong caret position, expected: (-1,-1), got: (%d,%d)\n", cpos.x, cpos.y);
786 r = SetCaretPos(w << 1, h << 1);
787 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
788 r = GetCaretPos(&cpos);
789 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
790 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);
791 r = SetCaretPos(w, h);
792 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
793 r = GetCaretPos(&cpos);
794 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
795 ok(cpos.x == w && cpos.y == h, "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w, h, cpos.x, cpos.y);
796 r = SetCaretPos(w - 1, h - 1);
797 ok(1 == r, "SetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
798 r = GetCaretPos(&cpos);
799 ok(1 == r, "GetCaretPos failed unexpectedly, expected: 1, got: %d\n", r);
800 ok(cpos.x == (w - 1) && cpos.y == (h - 1), "Wrong caret position, expected: (%d,%d), got: (%d,%d)\n", w - 1, h - 1, cpos.x, cpos.y);
802 DestroyWindow(hwndET2);
803 DestroyWindow(hwndMain);
806 static void ET2_check_change(void)
808 char szLocalString[MAXLEN];
809 /* This EN_UPDATE handler changes any 'foo' to 'bar'. */
810 GetWindowTextA(hwndET2, szLocalString, MAXLEN);
811 if (!strcmp(szLocalString, "foo"))
813 strcpy(szLocalString, "bar");
814 SendMessageA(hwndET2, WM_SETTEXT, 0, (LPARAM)szLocalString);
816 /* always leave the cursor at the end. */
817 SendMessageA(hwndET2, EM_SETSEL, MAXLEN - 1, MAXLEN - 1);
820 static void ET2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
822 if (id == ID_EDITTEST2 && codeNotify == EN_UPDATE)
823 ET2_check_change();
826 static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
828 switch (iMsg)
830 case WM_COMMAND:
831 ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
832 break;
834 return DefWindowProcA(hwnd, iMsg, wParam, lParam);
837 static void zero_notify(void)
839 notifications.en_change = 0;
840 notifications.en_maxtext = 0;
841 notifications.en_update = 0;
844 #define test_notify(enchange, enmaxtext, enupdate) \
845 do { \
846 ok(notifications.en_change == enchange, "expected %d EN_CHANGE notifications, " \
847 "got %d\n", enchange, notifications.en_change); \
848 ok(notifications.en_maxtext == enmaxtext, "expected %d EN_MAXTEXT notifications, " \
849 "got %d\n", enmaxtext, notifications.en_maxtext); \
850 ok(notifications.en_update == enupdate, "expected %d EN_UPDATE notifications, " \
851 "got %d\n", enupdate, notifications.en_update); \
852 } while(0)
854 static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
856 switch (msg)
858 case WM_COMMAND:
859 switch (HIWORD(wParam))
861 case EN_MAXTEXT:
862 notifications.en_maxtext++;
863 break;
864 case EN_UPDATE:
865 notifications.en_update++;
866 break;
867 case EN_CHANGE:
868 notifications.en_change++;
869 break;
871 break;
873 return DefWindowProcA(hWnd, msg, wParam, lParam);
876 /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response
877 * to these messages.
879 static void test_edit_control_3(void)
881 static const char *str = "this is a long string.";
882 static const char *str2 = "this is a long string.\r\nthis is a long string.\r\nthis is a long string.\r\nthis is a long string.";
883 HWND hWnd, hParent;
884 int len, dpi;
885 HDC hDC;
887 hDC = GetDC(NULL);
888 dpi = GetDeviceCaps(hDC, LOGPIXELSY);
889 ReleaseDC(NULL, hDC);
891 trace("EDIT: Test notifications\n");
893 hParent = CreateWindowExA(0,
894 szEditTest3Class,
895 NULL,
897 CW_USEDEFAULT, CW_USEDEFAULT, 10, 10,
898 NULL, NULL, NULL, NULL);
899 assert(hParent);
901 trace("EDIT: Single line, no ES_AUTOHSCROLL\n");
902 hWnd = CreateWindowExA(0,
903 "EDIT",
904 NULL,
906 10, 10, 50, 50,
907 hParent, NULL, NULL, NULL);
908 assert(hWnd);
910 zero_notify();
911 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
912 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
913 if (len == lstrlenA(str)) /* Win 8 */
914 test_notify(1, 0, 1);
915 else
916 test_notify(1, 1, 1);
918 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
919 zero_notify();
920 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
921 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
922 ok(1 == len, "wrong text length, expected 1, got %d\n", len);
923 test_notify(1, 0, 1);
925 zero_notify();
926 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
927 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
928 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
929 test_notify(1, 0, 1);
931 len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
932 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
933 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
934 SendMessageA(hParent, WM_SETFOCUS, 0, (LPARAM)hWnd);
935 len = SendMessageA(hWnd, EM_GETSEL, 0, 0);
936 ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
937 ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
939 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
941 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
942 zero_notify();
943 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
944 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
945 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
946 test_notify(1, 1, 1);
948 zero_notify();
949 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
950 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
951 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
952 test_notify(1, 0, 1);
954 DestroyWindow(hWnd);
956 trace("EDIT: Single line, ES_AUTOHSCROLL\n");
957 hWnd = CreateWindowExA(0,
958 "EDIT",
959 NULL,
960 ES_AUTOHSCROLL,
961 10, 10, 50, 50,
962 hParent, NULL, NULL, NULL);
963 assert(hWnd);
965 zero_notify();
966 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
967 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
968 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
969 test_notify(1, 0, 1);
971 zero_notify();
972 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
973 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
974 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
975 test_notify(1, 0, 1);
977 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
978 zero_notify();
979 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
980 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
981 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
982 test_notify(1, 0, 1);
984 zero_notify();
985 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
986 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
987 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
988 test_notify(1, 0, 1);
990 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
992 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
993 zero_notify();
994 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
995 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
996 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
997 test_notify(1, 1, 1);
999 zero_notify();
1000 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1001 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1002 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1003 test_notify(1, 0, 1);
1005 DestroyWindow(hWnd);
1007 trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1008 hWnd = CreateWindowExA(0,
1009 "EDIT",
1010 NULL,
1011 ES_MULTILINE,
1012 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1013 hParent, NULL, NULL, NULL);
1014 assert(hWnd);
1016 zero_notify();
1017 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
1018 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1019 if (len == lstrlenA(str)) /* Win 8 */
1020 test_notify(1, 0, 1);
1021 else
1023 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1024 test_notify(1, 1, 1);
1027 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1028 zero_notify();
1029 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
1030 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1031 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1032 test_notify(1, 0, 1);
1034 zero_notify();
1035 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1036 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1037 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1038 test_notify(0, 0, 0);
1040 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1042 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1043 zero_notify();
1044 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str);
1045 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1046 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1047 test_notify(1, 1, 1);
1049 zero_notify();
1050 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1051 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1052 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1053 test_notify(0, 0, 0);
1055 DestroyWindow(hWnd);
1057 trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n");
1058 hWnd = CreateWindowExA(0,
1059 "EDIT",
1060 NULL,
1061 ES_MULTILINE | ES_AUTOHSCROLL,
1062 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
1063 hParent, NULL, NULL, NULL);
1064 assert(hWnd);
1066 zero_notify();
1067 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1068 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1069 ok(0 == len, "text should have been truncated, expected 0, got %d\n", len);
1070 test_notify(1, 1, 1);
1072 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1073 zero_notify();
1074 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)"a");
1075 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1076 ok(1 == SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0), "wrong text length, expected 1, got %d\n", len);
1077 test_notify(1, 0, 1);
1079 zero_notify();
1080 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1081 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1082 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1083 test_notify(0, 0, 0);
1085 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1087 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1088 zero_notify();
1089 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1090 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1091 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1092 test_notify(1, 1, 1);
1094 zero_notify();
1095 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1096 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1097 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1098 test_notify(0, 0, 0);
1100 DestroyWindow(hWnd);
1102 trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n");
1103 hWnd = CreateWindowExA(0,
1104 "EDIT",
1105 NULL,
1106 ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
1107 10, 10, 50, 50,
1108 hParent, NULL, NULL, NULL);
1109 assert(hWnd);
1111 zero_notify();
1112 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1113 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1114 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1115 test_notify(1, 0, 1);
1117 zero_notify();
1118 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1119 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1120 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1121 test_notify(0, 0, 0);
1123 SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
1125 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"");
1126 zero_notify();
1127 SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2);
1128 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1129 ok(5 == len, "text should have been truncated to limit, expected 5, got %d\n", len);
1130 test_notify(1, 1, 1);
1132 zero_notify();
1133 SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2);
1134 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1135 ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n");
1136 test_notify(0, 0, 0);
1138 DestroyWindow(hWnd);
1141 static void test_char_from_pos(void)
1143 int lo, hi, mid, ret, i;
1144 HWND hwEdit;
1146 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1147 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1148 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1149 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1150 mid = lo + (hi - lo) / 2;
1152 for (i = lo; i < mid; i++)
1154 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1155 ok(0 == ret, "expected 0 got %d\n", ret);
1158 for (i = mid; i <= hi; i++)
1160 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1161 ok(1 == ret, "expected 1 got %d\n", ret);
1164 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1165 ok(-1 == ret, "expected -1 got %d\n", ret);
1166 DestroyWindow(hwEdit);
1168 hwEdit = create_editcontrol(ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1169 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1170 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1171 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1172 mid = lo + (hi - lo) / 2;
1174 for (i = lo; i < mid; i++)
1176 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1177 ok(0 == ret, "expected 0 got %d\n", ret);
1180 for (i = mid; i <= hi; i++)
1182 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1183 ok(1 == ret, "expected 1 got %d\n", ret);
1186 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1187 ok(-1 == ret, "expected -1 got %d\n", ret);
1188 DestroyWindow(hwEdit);
1190 hwEdit = create_editcontrol(ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1191 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1192 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1193 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1194 mid = lo + (hi - lo) / 2;
1196 for (i = lo; i < mid; i++)
1198 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1199 ok(0 == ret, "expected 0 got %d\n", ret);
1202 for (i = mid; i <= hi; i++)
1204 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1205 ok(1 == ret, "expected 1 got %d\n", ret);
1208 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1209 ok(-1 == ret, "expected -1 got %d\n", ret);
1210 DestroyWindow(hwEdit);
1212 hwEdit = create_editcontrol(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1213 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1214 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1215 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1216 mid = lo + (hi - lo) / 2 + 1;
1218 for (i = lo; i < mid; i++)
1220 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1221 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1224 for (i = mid; i <= hi; i++)
1226 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1227 ok(1 == ret, "expected 1 got %d\n", ret);
1230 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1231 ok(-1 == ret, "expected -1 got %d\n", ret);
1232 DestroyWindow(hwEdit);
1234 hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1235 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1236 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1237 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1238 mid = lo + (hi - lo) / 2 + 1;
1240 for (i = lo; i < mid; i++)
1242 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1243 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1246 for (i = mid; i <= hi; i++)
1248 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1249 ok(1 == ret, "expected 1 got %d\n", ret);
1252 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1253 ok(-1 == ret, "expected -1 got %d\n", ret);
1254 DestroyWindow(hwEdit);
1256 hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1257 SendMessageA(hwEdit, WM_SETTEXT, 0, (LPARAM)"aa");
1258 lo = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 0, 0));
1259 hi = LOWORD(SendMessageA(hwEdit, EM_POSFROMCHAR, 1, 0));
1260 mid = lo + (hi - lo) / 2 + 1;
1262 for (i = lo; i < mid; i++)
1264 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1265 ok((0 == ret || 1 == ret /* Vista */), "expected 0 or 1 got %d\n", ret);
1268 for (i = mid; i <= hi; i++)
1270 ret = LOWORD(SendMessageA(hwEdit, EM_CHARFROMPOS, 0, i));
1271 ok(1 == ret, "expected 1 got %d\n", ret);
1274 ret = SendMessageA(hwEdit, EM_POSFROMCHAR, 2, 0);
1275 ok(-1 == ret, "expected -1 got %d\n", ret);
1276 DestroyWindow(hwEdit);
1279 /* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL
1280 * truncates text that doesn't fit.
1282 static void test_edit_control_5(void)
1284 static const char *str = "test\r\ntest";
1285 HWND parentWnd;
1286 HWND hWnd;
1287 int len;
1288 RECT rc1 = { 10, 10, 11, 11};
1289 RECT rc;
1291 /* first show that a non-child won't do for this test */
1292 hWnd = CreateWindowExA(0,
1293 "EDIT",
1294 str,
1296 10, 10, 1, 1,
1297 NULL, NULL, NULL, NULL);
1298 assert(hWnd);
1299 /* size of non-child edit control is (much) bigger than requested */
1300 GetWindowRect( hWnd, &rc);
1301 ok( rc.right - rc.left > 20, "size of the window (%d) is smaller than expected\n",
1302 rc.right - rc.left);
1303 DestroyWindow(hWnd);
1304 /* so create a parent, and give it edit controls children to test with */
1305 parentWnd = CreateWindowExA(0,
1306 szEditTextPositionClass,
1307 "Edit Test", WS_VISIBLE |
1308 WS_OVERLAPPEDWINDOW,
1309 CW_USEDEFAULT, CW_USEDEFAULT,
1310 250, 250,
1311 NULL, NULL, hinst, NULL);
1312 assert(parentWnd);
1313 ShowWindow( parentWnd, SW_SHOW);
1314 /* single line */
1315 hWnd = CreateWindowExA(0,
1316 "EDIT",
1317 str, WS_VISIBLE | WS_BORDER |
1318 WS_CHILD,
1319 rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1320 parentWnd, NULL, NULL, NULL);
1321 assert(hWnd);
1322 GetClientRect( hWnd, &rc);
1323 ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1324 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc ));
1325 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1326 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1327 DestroyWindow(hWnd);
1328 /* multi line */
1329 hWnd = CreateWindowExA(0,
1330 "EDIT",
1331 str,
1332 WS_CHILD | ES_MULTILINE,
1333 rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
1334 parentWnd, NULL, NULL, NULL);
1335 assert(hWnd);
1336 GetClientRect( hWnd, &rc);
1337 ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top,
1338 "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc ));
1339 len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0);
1340 ok(lstrlenA(str) == len, "text shouldn't have been truncated\n");
1341 DestroyWindow(hWnd);
1342 DestroyWindow(parentWnd);
1345 /* Test WM_GETTEXT processing
1346 * after destroy messages
1348 static void test_edit_control_6(void)
1350 static const char *str = "test\r\ntest";
1351 char buf[MAXLEN];
1352 HWND hWnd;
1353 LONG ret;
1355 hWnd = CreateWindowExA(0, "EDIT", "Test", 0, 10, 10, 1, 1, NULL, NULL, hinst, NULL);
1356 ok(hWnd != NULL, "Failed to create edit control.\n");
1358 ret = SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str);
1359 ok(ret == TRUE, "Expected %d, got %d\n", TRUE, ret);
1360 ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1361 ok(ret == strlen(str), "Expected %s, got len %d\n", str, ret);
1362 ok(!strcmp(buf, str), "Expected %s, got %s\n", str, buf);
1364 buf[0] = 0;
1365 ret = SendMessageA(hWnd, WM_DESTROY, 0, 0);
1366 todo_wine
1367 ok(ret == 1, "Unexpected return value %d\n", ret);
1368 ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1369 ok(ret == strlen(str), "Expected %s, got len %d\n", str, ret);
1370 ok(!strcmp(buf, str), "Expected %s, got %s\n", str, buf);
1372 buf[0] = 0;
1373 ret = SendMessageA(hWnd, WM_NCDESTROY, 0, 0);
1374 ok(ret == 0, "Expected 0, got %d\n", ret);
1375 ret = SendMessageA(hWnd, WM_GETTEXT, MAXLEN, (LPARAM)buf);
1376 todo_wine {
1377 ok(ret == strlen("Test"), "Unexpected text length %d\n", ret);
1378 ok(!strcmp(buf, "Test"), "Unexpected text %s\n", buf);
1380 DestroyWindow(hWnd);
1383 static void test_edit_control_limittext(void)
1385 HWND hwEdit;
1386 DWORD r;
1388 /* Test default limit for single-line control */
1389 trace("EDIT: buffer limit for single-line\n");
1390 hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1391 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1392 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1393 SendMessageA(hwEdit, EM_SETLIMITTEXT, 0, 0);
1394 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1395 ok( r == 2147483646, "got limit %u (expected 2147483646)\n", r);
1396 DestroyWindow(hwEdit);
1398 /* Test default limit for multi-line control */
1399 trace("EDIT: buffer limit for multi-line\n");
1400 hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1401 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1402 ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
1403 SendMessageA(hwEdit, EM_SETLIMITTEXT, 0, 0);
1404 r = SendMessageA(hwEdit, EM_GETLIMITTEXT, 0, 0);
1405 ok( r == 4294967295U, "got limit %u (expected 4294967295)\n", r);
1406 DestroyWindow(hwEdit);
1409 /* Test EM_SCROLL */
1410 static void test_edit_control_scroll(void)
1412 static const char *single_line_str = "a";
1413 static const char *multiline_str = "Test\r\nText";
1414 HWND hwEdit;
1415 LONG ret;
1417 /* Check the return value when EM_SCROLL doesn't scroll
1418 * anything. Should not return true unless any lines were actually
1419 * scrolled. */
1420 hwEdit = CreateWindowA(
1421 "EDIT",
1422 single_line_str,
1423 WS_VSCROLL | ES_MULTILINE,
1424 1, 1, 100, 100,
1425 NULL, NULL, hinst, NULL);
1427 assert(hwEdit);
1429 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1430 ok(!ret, "Returned %x, expected 0.\n", ret);
1432 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEUP, 0);
1433 ok(!ret, "Returned %x, expected 0.\n", ret);
1435 ret = SendMessageA(hwEdit, EM_SCROLL, SB_LINEUP, 0);
1436 ok(!ret, "Returned %x, expected 0.\n", ret);
1438 ret = SendMessageA(hwEdit, EM_SCROLL, SB_LINEDOWN, 0);
1439 ok(!ret, "Returned %x, expected 0.\n", ret);
1441 DestroyWindow (hwEdit);
1443 /* SB_PAGEDOWN while at the beginning of a buffer with few lines
1444 should not cause EM_SCROLL to return a negative value of
1445 scrolled lines that would put us "before" the beginning. */
1446 hwEdit = CreateWindowA(
1447 "EDIT",
1448 multiline_str,
1449 WS_VSCROLL | ES_MULTILINE,
1450 0, 0, 100, 100,
1451 NULL, NULL, hinst, NULL);
1452 assert(hwEdit);
1454 ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0);
1455 ok(!ret, "Returned %x, expected 0.\n", ret);
1457 DestroyWindow (hwEdit);
1460 static void test_margins_usefontinfo(UINT charset)
1462 INT margins, threshold, expect, empty_expect, small_expect;
1463 HWND hwnd;
1464 HDC hdc;
1465 SIZE size;
1466 BOOL cjk;
1467 LOGFONTA lf;
1468 HFONT hfont;
1469 RECT rect;
1471 memset(&lf, 0, sizeof(lf));
1472 lf.lfHeight = -11;
1473 lf.lfWeight = FW_NORMAL;
1474 lf.lfCharSet = charset;
1475 strcpy(lf.lfFaceName, "Tahoma");
1477 hfont = CreateFontIndirectA(&lf);
1478 ok(hfont != NULL, "got %p\n", hfont);
1480 /* Big window rectangle */
1481 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 5000, 1000, NULL, NULL, NULL, NULL);
1482 ok(hwnd != NULL, "got %p\n", hwnd);
1483 GetClientRect(hwnd, &rect);
1484 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1486 hdc = GetDC(hwnd);
1487 hfont = SelectObject(hdc, hfont);
1488 size.cx = GdiGetCharDimensions( hdc, NULL, &size.cy );
1489 expect = MAKELONG(size.cx / 2, size.cx / 2);
1490 small_expect = 0;
1491 empty_expect = size.cx >= 28 ? small_expect : expect;
1493 charset = GetTextCharset(hdc);
1494 switch (charset)
1496 case SHIFTJIS_CHARSET:
1497 case HANGUL_CHARSET:
1498 case GB2312_CHARSET:
1499 case CHINESEBIG5_CHARSET:
1500 cjk = TRUE;
1501 break;
1502 default:
1503 cjk = FALSE;
1506 hfont = SelectObject(hdc, hfont);
1507 ReleaseDC(hwnd, hdc);
1509 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1510 ok(margins == 0, "got %x\n", margins);
1511 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1512 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1513 if (!cjk)
1514 ok(margins == expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1515 else
1517 ok(HIWORD(margins) > 0 && LOWORD(margins) > 0, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1518 expect = empty_expect = small_expect = margins;
1520 DestroyWindow(hwnd);
1522 threshold = (size.cx / 2 + size.cx) * 2;
1524 /* Size below which non-cjk margins are zero */
1525 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, threshold - 1, 100, NULL, NULL, NULL, NULL);
1526 ok(hwnd != NULL, "got %p\n", hwnd);
1527 GetClientRect(hwnd, &rect);
1528 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1530 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1531 ok(margins == 0, "got %x\n", margins);
1533 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1534 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1535 ok(margins == small_expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1536 DestroyWindow(hwnd);
1538 /* Size at which non-cjk margins become non-zero */
1539 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, threshold, 100, NULL, NULL, NULL, NULL);
1540 ok(hwnd != NULL, "got %p\n", hwnd);
1541 GetClientRect(hwnd, &rect);
1542 ok(!IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1544 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1545 ok(margins == 0, "got %x\n", margins);
1547 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1548 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1549 ok(margins == expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1550 DestroyWindow(hwnd);
1552 /* Empty rect */
1553 hwnd = CreateWindowExA(0, "Edit", "A", WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
1554 ok(hwnd != NULL, "got %p\n", hwnd);
1555 GetClientRect(hwnd, &rect);
1556 ok(IsRectEmpty(&rect), "got rect %s\n", wine_dbgstr_rect(&rect));
1558 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1559 ok(margins == 0, "got %x\n", margins);
1561 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));
1562 margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0);
1563 ok(margins == empty_expect, "%d: got %d, %d\n", charset, HIWORD(margins), LOWORD(margins));
1564 DestroyWindow(hwnd);
1566 DeleteObject(hfont);
1569 static void test_margins(void)
1571 DWORD old_margins, new_margins;
1572 RECT old_rect, new_rect;
1573 INT old_right_margin;
1574 HWND hwEdit;
1576 hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
1578 old_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1579 old_right_margin = HIWORD(old_margins);
1581 /* Check if setting the margins works */
1583 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(10, 0));
1584 new_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1585 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1586 ok(HIWORD(new_margins) == old_right_margin, "Wrong right margin: %d\n", HIWORD(new_margins));
1588 SendMessageA(hwEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG(0, 10));
1589 new_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1590 ok(LOWORD(new_margins) == 10, "Wrong left margin: %d\n", LOWORD(new_margins));
1591 ok(HIWORD(new_margins) == 10, "Wrong right margin: %d\n", HIWORD(new_margins));
1593 /* The size of the rectangle must decrease if we increase the margin */
1595 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
1596 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1597 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20));
1598 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1599 ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n");
1600 ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n");
1601 ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n");
1602 ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n");
1604 /* If we set the margin to same value as the current margin,
1605 the rectangle must not change */
1607 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1608 SetRect(&old_rect, 1, 1, 99, 99);
1609 SendMessageA(hwEdit, EM_SETRECT, 0, (LPARAM)&old_rect);
1610 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1611 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10));
1612 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1613 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1615 /* The lParam argument of the WM_SIZE message should be ignored. */
1617 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&old_rect);
1618 SendMessageA(hwEdit, WM_SIZE, SIZE_RESTORED, 0);
1619 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1620 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1621 SendMessageA(hwEdit, WM_SIZE, SIZE_MINIMIZED, 0);
1622 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1623 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1624 SendMessageA(hwEdit, WM_SIZE, SIZE_MAXIMIZED, 0);
1625 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1626 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1627 SendMessageA(hwEdit, WM_SIZE, SIZE_RESTORED, MAKELONG(10, 10));
1628 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM)&new_rect);
1629 ok(EqualRect(&old_rect, &new_rect), "The border of the rectangle has changed\n");
1631 DestroyWindow (hwEdit);
1633 test_margins_usefontinfo(ANSI_CHARSET);
1634 test_margins_usefontinfo(EASTEUROPE_CHARSET);
1636 test_margins_usefontinfo(SHIFTJIS_CHARSET);
1637 test_margins_usefontinfo(HANGUL_CHARSET);
1638 test_margins_usefontinfo(CHINESEBIG5_CHARSET);
1639 /* Don't test JOHAB_CHARSET. Treated as CJK by Win 8,
1640 but not by < Win 8 and Win 10. */
1642 test_margins_usefontinfo(DEFAULT_CHARSET);
1645 static INT CALLBACK find_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
1647 return 0;
1650 static void test_margins_font_change(void)
1652 DWORD margins, font_margins, ret;
1653 HFONT hfont, hfont2;
1654 HWND hwEdit;
1655 LOGFONTA lf;
1656 HDC hdc;
1658 hdc = GetDC(0);
1659 ret = EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0);
1660 ReleaseDC(0, hdc);
1661 if (ret)
1663 trace("Arial not found - skipping font change margin tests\n");
1664 return;
1667 hwEdit = create_child_editcontrol(0, 0);
1669 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1671 memset(&lf, 0, sizeof(lf));
1672 strcpy(lf.lfFaceName, "Arial");
1673 lf.lfHeight = 16;
1674 lf.lfCharSet = DEFAULT_CHARSET;
1675 hfont = CreateFontIndirectA(&lf);
1676 lf.lfHeight = 30;
1677 hfont2 = CreateFontIndirectA(&lf);
1679 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1680 font_margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1681 ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
1682 ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
1684 /* With 'small' edit controls, test that the margin doesn't get set */
1685 SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1686 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
1687 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1688 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1689 ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins));
1690 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
1692 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1693 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1694 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1695 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1696 ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
1698 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1699 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1700 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1701 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1702 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
1704 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1705 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1706 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1707 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
1709 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1710 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1711 ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
1712 ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));
1714 /* Above a certain size threshold then the margin is updated */
1715 SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
1716 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
1717 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1718 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1719 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1720 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1722 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
1723 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1724 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1725 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1726 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1728 SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
1729 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
1730 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1731 ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
1732 ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
1733 SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
1734 margins = SendMessageA(hwEdit, EM_GETMARGINS, 0, 0);
1735 ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins));
1736 ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins));
1738 SendMessageA(hwEdit, WM_SETFONT, 0, 0);
1740 DeleteObject(hfont2);
1741 DeleteObject(hfont);
1742 destroy_child_editcontrol(hwEdit);
1746 #define edit_pos_ok(exp, got, txt) \
1747 ok(exp == got, "wrong " #txt " expected %d got %d\n", exp, got);
1749 #define check_pos(hwEdit, set_height, test_top, test_height, test_left) \
1750 do { \
1751 RECT format_rect; \
1752 int left_margin; \
1753 set_client_height(hwEdit, set_height); \
1754 SendMessageA(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \
1755 left_margin = LOWORD(SendMessageA(hwEdit, EM_GETMARGINS, 0, 0)); \
1756 edit_pos_ok(test_top, format_rect.top, vertical position); \
1757 edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \
1758 edit_pos_ok(test_left, format_rect.left - left_margin, left); \
1759 } while(0)
1761 static void test_text_position_style(DWORD style)
1763 HWND hwEdit;
1764 HFONT font, oldFont;
1765 HDC dc;
1766 TEXTMETRICA metrics;
1767 INT b, bm, b2, b3;
1768 BOOL xb, single_line = !(style & ES_MULTILINE);
1770 b = GetSystemMetrics(SM_CYBORDER) + 1;
1771 b2 = 2 * b;
1772 b3 = 3 * b;
1773 bm = b2 - 1;
1775 /* Get a stock font for which we can determine the metrics */
1776 font = GetStockObject(SYSTEM_FONT);
1777 ok (font != NULL, "GetStockObject SYSTEM_FONT failed\n");
1778 dc = GetDC(NULL);
1779 ok (dc != NULL, "GetDC() failed\n");
1780 oldFont = SelectObject(dc, font);
1781 xb = GetTextMetricsA(dc, &metrics);
1782 ok (xb, "GetTextMetrics failed\n");
1783 SelectObject(dc, oldFont);
1784 ReleaseDC(NULL, dc);
1786 /* Windows' edit control has some bugs in multi-line mode:
1787 * - Sometimes the format rectangle doesn't get updated
1788 * (see workaround in set_client_height())
1789 * - If the height of the control is smaller than the height of a text
1790 * line, the format rectangle is still as high as a text line
1791 * (higher than the client rectangle) and the caret is not shown
1794 /* Edit controls that are in a parent window */
1796 hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0);
1797 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1798 if (single_line)
1799 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
1800 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
1801 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
1802 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
1803 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
1804 destroy_child_editcontrol(hwEdit);
1806 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0);
1807 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1808 if (single_line)
1809 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
1810 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
1811 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
1812 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
1813 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
1814 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
1815 destroy_child_editcontrol(hwEdit);
1817 hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE);
1818 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1819 if (single_line)
1820 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1821 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1822 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1823 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1824 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1825 destroy_child_editcontrol(hwEdit);
1827 hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE);
1828 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1829 if (single_line)
1830 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1831 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1832 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1833 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1834 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1835 destroy_child_editcontrol(hwEdit);
1838 /* Edit controls that are popup windows */
1840 hwEdit = create_editcontrol(style | WS_POPUP, 0);
1841 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1842 if (single_line)
1843 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0);
1844 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0);
1845 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0);
1846 check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0);
1847 check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0);
1848 DestroyWindow(hwEdit);
1850 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0);
1851 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1852 if (single_line)
1853 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b);
1854 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b);
1855 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b);
1856 check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b);
1857 check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b);
1858 check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b);
1859 DestroyWindow(hwEdit);
1861 hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE);
1862 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1863 if (single_line)
1864 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1865 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1866 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1867 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1868 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1869 DestroyWindow(hwEdit);
1871 hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE);
1872 SendMessageA(hwEdit, WM_SETFONT, (WPARAM) font, FALSE);
1873 if (single_line)
1874 check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1);
1875 check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1);
1876 check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1);
1877 check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1);
1878 check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1);
1879 DestroyWindow(hwEdit);
1882 static void test_text_position(void)
1884 trace("EDIT: Text position (Single line)\n");
1885 test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1886 trace("EDIT: Text position (Multi line)\n");
1887 test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL);
1890 static void test_espassword(void)
1892 HWND hwEdit;
1893 LONG r;
1894 char buffer[1024];
1895 const char* password = "secret";
1897 hwEdit = create_editcontrol(ES_PASSWORD, 0);
1898 r = get_edit_style(hwEdit);
1899 ok(r == ES_PASSWORD, "Wrong style expected ES_PASSWORD got: 0x%x\n", r);
1900 /* set text */
1901 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) password);
1902 ok(r == TRUE, "Expected: %d, got: %d\n", TRUE, r);
1904 /* select all, cut (ctrl-x) */
1905 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
1906 r = SendMessageA(hwEdit, WM_CHAR, 24, 0);
1907 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1909 /* get text */
1910 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1911 ok(r == strlen(password), "Expected: %s, got len %d\n", password, r);
1912 ok(strcmp(buffer, password) == 0, "expected %s, got %s\n", password, buffer);
1914 r = OpenClipboard(hwEdit);
1915 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1916 r = EmptyClipboard();
1917 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1918 r = CloseClipboard();
1919 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
1921 /* select all, copy (ctrl-c) and paste (ctrl-v) */
1922 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
1923 r = SendMessageA(hwEdit, WM_CHAR, 3, 0);
1924 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1925 r = SendMessageA(hwEdit, WM_CHAR, 22, 0);
1926 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1928 /* get text */
1929 buffer[0] = 0;
1930 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1931 ok(r == 0, "Expected: 0, got: %d\n", r);
1932 ok(strcmp(buffer, "") == 0, "expected empty string, got %s\n", buffer);
1934 DestroyWindow(hwEdit);
1937 static void test_undo(void)
1939 HWND hwEdit;
1940 LONG r;
1941 DWORD cpMin, cpMax;
1942 char buffer[1024];
1943 const char* text = "undo this";
1945 hwEdit = create_editcontrol(0, 0);
1946 r = get_edit_style(hwEdit);
1947 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
1949 /* set text */
1950 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) text);
1951 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
1953 /* select all, */
1954 cpMin = cpMax = 0xdeadbeef;
1955 SendMessageA(hwEdit, EM_SETSEL, 0, -1);
1956 r = SendMessageA(hwEdit, EM_GETSEL, (WPARAM) &cpMin, (LPARAM) &cpMax);
1957 ok((strlen(text) << 16) == r, "Unexpected length %d\n", r);
1958 ok(0 == cpMin, "Expected: %d, got %d\n", 0, cpMin);
1959 ok(9 == cpMax, "Expected: %d, got %d\n", 9, cpMax);
1961 /* cut (ctrl-x) */
1962 r = SendMessageA(hwEdit, WM_CHAR, 24, 0);
1963 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1965 /* get text */
1966 buffer[0] = 0;
1967 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1968 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
1969 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1971 /* undo (ctrl-z) */
1972 r = SendMessageA(hwEdit, WM_CHAR, 26, 0);
1973 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1975 /* get text */
1976 buffer[0] = 0;
1977 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1978 ok(strlen(text) == r, "Unexpected length %d\n", r);
1979 ok(0 == strcmp(buffer, text), "expected %s, got %s\n", text, buffer);
1981 /* undo again (ctrl-z) */
1982 r = SendMessageA(hwEdit, WM_CHAR, 26, 0);
1983 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
1985 /* get text */
1986 buffer[0] = 0;
1987 r = SendMessageA(hwEdit, WM_GETTEXT, 1024, (LPARAM) buffer);
1988 ok(r == 0, "Expected: %d, got len %d\n", 0, r);
1989 ok(0 == strcmp(buffer, ""), "expected %s, got %s\n", "", buffer);
1991 DestroyWindow(hwEdit);
1994 static void test_enter(void)
1996 char buffer[16];
1997 HWND hwEdit;
1998 LONG r;
2000 /* multiline */
2001 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2002 r = get_edit_style(hwEdit);
2003 ok(ES_MULTILINE == r, "Wrong style expected ES_MULTILINE got: 0x%x\n", r);
2005 /* set text */
2006 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2007 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2009 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2010 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2012 /* get text */
2013 buffer[0] = 0;
2014 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2015 ok(2 == r, "Expected: %d, got len %d\n", 2, r);
2016 ok(0 == strcmp(buffer, "\r\n"), "expected \"\\r\\n\", got \"%s\"\n", buffer);
2018 DestroyWindow (hwEdit);
2020 /* single line */
2021 hwEdit = create_editcontrol(0, 0);
2022 r = get_edit_style(hwEdit);
2023 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2025 /* set text */
2026 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2027 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2029 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2030 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2032 /* get text */
2033 buffer[0] = 0;
2034 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2035 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2036 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2038 DestroyWindow(hwEdit);
2040 /* single line with ES_WANTRETURN */
2041 hwEdit = create_editcontrol(ES_WANTRETURN, 0);
2042 r = get_edit_style(hwEdit);
2043 ok(ES_WANTRETURN == r, "Wrong style expected ES_WANTRETURN got: 0x%x\n", r);
2045 /* set text */
2046 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2047 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2049 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0);
2050 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2052 /* get text */
2053 buffer[0] = 0;
2054 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2055 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2056 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2058 DestroyWindow(hwEdit);
2061 static void test_tab(void)
2063 char buffer[16];
2064 HWND hwEdit;
2065 LONG r;
2067 /* multiline */
2068 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2069 r = get_edit_style(hwEdit);
2070 ok(ES_MULTILINE == r, "Wrong style expected ES_MULTILINE got: 0x%x\n", r);
2072 /* set text */
2073 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2074 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2076 r = SendMessageA(hwEdit, WM_CHAR, VK_TAB, 0);
2077 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2079 /* get text */
2080 buffer[0] = 0;
2081 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2082 ok(1 == r, "Expected: %d, got len %d\n", 1, r);
2083 ok(0 == strcmp(buffer, "\t"), "expected \"\\t\", got \"%s\"\n", buffer);
2085 DestroyWindow(hwEdit);
2087 /* single line */
2088 hwEdit = create_editcontrol(0, 0);
2089 r = get_edit_style(hwEdit);
2090 ok(0 == r, "Wrong style expected 0x%x got: 0x%x\n", 0, r);
2092 /* set text */
2093 r = SendMessageA(hwEdit , WM_SETTEXT, 0, (LPARAM) "");
2094 ok(TRUE == r, "Expected: %d, got: %d\n", TRUE, r);
2096 r = SendMessageA(hwEdit, WM_CHAR, VK_TAB, 0);
2097 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2099 /* get text */
2100 buffer[0] = 0;
2101 r = SendMessageA(hwEdit, WM_GETTEXT, 16, (LPARAM) buffer);
2102 ok(0 == r, "Expected: %d, got len %d\n", 0, r);
2103 ok(0 == strcmp(buffer, ""), "expected \"\", got \"%s\"\n", buffer);
2105 DestroyWindow(hwEdit);
2108 static void test_edit_dialog(void)
2110 int r;
2112 /* from bug 11841 */
2113 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 0);
2114 ok(333 == r, "Expected %d, got %d\n", 333, r);
2115 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 1);
2116 ok(111 == r, "Expected %d, got %d\n", 111, r);
2117 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 2);
2118 ok(444 == r, "Expected %d, got %d\n", 444, r);
2120 /* more tests for WM_CHAR */
2121 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 3);
2122 ok(444 == r, "Expected %d, got %d\n", 444, r);
2123 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 4);
2124 ok(444 == r, "Expected %d, got %d\n", 444, r);
2125 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 5);
2126 ok(444 == r, "Expected %d, got %d\n", 444, r);
2128 /* more tests for WM_KEYDOWN + WM_CHAR */
2129 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 6);
2130 ok(444 == r, "Expected %d, got %d\n", 444, r);
2131 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 7);
2132 ok(444 == r, "Expected %d, got %d\n", 444, r);
2133 r = DialogBoxParamA(hinst, "EDIT_READONLY_DIALOG", NULL, edit_dialog_proc, 8);
2134 ok(444 == r, "Expected %d, got %d\n", 444, r);
2136 /* tests with an editable edit control */
2137 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 0);
2138 ok(333 == r, "Expected %d, got %d\n", 333, r);
2139 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 1);
2140 ok(111 == r, "Expected %d, got %d\n", 111, r);
2141 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 2);
2142 ok(444 == r, "Expected %d, got %d\n", 444, r);
2144 /* tests for WM_CHAR */
2145 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 3);
2146 ok(444 == r, "Expected %d, got %d\n", 444, r);
2147 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 4);
2148 ok(444 == r, "Expected %d, got %d\n", 444, r);
2149 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 5);
2150 ok(444 == r, "Expected %d, got %d\n", 444, r);
2152 /* tests for WM_KEYDOWN + WM_CHAR */
2153 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 6);
2154 ok(444 == r, "Expected %d, got %d\n", 444, r);
2155 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 7);
2156 ok(444 == r, "Expected %d, got %d\n", 444, r);
2157 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 8);
2158 ok(444 == r, "Expected %d, got %d\n", 444, r);
2160 /* multiple tab tests */
2161 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 9);
2162 ok(22 == r, "Expected %d, got %d\n", 22, r);
2163 r = DialogBoxParamA(hinst, "EDIT_DIALOG", NULL, edit_dialog_proc, 10);
2164 ok(33 == r, "Expected %d, got %d\n", 33, r);
2167 static void test_multi_edit_dialog(void)
2169 int r;
2171 /* test for multiple edit dialogs (bug 12319) */
2172 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 0);
2173 ok(2222 == r, "Expected %d, got %d\n", 2222, r);
2174 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 1);
2175 ok(1111 == r, "Expected %d, got %d\n", 1111, r);
2176 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 2);
2177 ok(2222 == r, "Expected %d, got %d\n", 2222, r);
2178 r = DialogBoxParamA(hinst, "MULTI_EDIT_DIALOG", NULL, multi_edit_dialog_proc, 3);
2179 ok(11 == r, "Expected %d, got %d\n", 11, r);
2182 static void test_wantreturn_edit_dialog(void)
2184 int r;
2186 /* tests for WM_KEYDOWN */
2187 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 0);
2188 ok(333 == r, "Expected %d, got %d\n", 333, r);
2189 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 1);
2190 ok(444 == r, "Expected %d, got %d\n", 444, r);
2191 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 2);
2192 ok(444 == r, "Expected %d, got %d\n", 444, r);
2194 /* tests for WM_CHAR */
2195 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 3);
2196 ok(444 == r, "Expected %d, got %d\n", 444, r);
2197 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 4);
2198 ok(444 == r, "Expected %d, got %d\n", 444, r);
2199 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 5);
2200 ok(444 == r, "Expected %d, got %d\n", 444, r);
2202 /* tests for WM_KEYDOWN + WM_CHAR */
2203 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 6);
2204 ok(444 == r, "Expected %d, got %d\n", 444, r);
2205 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 7);
2206 ok(444 == r, "Expected %d, got %d\n", 444, r);
2207 r = DialogBoxParamA(hinst, "EDIT_WANTRETURN_DIALOG", NULL, edit_wantreturn_dialog_proc, 8);
2208 ok(444 == r, "Expected %d, got %d\n", 444, r);
2211 static void test_singleline_wantreturn_edit_dialog(void)
2213 int r;
2215 /* tests for WM_KEYDOWN */
2216 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 0);
2217 ok(222 == r, "Expected %d, got %d\n", 222, r);
2218 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 1);
2219 ok(111 == r, "Expected %d, got %d\n", 111, r);
2220 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 2);
2221 ok(444 == r, "Expected %d, got %d\n", 444, r);
2223 /* tests for WM_CHAR */
2224 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 3);
2225 ok(444 == r, "Expected %d, got %d\n", 444, r);
2226 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 4);
2227 ok(444 == r, "Expected %d, got %d\n", 444, r);
2228 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 5);
2229 ok(444 == r, "Expected %d, got %d\n", 444, r);
2231 /* tests for WM_KEYDOWN + WM_CHAR */
2232 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 6);
2233 ok(222 == r, "Expected %d, got %d\n", 222, r);
2234 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 7);
2235 ok(111 == r, "Expected %d, got %d\n", 111, r);
2236 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_DIALOG", NULL, edit_singleline_dialog_proc, 8);
2237 ok(444 == r, "Expected %d, got %d\n", 444, r);
2239 /* tests for WM_KEYDOWN */
2240 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 0);
2241 ok(222 == r, "Expected %d, got %d\n", 222, r);
2242 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 1);
2243 ok(111 == r, "Expected %d, got %d\n", 111, r);
2244 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 2);
2245 ok(444 == r, "Expected %d, got %d\n", 444, r);
2247 /* tests for WM_CHAR */
2248 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 3);
2249 ok(444 == r, "Expected %d, got %d\n", 444, r);
2250 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 4);
2251 ok(444 == r, "Expected %d, got %d\n", 444, r);
2252 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 5);
2253 ok(444 == r, "Expected %d, got %d\n", 444, r);
2255 /* tests for WM_KEYDOWN + WM_CHAR */
2256 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 6);
2257 ok(222 == r, "Expected %d, got %d\n", 222, r);
2258 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 7);
2259 ok(111 == r, "Expected %d, got %d\n", 111, r);
2260 r = DialogBoxParamA(hinst, "EDIT_SINGLELINE_WANTRETURN_DIALOG", NULL, edit_singleline_dialog_proc, 8);
2261 ok(444 == r, "Expected %d, got %d\n", 444, r);
2264 static int child_edit_wmkeydown_num_messages = 0;
2265 static INT_PTR CALLBACK child_edit_wmkeydown_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
2267 switch (msg)
2269 case WM_DESTROY:
2270 case WM_NCDESTROY:
2271 break;
2273 default:
2274 child_edit_wmkeydown_num_messages++;
2275 break;
2278 return FALSE;
2281 static void test_child_edit_wmkeydown(void)
2283 HWND hwEdit, hwParent;
2284 int r;
2286 hwEdit = create_child_editcontrol(0, 0);
2287 hwParent = GetParent(hwEdit);
2288 SetWindowLongPtrA(hwParent, GWLP_WNDPROC, (LONG_PTR)child_edit_wmkeydown_proc);
2289 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2290 ok(1 == r, "expected 1, got %d\n", r);
2291 ok(0 == child_edit_wmkeydown_num_messages, "expected 0, got %d\n", child_edit_wmkeydown_num_messages);
2292 destroy_child_editcontrol(hwEdit);
2295 static BOOL got_en_setfocus = FALSE;
2296 static BOOL got_wm_capturechanged = FALSE;
2297 static LRESULT (CALLBACK *p_edit_proc)(HWND, UINT, WPARAM, LPARAM);
2299 static LRESULT CALLBACK edit4_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
2301 switch (msg) {
2302 case WM_COMMAND:
2303 switch (HIWORD(wParam))
2305 case EN_SETFOCUS:
2306 got_en_setfocus = TRUE;
2307 break;
2309 break;
2310 case WM_CAPTURECHANGED:
2311 if (hWnd != (HWND)lParam)
2313 got_wm_capturechanged = TRUE;
2314 EndMenu();
2316 break;
2318 return DefWindowProcA(hWnd, msg, wParam, lParam);
2321 struct context_menu_messages
2323 unsigned int wm_command, em_setsel;
2326 static struct context_menu_messages menu_messages;
2328 static LRESULT CALLBACK child_edit_menu_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2330 switch (msg)
2332 case WM_ENTERIDLE:
2333 if (wParam == MSGF_MENU)
2335 HWND hwndMenu = (HWND)lParam;
2336 MENUBARINFO mbi = { sizeof(mbi) };
2337 if (GetMenuBarInfo(hwndMenu, OBJID_CLIENT, 0, &mbi))
2339 MENUITEMINFOA mii = { sizeof(MENUITEMINFOA), MIIM_STATE };
2340 if (GetMenuItemInfoA(mbi.hMenu, EM_SETSEL, FALSE, &mii))
2342 if (mii.fState & MFS_HILITE)
2344 PostMessageA(hwnd, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2345 PostMessageA(hwnd, WM_KEYUP, VK_RETURN, 0x1c0001);
2347 else
2349 PostMessageA(hwnd, WM_KEYDOWN, VK_DOWN, 0x500001);
2350 PostMessageA(hwnd, WM_KEYUP, VK_DOWN, 0x500001);
2355 break;
2356 case WM_COMMAND:
2357 menu_messages.wm_command++;
2358 break;
2359 case EM_SETSEL:
2360 menu_messages.em_setsel++;
2361 break;
2363 return CallWindowProcA(p_edit_proc, hwnd, msg, wParam, lParam);
2366 static void test_contextmenu(void)
2368 HWND hwndMain, hwndEdit;
2369 MSG msg;
2371 hwndMain = CreateWindowA(szEditTest4Class, "ET4", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
2372 0, 0, 200, 200, NULL, NULL, hinst, NULL);
2373 assert(hwndMain);
2375 hwndEdit = CreateWindowA("EDIT", NULL,
2376 WS_CHILD|WS_BORDER|WS_VISIBLE|ES_LEFT|ES_AUTOHSCROLL,
2377 0, 0, 150, 50, /* important this not be 0 size. */
2378 hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL);
2379 assert(hwndEdit);
2381 SetFocus(NULL);
2382 SetCapture(hwndMain);
2383 SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(10, 10));
2384 ok(got_en_setfocus, "edit box didn't get focused\n");
2385 ok(got_wm_capturechanged, "main window capture did not change\n");
2387 DestroyWindow(hwndEdit);
2389 hwndEdit = CreateWindowA("EDIT", "Test Text",
2390 WS_CHILD | WS_BORDER | WS_VISIBLE,
2391 0, 0, 100, 100,
2392 hwndMain, NULL, hinst, NULL);
2393 memset(&menu_messages, 0, sizeof(menu_messages));
2394 p_edit_proc = (void*)SetWindowLongPtrA(hwndEdit, GWLP_WNDPROC,
2395 (ULONG_PTR)child_edit_menu_proc);
2397 SetFocus(hwndEdit);
2398 SendMessageA(hwndEdit, WM_SETTEXT, 0, (LPARAM)"foo");
2399 SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(-1, -1));
2400 while (PeekMessageA(&msg, hwndEdit, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
2401 ok(menu_messages.wm_command == 0,
2402 "Expected no WM_COMMAND messages, got %d\n", menu_messages.wm_command);
2403 ok(menu_messages.em_setsel == 1,
2404 "Expected 1 EM_SETSEL message, got %d\n", menu_messages.em_setsel);
2406 DestroyWindow(hwndEdit);
2407 DestroyWindow(hwndMain);
2410 static BOOL register_classes(void)
2412 WNDCLASSA test2;
2413 WNDCLASSA test3;
2414 WNDCLASSA test4;
2415 WNDCLASSA text_position;
2417 test2.style = 0;
2418 test2.lpfnWndProc = ET2_WndProc;
2419 test2.cbClsExtra = 0;
2420 test2.cbWndExtra = 0;
2421 test2.hInstance = hinst;
2422 test2.hIcon = NULL;
2423 test2.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
2424 test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2425 test2.lpszMenuName = NULL;
2426 test2.lpszClassName = szEditTest2Class;
2427 if (!RegisterClassA(&test2)) return FALSE;
2429 test3.style = 0;
2430 test3.lpfnWndProc = edit3_wnd_procA;
2431 test3.cbClsExtra = 0;
2432 test3.cbWndExtra = 0;
2433 test3.hInstance = hinst;
2434 test3.hIcon = 0;
2435 test3.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
2436 test3.hbrBackground = GetStockObject(WHITE_BRUSH);
2437 test3.lpszMenuName = NULL;
2438 test3.lpszClassName = szEditTest3Class;
2439 if (!RegisterClassA(&test3)) return FALSE;
2441 test4.style = 0;
2442 test4.lpfnWndProc = edit4_wnd_procA;
2443 test4.cbClsExtra = 0;
2444 test4.cbWndExtra = 0;
2445 test4.hInstance = hinst;
2446 test4.hIcon = NULL;
2447 test4.hCursor = LoadCursorA (NULL, (LPCSTR)IDC_ARROW);
2448 test4.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2449 test4.lpszMenuName = NULL;
2450 test4.lpszClassName = szEditTest4Class;
2451 if (!RegisterClassA(&test4)) return FALSE;
2453 text_position.style = CS_HREDRAW | CS_VREDRAW;
2454 text_position.cbClsExtra = 0;
2455 text_position.cbWndExtra = 0;
2456 text_position.hInstance = hinst;
2457 text_position.hIcon = NULL;
2458 text_position.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
2459 text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2460 text_position.lpszMenuName = NULL;
2461 text_position.lpszClassName = szEditTextPositionClass;
2462 text_position.lpfnWndProc = DefWindowProcA;
2463 if (!RegisterClassA(&text_position)) return FALSE;
2465 return TRUE;
2468 static void UnregisterWindowClasses (void)
2470 UnregisterClassA(szEditTest2Class, hinst);
2471 UnregisterClassA(szEditTest3Class, hinst);
2472 UnregisterClassA(szEditTest4Class, hinst);
2473 UnregisterClassA(szEditTextPositionClass, hinst);
2476 static void test_fontsize(void)
2478 HWND hwEdit;
2479 HFONT hfont;
2480 HDC hDC;
2481 LOGFONTA lf;
2482 LONG r;
2483 char szLocalString[MAXLEN];
2484 int dpi;
2486 hDC = GetDC(NULL);
2487 dpi = GetDeviceCaps(hDC, LOGPIXELSY);
2488 ReleaseDC(NULL, hDC);
2490 memset(&lf,0,sizeof(LOGFONTA));
2491 strcpy(lf.lfFaceName,"Arial");
2492 lf.lfHeight = -300; /* taller than the edit box */
2493 lf.lfWeight = 500;
2494 hfont = CreateFontIndirectA(&lf);
2496 trace("EDIT: Oversized font (Multi line)\n");
2497 hwEdit= CreateWindowA("EDIT", NULL, ES_MULTILINE|ES_AUTOHSCROLL,
2498 0, 0, (150 * dpi) / 96, (50 * dpi) / 96, NULL, NULL,
2499 hinst, NULL);
2501 SendMessageA(hwEdit,WM_SETFONT,(WPARAM)hfont,0);
2503 if (winetest_interactive)
2504 ShowWindow (hwEdit, SW_SHOW);
2506 r = SendMessageA(hwEdit, WM_CHAR, 'A', 1);
2507 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2508 r = SendMessageA(hwEdit, WM_CHAR, 'B', 1);
2509 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2510 r = SendMessageA(hwEdit, WM_CHAR, 'C', 1);
2511 ok(1 == r, "Expected: %d, got: %d\n", 1, r);
2513 GetWindowTextA(hwEdit, szLocalString, MAXLEN);
2514 ok(strcmp(szLocalString, "ABC")==0,
2515 "Wrong contents of edit: %s\n", szLocalString);
2517 r = SendMessageA(hwEdit, EM_POSFROMCHAR,0,0);
2518 ok(r != -1,"EM_POSFROMCHAR failed index 0\n");
2519 r = SendMessageA(hwEdit, EM_POSFROMCHAR,1,0);
2520 ok(r != -1,"EM_POSFROMCHAR failed index 1\n");
2521 r = SendMessageA(hwEdit, EM_POSFROMCHAR,2,0);
2522 ok(r != -1,"EM_POSFROMCHAR failed index 2\n");
2523 r = SendMessageA(hwEdit, EM_POSFROMCHAR,3,0);
2524 ok(r == -1,"EM_POSFROMCHAR succeeded index 3\n");
2526 DestroyWindow (hwEdit);
2527 DeleteObject(hfont);
2530 struct dialog_mode_messages
2532 int wm_getdefid, wm_close, wm_command, wm_nextdlgctl;
2535 static struct dialog_mode_messages dm_messages;
2537 static void zero_dm_messages(void)
2539 dm_messages.wm_command = 0;
2540 dm_messages.wm_close = 0;
2541 dm_messages.wm_getdefid = 0;
2542 dm_messages.wm_nextdlgctl = 0;
2545 #define test_dm_messages(wmcommand, wmclose, wmgetdefid, wmnextdlgctl) \
2546 ok(dm_messages.wm_command == wmcommand, "expected %d WM_COMMAND messages, " \
2547 "got %d\n", wmcommand, dm_messages.wm_command); \
2548 ok(dm_messages.wm_close == wmclose, "expected %d WM_CLOSE messages, " \
2549 "got %d\n", wmclose, dm_messages.wm_close); \
2550 ok(dm_messages.wm_getdefid == wmgetdefid, "expected %d WM_GETDIFID messages, " \
2551 "got %d\n", wmgetdefid, dm_messages.wm_getdefid);\
2552 ok(dm_messages.wm_nextdlgctl == wmnextdlgctl, "expected %d WM_NEXTDLGCTL messages, " \
2553 "got %d\n", wmnextdlgctl, dm_messages.wm_nextdlgctl)
2555 static LRESULT CALLBACK dialog_mode_wnd_proc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
2557 switch (iMsg)
2559 case WM_COMMAND:
2560 dm_messages.wm_command++;
2561 break;
2562 case DM_GETDEFID:
2563 dm_messages.wm_getdefid++;
2564 return MAKELONG(ID_EDITTESTDBUTTON, DC_HASDEFID);
2565 case WM_NEXTDLGCTL:
2566 dm_messages.wm_nextdlgctl++;
2567 break;
2568 case WM_CLOSE:
2569 dm_messages.wm_close++;
2570 break;
2573 return DefWindowProcA(hwnd, iMsg, wParam, lParam);
2576 static void test_dialogmode(void)
2578 HWND hwEdit, hwParent, hwButton;
2579 MSG msg= {0};
2580 int len, r;
2581 hwEdit = create_child_editcontrol(ES_MULTILINE, 0);
2583 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2584 ok(1 == r, "expected 1, got %d\n", r);
2585 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2586 ok(11 == len, "expected 11, got %d\n", len);
2588 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, 0);
2589 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2591 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2592 ok(1 == r, "expected 1, got %d\n", r);
2593 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2594 ok(13 == len, "expected 13, got %d\n", len);
2596 r = SendMessageA(hwEdit, WM_GETDLGCODE, 0, (LPARAM)&msg);
2597 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2598 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2599 ok(1 == r, "expected 1, got %d\n", r);
2600 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2601 ok(13 == len, "expected 13, got %d\n", len);
2603 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2604 ok(1 == r, "expected 1, got %d\n", r);
2605 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2606 ok(13 == len, "expected 13, got %d\n", len);
2608 destroy_child_editcontrol(hwEdit);
2610 hwEdit = create_editcontrol(ES_MULTILINE, 0);
2612 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2613 ok(1 == r, "expected 1, got %d\n", r);
2614 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2615 ok(11 == len, "expected 11, got %d\n", len);
2617 msg.hwnd = hwEdit;
2618 msg.message = WM_KEYDOWN;
2619 msg.wParam = VK_BACK;
2620 msg.lParam = 0xe0001;
2621 r = SendMessageA(hwEdit, WM_GETDLGCODE, VK_BACK, (LPARAM)&msg);
2622 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2624 r = SendMessageA(hwEdit, WM_CHAR, VK_RETURN, 0x1c0001);
2625 ok(1 == r, "expected 1, got %d\n", r);
2626 len = SendMessageA(hwEdit, WM_GETTEXTLENGTH, 0, 0);
2627 ok(11 == len, "expected 11, got %d\n", len);
2629 DestroyWindow(hwEdit);
2631 hwEdit = create_child_editcontrol(0, 0);
2632 hwParent = GetParent(hwEdit);
2633 SetWindowLongPtrA(hwParent, GWLP_WNDPROC, (LONG_PTR)dialog_mode_wnd_proc);
2635 zero_dm_messages();
2636 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
2637 ok(1 == r, "expected 1, got %d\n", r);
2638 test_dm_messages(0, 0, 0, 0);
2639 zero_dm_messages();
2641 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2642 ok(1 == r, "expected 1, got %d\n", r);
2643 test_dm_messages(0, 0, 0, 0);
2644 zero_dm_messages();
2646 msg.hwnd = hwEdit;
2647 msg.message = WM_KEYDOWN;
2648 msg.wParam = VK_TAB;
2649 msg.lParam = 0xf0001;
2650 r = SendMessageA(hwEdit, WM_GETDLGCODE, VK_TAB, (LPARAM)&msg);
2651 ok(0x89 == r, "expected 0x89, got 0x%x\n", r);
2652 test_dm_messages(0, 0, 0, 0);
2653 zero_dm_messages();
2655 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2656 ok(1 == r, "expected 1, got %d\n", r);
2657 test_dm_messages(0, 0, 0, 0);
2658 zero_dm_messages();
2660 destroy_child_editcontrol(hwEdit);
2662 hwEdit = create_child_editcontrol(ES_MULTILINE, 0);
2663 hwParent = GetParent(hwEdit);
2664 SetWindowLongPtrA(hwParent, GWLP_WNDPROC, (LONG_PTR)dialog_mode_wnd_proc);
2666 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2667 ok(1 == r, "expected 1, got %d\n", r);
2668 test_dm_messages(0, 0, 0, 0);
2669 zero_dm_messages();
2671 msg.hwnd = hwEdit;
2672 msg.message = WM_KEYDOWN;
2673 msg.wParam = VK_ESCAPE;
2674 msg.lParam = 0x10001;
2675 r = SendMessageA(hwEdit, WM_GETDLGCODE, VK_ESCAPE, (LPARAM)&msg);
2676 ok(0x8d == r, "expected 0x8d, got 0x%x\n", r);
2677 test_dm_messages(0, 0, 0, 0);
2678 zero_dm_messages();
2680 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_ESCAPE, 0x10001);
2681 ok(1 == r, "expected 1, got %d\n", r);
2682 test_dm_messages(0, 0, 0, 0);
2683 zero_dm_messages();
2685 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_TAB, 0xf0001);
2686 ok(1 == r, "expected 1, got %d\n", r);
2687 test_dm_messages(0, 0, 0, 1);
2688 zero_dm_messages();
2690 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2691 ok(1 == r, "expected 1, got %d\n", r);
2692 test_dm_messages(0, 0, 1, 0);
2693 zero_dm_messages();
2695 hwButton = CreateWindowA("BUTTON", "OK", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
2696 100, 100, 50, 20, hwParent, (HMENU)ID_EDITTESTDBUTTON, hinst, NULL);
2697 ok(hwButton!=NULL, "CreateWindow failed with error code %d\n", GetLastError());
2699 r = SendMessageA(hwEdit, WM_KEYDOWN, VK_RETURN, 0x1c0001);
2700 ok(1 == r, "expected 1, got %d\n", r);
2701 test_dm_messages(0, 0, 1, 1);
2702 zero_dm_messages();
2704 DestroyWindow(hwButton);
2705 destroy_child_editcontrol(hwEdit);
2708 static void test_EM_GETHANDLE(void)
2710 static const WCHAR str1W[] = {'1','1','1','1','+','1','1','1','1','+','1','1','1','1','#',0};
2711 static const WCHAR str2W[] = {'2','2','2','2','-','2','2','2','2','-','2','2','2','2','-','2','2','2','2','#',0};
2712 static const char str0[] = "untouched";
2713 static const char str1[] = "1111+1111+1111#";
2714 static const char str1_1[] = "2111+1111+1111#";
2715 static const char str2[] = "2222-2222-2222-2222#";
2716 static const char str3[] = "3333*3333*3333*3333*3333#";
2717 CHAR current[42];
2718 HWND hEdit;
2719 HLOCAL hmem;
2720 HLOCAL hmem2;
2721 HLOCAL halloc;
2722 WCHAR *buffer;
2723 int len;
2724 int r;
2726 trace("EDIT: EM_GETHANDLE\n");
2728 /* EM_GETHANDLE is not supported for a single line edit control */
2729 hEdit = create_editcontrol(WS_BORDER, 0);
2730 ok(hEdit != NULL, "got %p (expected != NULL)\n", hEdit);
2732 hmem = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
2733 ok(hmem == NULL, "got %p (expected NULL)\n", hmem);
2734 DestroyWindow(hEdit);
2736 /* EM_GETHANDLE needs a multiline edit control */
2737 hEdit = create_editcontrol(WS_BORDER | ES_MULTILINE, 0);
2738 ok(hEdit != NULL, "got %p (expected != NULL)\n", hEdit);
2740 /* set some text */
2741 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
2742 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2743 ok((r == 1) && (len == lstrlenA(str1)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str1));
2745 lstrcpyA(current, str0);
2746 r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
2747 ok((r == lstrlenA(str1)) && !lstrcmpA(current, str1),
2748 "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1), str1);
2750 hmem = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
2751 ok(hmem != NULL, "got %p (expected != NULL)\n", hmem);
2752 /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
2753 buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
2755 buffer = LocalLock(hmem);
2756 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
2757 len = lstrlenW(buffer);
2758 todo_wine
2759 ok(len == lstrlenW(str1W) && !lstrcmpW(buffer, str1W), "Unexpected buffer contents %s, length %d.\n",
2760 wine_dbgstr_w(buffer), len);
2761 LocalUnlock(hmem);
2763 /* See if WM_GETTEXTLENGTH/WM_GETTEXT still work. */
2764 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2765 ok(len == lstrlenA(str1), "Unexpected text length %d.\n", len);
2767 lstrcpyA(current, str0);
2768 r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
2769 ok((r == lstrlenA(str1)) && !lstrcmpA(current, str1),
2770 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1), str1);
2772 /* Application altered buffer contents, see if WM_GETTEXTLENGTH/WM_GETTEXT pick that up. */
2773 buffer = LocalLock(hmem);
2774 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
2775 buffer[0] = '2';
2776 LocalUnlock(hmem);
2778 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2779 ok(len == lstrlenA(str1_1), "Unexpected text length %d.\n", len);
2781 lstrcpyA(current, str0);
2782 r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
2783 todo_wine
2784 ok(r == lstrlenA(str1_1) && !lstrcmpA(current, str1_1),
2785 "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1_1), str1_1);
2787 /* See if WM_SETTEXT/EM_REPLACESEL work. */
2788 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
2789 ok(r, "Failed to set text.\n");
2791 buffer = LocalLock(hmem);
2792 todo_wine
2793 ok(buffer != NULL && buffer[0] == '1', "Unexpected buffer contents\n");
2794 LocalUnlock(hmem);
2796 r = SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)str1_1);
2797 ok(r, "Failed to replace selection.\n");
2799 buffer = LocalLock(hmem);
2800 todo_wine
2801 ok(buffer != NULL && buffer[0] == '2', "Unexpected buffer contents\n");
2802 LocalUnlock(hmem);
2804 /* use LocalAlloc first to get a different handle */
2805 halloc = LocalAlloc(LMEM_MOVEABLE, 42);
2806 ok(halloc != NULL, "got %p (expected != NULL)\n", halloc);
2807 /* prepare our new memory */
2808 buffer = LocalLock(halloc);
2809 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
2810 lstrcpyW(buffer, str2W);
2811 LocalUnlock(halloc);
2813 /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
2814 LocalFree(hmem);
2815 /* use LocalAlloc after the LocalFree to likely consume the handle */
2816 hmem2 = LocalAlloc(LMEM_MOVEABLE, 42);
2817 ok(hmem2 != NULL, "got %p (expected != NULL)\n", hmem2);
2819 SendMessageA(hEdit, EM_SETHANDLE, (WPARAM)halloc, 0);
2821 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2822 todo_wine
2823 ok(len == lstrlenA(str2), "got %d (expected %d)\n", len, lstrlenA(str2));
2825 lstrcpyA(current, str0);
2826 r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
2827 todo_wine
2828 ok(r == lstrlenA(str2) && !lstrcmpA(current, str2),
2829 "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str2), str2);
2831 /* set a different text */
2832 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str3);
2833 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2834 ok((r == 1) && (len == lstrlenA(str3)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str3));
2836 lstrcpyA(current, str0);
2837 r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
2838 ok((r == lstrlenA(str3)) && !lstrcmpA(current, str3),
2839 "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str3), str3);
2841 LocalFree(hmem2);
2842 DestroyWindow(hEdit);
2844 /* Some apps have bugs ... */
2845 hEdit = create_editcontrol(WS_BORDER | ES_MULTILINE, 0);
2847 /* set some text */
2848 r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
2849 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2850 ok((r == 1) && (len == lstrlenA(str1)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str1));
2852 /* everything is normal up to EM_GETHANDLE */
2853 hmem = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
2854 /* Some messages still work while other messages fail.
2855 After LocalFree the memory handle, messages can crash the app */
2857 /* A buggy editor used EM_GETHANDLE twice */
2858 hmem2 = (HGLOBAL) SendMessageA(hEdit, EM_GETHANDLE, 0, 0);
2859 ok(hmem2 == hmem, "got %p (expected %p)\n", hmem2, hmem);
2861 /* Let the edit control free the memory handle */
2862 SendMessageA(hEdit, EM_SETHANDLE, (WPARAM)hmem2, 0);
2864 DestroyWindow(hEdit);
2867 static void test_paste(void)
2869 static const char *str = "this is a simple text";
2870 static const char *str2 = "first line\r\nsecond line";
2871 HWND hEdit, hMultilineEdit;
2872 HANDLE hmem, hmem_ret;
2873 char *buffer;
2874 int r, len;
2876 hEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
2877 hMultilineEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0);
2879 /* Prepare clipboard data with simple text */
2880 hmem = GlobalAlloc(GMEM_MOVEABLE, 255);
2881 ok(hmem != NULL, "got %p (expected != NULL)\n", hmem);
2882 buffer = GlobalLock(hmem);
2883 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
2884 strcpy(buffer, str);
2885 GlobalUnlock(hmem);
2887 r = OpenClipboard(hEdit);
2888 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2889 r = EmptyClipboard();
2890 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2891 hmem_ret = SetClipboardData(CF_TEXT, hmem);
2892 ok(hmem_ret == hmem, "expected %p, got %p\n", hmem, hmem_ret);
2893 r = CloseClipboard();
2894 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2896 /* Paste single line */
2897 SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)"");
2898 r = SendMessageA(hEdit, WM_PASTE, 0, 0);
2899 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2900 ok(strlen(str) == len, "got %d\n", len);
2902 /* Prepare clipboard data with multiline text */
2903 hmem = GlobalAlloc(GMEM_MOVEABLE, 255);
2904 ok(hmem != NULL, "got %p (expected != NULL)\n", hmem);
2905 buffer = GlobalLock(hmem);
2906 ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
2907 strcpy(buffer, str2);
2908 GlobalUnlock(hmem);
2910 r = OpenClipboard(hEdit);
2911 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2912 r = EmptyClipboard();
2913 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2914 hmem_ret = SetClipboardData(CF_TEXT, hmem);
2915 ok(hmem_ret == hmem, "expected %p, got %p\n", hmem, hmem_ret);
2916 r = CloseClipboard();
2917 ok(r == TRUE, "expected %d, got %d\n", TRUE, r);
2919 /* Paste multiline text in singleline edit - should be cut */
2920 SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)"");
2921 r = SendMessageA(hEdit, WM_PASTE, 0, 0);
2922 len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
2923 ok(strlen("first line") == len, "got %d\n", len);
2925 /* Paste multiline text in multiline edit */
2926 SendMessageA(hMultilineEdit, WM_SETTEXT, 0, (LPARAM)"");
2927 r = SendMessageA(hMultilineEdit, WM_PASTE, 0, 0);
2928 len = SendMessageA(hMultilineEdit, WM_GETTEXTLENGTH, 0, 0);
2929 ok(strlen(str2) == len, "got %d\n", len);
2931 /* Cleanup */
2932 DestroyWindow(hEdit);
2933 DestroyWindow(hMultilineEdit);
2936 static void test_EM_GETLINE(void)
2938 HWND hwnd[2];
2939 int i;
2941 hwnd[0] = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
2942 hwnd[1] = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
2944 for (i = 0; i < sizeof(hwnd)/sizeof(hwnd[0]); i++)
2946 static const WCHAR strW[] = {'t','e','x','t',0};
2947 static const char *str = "text";
2948 WCHAR buffW[16];
2949 char buff[16];
2950 int r;
2952 todo_wine_if(i == 0)
2953 ok(IsWindowUnicode(hwnd[i]), "Expected unicode window.\n");
2955 SendMessageA(hwnd[i], WM_SETTEXT, 0, (LPARAM)str);
2957 memset(buff, 0, sizeof(buff));
2958 *(WORD *)buff = sizeof(buff);
2959 r = SendMessageA(hwnd[i], EM_GETLINE, 0, (LPARAM)buff);
2960 ok(r == strlen(str), "Failed to get a line %d.\n", r);
2961 ok(!strcmp(buff, str), "Unexpected line data %s.\n", buff);
2963 memset(buff, 0, sizeof(buff));
2964 *(WORD *)buff = sizeof(buff);
2965 r = SendMessageA(hwnd[i], EM_GETLINE, 1, (LPARAM)buff);
2966 ok(r == strlen(str), "Failed to get a line %d.\n", r);
2967 ok(!strcmp(buff, str), "Unexpected line data %s.\n", buff);
2969 memset(buffW, 0, sizeof(buffW));
2970 *(WORD *)buffW = sizeof(buffW)/sizeof(buffW[0]);
2971 r = SendMessageW(hwnd[i], EM_GETLINE, 0, (LPARAM)buffW);
2972 ok(r == lstrlenW(strW), "Failed to get a line %d.\n", r);
2973 ok(!lstrcmpW(buffW, strW), "Unexpected line data %s.\n", wine_dbgstr_w(buffW));
2975 memset(buffW, 0, sizeof(buffW));
2976 *(WORD *)buffW = sizeof(buffW)/sizeof(buffW[0]);
2977 r = SendMessageW(hwnd[i], EM_GETLINE, 1, (LPARAM)buffW);
2978 ok(r == lstrlenW(strW), "Failed to get a line %d.\n", r);
2979 ok(!lstrcmpW(buffW, strW), "Unexpected line data %s.\n", wine_dbgstr_w(buffW));
2981 DestroyWindow(hwnd[i]);
2985 START_TEST(edit)
2987 ULONG_PTR ctx_cookie;
2988 HANDLE hCtx;
2989 BOOL b;
2991 if (!load_v6_module(&ctx_cookie, &hCtx))
2992 return;
2994 hinst = GetModuleHandleA(NULL);
2995 b = register_classes();
2996 ok(b, "Failed to register test classes.\n");
2997 if (!b) return;
2999 test_edit_control_1();
3000 test_edit_control_2();
3001 test_edit_control_3();
3002 test_char_from_pos();
3003 test_edit_control_5();
3004 test_edit_control_6();
3005 test_edit_control_limittext();
3006 test_edit_control_scroll();
3007 test_margins();
3008 test_margins_font_change();
3009 test_text_position();
3010 test_espassword();
3011 test_undo();
3012 test_enter();
3013 test_tab();
3014 test_edit_dialog();
3015 test_multi_edit_dialog();
3016 test_wantreturn_edit_dialog();
3017 test_singleline_wantreturn_edit_dialog();
3018 test_child_edit_wmkeydown();
3019 test_fontsize();
3020 test_dialogmode();
3021 test_contextmenu();
3022 test_EM_GETHANDLE();
3023 test_paste();
3024 test_EM_GETLINE();
3026 UnregisterWindowClasses();
3028 unload_v6_module(ctx_cookie, hCtx);