Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/riched20/editor.c | 81 ------------------------------------ dlls/riched20/editstr.h | 3 -- dlls/riched20/tests/editor.c | 15 ++++++- dlls/riched20/txthost.c | 76 +++++++++++++++++++++++++++++++-- dlls/riched20/txtsrv.c | 25 +++++++++++ 5 files changed, 112 insertions(+), 88 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 17b7d427d83..779472f1f04 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2909,14 +2909,6 @@ static BOOL ME_SetCursor(ME_TextEditor *editor) return TRUE; }
-static void ME_SetDefaultFormatRect(ME_TextEditor *editor) -{ - ITextHost_TxGetClientRect(editor->texthost, &editor->rcFormat); - editor->rcFormat.top += editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0; - editor->rcFormat.left += 1 + editor->selofs; - editor->rcFormat.right -= 1; -} - static LONG ME_GetSelectionType(ME_TextEditor *editor) { LONG sel_type = SEL_EMPTY; @@ -2987,7 +2979,6 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->texthost = texthost; ed->reOle = NULL; ed->bEmulateVersion10 = bEmulateVersion10; - ed->exStyleFlags = 0; ed->total_rows = 0; ITextHost_TxGetPropertyBits( texthost, TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_READONLY | TXTBIT_USEPASSWORD | TXTBIT_HIDESELECTION | TXTBIT_SAVESELECTION | @@ -3046,7 +3037,6 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ME_CheckCharOffsets(ed); SetRectEmpty(&ed->rcFormat); - ed->bDefaultFormatRect = TRUE; hr = ITextHost_TxGetSelectionBarWidth( ed->texthost, &selbarwidth ); /* FIXME: Convert selbarwidth from HIMETRIC to pixels */ if (hr == S_OK && selbarwidth) ed->selofs = SELECTIONBAR_WIDTH; @@ -3227,8 +3217,6 @@ static LRESULT ME_WmCreate(ME_TextEditor *editor, LPARAM lParam, BOOL unicode) if (lParam) text = unicode ? (void*)createW->lpszName : (void*)createA->lpszName;
- ME_SetDefaultFormatRect(editor); - max = (editor->scrollbars & ES_DISABLENOSCROLL) ? 1 : 0; if (~editor->scrollbars & ES_DISABLENOSCROLL || editor->scrollbars & WS_VSCROLL) ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, 0, max, TRUE); @@ -4212,78 +4200,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } break; } - case EM_GETRECT: - { - *((RECT *)lParam) = editor->rcFormat; - if (editor->bDefaultFormatRect) - ((RECT *)lParam)->left -= editor->selofs; - return 0; - } - case EM_SETRECT: - case EM_SETRECTNP: - { - if (lParam) - { - int border = 0; - RECT clientRect; - RECT *rc = (RECT *)lParam; - - border = editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0; - ITextHost_TxGetClientRect(editor->texthost, &clientRect); - if (wParam == 0) - { - editor->rcFormat.top = max(0, rc->top - border); - editor->rcFormat.left = max(0, rc->left - border); - editor->rcFormat.bottom = min(clientRect.bottom, rc->bottom); - editor->rcFormat.right = min(clientRect.right, rc->right + border); - } else if (wParam == 1) { - /* MSDN incorrectly says a wParam value of 1 causes the - * lParam rect to be used as a relative offset, - * however, the tests show it just prevents min/max bound - * checking. */ - editor->rcFormat.top = rc->top - border; - editor->rcFormat.left = rc->left - border; - editor->rcFormat.bottom = rc->bottom; - editor->rcFormat.right = rc->right + border; - } else { - return 0; - } - editor->bDefaultFormatRect = FALSE; - } - else - { - ME_SetDefaultFormatRect(editor); - editor->bDefaultFormatRect = TRUE; - } - editor_mark_rewrap_all( editor ); - ME_WrapMarkedParagraphs(editor); - ME_UpdateScrollBar(editor); - if (msg != EM_SETRECTNP) - ME_Repaint(editor); - return 0; - } case EM_REQUESTRESIZE: ME_SendRequestResize(editor, TRUE); return 0; - case WM_SETREDRAW: - goto do_default; - case WM_WINDOWPOSCHANGED: - { - RECT clientRect; - WINDOWPOS *winpos = (WINDOWPOS *)lParam; - - if (winpos->flags & SWP_NOCLIENTSIZE) goto do_default; - ITextHost_TxGetClientRect(editor->texthost, &clientRect); - if (editor->bDefaultFormatRect) { - ME_SetDefaultFormatRect(editor); - } else { - editor->rcFormat.right += clientRect.right - editor->prevClientRect.right; - editor->rcFormat.bottom += clientRect.bottom - editor->prevClientRect.bottom; - } - editor->prevClientRect = clientRect; - ME_RewrapRepaint(editor); - goto do_default; - } /* IME messages to make richedit controls IME aware */ case WM_IME_SETCONTEXT: case WM_IME_CONTROL: diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index a3e5970bff8..1f277cbf6bc 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -383,7 +383,6 @@ typedef struct tagME_TextEditor BOOL bEmulateVersion10; ME_TextBuffer *pBuffer; ME_Cursor *pCursors; - DWORD exStyleFlags; DWORD props; DWORD scrollbars; int nCursors; @@ -407,9 +406,7 @@ typedef struct tagME_TextEditor ME_Paragraph *last_sel_start_para, *last_sel_end_para; ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE]; int nZoomNumerator, nZoomDenominator; - RECT prevClientRect; RECT rcFormat; - BOOL bDefaultFormatRect; BOOL bWordWrap; int nTextLimit; EDITWORDBREAKPROCW pfnWordBreak; diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 1ce94f8ae64..19a1af25f73 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -7460,12 +7460,25 @@ static void test_format_rect(void) ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), wine_dbgstr_rect(&expected));
+ /* reset back to client rect and now try adding selection bar */ + SendMessageA(hwnd, EM_SETRECT, 0, 0); + expected = clientRect; + InflateRect(&expected, -1, 0); + SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); + ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), + wine_dbgstr_rect(&expected)); + SendMessageA(hwnd, EM_SETOPTIONS, ECOOP_OR, ECO_SELECTIONBAR); + SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); + ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), + wine_dbgstr_rect(&expected)); + SendMessageA(hwnd, EM_SETOPTIONS, ECOOP_AND, ~ECO_SELECTIONBAR); + /* Set the absolute value of the formatting rectangle. */ rc = clientRect; SendMessageA(hwnd, EM_SETRECT, 0, (LPARAM)&rc); expected = clientRect; SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); - ok(EqualRect(&rc, &expected), "[n=%d] rect %s != %s\n", n, wine_dbgstr_rect(&rc), + ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc), wine_dbgstr_rect(&expected));
/* MSDN documents the EM_SETRECT message as using the rectangle provided in diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c index 3ba522331b0..0325d5d41d8 100644 --- a/dlls/riched20/txthost.c +++ b/dlls/riched20/txthost.c @@ -43,8 +43,11 @@ struct host unsigned int dialog_mode : 1; unsigned int want_return : 1; unsigned int sel_bar : 1; + unsigned int client_edge : 1; + unsigned int use_set_rect : 1; PARAFORMAT2 para_fmt; DWORD props, scrollbars, event_mask; + RECT client_rect, set_rect; };
static const ITextHostVtbl textHostVtbl; @@ -76,6 +79,9 @@ static void host_init_props( struct host *host )
host->sel_bar = !!(style & ES_SELECTIONBAR); host->want_return = !!(style & ES_WANTRETURN); + + style = GetWindowLongW( host->window, GWL_EXSTYLE ); + host->client_edge = !!(style & WS_EX_CLIENTEDGE); }
struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 ) @@ -102,6 +108,9 @@ struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 ) texthost->editor = NULL; host_init_props( texthost ); texthost->event_mask = 0; + texthost->use_set_rect = 0; + SetRectEmpty( &texthost->set_rect ); + GetClientRect( hwnd, &texthost->client_rect );
return texthost; } @@ -301,8 +310,16 @@ DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8) DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect( ITextHost *iface, RECT *rect ) { struct host *host = impl_from_ITextHost( iface ); - int ret = GetClientRect( host->window, rect ); - return ret ? S_OK : E_FAIL; + + if (!host->use_set_rect) + { + *rect = host->client_rect; + if (host->client_edge) rect->top += 1; + InflateRect( rect, -1, 0 ); + } + else *rect = host->set_rect; + + return S_OK; }
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8) @@ -701,7 +718,6 @@ static BOOL create_windowed_editor( HWND hwnd, CREATESTRUCTW *create, BOOL emula IUnknown_QueryInterface( unk, &IID_ITextServices, (void **)&host->text_srv ); IUnknown_Release( unk );
- host->editor->exStyleFlags = GetWindowLongW( hwnd, GWL_EXSTYLE ); host->editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */ host->editor->hwndParent = create->hwndParent;
@@ -829,6 +845,12 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r { host->sel_bar ^= 1; props_mask |= TXTBIT_SELBARCHANGE; + if (host->use_set_rect) + { + int width = SELECTIONBAR_WIDTH; + host->set_rect.left += host->sel_bar ? width : -width; + props_mask |= TXTBIT_CLIENTRECTCHANGE; + } } if (change & ECO_VERTICAL) { @@ -939,6 +961,12 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam, hr = ITextServices_TxSendMessage( host->text_srv, msg, wc, lparam, &res ); break; } + + case WM_CREATE: + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 ); + res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr ); + break; + case WM_DESTROY: ITextHost_Release( &host->ITextHost_iface ); return 0; @@ -1002,6 +1030,10 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam, else hr = get_lineA( host->text_srv, wparam, lparam, &res ); break;
+ case EM_GETRECT: + hr = ITextHost_TxGetClientRect( &host->ITextHost_iface, (RECT *)lparam ); + break; + case EM_GETSELTEXT: { TEXTRANGEA range; @@ -1149,6 +1181,27 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam, SendMessageW( hwnd, EM_SETOPTIONS, op, mask ); return 1; } + case EM_SETRECT: + case EM_SETRECTNP: + { + RECT *rc = (RECT *)lparam; + + if (!rc) host->use_set_rect = 0; + else + { + if (wparam >= 2) break; + host->set_rect = *rc; + if (host->client_edge) + { + InflateRect( &host->set_rect, 1, 0 ); + host->set_rect.top -= 1; + } + if (!wparam) IntersectRect( &host->set_rect, &host->set_rect, &host->client_rect ); + host->use_set_rect = 1; + } + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 ); + break; + } case WM_SETTEXT: { char *textA = (char *)lparam; @@ -1183,6 +1236,23 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam, res = 0; break; } + case WM_WINDOWPOSCHANGED: + { + RECT client; + WINDOWPOS *winpos = (WINDOWPOS *)lparam; + + hr = S_FALSE; /* call defwndproc */ + if (winpos->flags & SWP_NOCLIENTSIZE) break; + GetClientRect( hwnd, &client ); + if (host->use_set_rect) + { + host->set_rect.right += client.right - host->client_rect.right; + host->set_rect.bottom += client.bottom - host->client_rect.bottom; + } + host->client_rect = client; + ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 ); + break; + } default: res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr ); } diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c index df62a2dd7c5..3f7688e6b25 100644 --- a/dlls/riched20/txtsrv.c +++ b/dlls/riched20/txtsrv.c @@ -206,6 +206,25 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxQueryHitPoint(ITextServices *ifac return E_NOTIMPL; }
+static HRESULT update_client_rect( struct text_services *services, const RECT *client ) +{ + RECT rect; + HRESULT hr = S_OK; + + if (!client) + { + hr = ITextHost_TxGetClientRect( services->host, &rect ); + client = ▭ + } + + if (SUCCEEDED( hr )) + { + services->editor->rcFormat = *client; + services->editor->rcFormat.left += services->editor->selofs; + } + return hr; +} + DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceActivate,8) DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxInplaceActivate(ITextServices *iface, LPCRECT prcClient) { @@ -365,6 +384,12 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServic } }
+ if (mask & TXTBIT_CLIENTRECTCHANGE) + { + hr = update_client_rect( services, NULL ); + if (SUCCEEDED( hr )) repaint = TRUE; + } + if (repaint) ME_RewrapRepaint( services->editor );
return S_OK;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=87098
Your paranoid android.
=== w7u_adm (32 bit report) ===
riched20: editor.c:6624: Test failed: wrong event mask (0x0) during WM_COMMAND
On Wed, Mar 17, 2021 at 04:20:42AM -0500, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=87098
Your paranoid android.
=== w7u_adm (32 bit report) ===
riched20: editor.c:6624: Test failed: wrong event mask (0x0) during WM_COMMAND
This is a random failure not related to this patch.
Huw.