richedit: Move message handling to function callable without window.

In order to make the message handling available to windowless richedit
controls, the message handling must be in a function that can be
called from the ITextServices_TxSendMessage method.  This method will
never have a handle to a window to pass to RichEditWndProc_common in
order to get the editor with GetWindowLongPtrW, but passing the editor
will work (even if hWnd is NULL).
This commit is contained in:
Dylan Smith 2008-12-19 10:57:28 -05:00 committed by Alexandre Julliard
parent 97a83147b3
commit 5dc1271ba6
2 changed files with 83 additions and 51 deletions

View File

@ -2724,11 +2724,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
}
#define UNSUPPORTED_MSG(e) \
case e: \
FIXME(#e ": stub\n"); \
return DefWindowProcW(hWnd, msg, wParam, lParam);
static const char * const edit_messages[] = {
"EM_GETSEL",
"EM_SETSEL",
@ -2868,18 +2863,60 @@ get_msg_name(UINT msg)
static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL unicode)
{
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
TRACE("hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
ME_TextEditor *editor;
HRESULT hresult;
LRESULT lresult;
TRACE("enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
hWnd, msg, get_msg_name(msg), wParam, lParam, unicode);
if (!editor && msg != WM_NCCREATE && msg != WM_NCDESTROY) {
ERR("called with invalid hWnd %p - application bug?\n", hWnd);
return 0;
editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
if (!editor)
{
if (msg == WM_NCCREATE)
{
CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
TRACE("WM_NCCREATE: style 0x%08x\n", pcs->style);
editor = ME_MakeEditor(hWnd);
SetWindowLongPtrW(hWnd, 0, (LONG_PTR)editor);
return TRUE;
}
else if (msg != WM_NCDESTROY)
{
ERR("called with invalid hWnd %p - application bug?\n", hWnd);
return 0;
}
}
lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
if (hresult == S_FALSE)
lresult = DefWindowProcW(hWnd, msg, wParam, lParam);
TRACE("exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n",
hWnd, msg, get_msg_name(msg), wParam, lParam, unicode, lresult);
return lresult;
}
#define UNSUPPORTED_MSG(e) \
case e: \
FIXME(#e ": stub\n"); \
*phresult = S_FALSE; \
return 0;
/* Handle messages for windowless and windoweded richedit controls.
*
* The LRESULT that is returned is a return value for window procs,
* and the phresult parameter is the COM return code needed by the
* text services interface. */
LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL unicode, HRESULT* phresult)
{
*phresult = S_OK;
switch(msg) {
UNSUPPORTED_MSG(EM_DISPLAYBAND)
UNSUPPORTED_MSG(EM_FINDWORDBREAK)
UNSUPPORTED_MSG(EM_FMTLINES)
@ -2923,7 +2960,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{
int vk = (int)((LPMSG)lParam)->wParam;
/* if style says we want return key */
if((vk == VK_RETURN) && (GetWindowLongW(hWnd, GWL_STYLE) & ES_WANTRETURN))
if((vk == VK_RETURN) && (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_WANTRETURN))
{
code |= DLGC_WANTMESSAGE;
}
@ -2935,14 +2972,6 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
return code;
}
case WM_NCCREATE:
{
CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
TRACE("WM_NCCREATE: style 0x%08x\n", pcs->style);
editor = ME_MakeEditor(hWnd);
SetWindowLongPtrW(hWnd, 0, (LONG_PTR)editor);
return TRUE;
}
case EM_EMPTYUNDOBUFFER:
ME_EmptyUndoStack(editor);
return 0;
@ -2989,7 +3018,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
/* these flags are equivalent to the ES_* counterparts */
DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD settings = GetWindowLongW(hWnd, GWL_STYLE) & mask;
DWORD settings = GetWindowLongW(editor->hWnd, GWL_STYLE) & mask;
return settings;
}
@ -3001,7 +3030,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
*/
DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD raw = GetWindowLongW(hWnd, GWL_STYLE);
DWORD raw = GetWindowLongW(editor->hWnd, GWL_STYLE);
DWORD settings = mask & raw;
DWORD oldSettings = settings;
DWORD changedSettings;
@ -3020,7 +3049,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
case ECOOP_XOR:
settings ^= lParam;
}
SetWindowLongW(hWnd, GWL_STYLE, (raw & ~mask) | (settings & mask));
SetWindowLongW(editor->hWnd, GWL_STYLE, (raw & ~mask) | (settings & mask));
changedSettings = oldSettings ^ settings;
@ -3170,8 +3199,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
editor->rgbBackColor = lParam;
editor->hbrBackground = CreateSolidBrush(editor->rgbBackColor);
}
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
InvalidateRect(editor->hWnd, NULL, TRUE);
UpdateWindow(editor->hWnd);
return lColor;
}
case EM_GETMODIFY:
@ -3187,12 +3216,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
case EM_SETREADONLY:
{
long nStyle = GetWindowLongW(hWnd, GWL_STYLE);
long nStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
if (wParam)
nStyle |= ES_READONLY;
else
nStyle &= ~ES_READONLY;
SetWindowLongW(hWnd, GWL_STYLE, nStyle);
SetWindowLongW(editor->hWnd, GWL_STYLE, nStyle);
return 0;
}
case EM_SETEVENTMASK:
@ -3347,9 +3376,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (!wParam)
wParam = (WPARAM)GetStockObject(SYSTEM_FONT);
GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf);
hDC = GetDC(hWnd);
hDC = GetDC(editor->hWnd);
ME_CharFormatFromLogFont(hDC, &lf, &fmt);
ReleaseDC(hWnd, hDC);
ReleaseDC(editor->hWnd, hDC);
ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), &fmt);
ME_SetDefaultCharFormat(editor, &fmt);
@ -3378,7 +3407,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
int len = -1;
/* uses default style! */
if (!(GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE))
if (!(GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE))
{
WCHAR * p;
@ -3771,19 +3800,19 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
SCROLLINFO si;
ME_SetDefaultFormatRect(editor);
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & WS_HSCROLL)
{ /* Squelch the default horizontal scrollbar it would make */
ShowScrollBar(editor->hWnd, SB_HORZ, FALSE);
}
si.cbSize = sizeof(si);
si.fMask = SIF_PAGE | SIF_RANGE;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
si.fMask |= SIF_DISABLENOSCROLL;
si.nMax = (si.fMask & SIF_DISABLENOSCROLL) ? 1 : 0;
si.nMin = 0;
si.nPage = 0;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
ME_CommitUndo(editor);
ME_WrapMarkedParagraphs(editor);
@ -3792,7 +3821,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
case WM_DESTROY:
ME_DestroyEditor(editor);
SetWindowLongPtrW(hWnd, 0, 0);
SetWindowLongPtrW(editor->hWnd, 0, 0);
return 0;
case WM_SETCURSOR:
{
@ -3805,10 +3834,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
SetFocus(hWnd);
SetFocus(editor->hWnd);
ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam),
ME_CalculateClickCount(editor, msg, wParam, lParam));
SetCapture(hWnd);
SetCapture(editor->hWnd);
ME_LinkNotify(editor,msg,wParam,lParam);
if (!ME_SetCursor(editor)) goto do_default;
break;
@ -3817,15 +3846,15 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
if (GetCapture() == hWnd)
if (GetCapture() == editor->hWnd)
ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
ME_LinkNotify(editor,msg,wParam,lParam);
/* Set cursor if mouse is captured, since WM_SETCURSOR won't be received. */
if (GetCapture() == hWnd)
if (GetCapture() == editor->hWnd)
ME_SetCursor(editor);
break;
case WM_LBUTTONUP:
if (GetCapture() == hWnd)
if (GetCapture() == editor->hWnd)
ReleaseCapture();
if (editor->nSelectionType == stDocument)
editor->nSelectionType = stPosition;
@ -3855,7 +3884,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
RECT rc;
PAINTSTRUCT ps;
hDC = BeginPaint(hWnd, &ps);
hDC = BeginPaint(editor->hWnd, &ps);
/* Erase area outside of the formatting rectangle */
if (ps.rcPaint.top < editor->rcFormat.top)
{
@ -3884,7 +3913,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint);
EndPaint(hWnd, &ps);
EndPaint(editor->hWnd, &ps);
}
break;
case WM_SETFOCUS:
@ -3902,7 +3931,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{
HDC hDC = (HDC)wParam;
RECT rc;
if (GetUpdateRect(hWnd,&rc,TRUE))
if (GetUpdateRect(editor->hWnd,&rc,TRUE))
{
FillRect(hDC, &rc, editor->hbrBackground);
}
@ -4013,12 +4042,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{
if (lParam)
{
DWORD exstyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
int border = (exstyle & WS_EX_CLIENTEDGE) ? 1 : 0;
RECT clientRect;
RECT *rc = (RECT *)lParam;
GetClientRect(hWnd, &clientRect);
GetClientRect(editor->hWnd, &clientRect);
if (wParam == 0)
{
editor->rcFormat.top = max(0, rc->top - border);
@ -4052,12 +4081,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_SendRequestResize(editor, TRUE);
return 0;
case WM_SETREDRAW:
return DefWindowProcW(hWnd, msg, wParam, lParam);
goto do_default;
case WM_SIZE:
{
RECT clientRect;
GetClientRect(hWnd, &clientRect);
GetClientRect(editor->hWnd, &clientRect);
if (editor->bDefaultFormatRect) {
ME_SetDefaultFormatRect(editor);
} else {
@ -4066,7 +4095,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
editor->prevClientRect = clientRect;
ME_RewrapRepaint(editor);
return DefWindowProcW(hWnd, msg, wParam, lParam);
goto do_default;
}
/* IME messages to make richedit controls IME aware */
case WM_IME_SETCONTEXT:
@ -4087,7 +4116,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
HIMC hIMC;
ME_Style *style = ME_GetInsertStyle(editor, 0);
hIMC = ImmGetContext(hWnd);
hIMC = ImmGetContext(editor->hWnd);
ME_DeleteSelection(editor);
ME_CommitUndo(editor);
ME_SaveTempStyle(editor);
@ -4203,7 +4232,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
break;
default:
do_default:
return DefWindowProcW(hWnd, msg, wParam, lParam);
*phresult = S_FALSE;
break;
}
return 0L;
}

View File

@ -271,6 +271,8 @@ void ME_DeleteReObject(REOBJECT* reo);
/* editor.c */
ME_TextEditor *ME_MakeEditor(HWND hWnd);
void ME_DestroyEditor(ME_TextEditor *editor);
LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL unicode, HRESULT* phresult);
void ME_SendOldNotify(ME_TextEditor *editor, int nCode);
void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam);
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);