[3/5] richedit: Prevented using NULL hwnd for certain operations.
Dylan Smith
dylan.ah.smith at gmail.com
Tue Jan 20 00:41:36 CST 2009
Certain operations will simply not be done for windowless richedit
controls, such as WM_PAINT which isn't done for windowless richedit
controls since ITextServices provides a TxDraw method.
WM_ERASEBACKGROUND also seems to be similar in this way.
Instead of doing these operations that don't have any obvious way to be
done through the ITextHost interface, I just prevented them from
happening, or moved the code to the window proc for windowed richedit
controls.
Windowed richedit controls should still have the same behaviour.
---
dlls/riched20/editor.c | 207 ++++++++++++++++++++++++++---------------------
dlls/riched20/editstr.h | 1 +
dlls/riched20/paint.c | 52 ++++++++-----
dlls/riched20/txthost.c | 1 +
4 files changed, 150 insertions(+), 111 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index ce47c8d..cd2312b 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2546,23 +2546,26 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
pt.x = (short)LOWORD(messagePos);
pt.y = (short)HIWORD(messagePos);
- sbi.cbSize = sizeof(sbi);
- GetScrollBarInfo(editor->hWnd, OBJID_HSCROLL, &sbi);
- if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) &&
- PtInRect(&sbi.rcScrollBar, pt))
+ if (editor->hWnd)
{
- ITextHost_TxSetCursor(editor->texthost,
- LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE);
- return TRUE;
- }
- sbi.cbSize = sizeof(sbi);
- GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi);
- if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) &&
- PtInRect(&sbi.rcScrollBar, pt))
- {
- ITextHost_TxSetCursor(editor->texthost,
- LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE);
- return TRUE;
+ sbi.cbSize = sizeof(sbi);
+ GetScrollBarInfo(editor->hWnd, OBJID_HSCROLL, &sbi);
+ if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) &&
+ PtInRect(&sbi.rcScrollBar, pt))
+ {
+ ITextHost_TxSetCursor(editor->texthost,
+ LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE);
+ return TRUE;
+ }
+ sbi.cbSize = sizeof(sbi);
+ GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi);
+ if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) &&
+ PtInRect(&sbi.rcScrollBar, pt))
+ {
+ ITextHost_TxSetCursor(editor->texthost,
+ LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE);
+ return TRUE;
+ }
}
ITextHost_TxScreenToClient(editor->texthost, &pt);
@@ -2630,10 +2633,8 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
static void ME_SetDefaultFormatRect(ME_TextEditor *editor)
{
- DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
-
ITextHost_TxGetClientRect(editor->texthost, &editor->rcFormat);
- editor->rcFormat.top += (exstyle & WS_EX_CLIENTEDGE ? 1 : 0);
+ editor->rcFormat.top += editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0;
editor->rcFormat.left += 1 + editor->selofs;
editor->rcFormat.right -= 1;
}
@@ -2643,7 +2644,7 @@ static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
CHARRANGE selrange;
HMENU menu;
int seltype = 0;
- if(!editor->lpOleCallback)
+ if(!editor->lpOleCallback || !editor->hWnd)
return FALSE;
ME_GetSelection(editor, &selrange.cpMin, &selrange.cpMax);
if(selrange.cpMin == selrange.cpMax)
@@ -3125,12 +3126,12 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
case EM_SETOPTIONS:
{
- /* these flags are equivalent to ES_* counterparts
- * ECO_READONLY is already implemented in the code, only requires
- * setting the bit to work
- */
- DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
- ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
+ /* these flags are equivalent to ES_* counterparts, except for
+ * ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart,
+ * but is still stored in editor->styleFlags. */
+ const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+ ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
+ ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION;
DWORD settings = mask & editor->styleFlags;
DWORD oldSettings = settings;
DWORD changedSettings;
@@ -3151,14 +3152,8 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
changedSettings = oldSettings ^ settings;
- if (settings & ECO_AUTOWORDSELECTION)
- FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
-
if (oldSettings ^ settings) {
- DWORD dwStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
-
editor->styleFlags = (editor->styleFlags & ~mask) | (settings & mask);
- SetWindowLongW(editor->hWnd, GWL_STYLE, (dwStyle & ~mask) | (settings & mask));
if (settings & ECO_SELECTIONBAR) {
editor->selofs = SELECTIONBAR_WIDTH;
@@ -3180,6 +3175,8 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
FIXME("ECO_NOHIDESEL not implemented yet!\n");
if (settings & ECO_WANTRETURN)
FIXME("ECO_WANTRETURN not implemented yet!\n");
+ if (settings & ECO_AUTOWORDSELECTION)
+ FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
return settings;
}
@@ -3333,15 +3330,10 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
case EM_SETREADONLY:
{
- LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
- if (wParam) {
+ if (wParam)
editor->styleFlags |= ES_READONLY;
- winStyle |= ES_READONLY;
- } else {
+ else
editor->styleFlags &= ~ES_READONLY;
- winStyle &= ~ES_READONLY;
- }
- SetWindowLongW(editor->hWnd, GWL_STYLE, winStyle);
return 0;
}
case EM_SETEVENTMASK:
@@ -3931,8 +3923,13 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
si.nMax = (si.fMask & SIF_DISABLENOSCROLL) ? 1 : 0;
si.nMin = 0;
si.nPage = 0;
- SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
- SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
+ if (editor->hWnd) {
+ SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
+ SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
+ } else {
+ ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, si.nMin, si.nMax, TRUE);
+ ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, si.nMin, si.nMax, TRUE);
+ }
ME_CommitUndo(editor);
ME_WrapMarkedParagraphs(editor);
@@ -4000,44 +3997,6 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
if (!ME_ShowContextMenu(editor, (short)LOWORD(lParam), (short)HIWORD(lParam)))
goto do_default;
break;
- case WM_PAINT:
- {
- HDC hDC;
- RECT rc;
- PAINTSTRUCT ps;
-
- hDC = BeginPaint(editor->hWnd, &ps);
- /* Erase area outside of the formatting rectangle */
- if (ps.rcPaint.top < editor->rcFormat.top)
- {
- rc = ps.rcPaint;
- rc.bottom = editor->rcFormat.top;
- FillRect(hDC, &rc, editor->hbrBackground);
- ps.rcPaint.top = editor->rcFormat.top;
- }
- if (ps.rcPaint.bottom > editor->rcFormat.bottom) {
- rc = ps.rcPaint;
- rc.top = editor->rcFormat.bottom;
- FillRect(hDC, &rc, editor->hbrBackground);
- ps.rcPaint.bottom = editor->rcFormat.bottom;
- }
- if (ps.rcPaint.left < editor->rcFormat.left) {
- rc = ps.rcPaint;
- rc.right = editor->rcFormat.left;
- FillRect(hDC, &rc, editor->hbrBackground);
- ps.rcPaint.left = editor->rcFormat.left;
- }
- if (ps.rcPaint.right > editor->rcFormat.right) {
- rc = ps.rcPaint;
- rc.left = editor->rcFormat.right;
- FillRect(hDC, &rc, editor->hbrBackground);
- ps.rcPaint.right = editor->rcFormat.right;
- }
-
- ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint);
- EndPaint(editor->hWnd, &ps);
- }
- break;
case WM_SETFOCUS:
editor->bHaveFocus = TRUE;
ME_ShowCaret(editor);
@@ -4049,16 +4008,6 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_HideCaret(editor);
ME_SendOldNotify(editor, EN_KILLFOCUS);
return 0;
- case WM_ERASEBKGND:
- {
- HDC hDC = (HDC)wParam;
- RECT rc;
- if (GetUpdateRect(editor->hWnd,&rc,TRUE))
- {
- FillRect(hDC, &rc, editor->hbrBackground);
- }
- return 1;
- }
case WM_COMMAND:
TRACE("editor wnd command = %d\n", LOWORD(wParam));
return 0;
@@ -4242,11 +4191,11 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
{
if (lParam)
{
- DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
- int border = (exstyle & WS_EX_CLIENTEDGE) ? 1 : 0;
+ 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)
{
@@ -4467,7 +4416,81 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
}
- lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
+ switch (msg)
+ {
+ case WM_PAINT:
+ {
+ HDC hDC;
+ RECT rc;
+ PAINTSTRUCT ps;
+
+ hDC = BeginPaint(editor->hWnd, &ps);
+ /* Erase area outside of the formatting rectangle */
+ if (ps.rcPaint.top < editor->rcFormat.top)
+ {
+ rc = ps.rcPaint;
+ rc.bottom = editor->rcFormat.top;
+ FillRect(hDC, &rc, editor->hbrBackground);
+ ps.rcPaint.top = editor->rcFormat.top;
+ }
+ if (ps.rcPaint.bottom > editor->rcFormat.bottom) {
+ rc = ps.rcPaint;
+ rc.top = editor->rcFormat.bottom;
+ FillRect(hDC, &rc, editor->hbrBackground);
+ ps.rcPaint.bottom = editor->rcFormat.bottom;
+ }
+ if (ps.rcPaint.left < editor->rcFormat.left) {
+ rc = ps.rcPaint;
+ rc.right = editor->rcFormat.left;
+ FillRect(hDC, &rc, editor->hbrBackground);
+ ps.rcPaint.left = editor->rcFormat.left;
+ }
+ if (ps.rcPaint.right > editor->rcFormat.right) {
+ rc = ps.rcPaint;
+ rc.left = editor->rcFormat.right;
+ FillRect(hDC, &rc, editor->hbrBackground);
+ ps.rcPaint.right = editor->rcFormat.right;
+ }
+
+ ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint);
+ EndPaint(editor->hWnd, &ps);
+ return 0;
+ }
+ case WM_ERASEBKGND:
+ {
+ HDC hDC = (HDC)wParam;
+ RECT rc;
+
+ if (GetUpdateRect(editor->hWnd, &rc, TRUE))
+ FillRect(hDC, &rc, editor->hbrBackground);
+ return 1;
+ }
+ case EM_SETOPTIONS:
+ {
+ DWORD dwStyle;
+ const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+ ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
+ ECO_SELECTIONBAR;
+ lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
+ dwStyle = GetWindowLongW(hWnd, GWL_STYLE);
+ dwStyle = (dwStyle & ~mask) | (lresult & mask);
+ SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
+ return lresult;
+ }
+ case EM_SETREADONLY:
+ {
+ DWORD dwStyle;
+ lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
+ dwStyle = GetWindowLongW(hWnd, GWL_STYLE);
+ dwStyle &= ~ES_READONLY;
+ if (wParam)
+ dwStyle |= ES_READONLY;
+ SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
+ return lresult;
+ }
+ default:
+ lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
+ }
if (hresult == S_FALSE)
lresult = DefWindowProcW(hWnd, msg, wParam, lParam);
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 02fa828..7ac476d 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -338,6 +338,7 @@ typedef struct tagME_TextEditor
ME_TextBuffer *pBuffer;
ME_Cursor *pCursors;
DWORD styleFlags;
+ DWORD exStyleFlags;
int nCursors;
SIZE sizeWindow;
int nTotalLength, nLastTotalLength;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index c5eafe1..728b623 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -1036,7 +1036,6 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
{
- LONG winStyle;
BOOL bScrollBarIsVisible, bScrollBarWillBeVisible;
int scrollX = 0, scrollY = 0;
@@ -1065,20 +1064,23 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
NULL, NULL, SW_INVALIDATE);
ME_Repaint(editor);
- winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
- bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
- bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx)
- || (editor->styleFlags & ES_DISABLENOSCROLL);
- if (bScrollBarIsVisible != bScrollBarWillBeVisible)
- ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
- bScrollBarWillBeVisible);
-
- bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
- bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy)
- || (editor->styleFlags & ES_DISABLENOSCROLL);
- if (bScrollBarIsVisible != bScrollBarWillBeVisible)
- ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
- bScrollBarWillBeVisible);
+ if (editor->hWnd)
+ {
+ LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
+ bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
+ bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx)
+ || (editor->styleFlags & ES_DISABLENOSCROLL);
+ if (bScrollBarIsVisible != bScrollBarWillBeVisible)
+ ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
+ bScrollBarWillBeVisible);
+
+ bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
+ bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy)
+ || (editor->styleFlags & ES_DISABLENOSCROLL);
+ if (bScrollBarIsVisible != bScrollBarWillBeVisible)
+ ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
+ bScrollBarWillBeVisible);
+ }
ME_UpdateScrollBar(editor);
}
@@ -1152,8 +1154,14 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
editor->horz_si.nMin = si.nMin;
editor->horz_si.nMax = si.nMax;
editor->horz_si.nPage = si.nPage;
- if (bScrollBarWillBeVisible || bScrollBarWasVisible)
- SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
+ if (bScrollBarWillBeVisible || bScrollBarWasVisible) {
+ if (editor->hWnd) {
+ SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
+ } else {
+ ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, si.nMin, si.nMax, FALSE);
+ ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, si.nPos, TRUE);
+ }
+ }
}
if (si.fMask & SIF_DISABLENOSCROLL)
@@ -1186,8 +1194,14 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
editor->vert_si.nMin = si.nMin;
editor->vert_si.nMax = si.nMax;
editor->vert_si.nPage = si.nPage;
- if (bScrollBarWillBeVisible || bScrollBarWasVisible)
- SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
+ if (bScrollBarWillBeVisible || bScrollBarWasVisible) {
+ if (editor->hWnd) {
+ SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
+ } else {
+ ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, si.nMin, si.nMax, FALSE);
+ ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, si.nPos, TRUE);
+ }
+ }
}
if (si.fMask & SIF_DISABLENOSCROLL)
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index 6a4ed56..a8a47f6 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -58,6 +58,7 @@ ITextHost *ME_CreateTextHost(HWND hwnd, BOOL bEmulateVersion10)
texthost->bEmulateVersion10 = bEmulateVersion10;
editor = ME_MakeEditor((ITextHost*)texthost, bEmulateVersion10);
+ editor->exStyleFlags = GetWindowLongW(hwnd, GWL_EXSTYLE);
editor->hWnd = hwnd; /* FIXME: Remove editor's dependance on hWnd */
SetWindowLongPtrW(hwnd, 0, (LONG_PTR)editor);
}
More information about the wine-patches
mailing list