[PATCH 4/5] riched20: Handle the client rect changes in the host.
Huw Davies
huw at codeweavers.com
Wed Mar 17 03:45:27 CDT 2021
Signed-off-by: Huw Davies <huw at 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;
--
2.23.0
More information about the wine-devel
mailing list