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