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