diff --git a/dlls/user/edit.c b/dlls/user/edit.c index ec2d7dc3a5a..a9785d50360 100644 --- a/dlls/user/edit.c +++ b/dlls/user/edit.c @@ -2186,13 +2186,39 @@ static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, */ static void EDIT_SetRectNP(EDITSTATE *es, LPRECT rc) { + RECT ClientRect; + LONG_PTR ExStyle; + CopyRect(&es->format_rect, rc); - if (es->style & WS_BORDER) { - INT bw = GetSystemMetrics(SM_CXBORDER) + 1; - es->format_rect.left += bw; - es->format_rect.top += bw; - es->format_rect.right -= bw; - es->format_rect.bottom -= bw; + if (es->style & ES_MULTILINE) + { + if (es->style & WS_BORDER) { + INT bw = GetSystemMetrics(SM_CXBORDER) + 1; + es->format_rect.left += bw; + es->format_rect.right -= bw; + es->format_rect.top += bw; + es->format_rect.bottom -= bw; + } + } + else + { + ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE); + if (ExStyle & WS_EX_CLIENTEDGE) { + if (es->line_height + 2 <= + es->format_rect.bottom - es->format_rect.top) { + es->format_rect.top++; + es->format_rect.bottom--; + } + } else if (es->style & WS_BORDER) { + INT bw = GetSystemMetrics(SM_CXBORDER) + 1; + es->format_rect.left += bw; + es->format_rect.right -= bw; + if (es->line_height + 2 * bw <= + es->format_rect.bottom - es->format_rect.top) { + es->format_rect.top += bw; + es->format_rect.bottom -= bw; + } + } } es->format_rect.left += es->left_margin; es->format_rect.right -= es->right_margin; @@ -2224,6 +2250,10 @@ static void EDIT_SetRectNP(EDITSTATE *es, LPRECT rc) /* Windows doesn't care to fix text placement for SL controls */ es->format_rect.bottom = es->format_rect.top + es->line_height; + /* Always stay within the client area */ + GetClientRect(es->hwndSelf, &ClientRect); + es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom); + if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); } diff --git a/dlls/user/tests/edit.c b/dlls/user/tests/edit.c index a70bef9f2f9..d1d7c3969a5 100644 --- a/dlls/user/tests/edit.c +++ b/dlls/user/tests/edit.c @@ -23,11 +23,12 @@ #include "wine/test.h" -HWND create_editcontrol (DWORD style) +HWND create_editcontrol (DWORD style, DWORD exstyle) { HWND handle; - handle = CreateWindow("EDIT", + handle = CreateWindowEx(exstyle, + "EDIT", NULL, ES_AUTOHSCROLL | ES_AUTOVSCROLL | style, 10, 10, 300, 300, @@ -61,17 +62,33 @@ static LONG get_edit_style (HWND hwnd) ); } +static void set_client_height(HWND Wnd, unsigned Height) +{ + RECT ClientRect, WindowRect; + + GetWindowRect(Wnd, &WindowRect); + GetClientRect(Wnd, &ClientRect); + SetWindowPos(Wnd, NULL, WindowRect.left, WindowRect.top, + WindowRect.right - WindowRect.left, + Height + (WindowRect.bottom - WindowRect.top) - (ClientRect.bottom - ClientRect.top), + SWP_NOMOVE | SWP_NOZORDER); +} + static void test_edit_control(void) { HWND hwEdit; MSG msMessage; int i; LONG r; + HFONT Font, OldFont; + HDC Dc; + TEXTMETRIC Metrics; + RECT FormatRect; msMessage.message = WM_KEYDOWN; trace("EDIT: Single line\n"); - hwEdit = create_editcontrol(0); + hwEdit = create_editcontrol(0, 0); r = get_edit_style(hwEdit); ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -84,7 +101,7 @@ static void test_edit_control(void) DestroyWindow (hwEdit); trace("EDIT: Single line want returns\n"); - hwEdit = create_editcontrol(ES_WANTRETURN); + hwEdit = create_editcontrol(ES_WANTRETURN, 0); r = get_edit_style(hwEdit); ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -97,7 +114,7 @@ static void test_edit_control(void) DestroyWindow (hwEdit); trace("EDIT: Multiline line\n"); - hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL); + hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL, 0); r = get_edit_style(hwEdit); ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -110,7 +127,7 @@ static void test_edit_control(void) DestroyWindow (hwEdit); trace("EDIT: Multi line want returns\n"); - hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN); + hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN, 0); r = get_edit_style(hwEdit); ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -121,6 +138,129 @@ static void test_edit_control(void) "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r); } DestroyWindow (hwEdit); + + /* Get a stock font for which we can determine the metrics */ + Font = GetStockObject(SYSTEM_FONT); + assert(NULL != Font); + Dc = GetDC(NULL); + assert(NULL != Dc); + OldFont = SelectObject(Dc, Font); + assert(NULL != OldFont); + if (! GetTextMetrics(Dc, &Metrics)) + { + assert(FALSE); + } + SelectObject(Dc, OldFont); + ReleaseDC(NULL, Dc); + + trace("EDIT: vertical text position\n"); + hwEdit = create_editcontrol(WS_POPUP, 0); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); + set_client_height(hwEdit, Metrics.tmHeight - 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 2); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 10); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + DestroyWindow(hwEdit); + + hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, 0); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); + set_client_height(hwEdit, Metrics.tmHeight - 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 2); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 3); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 4); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(2 == FormatRect.top, "wrong vertical position expected 2 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 10); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(2 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + DestroyWindow(hwEdit); + + hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); + set_client_height(hwEdit, Metrics.tmHeight - 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 2); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 4); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 10); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + DestroyWindow(hwEdit); + + hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); + set_client_height(hwEdit, Metrics.tmHeight - 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight - 1 == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight - 1, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 1); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(0 == FormatRect.top, "wrong vertical position expected 0 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 2); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 4); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + set_client_height(hwEdit, Metrics.tmHeight + 10); + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &FormatRect); + ok(1 == FormatRect.top, "wrong vertical position expected 1 got %ld\n", FormatRect.top); + ok(Metrics.tmHeight == FormatRect.bottom - FormatRect.top, "wrong height expected %ld got %ld\n", Metrics.tmHeight, FormatRect.bottom - FormatRect.top); + DestroyWindow(hwEdit); } START_TEST(edit)