Author: cwittich
Date: Sat Dec 27 02:49:35 2008
New Revision: 38370
URL:
http://svn.reactos.org/svn/reactos?rev=38370&view=rev
Log:
sync riched20 with wine 1.1.11
Modified:
trunk/reactos/dll/win32/riched20/caret.c
trunk/reactos/dll/win32/riched20/clipboard.c
trunk/reactos/dll/win32/riched20/editor.c
trunk/reactos/dll/win32/riched20/editor.h
trunk/reactos/dll/win32/riched20/editstr.h
trunk/reactos/dll/win32/riched20/paint.c
trunk/reactos/dll/win32/riched20/para.c
trunk/reactos/dll/win32/riched20/reader.c
trunk/reactos/dll/win32/riched20/rtf.h
trunk/reactos/dll/win32/riched20/run.c
trunk/reactos/dll/win32/riched20/string.c
trunk/reactos/dll/win32/riched20/wrap.c
trunk/reactos/dll/win32/riched20/writer.c
Modified: trunk/reactos/dll/win32/riched20/caret.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/caret.c…
==============================================================================
--- trunk/reactos/dll/win32/riched20/caret.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/caret.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -214,8 +214,9 @@
}
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
- *x = run->member.run.pt.x + sz.cx;
- *y = para->member.para.pt.y + row->member.row.nBaseline +
run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
+ *x = c.rcView.left + run->member.run.pt.x + sz.cx;
+ *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
+ + run->member.run.pt.y - pSizeRun->member.run.nAscent -
ME_GetYScrollPos(editor);
ME_DestroyContext(&c, editor->hWnd);
return;
}
@@ -236,10 +237,7 @@
ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y,
&height);
if(editor->bHaveFocus && !ME_IsSelection(editor))
{
- RECT rect;
-
- GetClientRect(editor->hWnd, &rect);
- x = min(x, rect.right-2);
+ x = min(x, editor->rcFormat.right-1);
CreateCaret(editor->hWnd, NULL, 0, height);
SetCaretPos(x, y);
}
@@ -922,6 +920,9 @@
int rx = 0;
BOOL isExact = TRUE;
+ x -= editor->rcFormat.left;
+ y -= editor->rcFormat.top;
+
if (is_eol)
*is_eol = 0;
@@ -1109,13 +1110,13 @@
ME_FindPixelPos(editor, x, y, &editor->pCursors[0],
&editor->bCaretAtEnd);
- if (x >= editor->selofs || is_shift)
+ if (x >= editor->rcFormat.left || is_shift)
{
if (clickNum > 1)
{
editor->pCursors[1] = editor->pCursors[0];
if (is_shift) {
- if (x >= editor->selofs)
+ if (x >= editor->rcFormat.left)
ME_SelectByType(editor, stWord);
else
ME_SelectByType(editor, stParagraph);
@@ -1177,16 +1178,10 @@
memcmp(&editor->pCursors[1], &editor->pCursors[3],
sizeof(ME_Cursor)))
{
/* The scroll the cursor towards the other end, since it was the one
- * extended by ME_ExtendAnchorSelection
- */
- ME_Cursor tmpCursor = editor->pCursors[0];
- editor->pCursors[0] = editor->pCursors[1];
- editor->pCursors[1] = tmpCursor;
- SendMessageW(editor->hWnd, EM_SCROLLCARET, 0, 0);
- editor->pCursors[1] = editor->pCursors[0];
- editor->pCursors[0] = tmpCursor;
+ * extended by ME_ExtendAnchorSelection */
+ ME_EnsureVisible(editor, editor->pCursors[1].pRun);
} else {
- SendMessageW(editor->hWnd, EM_SCROLLCARET, 0, 0);
+ ME_EnsureVisible(editor, editor->pCursors[0].pRun);
}
ME_InvalidateSelection(editor);
@@ -1571,11 +1566,9 @@
if (!(editor->nEventMask & ENM_SELCHANGE))
return;
-
- sc.nmhdr.hwndFrom = editor->hWnd;
- sc.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
+
sc.nmhdr.code = EN_SELCHANGE;
- SendMessageW(editor->hWnd, EM_EXGETSEL, 0, (LPARAM)&sc.chrg);
+ ME_GetSelection(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
sc.seltyp = SEL_EMPTY;
if (sc.chrg.cpMin != sc.chrg.cpMax)
sc.seltyp |= SEL_TEXT;
Modified: trunk/reactos/dll/win32/riched20/clipboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/clipboa…
==============================================================================
--- trunk/reactos/dll/win32/riched20/clipboard.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/clipboard.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -334,7 +334,7 @@
pars = ME_CountParagraphsBetween(editor, lpchrg->cpMin, lpchrg->cpMax);
len = lpchrg->cpMax-lpchrg->cpMin;
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR)*(len+pars+1));
- data = (WCHAR *)GlobalLock(ret);
+ data = GlobalLock(ret);
len = ME_GetTextW(editor, data, lpchrg->cpMin, len, TRUE);
data[len] = 0;
GlobalUnlock(ret);
@@ -359,7 +359,7 @@
int nNewSize = (((nMaxSize+cb+1)|0x1FFFF)+1) & 0xFFFE0000;
pData->hData = GlobalReAlloc(pData->hData, nNewSize, 0);
}
- pDest = (BYTE *)GlobalLock(pData->hData);
+ pDest = GlobalLock(pData->hData);
memcpy(pDest + pData->nLength, lpBuff, cb);
pData->nLength += cb;
pDest[pData->nLength] = '\0';
Modified: trunk/reactos/dll/win32/riched20/editor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editor.…
==============================================================================
--- trunk/reactos/dll/win32/riched20/editor.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/editor.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -99,6 +99,7 @@
- EM_SETFONTSIZE
- EM_SETIMECOLOR 1.0asian
- EM_SETIMEOPTIONS 1.0asian
+ - EM_SETIMESTATUS
- EM_SETLANGOPTIONS 2.0
- EM_SETLIMITTEXT
- EM_SETMARGINS
@@ -1425,7 +1426,7 @@
ME_DisplayItem *para_item;
style = editor->pBuffer->pDefaultStyle;
ME_AddRefStyle(style);
- SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
+ ME_SetSelection(editor, 0, 0);
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor), FALSE);
from = to = 0;
ME_ClearTempStyle(editor);
@@ -1469,7 +1470,6 @@
memset(&parser, 0, sizeof parser);
RTFSetEditStream(&parser, &inStream);
parser.rtfFormat = format&(SF_TEXT|SF_RTF);
- parser.hwndEdit = editor->hWnd;
parser.editor = editor;
parser.style = style;
WriterInit(&parser);
@@ -1559,7 +1559,7 @@
ME_GetSelection(editor, &to, &to2);
/* put the cursor at the top */
if (!(format & SFF_SELECTION))
- SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
+ ME_SetSelection(editor, 0, 0);
}
/* Restore saved undo mode */
@@ -1938,6 +1938,73 @@
return -1;
}
+static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
+{
+ int nStart, nCount; /* in chars */
+
+ if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
+ FIXME("GETTEXTEX flags 0x%08x not supported\n", ex->flags &
~(GT_SELECTION | GT_USECRLF));
+
+ if (ex->flags & GT_SELECTION)
+ {
+ ME_GetSelection(editor, &nStart, &nCount);
+ nCount -= nStart;
+ }
+ else
+ {
+ nStart = 0;
+ nCount = 0x7fffffff;
+ }
+ if (ex->codepage == 1200)
+ {
+ nCount = min(nCount, ex->cb / sizeof(WCHAR) - 1);
+ return ME_GetTextW(editor, (LPWSTR)pText, nStart, nCount, ex->flags &
GT_USECRLF);
+ }
+ else
+ {
+ /* potentially each char may be a CR, why calculate the exact value with O(N) when
+ we can just take a bigger buffer? :)
+ The above assumption still holds with CR/LF counters, since CR->CRLF
expansion
+ occurs only in richedit 2.0 mode, in which line breaks have only one CR
+ */
+ int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
+ LPWSTR buffer;
+ DWORD buflen = ex->cb;
+ LRESULT rc;
+ DWORD flags = 0;
+
+ nCount = min(nCount, ex->cb - 1);
+ buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
+
+ buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags &
GT_USECRLF);
+ rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen+1,
+ (LPSTR)pText, ex->cb, ex->lpDefaultChar,
ex->lpUsedDefChar);
+ if (rc) rc--; /* do not count 0 terminator */
+
+ heap_free(buffer);
+ return rc;
+ }
+}
+
+static int ME_GetTextRange(ME_TextEditor *editor, TEXTRANGEW *rng, BOOL unicode)
+{
+ if (unicode)
+ return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin,
+ rng->chrg.cpMax-rng->chrg.cpMin, 0);
+ else
+ {
+ int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
+ WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
+ int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, 0);
+ /* FIXME this is a potential security hole (buffer overrun)
+ if you know more about wchar->mbyte conversion please explain
+ */
+ WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)rng->lpstrText, nLen+1,
NULL, NULL);
+ FREE_OBJ(p);
+ return nChars;
+ }
+}
+
typedef struct tagME_GlobalDestStruct
{
HGLOBAL hData;
@@ -1952,7 +2019,7 @@
cb = cb >> 1;
pDest = (WORD *)lpBuff;
- pSrc = (WORD *)GlobalLock(pData->hData);
+ pSrc = GlobalLock(pData->hData);
for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
pDest[i] = pSrc[pData->nLength+i];
}
@@ -1969,7 +2036,7 @@
BYTE *pSrc, *pDest;
pDest = lpBuff;
- pSrc = (BYTE *)GlobalLock(pData->hData);
+ pSrc = GlobalLock(pData->hData);
for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
pDest[i] = pSrc[pData->nLength+i];
}
@@ -2178,10 +2245,176 @@
return FALSE;
}
+static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode,
+ LPARAM flags, BOOL unicode)
+{
+ WCHAR wstr;
+
+ if (unicode)
+ wstr = (WCHAR)charCode;
+ else
+ {
+ CHAR charA = charCode;
+ MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1);
+ }
+
+ if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) {
+ MessageBeep(MB_ICONERROR);
+ return 0; /* FIXME really 0 ? */
+ }
+
+ if (((unsigned)wstr)>=' '
+ || (wstr=='\r' && (GetWindowLongW(editor->hWnd, GWL_STYLE) &
ES_MULTILINE))
+ || wstr=='\t') {
+ ME_Cursor cursor = editor->pCursors[0];
+ ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
+ int from, to;
+ BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
+ ME_GetSelection(editor, &from, &to);
+ if (wstr=='\t'
+ /* v4.1 allows tabs to be inserted with ctrl key down */
+ && !(ctrl_is_down && !editor->bEmulateVersion10)
+ )
+ {
+ ME_DisplayItem *para;
+ BOOL bSelectedRow = FALSE;
+
+ para = ME_GetParagraph(cursor.pRun);
+ if (ME_IsSelection(editor) &&
+ cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+ to == ME_GetCursorOfs(editor, 0) &&
+ para->member.para.prev_para->type == diParagraph)
+ {
+ para = para->member.para.prev_para;
+ bSelectedRow = TRUE;
+ }
+ if (ME_IsInTable(para))
+ {
+ ME_TabPressedInTable(editor, bSelectedRow);
+ ME_CommitUndo(editor);
+ return 0;
+ }
+ } else if (!editor->bEmulateVersion10) { /* v4.1 */
+ if (para->member.para.nFlags & MEPF_ROWEND) {
+ if (wstr=='\r') {
+ /* Add a new table row after this row. */
+ para = ME_AppendTableRow(editor, para);
+ para = para->member.para.next_para;
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ ME_CommitUndo(editor);
+ ME_CheckTablesForCorruption(editor);
+ ME_UpdateRepaint(editor);
+ return 0;
+ } else if (from == to) {
+ para = para->member.para.next_para;
+ if (para->member.para.nFlags & MEPF_ROWSTART)
+ para = para->member.para.next_para;
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ }
+ }
+ else if (para == ME_GetParagraph(editor->pCursors[1].pRun) &&
+ cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 &&
+ para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART
&&
+ !para->member.para.prev_para->member.para.nCharOfs)
+ {
+ /* Insert a newline before the table. */
+ WCHAR endl = '\r';
+ para = para->member.para.prev_para;
+ para->member.para.nFlags &= ~MEPF_ROWSTART;
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[1] = editor->pCursors[0];
+ ME_InsertTextFromCursor(editor, 0, &endl, 1,
+ editor->pCursors[0].pRun->member.run.style);
+ para = editor->pBuffer->pFirst->member.para.next_para;
+ ME_SetDefaultParaFormat(para->member.para.pFmt);
+ para->member.para.nFlags = MEPF_REWRAP;
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[1] = editor->pCursors[0];
+ para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART;
+ ME_CommitCoalescingUndo(editor);
+ ME_CheckTablesForCorruption(editor);
+ ME_UpdateRepaint(editor);
+ return 0;
+ }
+ } else { /* v1.0 - 3.0 */
+ ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
+ if (ME_IsInTable(cursor.pRun))
+ {
+ if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
+ {
+ if (from == to) {
+ if (wstr=='\r') {
+ ME_ContinueCoalescingTransaction(editor);
+ para = ME_AppendTableRow(editor, para);
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ ME_CommitCoalescingUndo(editor);
+ ME_UpdateRepaint(editor);
+ } else {
+ /* Text should not be inserted at the end of the table. */
+ MessageBeep(-1);
+ }
+ return 0;
+ }
+ } else if (wstr == '\r') {
+ ME_ContinueCoalescingTransaction(editor);
+ if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
+ !ME_IsInTable(para->member.para.prev_para))
+ {
+ /* Insert newline before table */
+ WCHAR endl = '\r';
+ cursor.pRun = ME_FindItemBack(para, diRun);
+ if (cursor.pRun)
+ editor->pCursors[0].pRun = cursor.pRun;
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ ME_InsertTextFromCursor(editor, 0, &endl, 1,
+ editor->pCursors[0].pRun->member.run.style);
+ } else {
+ editor->pCursors[1] = editor->pCursors[0];
+ para = ME_AppendTableRow(editor, para);
+ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
+ editor->pCursors[0].nOffset = 0;
+ editor->pCursors[1] = editor->pCursors[0];
+ }
+ ME_CommitCoalescingUndo(editor);
+ ME_UpdateRepaint(editor);
+ return 0;
+ }
+ }
+ }
+ /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
+ /* WM_CHAR is restricted to nTextLimit */
+ if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
+ {
+ ME_Style *style = ME_GetInsertStyle(editor, 0);
+ ME_SaveTempStyle(editor);
+ ME_ContinueCoalescingTransaction(editor);
+ if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000))
+ ME_InsertEndRowFromCursor(editor, 0);
+ else
+ ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
+ ME_ReleaseStyle(style);
+ ME_CommitCoalescingUndo(editor);
+ SetCursor(NULL);
+ }
+
+ if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
+
+ ME_UpdateRepaint(editor);
+ }
+ return 0;
+}
+
/* Process the message and calculate the new click count.
*
* returns: The click count if it is mouse down event, else returns 0. */
-static int ME_CalculateClickCount(HWND hWnd, UINT msg, WPARAM wParam,
+static int ME_CalculateClickCount(ME_TextEditor *editor, UINT msg, WPARAM wParam,
LPARAM lParam)
{
static int clickNum = 0;
@@ -2203,7 +2436,9 @@
{
static MSG prevClickMsg;
MSG clickMsg;
- clickMsg.hwnd = hWnd;
+ /* Compare the editor instead of the hwnd so that the this
+ * can still be done for windowless richedit controls. */
+ clickMsg.hwnd = (HWND)editor;
clickMsg.message = msg;
clickMsg.wParam = wParam;
clickMsg.lParam = lParam;
@@ -2257,9 +2492,26 @@
}
ScreenToClient(editor->hWnd, &pt);
- if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_SELECTIONBAR) &&
- (pt.x < editor->selofs ||
- (editor->nSelectionType == stLine && GetCapture() ==
editor->hWnd)))
+ if (editor->nSelectionType == stLine && GetCapture() == editor->hWnd) {
+ SetCursor(hLeft);
+ return TRUE;
+ }
+ if (!editor->bEmulateVersion10 /* v4.1 */ &&
+ pt.y < editor->rcFormat.top &&
+ pt.x < editor->rcFormat.left)
+ {
+ SetCursor(hLeft);
+ return TRUE;
+ }
+ if (pt.y < editor->rcFormat.top || pt.y > editor->rcFormat.bottom)
+ {
+ if (editor->bEmulateVersion10) /* v1.0 - 3.0 */
+ SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW));
+ else /* v4.1 */
+ SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_IBEAM));
+ return TRUE;
+ }
+ if (pt.x < editor->rcFormat.left)
{
SetCursor(hLeft);
return TRUE;
@@ -2293,6 +2545,16 @@
}
SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_IBEAM));
return TRUE;
+}
+
+static void ME_SetDefaultFormatRect(ME_TextEditor *editor)
+{
+ DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
+
+ GetClientRect(editor->hWnd, &editor->rcFormat);
+ editor->rcFormat.top += (exstyle & WS_EX_CLIENTEDGE ? 1 : 0);
+ editor->rcFormat.left += 1 + editor->selofs;
+ editor->rcFormat.right -= 1;
}
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
@@ -2343,7 +2605,6 @@
ed->pCursors[2] = ed->pCursors[0];
ed->pCursors[3] = ed->pCursors[1];
ed->nLastTotalLength = ed->nTotalLength = 0;
- ed->nHeight = 0;
ed->nUDArrowX = -1;
ed->nSequence = 0;
ed->rgbBackColor = -1;
@@ -2379,6 +2640,7 @@
ed->selofs = SELECTIONBAR_WIDTH;
else
ed->selofs = 0;
+ ed->bDefaultFormatRect = TRUE;
ed->nSelectionType = stPosition;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD)
@@ -2461,11 +2723,6 @@
return TRUE;
}
-
-#define UNSUPPORTED_MSG(e) \
- case e: \
- FIXME(#e ": stub\n"); \
- return DefWindowProcW(hWnd, msg, wParam, lParam);
static const char * const edit_messages[] = {
"EM_GETSEL",
@@ -2507,7 +2764,9 @@
"EM_GETMARGINS",
"EM_GETLIMITTEXT",
"EM_POSFROMCHAR",
- "EM_CHARFROMPOS"
+ "EM_CHARFROMPOS",
+ "EM_SETIMESTATUS",
+ "EM_GETIMESTATUS"
};
static const char * const richedit_messages[] = {
@@ -2604,18 +2863,60 @@
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)
@@ -2623,7 +2924,8 @@
UNSUPPORTED_MSG(EM_GETBIDIOPTIONS)
UNSUPPORTED_MSG(EM_GETEDITSTYLE)
UNSUPPORTED_MSG(EM_GETIMECOMPMODE)
- /* UNSUPPORTED_MSG(EM_GETIMESTATUS) missing in Wine headers */
+ UNSUPPORTED_MSG(EM_GETIMESTATUS)
+ UNSUPPORTED_MSG(EM_SETIMESTATUS)
UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
/* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
UNSUPPORTED_MSG(EM_GETREDONAME)
@@ -2658,7 +2960,7 @@
{
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;
}
@@ -2669,14 +2971,6 @@
}
}
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);
@@ -2723,8 +3017,8 @@
{
/* these flags are equivalent to the ES_* counterparts */
DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
- ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN;
- DWORD settings = GetWindowLongW(hWnd, GWL_STYLE) & mask;
+ ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
+ DWORD settings = GetWindowLongW(editor->hWnd, GWL_STYLE) & mask;
return settings;
}
@@ -2736,8 +3030,10 @@
*/
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;
switch(wParam)
{
@@ -2753,15 +3049,23 @@
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;
if (settings & ECO_AUTOWORDSELECTION)
FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
- if (settings & ECO_SELECTIONBAR)
+
+ if (oldSettings ^ settings) {
+ if (settings & ECO_SELECTIONBAR) {
editor->selofs = SELECTIONBAR_WIDTH;
- else
+ editor->rcFormat.left += SELECTIONBAR_WIDTH;
+ } else {
editor->selofs = 0;
- ME_WrapMarkedParagraphs(editor);
+ editor->rcFormat.left -= SELECTIONBAR_WIDTH;
+ }
+ ME_WrapMarkedParagraphs(editor);
+ }
if (settings & ECO_VERTICAL)
FIXME("ECO_VERTICAL not implemented yet!\n");
@@ -2895,8 +3199,8 @@
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:
@@ -2912,12 +3216,12 @@
}
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:
@@ -3060,23 +3364,8 @@
return len;
}
case EM_SCROLLCARET:
- {
- int top, bottom; /* row's edges relative to document top */
- int nPos;
- ME_DisplayItem *para, *row;
-
- nPos = ME_GetYScrollPos(editor);
- row = ME_RowStart(editor->pCursors[0].pRun);
- para = ME_GetParagraph(row);
- top = para->member.para.pt.y + row->member.row.pt.y;
- bottom = top + row->member.row.nHeight;
-
- if (top < nPos) /* caret above window */
- ME_ScrollAbs(editor, top);
- else if (nPos + editor->sizeWindow.cy < bottom) /*below*/
- ME_ScrollAbs(editor, bottom - editor->sizeWindow.cy);
+ ME_EnsureVisible(editor, editor->pCursors[0].pRun);
return 0;
- }
case WM_SETFONT:
{
LOGFONTW lf;
@@ -3087,9 +3376,9 @@
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);
@@ -3118,7 +3407,7 @@
int len = -1;
/* uses default style! */
- if (!(GetWindowLongW(hWnd, GWL_STYLE) & ES_MULTILINE))
+ if (!(GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE))
{
WCHAR * p;
@@ -3198,12 +3487,13 @@
ex.codepage = unicode ? 1200 : CP_ACP;
ex.lpDefaultChar = NULL;
ex.lpUsedDefChar = NULL;
- rc = RichEditWndProc_common(hWnd, EM_GETTEXTEX, (WPARAM)&ex, unicode ?
(LPARAM)bufferW : (LPARAM)bufferA, unicode);
+
+ rc = ME_GetTextEx(editor, &ex, unicode ? (LPARAM)bufferW : (LPARAM)bufferA);
if (unicode)
{
memcpy((LPWSTR)lParam, bufferW, wParam * sizeof(WCHAR));
- if (lstrlenW(bufferW) >= wParam) rc = 0;
+ if (strlenW(bufferW) >= wParam) rc = 0;
}
else
{
@@ -3215,52 +3505,7 @@
return rc;
}
case EM_GETTEXTEX:
- {
- GETTEXTEX *ex = (GETTEXTEX*)wParam;
- int nStart, nCount; /* in chars */
-
- if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
- FIXME("GETTEXTEX flags 0x%08x not supported\n", ex->flags &
~(GT_SELECTION | GT_USECRLF));
-
- if (ex->flags & GT_SELECTION)
- {
- ME_GetSelection(editor, &nStart, &nCount);
- nCount -= nStart;
- }
- else
- {
- nStart = 0;
- nCount = 0x7fffffff;
- }
- if (ex->codepage == 1200)
- {
- nCount = min(nCount, ex->cb / sizeof(WCHAR) - 1);
- return ME_GetTextW(editor, (LPWSTR)lParam, nStart, nCount, ex->flags &
GT_USECRLF);
- }
- else
- {
- /* potentially each char may be a CR, why calculate the exact value with O(N) when
- we can just take a bigger buffer? :)
- The above assumption still holds with CR/LF counters, since CR->CRLF
expansion
- occurs only in richedit 2.0 mode, in which line breaks have only one CR
- */
- int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
- LPWSTR buffer;
- DWORD buflen = ex->cb;
- LRESULT rc;
- DWORD flags = 0;
-
- nCount = min(nCount, ex->cb - 1);
- buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
-
- buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags &
GT_USECRLF);
- rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen+1, (LPSTR)lParam,
ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
- if (rc) rc--; /* do not count 0 terminator */
-
- heap_free(buffer);
- return rc;
- }
- }
+ return ME_GetTextEx(editor, (GETTEXTEX*)wParam, lParam);
case EM_GETSELTEXT:
{
int from, to;
@@ -3269,7 +3514,7 @@
tr.chrg.cpMin = from;
tr.chrg.cpMax = to;
tr.lpstrText = (WCHAR *)lParam;
- return RichEditWndProc_common(hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr, unicode);
+ return ME_GetTextRange(editor, &tr, unicode);
}
case EM_GETSCROLLPOS:
{
@@ -3284,20 +3529,7 @@
TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d emul1.0=%d length=%d\n",
rng->chrg.cpMin, rng->chrg.cpMax, unicode,
editor->bEmulateVersion10, ME_GetTextLength(editor));
- if (unicode)
- return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin,
rng->chrg.cpMax-rng->chrg.cpMin, 0);
- else
- {
- int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
- WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
- int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, 0);
- /* FIXME this is a potential security hole (buffer overrun)
- if you know more about wchar->mbyte conversion please explain
- */
- WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)rng->lpstrText, nLen+1,
NULL, NULL);
- FREE_OBJ(p);
- return nChars;
- }
+ return ME_GetTextRange(editor, rng, unicode);
}
case EM_GETLINE:
{
@@ -3338,7 +3570,7 @@
{
if (run && (run->member.run.nFlags & MERF_ENDPARA))
{
- unsigned int i;
+ int i;
/* Write as many \r as encoded in end-of-paragraph, space allowing */
for (i = 0; i < run->member.run.nCR && nCharsLeft > 0; i++,
nCharsLeft--)
{
@@ -3544,18 +3776,16 @@
nCharOfs = lParam;
nLength = ME_GetTextLength(editor);
nCharOfs = min(nCharOfs, nLength);
+ nCharOfs = max(nCharOfs, 0);
ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
assert(pRun->type == diRun);
pt.y = pRun->member.run.pt.y;
pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run,
nOffset);
- pt.y += ME_GetParagraph(pRun)->member.para.pt.y;
- pt.x += editor->selofs;
- pt.x++; /* for some reason native offsets x by one */
-
- si.cbSize = sizeof(si);
- si.fMask = SIF_POS;
- if (GetScrollInfo(editor->hWnd, SB_VERT, &si)) pt.y -= si.nPos;
+ pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top;
+ pt.x += editor->rcFormat.left;
+
+ pt.y -= editor->vert_si.nPos;
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
if (GetScrollInfo(editor->hWnd, SB_HORZ, &si)) pt.x -= si.nPos;
@@ -3569,20 +3799,20 @@
{
SCROLLINFO si;
- GetClientRect(hWnd, &editor->rcFormat);
- if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
+ ME_SetDefaultFormatRect(editor);
+ 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);
@@ -3591,7 +3821,7 @@
}
case WM_DESTROY:
ME_DestroyEditor(editor);
- SetWindowLongPtrW(hWnd, 0, 0);
+ SetWindowLongPtrW(editor->hWnd, 0, 0);
return 0;
case WM_SETCURSOR:
{
@@ -3604,10 +3834,10 @@
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(hWnd, msg, wParam, lParam));
- SetCapture(hWnd);
+ ME_CalculateClickCount(editor, msg, wParam, lParam));
+ SetCapture(editor->hWnd);
ME_LinkNotify(editor,msg,wParam,lParam);
if (!ME_SetCursor(editor)) goto do_default;
break;
@@ -3616,15 +3846,15 @@
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;
@@ -3651,11 +3881,39 @@
case WM_PAINT:
{
HDC hDC;
+ 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)
+ {
+ 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(hWnd, &ps);
+ EndPaint(editor->hWnd, &ps);
}
break;
case WM_SETFOCUS:
@@ -3673,7 +3931,7 @@
{
HDC hDC = (HDC)wParam;
RECT rc;
- if (GetUpdateRect(hWnd,&rc,TRUE))
+ if (GetUpdateRect(editor->hWnd,&rc,TRUE))
{
FillRect(hDC, &rc, editor->hbrBackground);
}
@@ -3694,170 +3952,8 @@
if (ME_KeyDown(editor, LOWORD(wParam)))
return 0;
goto do_default;
- case WM_CHAR:
- {
- WCHAR wstr;
-
- if (unicode)
- wstr = (WCHAR)wParam;
- else
- {
- CHAR charA = wParam;
- MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1);
- }
-
- if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY) {
- MessageBeep(MB_ICONERROR);
- return 0; /* FIXME really 0 ? */
- }
-
- if (((unsigned)wstr)>=' '
- || (wstr=='\r' && (GetWindowLongW(hWnd, GWL_STYLE) &
ES_MULTILINE))
- || wstr=='\t') {
- ME_Cursor cursor = editor->pCursors[0];
- ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
- int from, to;
- BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
- ME_GetSelection(editor, &from, &to);
- if (wstr=='\t'
- /* v4.1 allows tabs to be inserted with ctrl key down */
- && !(ctrl_is_down && !editor->bEmulateVersion10)
- )
- {
- ME_DisplayItem *para;
- BOOL bSelectedRow = FALSE;
-
- para = ME_GetParagraph(cursor.pRun);
- if (ME_IsSelection(editor) &&
- cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
- to == ME_GetCursorOfs(editor, 0) &&
- para->member.para.prev_para->type == diParagraph)
- {
- para = para->member.para.prev_para;
- bSelectedRow = TRUE;
- }
- if (ME_IsInTable(para))
- {
- ME_TabPressedInTable(editor, bSelectedRow);
- ME_CommitUndo(editor);
- return 0;
- }
- } else if (!editor->bEmulateVersion10) { /* v4.1 */
- if (para->member.para.nFlags & MEPF_ROWEND) {
- if (wstr=='\r') {
- /* Add a new table row after this row. */
- para = ME_AppendTableRow(editor, para);
- para = para->member.para.next_para;
- editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
- editor->pCursors[0].nOffset = 0;
- editor->pCursors[1] = editor->pCursors[0];
- ME_CommitUndo(editor);
- ME_CheckTablesForCorruption(editor);
- ME_UpdateRepaint(editor);
- return 0;
- } else if (from == to) {
- para = para->member.para.next_para;
- if (para->member.para.nFlags & MEPF_ROWSTART)
- para = para->member.para.next_para;
- editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
- editor->pCursors[0].nOffset = 0;
- editor->pCursors[1] = editor->pCursors[0];
- }
- }
- else if (para == ME_GetParagraph(editor->pCursors[1].pRun) &&
- cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 &&
- para->member.para.prev_para->member.para.nFlags &
MEPF_ROWSTART &&
- !para->member.para.prev_para->member.para.nCharOfs)
- {
- /* Insert a newline before the table. */
- WCHAR endl = '\r';
- para = para->member.para.prev_para;
- para->member.para.nFlags &= ~MEPF_ROWSTART;
- editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
- editor->pCursors[1] = editor->pCursors[0];
- ME_InsertTextFromCursor(editor, 0, &endl, 1,
- editor->pCursors[0].pRun->member.run.style);
- para = editor->pBuffer->pFirst->member.para.next_para;
- ME_SetDefaultParaFormat(para->member.para.pFmt);
- para->member.para.nFlags = MEPF_REWRAP;
- editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
- editor->pCursors[1] = editor->pCursors[0];
- para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART;
- ME_CommitCoalescingUndo(editor);
- ME_CheckTablesForCorruption(editor);
- ME_UpdateRepaint(editor);
- return 0;
- }
- } else { /* v1.0 - 3.0 */
- ME_DisplayItem *para = ME_GetParagraph(cursor.pRun);
- if (ME_IsInTable(cursor.pRun))
- {
- if (cursor.pRun->member.run.nFlags & MERF_ENDPARA)
- {
- if (from == to) {
- if (wstr=='\r') {
- ME_ContinueCoalescingTransaction(editor);
- para = ME_AppendTableRow(editor, para);
- editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
- editor->pCursors[0].nOffset = 0;
- editor->pCursors[1] = editor->pCursors[0];
- ME_CommitCoalescingUndo(editor);
- ME_UpdateRepaint(editor);
- } else {
- /* Text should not be inserted at the end of the table. */
- MessageBeep(-1);
- }
- return 0;
- }
- } else if (wstr == '\r') {
- ME_ContinueCoalescingTransaction(editor);
- if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 &&
- !ME_IsInTable(para->member.para.prev_para))
- {
- /* Insert newline before table */
- WCHAR endl = '\r';
- cursor.pRun = ME_FindItemBack(para, diRun);
- if (cursor.pRun)
- editor->pCursors[0].pRun = cursor.pRun;
- editor->pCursors[0].nOffset = 0;
- editor->pCursors[1] = editor->pCursors[0];
- ME_InsertTextFromCursor(editor, 0, &endl, 1,
- editor->pCursors[0].pRun->member.run.style);
- } else {
- editor->pCursors[1] = editor->pCursors[0];
- para = ME_AppendTableRow(editor, para);
- editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun);
- editor->pCursors[0].nOffset = 0;
- editor->pCursors[1] = editor->pCursors[0];
- }
- ME_CommitCoalescingUndo(editor);
- ME_UpdateRepaint(editor);
- return 0;
- }
- }
- }
- /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
- /* WM_CHAR is restricted to nTextLimit */
- if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
- {
- ME_Style *style = ME_GetInsertStyle(editor, 0);
- ME_SaveTempStyle(editor);
- ME_ContinueCoalescingTransaction(editor);
- if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000))
- ME_InsertEndRowFromCursor(editor, 0);
- else
- ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
- ME_ReleaseStyle(style);
- ME_CommitCoalescingUndo(editor);
- SetCursor(NULL);
- }
-
- if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
-
- ME_UpdateRepaint(editor);
- }
- return 0;
- }
+ case WM_CHAR:
+ return ME_Char(editor, wParam, lParam, unicode);
case WM_UNICHAR:
if (unicode)
{
@@ -3867,10 +3963,11 @@
if(wParam > 0xffff) /* convert to surrogates */
{
wParam -= 0x10000;
- SendMessageW(editor->hWnd, WM_CHAR, (wParam >> 10) + 0xd800,
0);
- SendMessageW(editor->hWnd, WM_CHAR, (wParam & 0x03ff) + 0xdc00,
0);
+ ME_Char(editor, (wParam >> 10) + 0xd800, 0, TRUE);
+ ME_Char(editor, (wParam & 0x03ff) + 0xdc00, 0, TRUE);
+ } else {
+ ME_Char(editor, wParam, 0, TRUE);
}
- else SendMessageW(editor->hWnd, WM_CHAR, wParam, 0);
}
return 0;
}
@@ -3936,6 +4033,8 @@
case EM_GETRECT:
{
*((RECT *)lParam) = editor->rcFormat;
+ if (editor->bDefaultFormatRect)
+ ((RECT *)lParam)->left -= editor->selofs;
return 0;
}
case EM_SETRECT:
@@ -3943,23 +4042,36 @@
{
if (lParam)
{
+ DWORD exstyle = GetWindowLongW(editor->hWnd, GWL_EXSTYLE);
+ int border = (exstyle & WS_EX_CLIENTEDGE) ? 1 : 0;
+ RECT clientRect;
RECT *rc = (RECT *)lParam;
-
- if (wParam)
+
+ GetClientRect(editor->hWnd, &clientRect);
+ if (wParam == 0)
{
- editor->rcFormat.left += rc->left;
- editor->rcFormat.top += rc->top;
- editor->rcFormat.right += rc->right;
- editor->rcFormat.bottom += rc->bottom;
- }
- else
- {
- editor->rcFormat = *rc;
- }
+ 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
{
- GetClientRect(hWnd, &editor->rcFormat);
+ ME_SetDefaultFormatRect(editor);
+ editor->bDefaultFormatRect = TRUE;
}
if (msg != EM_SETRECTNP)
ME_RewrapRepaint(editor);
@@ -3969,12 +4081,21 @@
ME_SendRequestResize(editor, TRUE);
return 0;
case WM_SETREDRAW:
- return DefWindowProcW(hWnd, msg, wParam, lParam);
+ goto do_default;
case WM_SIZE:
{
- GetClientRect(hWnd, &editor->rcFormat);
+ RECT clientRect;
+
+ GetClientRect(editor->hWnd, &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);
- return DefWindowProcW(hWnd, msg, wParam, lParam);
+ goto do_default;
}
/* IME messages to make richedit controls IME aware */
case WM_IME_SETCONTEXT:
@@ -3995,7 +4116,7 @@
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);
@@ -4064,7 +4185,12 @@
LRESULT ret;
int mask = 0;
int changes = 0;
- ret = RichEditWndProc_common(hWnd, WM_GETTEXTLENGTH, 0, 0, unicode);
+ GETTEXTLENGTHEX how;
+
+ /* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */
+ how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) |
GTL_NUMCHARS;
+ how.codepage = unicode ? 1200 : CP_ACP;
+ ret = ME_GetTextLengthEx(editor, &how);
if (!ret)
{
/*Check for valid wParam*/
@@ -4106,7 +4232,8 @@
break;
default:
do_default:
- return DefWindowProcW(hWnd, msg, wParam, lParam);
+ *phresult = S_FALSE;
+ break;
}
return 0L;
}
@@ -4148,7 +4275,9 @@
{
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
+ TRACE("Emulating version 1.0 (hWnd=%p)\n", hWnd);
editor->bEmulateVersion10 = TRUE;
+ editor->bWordWrap = (GetWindowLongW(hWnd, GWL_STYLE) & ES_AUTOHSCROLL) ? FALSE
: TRUE;
editor->pBuffer->pLast->member.para.nCharOfs = 2;
assert(editor->pBuffer->pLast->prev->type == diRun);
assert(editor->pBuffer->pLast->prev->member.run.nFlags &
MERF_ENDPARA);
@@ -4329,7 +4458,7 @@
wcW.hInstance = NULL; /* hInstance would register DLL-local class */
wcW.hIcon = NULL;
wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
- wcW.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+ wcW.hbrBackground = GetStockObject(NULL_BRUSH);
wcW.lpszMenuName = NULL;
if (is_version_nt())
@@ -4355,7 +4484,7 @@
wcA.hInstance = NULL; /* hInstance would register DLL-local class */
wcA.hIcon = NULL;
wcA.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
- wcA.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+ wcA.hbrBackground = GetStockObject(NULL_BRUSH);
wcA.lpszMenuName = NULL;
wcA.lpszClassName = "RichEdit20A";
if (!RegisterClassA(&wcA)) return FALSE;
@@ -4424,95 +4553,6 @@
return result;
}
-
-int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar)
-{
- struct prefix_s {
- const char *text;
- int length;
- } prefixes[12] = {
- {"http:", 5},
- {"file:", 6},
- {"mailto:", 8},
- {"ftp:", 5},
- {"https:", 7},
- {"gopher:", 8},
- {"nntp:", 6},
- {"prospero:", 10},
- {"telnet:", 8},
- {"news:", 6},
- {"wais:", 6},
- {"www.", 5}
- };
- CHARRANGE ins_pt;
- int curf_ef, link_ef, def_ef;
- int cur_prefx, prefx_cnt;
- int sel_min, sel_max;
- int car_pos = 0;
- int text_pos=-1;
- int URLmin, URLmax = 0;
- FINDTEXTA ft;
- CHARFORMAT2W cur_format;
- CHARFORMAT2W default_format;
- CHARFORMAT2W link;
- RichEditANSIWndProc(editor->hWnd, EM_EXGETSEL, (WPARAM) 0, (LPARAM) &ins_pt);
- sel_min = ins_pt.cpMin;
- sel_max = ins_pt.cpMax;
- if (sel_min==sel_max)
- car_pos = sel_min;
- if (sel_min!=sel_max)
- car_pos = ME_GetTextLength(editor)+1;
- cur_format.cbSize = sizeof(cur_format);
- default_format.cbSize = sizeof(default_format);
- RichEditANSIWndProc(editor->hWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)
&cur_format);
- RichEditANSIWndProc(editor->hWnd, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)
&default_format);
- link.cbSize = sizeof(link);
- link.dwMask = CFM_LINK;
- link.dwEffects = CFE_LINK;
- curf_ef = cur_format.dwEffects & link.dwEffects;
- def_ef = default_format.dwEffects & link.dwEffects;
- link_ef = link.dwEffects & link.dwEffects;
- if (curf_ef == link_ef)
- {
- if( curChar == '\n' || curChar=='\r' || curChar==' ')
- {
- ME_SetSelection(editor, car_pos, car_pos);
- RichEditANSIWndProc(editor->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)
&default_format);
- text_pos=-1;
- return 0;
- }
- }
- if (curf_ef == def_ef)
- {
- cur_prefx = 0;
- prefx_cnt = (sizeof(prefixes)/sizeof(struct prefix_s))-1;
- while (cur_prefx<=prefx_cnt)
- {
- if (text_pos == -1)
- {
- ft.lpstrText = prefixes[cur_prefx].text;
- URLmin=max(0,(car_pos-prefixes[cur_prefx].length));
- URLmax=max(0, car_pos);
- if ((car_pos == 0) && (ME_GetTextLength(editor) != 0))
- {
- URLmax = ME_GetTextLength(editor)+1;
- }
- ft.chrg.cpMin = URLmin;
- ft.chrg.cpMax = URLmax;
- text_pos=RichEditANSIWndProc(editor->hWnd, EM_FINDTEXT, FR_DOWN,
(LPARAM)&ft);
- cur_prefx++;
- }
- if (text_pos != -1)
- {
- ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link);
- ME_RewrapRepaint(editor);
- break;
- }
- }
- }
- return 0;
-}
-
static BOOL isurlspecial(WCHAR c)
{
@@ -4647,7 +4687,7 @@
};
LPWSTR bufferW = NULL;
WCHAR bufW[32];
- int i;
+ unsigned int i;
if (sel_max == -1) sel_max = ME_GetTextLength(editor);
assert(sel_min <= sel_max);
@@ -4655,9 +4695,9 @@
{
if (sel_max - sel_min < prefixes[i].length) continue;
if (bufferW == NULL) {
- bufferW = (LPWSTR)heap_alloc((sel_max - sel_min + 1) * sizeof(WCHAR));
- }
- ME_GetTextW(editor, bufferW, sel_min, min(sel_max - sel_min,
strlen(prefixes[i].text)), 0);
+ bufferW = heap_alloc((sel_max - sel_min + 1) * sizeof(WCHAR));
+ }
+ ME_GetTextW(editor, bufferW, sel_min, min(sel_max - sel_min,
lstrlenA(prefixes[i].text)), 0);
MultiByteToWideChar(CP_ACP, 0, prefixes[i].text, -1, bufW, 32);
if (!lstrcmpW(bufW, bufferW))
{
Modified: trunk/reactos/dll/win32/riched20/editor.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editor.…
==============================================================================
--- trunk/reactos/dll/win32/riched20/editor.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/editor.h [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -268,11 +268,11 @@
void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src);
void ME_DeleteReObject(REOBJECT* reo);
-/* wintest.c */
-
/* 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);
@@ -282,7 +282,6 @@
void ME_RTFTblAttrHook(struct _RTF_Info *info);
void ME_RTFSpecialCharHook(struct _RTF_Info *info);
void ME_StreamInFill(ME_InStream *stream);
-int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar);
extern int me_debug;
extern void DoWrap(ME_TextEditor *editor);
extern BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_max,
Modified: trunk/reactos/dll/win32/riched20/editstr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editstr…
==============================================================================
--- trunk/reactos/dll/win32/riched20/editstr.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/editstr.h [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -90,7 +90,7 @@
diUndoPotentialEndTransaction, /* 20 - allows grouping typed chars for undo */
} ME_DIType;
-#define SELECTIONBAR_WIDTH 9
+#define SELECTIONBAR_WIDTH 8
/******************************** run flags *************************/
#define MERF_STYLEFLAGS 0x0FFF
@@ -333,7 +333,6 @@
int nCursors;
SIZE sizeWindow;
int nTotalLength, nLastTotalLength;
- int nHeight;
int nUDArrowX;
int nSequence;
COLORREF rgbBackColor;
@@ -350,7 +349,9 @@
ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara;
ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
int nZoomNumerator, nZoomDenominator;
+ RECT prevClientRect;
RECT rcFormat;
+ BOOL bDefaultFormatRect;
BOOL bWordWrap;
int nInvalidOfs;
int nTextLimit;
Modified: trunk/reactos/dll/win32/riched20/paint.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/paint.c…
==============================================================================
--- trunk/reactos/dll/win32/riched20/paint.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/paint.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -23,10 +23,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
-void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *rcUpdate)
{
+void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT
*rcUpdate)
+{
ME_DisplayItem *item;
ME_Context c;
int yoffset;
+ int ys, ye;
editor->nSequence++;
yoffset = ME_GetYScrollPos(editor);
@@ -34,105 +36,70 @@
SetBkMode(hDC, TRANSPARENT);
ME_MoveCaret(editor); /* Calls ME_WrapMarkedParagraphs */
item = editor->pBuffer->pFirst->next;
- c.pt.y -= yoffset;
- while(item != editor->pBuffer->pLast) {
- int yTextOffset = 0;
- int ye;
+ /* This context point is an offset for the paragraph positions stored
+ * during wrapping. It shouldn't be modified during painting. */
+ c.pt.x = c.rcView.left;
+ c.pt.y = c.rcView.top - yoffset;
+ while(item != editor->pBuffer->pLast)
+ {
assert(item->type == diParagraph);
+
+ ys = c.pt.y + item->member.para.pt.y;
if (item->member.para.pCell
!= item->member.para.next_para->member.para.pCell)
{
ME_Cell *cell = NULL;
cell = &ME_FindItemBack(item->member.para.next_para,
diCell)->member.cell;
- ye = cell->pt.y + cell->nHeight - yoffset;
+ ye = c.pt.y + cell->pt.y + cell->nHeight;
} else {
- ye = c.pt.y + item->member.para.nHeight;
- }
- if (!(item->member.para.nFlags & MEPF_ROWEND) &&
+ ye = ys + item->member.para.nHeight;
+ }
+ if (item->member.para.pCell && !(item->member.para.nFlags &
MEPF_ROWEND) &&
item->member.para.pCell !=
item->member.para.prev_para->member.para.pCell)
{
- ME_DisplayItem *cell;
- if (item->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART)
- cell = item->member.para.pCell;
- else
- cell = item->member.para.prev_para->member.para.pCell;
- assert(cell);
/* the border shifts the text down */
- yTextOffset = cell->member.cell.yTextOffset;
- ye += yTextOffset;
- }
+ ys -= item->member.para.pCell->member.cell.yTextOffset;
+ }
+
if (!bOnlyNew || (item->member.para.nFlags & MEPF_REPAINT))
{
+ /* Draw the pargraph if any of the paragraph is in the update region. */
BOOL bPaint = (rcUpdate == NULL);
if (rcUpdate)
- bPaint = c.pt.y<rcUpdate->bottom && ye>rcUpdate->top;
+ bPaint = ys < rcUpdate->bottom && ye > rcUpdate->top;
if (bPaint)
{
- c.pt.y += yTextOffset;
ME_DrawParagraph(&c, item);
- if (!rcUpdate || (rcUpdate->top<=c.pt.y-yTextOffset &&
rcUpdate->bottom>=ye))
+ /* Clear the repaint flag if the whole paragraph is in the
+ * update region. */
+ if (!rcUpdate || (rcUpdate->top <= ys && rcUpdate->bottom >=
ye))
item->member.para.nFlags &= ~MEPF_REPAINT;
}
}
- if (item->member.para.pCell)
- {
- ME_Cell *cell = &item->member.para.pCell->member.cell;
- ME_DisplayItem *next_para = item->member.para.next_para;
- c.pt.x = cell->pt.x + cell->nWidth;
- if (item->member.para.pCell == next_para->member.para.pCell &&
- !(next_para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND)))
- {
- c.pt.y = ye;
- } else {
- if (next_para->member.para.nFlags & MEPF_ROWSTART)
- {
- cell = &ME_FindItemFwd(next_para, diCell)->member.cell;
- }
- else if (next_para->member.para.nFlags & MEPF_ROWEND)
- {
- cell = &cell->next_cell->member.cell;
- }
- else
- {
- cell = &next_para->member.para.pCell->member.cell;
- }
- c.pt.y = cell->pt.y - yoffset;
- }
- } else if (!(item->member.para.nFlags & MEPF_ROWSTART)) {
- c.pt.y = ye;
- }
item = item->member.para.next_para;
}
- if (c.pt.y<c.rcView.bottom) {
+ if (c.pt.y + editor->nTotalLength < c.rcView.bottom)
+ {
+ /* Fill space after the end of the text. */
RECT rc;
- int xs = c.rcView.left, xe = c.rcView.right;
- int ys = c.pt.y, ye = c.rcView.bottom;
-
+ rc.top = c.pt.y + editor->nTotalLength;
+ rc.left = c.rcView.left;
+ rc.bottom = c.rcView.bottom;
+ rc.right = c.rcView.right;
+
if (bOnlyNew)
{
- int y1 = editor->nTotalLength-yoffset, y2 =
editor->nLastTotalLength-yoffset;
- if (y1<y2)
- ys = y1, ye = y2+1;
+ /* Only erase region drawn from previous call to ME_PaintContent */
+ if (editor->nTotalLength < editor->nLastTotalLength)
+ rc.bottom = c.pt.y + editor->nLastTotalLength;
else
- ys = ye;
- }
-
- if (rcUpdate && ys!=ye)
- {
- xs = rcUpdate->left, xe = rcUpdate->right;
- if (rcUpdate->top > ys)
- ys = rcUpdate->top;
- if (rcUpdate->bottom < ye)
- ye = rcUpdate->bottom;
- }
-
- if (ye>ys) {
- rc.left = xs;
- rc.top = ys;
- rc.right = xe;
- rc.bottom = ye;
+ SetRectEmpty(&rc);
+ }
+
+ IntersectRect(&rc, &rc, rcUpdate);
+
+ if (!IsRectEmpty(&rc))
FillRect(hDC, &rc, c.editor->hbrBackground);
- }
}
if (editor->nTotalLength != editor->nLastTotalLength)
ME_SendRequestResize(editor, FALSE);
@@ -441,7 +408,7 @@
if (runofs >= nSelFrom && runofs < nSelTo)
{
ME_HighlightSpace(c, x, y, wszSpace, 1, run->style, 0, 0, 1,
- c->pt.y + start->member.row.pt.y,
+ c->pt.y + para->pt.y + start->member.row.pt.y,
start->member.row.nHeight);
}
return;
@@ -452,8 +419,8 @@
/* wszSpace is used instead of the tab character because otherwise
* an unwanted symbol can be inserted instead. */
ME_DrawTextWithStyle(c, x, y, wszSpace, 1, run->style, run->nWidth,
- nSelFrom-runofs,nSelTo-runofs,
- c->pt.y + start->member.row.pt.y,
+ nSelFrom-runofs, nSelTo-runofs,
+ c->pt.y + para->pt.y + start->member.row.pt.y,
start->member.row.nHeight);
return;
}
@@ -467,13 +434,17 @@
ME_String *szMasked =
ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText));
ME_DrawTextWithStyle(c, x, y,
szMasked->szData, ME_StrVLen(szMasked), run->style, run->nWidth,
- nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.pt.y,
start->member.row.nHeight);
+ nSelFrom-runofs,nSelTo-runofs,
+ c->pt.y + para->pt.y + start->member.row.pt.y,
+ start->member.row.nHeight);
ME_DestroyString(szMasked);
}
else
ME_DrawTextWithStyle(c, x, y,
run->strText->szData, ME_StrVLen(run->strText), run->style,
run->nWidth,
- nSelFrom-runofs,nSelTo-runofs, c->pt.y+start->member.row.pt.y,
start->member.row.nHeight);
+ nSelFrom-runofs,nSelTo-runofs,
+ c->pt.y + para->pt.y + start->member.row.pt.y,
+ start->member.row.nHeight);
}
}
@@ -728,11 +699,11 @@
int width;
BOOL atTop = (para->pCell != para->prev_para->member.para.pCell);
BOOL atBottom = (para->pCell != para->next_para->member.para.pCell);
- int top = (atTop ? cell->pt.y : para->pt.y) -
ME_GetYScrollPos(c->editor);
+ int top = c->pt.y + (atTop ? cell->pt.y : para->pt.y);
int bottom = (atBottom ?
- cell->pt.y + cell->nHeight - ME_GetYScrollPos(c->editor):
+ c->pt.y + cell->pt.y + cell->nHeight :
top + para->nHeight + (atTop ? cell->yTextOffset : 0));
- rc.left = cell->pt.x;
+ rc.left = c->pt.x + cell->pt.x;
rc.right = rc.left + cell->nWidth;
if (atTop) {
/* Erase gap before text if not all borders are the same height. */
@@ -745,7 +716,7 @@
}
}
/* Draw cell borders.
- * The borders borders are draw in is left, top, bottom, right in order
+ * The order borders are draw in is left, top, bottom, right in order
* to be consistent with native richedit. This is noticeable from the
* overlap of borders of different colours. */
if (!(para->nFlags & MEPF_ROWEND)) {
@@ -798,10 +769,10 @@
ME_DisplayItem *nextEndCell;
nextEndCell = ME_FindItemBack(ME_GetTableRowEnd(paraAfterRow), diCell);
assert(nextEndCell && !nextEndCell->member.cell.next_cell);
- rc.left = nextEndCell->member.cell.pt.x;
+ rc.left = c->pt.x + nextEndCell->member.cell.pt.x;
/* FIXME: Native draws FROM the bottom of the table rather than
* TO the bottom of the table in this case, but just doing so here
- * will case the next row to erase the border. */
+ * will cause the next row to erase the border. */
/*
rc.top = bottom;
rc.bottom = rc.top + width;
@@ -860,12 +831,12 @@
oldpen = SelectObject(c->hDC, pen);
/* Find the start relative to the text */
- firstX = ME_FindItemFwd(paragraph, diRun)->member.run.pt.x;
+ firstX = c->pt.x + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x;
/* Go back by the horizontal gap, which is stored in dxOffset */
firstX -= ME_twips2pointsX(c, para->pFmt->dxOffset);
/* The left edge, stored in dxStartIndent affected just the first edge */
startX = firstX - ME_twips2pointsX(c, para->pFmt->dxStartIndent);
- rowY = c->pt.y;
+ rowY = c->pt.y + para->pt.y;
if (para->pFmt->dwMask & PFM_SPACEBEFORE)
rowY += ME_twips2pointsY(c, para->pFmt->dySpaceBefore);
nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight;
@@ -907,53 +878,54 @@
}
}
-void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
+void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
+{
int align = SetTextAlign(c->hDC, TA_BASELINE);
ME_DisplayItem *p;
ME_Run *run;
ME_Paragraph *para = NULL;
RECT rc, bounds;
- int y = c->pt.y;
+ int y;
int height = 0, baseline = 0, no=0;
BOOL visible = FALSE;
- c->pt.x = c->rcView.left;
- rc.left = c->rcView.left;
+ rc.left = c->pt.x;
rc.right = c->rcView.right;
- for (p = paragraph; p!=paragraph->member.para.next_para; p = p->next) {
+
+ assert(paragraph);
+ para = ¶graph->member.para;
+ y = c->pt.y + para->pt.y;
+ if (para->pCell)
+ {
+ ME_Cell *cell = ¶->pCell->member.cell;
+ rc.left = c->pt.x + cell->pt.x;
+ rc.right = rc.left + cell->nWidth;
+ }
+ if (para->nFlags & MEPF_ROWSTART) {
+ ME_Cell *cell = ¶->next_para->member.para.pCell->member.cell;
+ rc.right = c->pt.x + cell->pt.x;
+ } else if (para->nFlags & MEPF_ROWEND) {
+ ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell;
+ rc.left = c->pt.x + cell->pt.x + cell->nWidth;
+ }
+ ME_DrawParaDecoration(c, para, y, &bounds);
+ y += bounds.top;
+ rc.left += bounds.left;
+ rc.right -= bounds.right;
+
+ for (p = paragraph->next; p != para->next_para; p = p->next)
+ {
switch(p->type) {
case diParagraph:
- para = &p->member.para;
- assert(para);
- if (para->pCell)
- {
- ME_Cell *cell = ¶->pCell->member.cell;
- rc.left = cell->pt.x;
- rc.right = rc.left + cell->nWidth;
- }
- if (para->nFlags & MEPF_ROWSTART) {
- ME_Cell *cell = ¶->next_para->member.para.pCell->member.cell;
- rc.right = cell->pt.x;
- } else if (para->nFlags & MEPF_ROWEND) {
- ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell;
- rc.left = cell->pt.x + cell->nWidth;
- }
- ME_DrawParaDecoration(c, para, y, &bounds);
- y += bounds.top;
+ assert(FALSE);
break;
case diStartRow:
- /* we should have seen a diParagraph before */
- assert(para);
y += height;
rc.top = y;
- if (para->nFlags & MEPF_ROWSTART) {
- ME_Cell *cell = ¶->next_para->member.para.pCell->member.cell;
- rc.bottom = y + cell->nHeight;
- } else if (para->nFlags & MEPF_ROWEND) {
- ME_Cell *cell = ¶->prev_para->member.para.pCell->member.cell;
- rc.bottom = y + cell->nHeight;
+ if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) {
+ rc.bottom = y + para->nHeight;
} else {
- rc.bottom = y+p->member.row.nHeight;
+ rc.bottom = y + p->member.row.nHeight;
}
visible = RectVisible(c->hDC, &rc);
if (visible) {
@@ -976,10 +948,11 @@
assert(para);
run = &p->member.run;
if (visible && me_debug) {
- rc.left = c->rcView.left+run->pt.x;
- rc.right = c->rcView.left+run->pt.x+run->nWidth;
- rc.top = c->pt.y+run->pt.y;
- rc.bottom = c->pt.y+run->pt.y+height;
+ RECT rc;
+ rc.left = c->pt.x + run->pt.x;
+ rc.right = rc.left + run->nWidth;
+ rc.top = c->pt.y + para->pt.y + run->pt.y;
+ rc.bottom = rc.bottom + height;
TRACE("rc = (%d, %d, %d, %d)\n", rc.left, rc.top, rc.right,
rc.bottom);
if (run->nFlags & MERF_SKIPPED)
DrawFocusRect(c->hDC, &rc);
@@ -987,28 +960,27 @@
FrameRect(c->hDC, &rc, GetSysColorBrush(COLOR_GRAYTEXT));
}
if (visible)
- ME_DrawRun(c, run->pt.x, c->pt.y+run->pt.y+baseline, p,
¶graph->member.para);
+ ME_DrawRun(c, c->pt.x + run->pt.x,
+ c->pt.y + para->pt.y + run->pt.y + baseline, p, para);
if (me_debug)
{
/* I'm using %ls, hope wsprintfW is not going to use wrong (4-byte) WCHAR
version */
const WCHAR wszRunDebug[] =
{'[','%','d',':','%','x',']','
','%','l','s',0};
WCHAR buf[2560];
POINT pt;
- pt.x = run->pt.x;
- pt.y = c->pt.y + run->pt.y;
+ pt.x = c->pt.x + run->pt.x;
+ pt.y = c->pt.y + para->pt.y + run->pt.y;
wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags,
p->member.run.strText->szData);
ME_DebugWrite(c->hDC, &pt, buf);
}
- /* c->pt.x += p->member.run.nWidth; */
break;
case diCell:
/* Clear any space at the bottom of the cell after the text. */
- if (para->nFlags & MEPF_ROWSTART)
+ if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
break;
y += height;
- rc.top = y;
- rc.bottom = p->member.cell.pt.y + p->member.cell.nHeight
- - ME_GetYScrollPos(c->editor);
+ rc.top = c->pt.y + para->pt.y + para->nHeight;
+ rc.bottom = c->pt.y + p->member.cell.pt.y + p->member.cell.nHeight;
if (RectVisible(c->hDC, &rc))
{
FillRect(c->hDC, &rc, c->editor->hbrBackground);
@@ -1084,7 +1056,7 @@
hWnd = editor->hWnd;
winStyle = GetWindowLongW(hWnd, GWL_STYLE);
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
- bScrollBarWillBeVisible = (editor->nHeight > editor->sizeWindow.cy)
+ bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy)
|| (winStyle & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
{
@@ -1110,7 +1082,7 @@
hWnd = editor->hWnd;
si.cbSize = sizeof(si);
bScrollBarWasVisible = ME_GetYScrollVisible(editor);
- bScrollBarWillBeVisible = editor->nHeight > editor->sizeWindow.cy;
+ bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy;
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
Modified: trunk/reactos/dll/win32/riched20/para.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/para.c?…
==============================================================================
--- trunk/reactos/dll/win32/riched20/para.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/para.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -38,7 +38,7 @@
ME_InitContext(&c, editor, GetDC(editor->hWnd));
- hf = (HFONT)GetStockObject(SYSTEM_FONT);
+ hf = GetStockObject(SYSTEM_FONT);
assert(hf);
GetObjectW(hf, sizeof(LOGFONTW), &lf);
ZeroMemory(&cf, sizeof(cf));
Modified: trunk/reactos/dll/win32/riched20/reader.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/reader.…
==============================================================================
--- trunk/reactos/dll/win32/riched20/reader.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/reader.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -673,7 +673,7 @@
}
/* escaped char */
- /*if (index (":{}\\", c) != (char *) NULL)*/ /* escaped char */
+ /*if (index (":{}\\", c) != NULL)*/ /* escaped char */
if (c == ':' || c == '{' || c == '}' || c == '\\')
{
info->rtfClass = rtfText;
@@ -2289,7 +2289,7 @@
{ rtfVersion, -1, "rtf", 0 },
{ rtfDefFont, -1, "deff", 0 },
- { 0, -1, (char *) NULL, 0 }
+ { 0, -1, NULL, 0 }
};
#define RTF_KEY_COUNT (sizeof(rtfKey) / sizeof(RTFKey))
@@ -2326,7 +2326,7 @@
void LookupCleanup(void)
{
- int i;
+ unsigned int i;
for (i=0; i<RTF_KEY_COUNT*2; i++)
{
Modified: trunk/reactos/dll/win32/riched20/rtf.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/rtf.h?r…
==============================================================================
--- trunk/reactos/dll/win32/riched20/rtf.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/rtf.h [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -1157,9 +1157,6 @@
ME_InStream *stream;
- /* edit window to output to */
- HWND hwndEdit;
-
ME_TextEditor *editor;
ME_Style *style;
Modified: trunk/reactos/dll/win32/riched20/run.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/run.c?r…
==============================================================================
--- trunk/reactos/dll/win32/riched20/run.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/run.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -692,7 +692,7 @@
{
pos += lDefaultTab - (pos % lDefaultTab);
}
- ppos = ME_twips2pointsX(c, pos) + c->editor->selofs;
+ ppos = ME_twips2pointsX(c, pos);
if (ppos > startx + run->pt.x) {
size.cx = ppos - startx - run->pt.x;
break;
@@ -813,7 +813,7 @@
undo->nStart = tmp.pRun->member.run.nCharOfs+para->member.para.nCharOfs;
undo->nLen = tmp.pRun->member.run.strText->nLen;
undo->di.member.ustyle = tmp.pRun->member.run.style;
- /* we'd have to addref undo..ustyle and release tmp...style
+ /* we'd have to addref undo...ustyle and release tmp...style
but they'd cancel each other out so we can do nothing instead */
}
else
@@ -872,8 +872,6 @@
*/
void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
- int nFrom, nTo;
- ME_GetSelection(editor, &nFrom, &nTo);
ME_CopyCharFormat(pFmt, &editor->pBuffer->pDefaultStyle->fmt);
}
Modified: trunk/reactos/dll/win32/riched20/string.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/string.…
==============================================================================
--- trunk/reactos/dll/win32/riched20/string.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/string.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -342,7 +342,7 @@
int result;
int buffer_size = WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
NULL, 0, NULL, NULL);
- char *buffer = (char*)heap_alloc(buffer_size);
+ char *buffer = heap_alloc(buffer_size);
WideCharToMultiByte(CP_ACP, 0, str->szData, str->nLen,
buffer, buffer_size, NULL, NULL);
result = editor->pfnWordBreak(str->szData, start, str->nLen, code);
Modified: trunk/reactos/dll/win32/riched20/wrap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/wrap.c?…
==============================================================================
--- trunk/reactos/dll/win32/riched20/wrap.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/wrap.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -78,8 +78,7 @@
wc->bWordWrap = TRUE;
} else {
wc->nAvailWidth = wc->context->rcView.right -
wc->context->rcView.left
- - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin
- - wc->context->editor->selofs;
+ - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) -
wc->nRightMargin;
}
wc->pt.x = wc->context->pt.x;
if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
@@ -458,7 +457,7 @@
static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp);
-static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD beginofs) {
+static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
ME_DisplayItem *p;
ME_WrapContext wc;
int border = 0;
@@ -573,28 +572,26 @@
}
}
-BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
+BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
+{
ME_DisplayItem *item;
ME_Context c;
BOOL bModified = FALSE;
int yStart = -1;
- int yLastPos = 0;
ME_InitContext(&c, editor, GetDC(editor->hWnd));
- c.pt.x = editor->selofs;
- editor->nHeight = 0;
+ c.pt.x = 0;
item = editor->pBuffer->pFirst->next;
while(item != editor->pBuffer->pLast) {
BOOL bRedraw = FALSE;
assert(item->type == diParagraph);
- editor->nHeight = max(editor->nHeight, item->member.para.pt.y);
if ((item->member.para.nFlags & MEPF_REWRAP)
|| (item->member.para.pt.y != c.pt.y))
bRedraw = TRUE;
item->member.para.pt = c.pt;
- ME_WrapTextParagraph(&c, item, editor->selofs);
+ ME_WrapTextParagraph(&c, item);
if (bRedraw)
{
@@ -604,8 +601,6 @@
}
bModified = bModified | bRedraw;
-
- yLastPos = max(yLastPos, c.pt.y);
if (item->member.para.nFlags & MEPF_ROWSTART)
{
@@ -698,7 +693,8 @@
c.pt.x = cell->pt.x + cell->nWidth;
c.pt.y = cell->pt.y;
cell->next_cell->member.cell.pt = c.pt;
- c.pt.y += cell->yTextOffset;
+ if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND))
+ c.pt.y += cell->yTextOffset;
}
else
{
@@ -707,7 +703,7 @@
c.pt.x = item->member.para.pCell->member.cell.pt.x;
} else {
/* Normal paragraph */
- c.pt.x = editor->selofs;
+ c.pt.x = 0;
}
c.pt.y += item->member.para.nHeight;
}
@@ -718,17 +714,9 @@
editor->nTotalLength = c.pt.y;
editor->pBuffer->pLast->member.para.pt.x = 0;
- editor->pBuffer->pLast->member.para.pt.y = yLastPos;
+ editor->pBuffer->pLast->member.para.pt.y = c.pt.y;
ME_DestroyContext(&c, editor->hWnd);
-
- /* Each paragraph may contain multiple rows, which should be scrollable, even
- if the containing paragraph has pt.y == 0 */
- item = editor->pBuffer->pFirst;
- while ((item = ME_FindItemFwd(item, diStartRow)) != NULL) {
- assert(item->type == diStartRow);
- editor->nHeight = max(editor->nHeight, item->member.row.pt.y);
- }
if (bModified || editor->nTotalLength < editor->nLastTotalLength)
ME_InvalidateMarkedParagraphs(editor);
@@ -749,16 +737,18 @@
item = editor->pBuffer->pFirst;
while(item != editor->pBuffer->pLast) {
if (item->member.para.nFlags & MEPF_REPAINT) {
- rc.top = item->member.para.pt.y - ofs;
- rc.bottom = item->member.para.pt.y + item->member.para.nHeight - ofs;
+ rc.top = c.rcView.top + item->member.para.pt.y - ofs;
+ rc.bottom = max(c.rcView.top + item->member.para.pt.y
+ + item->member.para.nHeight - ofs,
+ c.rcView.bottom);
InvalidateRect(editor->hWnd, &rc, TRUE);
}
item = item->member.para.next_para;
}
if (editor->nTotalLength < editor->nLastTotalLength)
{
- rc.top = editor->nTotalLength - ofs;
- rc.bottom = editor->nLastTotalLength - ofs;
+ rc.top = c.rcView.top + editor->nTotalLength - ofs;
+ rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs;
InvalidateRect(editor->hWnd, &rc, TRUE);
}
ME_DestroyContext(&c, editor->hWnd);
Modified: trunk/reactos/dll/win32/riched20/writer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/writer.…
==============================================================================
--- trunk/reactos/dll/win32/riched20/writer.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/riched20/writer.c [iso-8859-1] Sat Dec 27 02:49:35 2008
@@ -201,7 +201,7 @@
{
ME_DisplayItem *item = pFirstRun;
ME_FontTableItem *table = pStream->fonttbl;
- int i;
+ unsigned int i;
ME_DisplayItem *pLastPara = ME_GetParagraph(pLastRun);
ME_DisplayItem *pCell = NULL;
@@ -264,7 +264,7 @@
{
if (borders[i]->width > 0)
{
- int j;
+ unsigned int j;
COLORREF crColor = borders[i]->colorRef;
for (j = 1; j < pStream->nColorTblLen; j++)
if (pStream->colortbl[j] == crColor)
@@ -348,7 +348,7 @@
{
if (borders[i]->width)
{
- int j;
+ unsigned int j;
COLORREF crColor = borders[i]->colorRef;
sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]);
sprintf(props + strlen(props), "\\brdrs");
@@ -380,7 +380,7 @@
{
if (borders[i]->width)
{
- int j;
+ unsigned int j;
COLORREF crColor = borders[i]->colorRef;
sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]);
sprintf(props + strlen(props), "\\brdrs");
@@ -555,7 +555,7 @@
ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
{
char props[STREAMOUT_BUFFER_SIZE] = "";
- int i;
+ unsigned int i;
if (fmt->dwMask & CFM_ALLCAPS && fmt->dwEffects & CFE_ALLCAPS)
strcat(props, "\\caps");