Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/tests/edit.c | 122 ++++++++++++++------------------------------- 1 file changed, 37 insertions(+), 85 deletions(-)
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index 0d95df3371..41eb5856e3 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <assert.h> #include <windows.h> #include <commctrl.h>
@@ -545,14 +544,10 @@ static HWND create_editcontrol (DWORD style, DWORD exstyle) { HWND handle;
- handle = CreateWindowExA(exstyle, - "EDIT", - "Test Text", - style, - 10, 10, 300, 300, - NULL, NULL, hinst, NULL); + handle = CreateWindowExA(exstyle, WC_EDITA, "Text Text", style, 10, 10, 300, 300, + NULL, NULL, hinst, NULL); ok (handle != NULL, "CreateWindow EDIT Control failed\n"); - assert (handle); + if (winetest_interactive) ShowWindow (handle, SW_SHOW); return handle; @@ -587,7 +582,6 @@ static HWND create_child_editcontrol (DWORD style, DWORD exstyle) rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinst, NULL); ok (parentWnd != NULL, "CreateWindow EDIT Test failed\n"); - assert(parentWnd);
editWnd = CreateWindowExA(exstyle, "EDIT", @@ -596,7 +590,6 @@ static HWND create_child_editcontrol (DWORD style, DWORD exstyle) 0, 0, 300, 300, parentWnd, NULL, hinst, NULL); ok (editWnd != NULL, "CreateWindow EDIT Test Text failed\n"); - assert(editWnd); if (winetest_interactive) ShowWindow (parentWnd, SW_SHOW); return editWnd; @@ -743,15 +736,14 @@ static void test_edit_control_2(void) /* Create main and edit windows. */ hwndMain = CreateWindowA(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, NULL, NULL, hinst, NULL); - assert(hwndMain); + ok(hwndMain != NULL, "Failed to create control parent.\n"); if (winetest_interactive) ShowWindow (hwndMain, SW_SHOW);
- hwndET2 = CreateWindowA("EDIT", NULL, - WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL, - 0, 0, w, h, /* important this not be 0 size. */ - hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL); - assert(hwndET2); + hwndET2 = CreateWindowA(WC_EDITA, NULL, WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL, + 0, 0, w, h, /* important this not be 0 size. */ + hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL); + ok(hwndET2 != NULL, "Failed to create Edit control.\n"); if (winetest_interactive) ShowWindow (hwndET2, SW_SHOW);
@@ -896,16 +888,11 @@ static void test_edit_control_3(void) 0, CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, NULL, NULL, NULL, NULL); - assert(hParent); + ok(hParent != NULL, "Failed to create control parent.\n");
trace("EDIT: Single line, no ES_AUTOHSCROLL\n"); - hWnd = CreateWindowExA(0, - "EDIT", - NULL, - 0, - 10, 10, 50, 50, - hParent, NULL, NULL, NULL); - assert(hWnd); + hWnd = CreateWindowExA(0, WC_EDITA, NULL, 0, 10, 10, 50, 50, hParent, NULL, NULL, NULL); + ok(hWnd != NULL, "Failed to create Edit control.\n");
zero_notify(); SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str); @@ -954,13 +941,8 @@ static void test_edit_control_3(void) DestroyWindow(hWnd);
trace("EDIT: Single line, ES_AUTOHSCROLL\n"); - hWnd = CreateWindowExA(0, - "EDIT", - NULL, - ES_AUTOHSCROLL, - 10, 10, 50, 50, - hParent, NULL, NULL, NULL); - assert(hWnd); + hWnd = CreateWindowExA(0, WC_EDITA, NULL, ES_AUTOHSCROLL, 10, 10, 50, 50, hParent, NULL, NULL, NULL); + ok(hWnd != NULL, "Failed to create Edit control.\n");
zero_notify(); SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str); @@ -1005,13 +987,10 @@ static void test_edit_control_3(void) DestroyWindow(hWnd);
trace("EDIT: Multline, no ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n"); - hWnd = CreateWindowExA(0, - "EDIT", - NULL, - ES_MULTILINE, + hWnd = CreateWindowExA(0, WC_EDITA, NULL, ES_MULTILINE, 10, 10, (50 * dpi) / 96, (50 * dpi) / 96, hParent, NULL, NULL, NULL); - assert(hWnd); + ok(hWnd != NULL, "Failed to create Edit control.\n");
zero_notify(); SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str); @@ -1055,13 +1034,10 @@ static void test_edit_control_3(void) DestroyWindow(hWnd);
trace("EDIT: Multline, ES_AUTOHSCROLL, no ES_AUTOVSCROLL\n"); - hWnd = CreateWindowExA(0, - "EDIT", - NULL, - ES_MULTILINE | ES_AUTOHSCROLL, + hWnd = CreateWindowExA(0, WC_EDITA, NULL, ES_MULTILINE | ES_AUTOHSCROLL, 10, 10, (50 * dpi) / 96, (50 * dpi) / 96, hParent, NULL, NULL, NULL); - assert(hWnd); + ok(hWnd != NULL, "Failed to create Edit control.\n");
zero_notify(); SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2); @@ -1100,13 +1076,9 @@ static void test_edit_control_3(void) DestroyWindow(hWnd);
trace("EDIT: Multline, ES_AUTOHSCROLL and ES_AUTOVSCROLL\n"); - hWnd = CreateWindowExA(0, - "EDIT", - NULL, - ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, - 10, 10, 50, 50, - hParent, NULL, NULL, NULL); - assert(hWnd); + hWnd = CreateWindowExA(0, WC_EDITA, NULL, ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, + 10, 10, 50, 50, hParent, NULL, NULL, NULL); + ok(hWnd != NULL, "Failed to create Edit control.\n");
zero_notify(); SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2); @@ -1289,13 +1261,9 @@ static void test_edit_control_5(void) RECT rc;
/* first show that a non-child won't do for this test */ - hWnd = CreateWindowExA(0, - "EDIT", - str, - 0, - 10, 10, 1, 1, - NULL, NULL, NULL, NULL); - assert(hWnd); + hWnd = CreateWindowExA(0, WC_EDITA, str, 0, 10, 10, 1, 1, NULL, NULL, NULL, NULL); + ok(hWnd != NULL, "Failed to create Edit control.\n"); + /* size of non-child edit control is (much) bigger than requested */ GetWindowRect( hWnd, &rc); ok( rc.right - rc.left > 20, "size of the window (%d) is smaller than expected\n", @@ -1309,16 +1277,13 @@ static void test_edit_control_5(void) CW_USEDEFAULT, CW_USEDEFAULT, 250, 250, NULL, NULL, hinst, NULL); - assert(parentWnd); + ok(parentWnd != NULL, "Failed to create control parent.\n"); ShowWindow( parentWnd, SW_SHOW); /* single line */ - hWnd = CreateWindowExA(0, - "EDIT", - str, WS_VISIBLE | WS_BORDER | - WS_CHILD, + hWnd = CreateWindowExA(0, WC_EDITA, str, WS_VISIBLE | WS_BORDER | WS_CHILD, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top, parentWnd, NULL, NULL, NULL); - assert(hWnd); + ok(hWnd != NULL, "Failed to create Edit control.\n"); GetClientRect( hWnd, &rc); ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top, "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc )); @@ -1326,13 +1291,10 @@ static void test_edit_control_5(void) ok(lstrlenA(str) == len, "text shouldn't have been truncated\n"); DestroyWindow(hWnd); /* multi line */ - hWnd = CreateWindowExA(0, - "EDIT", - str, - WS_CHILD | ES_MULTILINE, + hWnd = CreateWindowExA(0, WC_EDITA, str, WS_CHILD | ES_MULTILINE, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top, parentWnd, NULL, NULL, NULL); - assert(hWnd); + ok(hWnd != NULL, "Failed to create Edit control.\n"); GetClientRect( hWnd, &rc); ok( rc.right == rc1.right - rc1.left && rc.bottom == rc1.bottom - rc1.top, "Client rectangle not the expected size %s\n", wine_dbgstr_rect( &rc )); @@ -1417,14 +1379,9 @@ static void test_edit_control_scroll(void) /* Check the return value when EM_SCROLL doesn't scroll * anything. Should not return true unless any lines were actually * scrolled. */ - hwEdit = CreateWindowA( - "EDIT", - single_line_str, - WS_VSCROLL | ES_MULTILINE, - 1, 1, 100, 100, - NULL, NULL, hinst, NULL); - - assert(hwEdit); + hwEdit = CreateWindowA(WC_EDITA, single_line_str, WS_VSCROLL | ES_MULTILINE, + 1, 1, 100, 100, NULL, NULL, hinst, NULL); + ok(hwEdit != NULL, "Failed to create Edit control.\n");
ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0); ok(!ret, "Returned %x, expected 0.\n", ret); @@ -1443,13 +1400,9 @@ static void test_edit_control_scroll(void) /* SB_PAGEDOWN while at the beginning of a buffer with few lines should not cause EM_SCROLL to return a negative value of scrolled lines that would put us "before" the beginning. */ - hwEdit = CreateWindowA( - "EDIT", - multiline_str, - WS_VSCROLL | ES_MULTILINE, - 0, 0, 100, 100, - NULL, NULL, hinst, NULL); - assert(hwEdit); + hwEdit = CreateWindowA(WC_EDITA, multiline_str, WS_VSCROLL | ES_MULTILINE, + 0, 0, 100, 100, NULL, NULL, hinst, NULL); + ok(hwEdit != NULL, "Failed to create Edit control.\n");
ret = SendMessageA(hwEdit, EM_SCROLL, SB_PAGEDOWN, 0); ok(!ret, "Returned %x, expected 0.\n", ret); @@ -2370,13 +2323,12 @@ static void test_contextmenu(void)
hwndMain = CreateWindowA(szEditTest4Class, "ET4", WS_OVERLAPPEDWINDOW|WS_VISIBLE, 0, 0, 200, 200, NULL, NULL, hinst, NULL); - assert(hwndMain); + ok(hwndMain != NULL, "Failed to create control parent.\n");
- hwndEdit = CreateWindowA("EDIT", NULL, - WS_CHILD|WS_BORDER|WS_VISIBLE|ES_LEFT|ES_AUTOHSCROLL, + hwndEdit = CreateWindowA(WC_EDITA, NULL, WS_CHILD|WS_BORDER|WS_VISIBLE|ES_LEFT|ES_AUTOHSCROLL, 0, 0, 150, 50, /* important this not be 0 size. */ hwndMain, (HMENU) ID_EDITTEST2, hinst, NULL); - assert(hwndEdit); + ok(hwndEdit != NULL, "Failed to create Edit control.\n");
SetFocus(NULL); SetCapture(hwndMain);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
Fixes https://bugs.winehq.org/show_bug.cgi?id=40002
dlls/comctl32/edit.c | 63 ++++++++++---------- dlls/comctl32/tests/edit.c | 139 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 31 deletions(-)
diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c index 67d77dafab..10ff5fb0f3 100644 --- a/dlls/comctl32/edit.c +++ b/dlls/comctl32/edit.c @@ -3382,16 +3382,23 @@ static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key) * WM_KILLFOCUS * */ -static LRESULT EDIT_WM_KillFocus(EDITSTATE *es) +static LRESULT EDIT_WM_KillFocus(HTHEME theme, EDITSTATE *es) { - es->flags &= ~EF_FOCUSED; - DestroyCaret(); - if(!(es->style & ES_NOHIDESEL)) - EDIT_InvalidateText(es, es->selection_start, es->selection_end); - EDIT_NOTIFY_PARENT(es, EN_KILLFOCUS); - /* throw away left over scroll when we lose focus */ - es->wheelDeltaRemainder = 0; - return 0; + UINT flags = RDW_INVALIDATE | RDW_UPDATENOW; + + es->flags &= ~EF_FOCUSED; + DestroyCaret(); + if (!(es->style & ES_NOHIDESEL)) + EDIT_InvalidateText(es, es->selection_start, es->selection_end); + EDIT_NOTIFY_PARENT(es, EN_KILLFOCUS); + /* Throw away left over scroll when we lose focus */ + es->wheelDeltaRemainder = 0; + + if (theme) + flags |= RDW_FRAME; + + RedrawWindow(es->hwndSelf, NULL, NULL, flags); + return 0; }
@@ -3656,26 +3663,24 @@ static void EDIT_WM_NCPaint(HWND hwnd, HRGN region) * WM_SETFOCUS * */ -static void EDIT_WM_SetFocus(EDITSTATE *es) +static void EDIT_WM_SetFocus(HTHEME theme, EDITSTATE *es) { - es->flags |= EF_FOCUSED; + UINT flags = RDW_INVALIDATE | RDW_UPDATENOW;
- if (!(es->style & ES_NOHIDESEL)) - EDIT_InvalidateText(es, es->selection_start, es->selection_end); + es->flags |= EF_FOCUSED;
- /* single line edit updates itself */ - if (IsWindowVisible(es->hwndSelf) && !(es->style & ES_MULTILINE)) - { - HDC hdc = GetDC(es->hwndSelf); - EDIT_WM_Paint(es, hdc); - ReleaseDC(es->hwndSelf, hdc); - } + if (!(es->style & ES_NOHIDESEL)) + EDIT_InvalidateText(es, es->selection_start, es->selection_end);
- CreateCaret(es->hwndSelf, 0, 1, es->line_height); - EDIT_SetCaretPos(es, es->selection_end, - es->flags & EF_AFTER_WRAP); - ShowCaret(es->hwndSelf); - EDIT_NOTIFY_PARENT(es, EN_SETFOCUS); + CreateCaret(es->hwndSelf, 0, 1, es->line_height); + EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); + ShowCaret(es->hwndSelf); + EDIT_NOTIFY_PARENT(es, EN_SETFOCUS); + + if (theme) + flags |= RDW_FRAME | RDW_ERASE; + + RedrawWindow(es->hwndSelf, NULL, NULL, flags); }
@@ -4827,9 +4832,7 @@ static LRESULT CALLBACK EDIT_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR break;
case WM_KILLFOCUS: - result = EDIT_WM_KillFocus(es); - if (theme) - RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); + result = EDIT_WM_KillFocus(theme, es); break;
case WM_LBUTTONDBLCLK: @@ -4866,9 +4869,7 @@ static LRESULT CALLBACK EDIT_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR break;
case WM_SETFOCUS: - EDIT_WM_SetFocus(es); - if (theme) - RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); + EDIT_WM_SetFocus(theme, es); break;
case WM_SETFONT: diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index 41eb5856e3..7e9e7e7634 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -23,6 +23,7 @@
#include "wine/test.h" #include "v6util.h" +#include "msg.h"
#ifndef ES_COMBO #define ES_COMBO 0x200 @@ -32,6 +33,20 @@ #define ID_EDITTEST2 99 #define MAXLEN 200
+enum seq_index +{ + COMBINED_SEQ_INDEX = 0, + NUM_MSG_SEQUENCES, +}; + +enum msg_id +{ + PARENT_ID, + EDIT_ID, +}; + +static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; + struct edit_notify { int en_change, en_maxtext, en_update; }; @@ -865,6 +880,66 @@ static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPAR return DefWindowProcA(hWnd, msg, wParam, lParam); }
+static LRESULT CALLBACK parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static LONG defwndproc_counter = 0; + struct message msg = { 0 }; + LRESULT ret; + + msg.message = message; + msg.flags = sent|wparam|id; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.id = PARENT_ID; + + if (message != WM_IME_SETCONTEXT && + message != WM_IME_NOTIFY && + message != WM_GETICON && + message != WM_DWMNCRENDERINGCHANGED && + message != WM_GETMINMAXINFO && + message != WM_PAINT && + message != WM_CTLCOLOREDIT && + message < 0xc000) + { + add_message(sequences, COMBINED_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + ret = DefWindowProcA(hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + +static LRESULT CALLBACK edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + static LONG defwndproc_counter = 0; + struct message msg = { 0 }; + LRESULT ret; + + msg.message = message; + msg.flags = sent|wparam|id; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.id = EDIT_ID; + + if (message != WM_IME_SETCONTEXT && + message != WM_IME_NOTIFY) + { + add_message(sequences, COMBINED_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + if (IsWindowUnicode(hwnd)) + ret = CallWindowProcW(oldproc, hwnd, message, wParam, lParam); + else + ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + /* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response * to these messages. */ @@ -2365,6 +2440,7 @@ static BOOL register_classes(void) WNDCLASSA test3; WNDCLASSA test4; WNDCLASSA text_position; + WNDCLASSA wc;
test2.style = 0; test2.lpfnWndProc = ET2_WndProc; @@ -2414,6 +2490,12 @@ static BOOL register_classes(void) text_position.lpfnWndProc = DefWindowProcA; if (!RegisterClassA(&text_position)) return FALSE;
+ memset(&wc, 0, sizeof(wc)); + wc.lpfnWndProc = parent_wnd_proc; + wc.hInstance = GetModuleHandleA(NULL); + wc.lpszClassName = "ParentWnd"; + if (!RegisterClassA(&wc)) return FALSE; + return TRUE; }
@@ -2958,6 +3040,60 @@ static void test_wordbreak_proc(void) DestroyWindow(hwnd); }
+static const struct message setfocus_combined_seq[] = +{ + { WM_KILLFOCUS, sent|id, 0, 0, PARENT_ID }, + { WM_SETFOCUS, sent|id, 0, 0, EDIT_ID }, + { WM_COMMAND, sent|wparam|id, MAKEWPARAM(1, EN_SETFOCUS), 0, PARENT_ID }, + { WM_PAINT, sent|id, 0, 0, EDIT_ID }, + { WM_NCPAINT, sent|id|defwinproc|optional, 0, 0, EDIT_ID }, + { WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, EDIT_ID }, + { 0 } +}; + +static const struct message killfocus_combined_seq[] = +{ + { WM_KILLFOCUS, sent|id, 0, 0, EDIT_ID }, + { WM_COMMAND, sent|wparam|id, MAKEWPARAM(1, EN_KILLFOCUS), 0, PARENT_ID }, + { WM_SETFOCUS, sent|id, 0, 0, PARENT_ID }, + { WM_PAINT, sent|id, 0, 0, EDIT_ID }, + { WM_NCPAINT, sent|id|defwinproc|optional, 0, 0, EDIT_ID }, + { 0 } +}; + +static void test_change_focus(void) +{ + HWND hwnd, parent_wnd; + WNDPROC oldproc; + MSG msg; + + parent_wnd = CreateWindowA("ParentWnd", "", WS_OVERLAPPEDWINDOW, + 0, 0, 200, 200, NULL, NULL, GetModuleHandleA(NULL), NULL); + ok(parent_wnd != NULL, "Failed to create control parent.\n"); + SetWindowPos(parent_wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); + ShowWindow(parent_wnd, SW_SHOW); + + hwnd = CreateWindowExA(0, WC_EDITA, "Test", WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, + parent_wnd, (HMENU)1, GetModuleHandleA(NULL), NULL); + ok(hwnd != NULL, "Failed to create Edit control.\n"); + + oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)edit_subclass_proc); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); + + SetFocus(parent_wnd); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + SetFocus(hwnd); + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + ok_sequence(sequences, COMBINED_SEQ_INDEX, setfocus_combined_seq, "Set focus", TRUE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + SetFocus(parent_wnd); + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + ok_sequence(sequences, COMBINED_SEQ_INDEX, killfocus_combined_seq, "Kill focus", TRUE); + + DestroyWindow(hwnd); +} + START_TEST(edit) { ULONG_PTR ctx_cookie; @@ -2967,6 +3103,8 @@ START_TEST(edit) if (!load_v6_module(&ctx_cookie, &hCtx)) return;
+ init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + hinst = GetModuleHandleA(NULL); b = register_classes(); ok(b, "Failed to register test classes.\n"); @@ -2999,6 +3137,7 @@ START_TEST(edit) test_paste(); test_EM_GETLINE(); test_wordbreak_proc(); + test_change_focus();
UnregisterWindowClasses();