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