Added EM_SETRECT, EM_SETRECTNP, and WM_SETREDRAW message handling.

Added support for GT_SELECTION flag in EM_GETTEXTEX handler.
This commit is contained in:
Phil Krylov 2005-08-15 09:47:14 +00:00 committed by Alexandre Julliard
parent 61b2fba9d7
commit f1184b466d
5 changed files with 150 additions and 62 deletions

View File

@ -28,7 +28,7 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
c->pt.x = 0; c->pt.x = 0;
c->pt.y = 0; c->pt.y = 0;
c->hbrMargin = CreateSolidBrush(RGB(224,224,224)); c->hbrMargin = CreateSolidBrush(RGB(224,224,224));
GetClientRect(editor->hWnd, &c->rcView); c->rcView = editor->rcFormat;
} }
void ME_DestroyContext(ME_Context *c) void ME_DestroyContext(ME_Context *c)

View File

@ -58,7 +58,7 @@
+ EM_GETPARAFORMAT + EM_GETPARAFORMAT
- EM_GETPASSWORDCHAR 2.0 - EM_GETPASSWORDCHAR 2.0
- EM_GETPUNCTUATION 1.0asian - EM_GETPUNCTUATION 1.0asian
- EM_GETRECT + EM_GETRECT
- EM_GETREDONAME 2.0 - EM_GETREDONAME 2.0
+ EM_GETSEL + EM_GETSEL
+ EM_GETSELTEXT (ANSI&Unicode) + EM_GETSELTEXT (ANSI&Unicode)
@ -106,8 +106,8 @@
- EM_SETPASSWORDCHAR 2.0 - EM_SETPASSWORDCHAR 2.0
- EM_SETPUNCTUATION 1.0asian - EM_SETPUNCTUATION 1.0asian
+ EM_SETREADONLY no beep on modification attempt + EM_SETREADONLY no beep on modification attempt
- EM_SETRECT + EM_SETRECT
- EM_SETRECTNP (EM_SETRECT without repainting) - not supported in RICHEDIT + EM_SETRECTNP (EM_SETRECT without repainting)
+ EM_SETSEL + EM_SETSEL
- EM_SETSCROLLPOS 3.0 - EM_SETSCROLLPOS 3.0
- EM_SETTABSTOPS 3.0 - EM_SETTABSTOPS 3.0
@ -613,8 +613,11 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_ReleaseStyle(style); ME_ReleaseStyle(style);
editor->nEventMask = nEventMask; editor->nEventMask = nEventMask;
InvalidateRect(editor->hWnd, NULL, TRUE); if (editor->bRedraw)
ME_UpdateRepaint(editor); {
InvalidateRect(editor->hWnd, NULL, TRUE);
ME_UpdateRepaint(editor);
}
if (!(format & SFF_SELECTION)) { if (!(format & SFF_SELECTION)) {
ME_ClearTempStyle(editor); ME_ClearTempStyle(editor);
} }
@ -748,6 +751,8 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nLastSelStart = ed->nLastSelEnd = 0; ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->nScrollPosY = 0; ed->nScrollPosY = 0;
ed->nZoomNumerator = ed->nZoomDenominator = 0; ed->nZoomNumerator = ed->nZoomDenominator = 0;
ed->bRedraw = TRUE;
GetClientRect(hWnd, &ed->rcFormat);
for (i=0; i<HFONT_CACHE_SIZE; i++) for (i=0; i<HFONT_CACHE_SIZE; i++)
{ {
ed->pFontCache[i].nRefs = 0; ed->pFontCache[i].nRefs = 0;
@ -1016,12 +1021,11 @@ get_msg_name(UINT msg)
* RichEditANSIWndProc (RICHED20.10) * RichEditANSIWndProc (RICHED20.10)
*/ */
LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hDC;
PAINTSTRUCT ps;
SCROLLINFO si; SCROLLINFO si;
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0); ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0);
TRACE("msg %d (%s) %08x %08lx\n", msg, get_msg_name(msg), wParam, lParam); TRACE("hWnd %p msg %d (%s) %08x %08lx\n",
hWnd, msg, get_msg_name(msg), wParam, lParam);
switch(msg) { switch(msg) {
@ -1043,7 +1047,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
/* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */ /* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
UNSUPPORTED_MSG(EM_GETOPTIONS) UNSUPPORTED_MSG(EM_GETOPTIONS)
UNSUPPORTED_MSG(EM_GETPASSWORDCHAR) UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_GETRECT)
UNSUPPORTED_MSG(EM_GETREDONAME) UNSUPPORTED_MSG(EM_GETREDONAME)
UNSUPPORTED_MSG(EM_GETSCROLLPOS) UNSUPPORTED_MSG(EM_GETSCROLLPOS)
UNSUPPORTED_MSG(EM_GETTEXTMODE) UNSUPPORTED_MSG(EM_GETTEXTMODE)
@ -1067,8 +1070,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
UNSUPPORTED_MSG(EM_SETOPTIONS) UNSUPPORTED_MSG(EM_SETOPTIONS)
UNSUPPORTED_MSG(EM_SETPALETTE) UNSUPPORTED_MSG(EM_SETPALETTE)
UNSUPPORTED_MSG(EM_SETPASSWORDCHAR) UNSUPPORTED_MSG(EM_SETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_SETRECT)
UNSUPPORTED_MSG(EM_SETRECTNP)
UNSUPPORTED_MSG(EM_SETSCROLLPOS) UNSUPPORTED_MSG(EM_SETSCROLLPOS)
UNSUPPORTED_MSG(EM_SETTABSTOPS) UNSUPPORTED_MSG(EM_SETTABSTOPS)
UNSUPPORTED_MSG(EM_SETTARGETDEVICE) UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
@ -1190,9 +1191,12 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
if (wParam) if (wParam)
editor->rgbBackColor = -1; editor->rgbBackColor = -1;
else else
editor->rgbBackColor = lParam; editor->rgbBackColor = lParam;
InvalidateRect(hWnd, NULL, TRUE); if (editor->bRedraw)
UpdateWindow(hWnd); {
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
}
return lColor; return lColor;
} }
case EM_GETMODIFY: case EM_GETMODIFY:
@ -1277,10 +1281,13 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
if (nPos<0) if (nPos<0)
nPos = 0; nPos = 0;
if (nPos != editor->nScrollPosY) { if (nPos != editor->nScrollPosY) {
ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL); if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
UpdateWindow(hWnd);
}
editor->nScrollPosY = nPos; editor->nScrollPosY = nPos;
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
UpdateWindow(hWnd);
} }
return TRUE; /* Should return false if a single line richedit control */ return TRUE; /* Should return false if a single line richedit control */
} }
@ -1429,20 +1436,35 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_GETTEXTEX: case EM_GETTEXTEX:
{ {
GETTEXTEX *ex = (GETTEXTEX*)wParam; GETTEXTEX *ex = (GETTEXTEX*)wParam;
int nStart, nCount;
if (ex->flags != 0) if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
FIXME("Unhandled EM_GETTEXTEX flags 0x%lx\n",ex->flags); FIXME("GETTEXTEX flags 0x%08lx not supported\n", ex->flags & ~(GT_SELECTION | GT_USECRLF));
if (IsWindowUnicode(hWnd)) if (ex->flags & GT_SELECTION)
return ME_GetTextW(editor, (LPWSTR)lParam, 0, ex->cb, FALSE); {
ME_GetSelection(editor, &nStart, &nCount);
nCount -= nStart;
nCount = min(nCount, ex->cb - 1);
}
else else
{ {
LPWSTR buffer = HeapAlloc(GetProcessHeap(),0,ex->cb*sizeof(WCHAR)); nStart = 0;
nCount = ex->cb - 1;
}
if (ex->codepage == 1200 || IsWindowUnicode(hWnd))
{
nCount = min(nCount, ex->cb / sizeof(WCHAR) - 1);
return ME_GetTextW(editor, (LPWSTR)lParam, nStart, nCount, ex->flags & GT_USECRLF);
}
else
{
LPWSTR buffer = HeapAlloc(GetProcessHeap(), 0, (nCount + 1) * sizeof(WCHAR));
DWORD buflen = ex->cb; DWORD buflen = ex->cb;
LRESULT rc; LRESULT rc;
DWORD flags = 0; DWORD flags = 0;
buflen = ME_GetTextW(editor, buffer, 0, buflen, FALSE); buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags & GT_USECRLF);
rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar); rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar);
HeapFree(GetProcessHeap(),0,buffer); HeapFree(GetProcessHeap(),0,buffer);
@ -1463,12 +1485,12 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
{ {
TEXTRANGEW *rng = (TEXTRANGEW *)lParam; TEXTRANGEW *rng = (TEXTRANGEW *)lParam;
if (IsWindowUnicode(hWnd)) if (IsWindowUnicode(hWnd))
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, FALSE); return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, editor->bEmulateVersion10);
else else
{ {
int nLen = rng->chrg.cpMax-rng->chrg.cpMin; int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1); WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, FALSE); int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, editor->bEmulateVersion10);
/* FIXME this is a potential security hole (buffer overrun) /* FIXME this is a potential security hole (buffer overrun)
if you know more about wchar->mbyte conversion please explain if you know more about wchar->mbyte conversion please explain
*/ */
@ -1476,7 +1498,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
FREE_OBJ(p); FREE_OBJ(p);
return nChars; return nChars;
} }
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, FALSE);
} }
case EM_GETLINECOUNT: case EM_GETLINECOUNT:
{ {
@ -1611,9 +1632,15 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
ReleaseCapture(); ReleaseCapture();
break; break;
case WM_PAINT: case WM_PAINT:
hDC = BeginPaint(hWnd, &ps); if (editor->bRedraw)
ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint); {
EndPaint(hWnd, &ps); HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hWnd, &ps);
ME_PaintContent(editor, hDC, FALSE, &ps.rcPaint);
EndPaint(hWnd, &ps);
}
break; break;
case WM_SETFOCUS: case WM_SETFOCUS:
ME_ShowCaret(editor); ME_ShowCaret(editor);
@ -1625,14 +1652,17 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
return 0; return 0;
case WM_ERASEBKGND: case WM_ERASEBKGND:
{ {
HDC hDC = (HDC)wParam; if (editor->bRedraw)
RECT rc;
COLORREF rgbBG = ME_GetBackColor(editor);
if (GetUpdateRect(hWnd,&rc,TRUE))
{ {
HBRUSH hbr = CreateSolidBrush(rgbBG); HDC hDC = (HDC)wParam;
FillRect(hDC, &rc, hbr); RECT rc;
DeleteObject(hbr); COLORREF rgbBG = ME_GetBackColor(editor);
if (GetUpdateRect(hWnd,&rc,TRUE))
{
HBRUSH hbr = CreateSolidBrush(rgbBG);
FillRect(hDC, &rc, hbr);
DeleteObject(hbr);
}
} }
return 1; return 1;
} }
@ -1715,10 +1745,13 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
break; break;
} }
if (nPos != editor->nScrollPosY) { if (nPos != editor->nScrollPosY) {
ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL); if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
UpdateWindow(hWnd);
}
editor->nScrollPosY = nPos; editor->nScrollPosY = nPos;
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
UpdateWindow(hWnd);
} }
break; break;
} }
@ -1735,15 +1768,54 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
if (nPos<0) if (nPos<0)
nPos = 0; nPos = 0;
if (nPos != editor->nScrollPosY) { if (nPos != editor->nScrollPosY) {
ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL); if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
UpdateWindow(hWnd);
}
editor->nScrollPosY = nPos; editor->nScrollPosY = nPos;
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
UpdateWindow(hWnd);
} }
break; break;
} }
case EM_GETRECT:
{
*((RECT *)lParam) = editor->rcFormat;
return 0;
}
case EM_SETRECT:
case EM_SETRECTNP:
{
if (lParam)
{
RECT *rc = (RECT *)lParam;
if (wParam)
{
editor->rcFormat.left += rc->left;
editor->rcFormat.top += rc->top;
editor->rcFormat.right += rc->right;
editor->rcFormat.bottom += rc->bottom;
}
else
{
editor->rcFormat = *rc;
}
}
else
{
GetClientRect(hWnd, &editor->rcFormat);
}
if (msg != EM_SETRECTNP)
ME_RewrapRepaint(editor);
return 0;
}
case WM_SETREDRAW:
editor->bRedraw = wParam;
return 0;
case WM_SIZE: case WM_SIZE:
{ {
GetClientRect(hWnd, &editor->rcFormat);
ME_RewrapRepaint(editor); ME_RewrapRepaint(editor);
return DefWindowProcW(hWnd, msg, wParam, lParam); return DefWindowProcW(hWnd, msg, wParam, lParam);
} }
@ -1837,11 +1909,12 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in
if (item->member.run.nFlags & MERF_ENDPARA) if (item->member.run.nFlags & MERF_ENDPARA)
{ {
if (bCRLF) { *buffer++ = '\r';
*buffer++ = '\r'; if (bCRLF)
{
*buffer = '\n';
nWritten++; nWritten++;
} }
*buffer = '\n';
assert(nLen == 1); assert(nLen == 1);
} }
else else

View File

@ -270,6 +270,8 @@ typedef struct tagME_TextEditor
BOOL bScrollX, bScrollY; BOOL bScrollX, bScrollY;
int nScrollPosY; int nScrollPosY;
int nZoomNumerator, nZoomDenominator; int nZoomNumerator, nZoomDenominator;
RECT rcFormat;
BOOL bRedraw;
} ME_TextEditor; } ME_TextEditor;
typedef struct tagME_Context typedef struct tagME_Context

View File

@ -154,12 +154,15 @@ void ME_Repaint(ME_TextEditor *editor)
if (ME_WrapMarkedParagraphs(editor)) { if (ME_WrapMarkedParagraphs(editor)) {
ME_UpdateScrollBar(editor); ME_UpdateScrollBar(editor);
} }
hDC = GetDC(editor->hWnd); if (editor->bRedraw)
ME_HideCaret(editor); {
ME_PaintContent(editor, hDC, TRUE, NULL); hDC = GetDC(editor->hWnd);
ReleaseDC(editor->hWnd, hDC); ME_HideCaret(editor);
ME_ShowCaret(editor); ME_PaintContent(editor, hDC, TRUE, NULL);
ME_EnsureVisible(editor, pCursor->pRun); ReleaseDC(editor->hWnd, hDC);
ME_ShowCaret(editor);
ME_EnsureVisible(editor, pCursor->pRun);
}
} }
void ME_UpdateRepaint(ME_TextEditor *editor) void ME_UpdateRepaint(ME_TextEditor *editor)
@ -415,10 +418,13 @@ void ME_Scroll(ME_TextEditor *editor, int cx, int cy)
GetScrollInfo(hWnd, SB_VERT, &si); GetScrollInfo(hWnd, SB_VERT, &si);
si.nPos = editor->nScrollPosY -= cy; si.nPos = editor->nScrollPosY -= cy;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE); SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
if (abs(cy) > editor->sizeWindow.cy) if (editor->bRedraw)
InvalidateRect(editor->hWnd, NULL, TRUE); {
else if (abs(cy) > editor->sizeWindow.cy)
ScrollWindowEx(hWnd, cx, cy, NULL, NULL, NULL, NULL, SW_ERASE|SW_INVALIDATE); InvalidateRect(editor->hWnd, NULL, TRUE);
else
ScrollWindowEx(hWnd, cx, cy, NULL, NULL, NULL, NULL, SW_ERASE|SW_INVALIDATE);
}
} }
void ME_UpdateScrollBar(ME_TextEditor *editor) void ME_UpdateScrollBar(ME_TextEditor *editor)
@ -495,14 +501,20 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
if (yrel < 0) { if (yrel < 0) {
editor->nScrollPosY = y; editor->nScrollPosY = y;
SetScrollPos(hWnd, SB_VERT, y, TRUE); SetScrollPos(hWnd, SB_VERT, y, TRUE);
ScrollWindow(hWnd, 0, -yrel, NULL, NULL); if (editor->bRedraw)
UpdateWindow(hWnd); {
ScrollWindow(hWnd, 0, -yrel, NULL, NULL);
UpdateWindow(hWnd);
}
} else if (yrel + yheight > editor->sizeWindow.cy) { } else if (yrel + yheight > editor->sizeWindow.cy) {
int newy = y+yheight-editor->sizeWindow.cy; int newy = y+yheight-editor->sizeWindow.cy;
editor->nScrollPosY = newy; editor->nScrollPosY = newy;
SetScrollPos(hWnd, SB_VERT, newy, TRUE); SetScrollPos(hWnd, SB_VERT, newy, TRUE);
ScrollWindow(hWnd, 0, -(newy-yold), NULL, NULL); if (editor->bRedraw)
UpdateWindow(hWnd); {
ScrollWindow(hWnd, 0, -(newy-yold), NULL, NULL);
UpdateWindow(hWnd);
}
} }
} }

View File

@ -654,9 +654,10 @@ typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
#define TM_SINGLECODEPAGE 0x00000010 #define TM_SINGLECODEPAGE 0x00000010
#define TM_MULTICODEPAGE 0x00000020 #define TM_MULTICODEPAGE 0x00000020
/* GETTEXT structure flags */ /* GETTEXTEX structure flags */
#define GT_DEFAULT 0x00000000 #define GT_DEFAULT 0x00000000
#define GT_USECRLF 0x00000001 #define GT_USECRLF 0x00000001
#define GT_SELECTION 0x00000002
/* Options of the EM_SETTYPOGRAPHYOPTIONS message */ /* Options of the EM_SETTYPOGRAPHYOPTIONS message */
#define TO_ADVANCEDTYPOGRAPHY 0x00000001 #define TO_ADVANCEDTYPOGRAPHY 0x00000001