riched20: implement EM_SCROLLCARET and EM_GETSCROLLPOS
tkho at ucla.edu
tkho at ucla.edu
Wed Feb 15 18:08:15 CST 2006
This patch addresses bug 4567 <http://bugs.winehq.org/show_bug.cgi?id=4567>,
adding implementations for EM_SCROLLCARET and EM_GETSCROLLPOS
2006-02-15 Thomas Kho <tkho at ucla.edu>
* dlls/riched20/editor.c
riched20: Implemented EM_GETSCROLLPOS and EM_SCROLLCARET
* dlls/riched20/tests/editor.c:
riched20: Added conformance tests for EM_GETSCROLLPOS and EM_SCROLLCARET
editor.c | 48 ++++++++++++++++++++++++++++++++++---
tests/editor.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 4 deletions(-)
Signed-off-by: Thomas Kho <tkho at ucla.edu>
Index: editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.89
diff -u -r1.89 editor.c
--- editor.c 15 Feb 2006 13:04:38 -0000 1.89
+++ editor.c 15 Feb 2006 17:46:55 -0000
@@ -64,7 +64,7 @@
- EM_GETREDONAME 2.0
+ EM_GETSEL
+ EM_GETSELTEXT (ANSI&Unicode)
- - EM_GETSCROLLPOS 3.0
+ + EM_GETSCROLLPOS 3.0 (only Y value valid)
! - EM_GETTHUMB
- EM_GETTEXTEX 2.0
+ EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented)
@@ -88,7 +88,7 @@
+ EM_REQUESTRESIZE
+ EM_REPLACESEL (proper style?) ANSI&Unicode
- EM_SCROLL
- - EM_SCROLLCARET
+ + EM_SCROLLCARET
- EM_SELECTIONTYPE
- EM_SETBIDIOPTIONS 3.0
+ EM_SETBKGNDCOLOR
@@ -1319,7 +1319,6 @@
UNSUPPORTED_MSG(EM_GETOPTIONS)
UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_GETREDONAME)
- UNSUPPORTED_MSG(EM_GETSCROLLPOS)
UNSUPPORTED_MSG(EM_GETTEXTMODE)
UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
UNSUPPORTED_MSG(EM_GETUNDONAME)
@@ -1328,7 +1327,6 @@
UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */
UNSUPPORTED_MSG(EM_PASTESPECIAL)
UNSUPPORTED_MSG(EM_SCROLL)
- UNSUPPORTED_MSG(EM_SCROLLCARET)
UNSUPPORTED_MSG(EM_SELECTIONTYPE)
UNSUPPORTED_MSG(EM_SETBIDIOPTIONS)
UNSUPPORTED_MSG(EM_SETEDITSTYLE)
@@ -1629,6 +1627,41 @@
ME_UpdateRepaint(editor);
return 0;
}
+ case EM_SCROLLCARET:
+ {
+ int top, bottom; /* row's edges relative to document top */
+ ME_DisplayItem *para, *row;
+
+ row = ME_RowStart(editor->pCursors[0].pRun);
+ para = ME_GetParagraph(row);
+ top = para->member.para.nYPos + row->member.row.nYPos;
+ bottom = top + row->member.row.nHeight;
+
+ if ((top < editor->nScrollPosY)
+ || (editor->nScrollPosY + editor->sizeWindow.cy < bottom))
+ {
+ int dy;
+ int prevScrollPosY = editor->nScrollPosY;
+
+ if (top < editor->nScrollPosY) /* caret above window */
+ editor->nScrollPosY = top;
+ else /* caret below window */
+ editor->nScrollPosY = bottom - editor->sizeWindow.cy;
+
+ if (editor->nScrollPosY < 0)
+ editor->nScrollPosY = 0;
+
+ dy = prevScrollPosY - editor->nScrollPosY;
+ SetScrollPos(hWnd, SB_VERT, editor->nScrollPosY, TRUE);
+ if (editor->bRedraw)
+ {
+ ScrollWindow(hWnd, 0, dy, NULL, NULL);
+ UpdateWindow(hWnd);
+ }
+ }
+
+ return 0;
+ }
case WM_SETTEXT:
{
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
@@ -1797,6 +1830,13 @@
tr.lpstrText = (WCHAR *)lParam;
return RichEditANSIWndProc(hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
}
+ case EM_GETSCROLLPOS:
+ {
+ POINT *point = (POINT *)lParam;
+ point->x = 0; /* FIXME side scrolling not implemented */
+ point->y = editor->nScrollPosY;
+ return 1;
+ }
case EM_GETTEXTRANGE:
{
TEXTRANGEW *rng = (TEXTRANGEW *)lParam;
Index: tests/editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/tests/editor.c,v
retrieving revision 1.2
diff -u -r1.2 editor.c
--- tests/editor.c 15 Feb 2006 13:04:38 -0000 1.2
+++ tests/editor.c 15 Feb 2006 17:46:55 -0000
@@ -183,6 +183,78 @@
DestroyWindow(hwndRichEdit);
}
+static int get_scroll_pos_y(HWND hwnd)
+{
+ POINT p = {-1, -1};
+ SendMessage(hwnd, EM_GETSCROLLPOS, 0, (LPARAM) &p);
+ ok(p.x != -1 && p.y != -1, "p.x:%ld p.y:%ld\n", p.x, p.y);
+ return p.y;
+}
+
+static void move_cursor(HWND hwnd, long charindex)
+{
+ CHARRANGE cr;
+ cr.cpMax = charindex;
+ cr.cpMin = charindex;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) &cr);
+}
+
+static void line_scroll(HWND hwnd, int amount)
+{
+ SendMessage(hwnd, EM_LINESCROLL, 0, amount);
+}
+
+static void test_EM_SCROLLCARET(void)
+{
+ int prevY, curY;
+ HWND hwndRichEdit = new_richedit(NULL);
+ const char text[] = "aa\n"
+ "this is a long line of text that should be longer than the "
+ "control's width\n"
+ "cc\n"
+ "dd\n"
+ "ee\n"
+ "ff\n"
+ "gg\n"
+ "hh\n";
+
+ /* Can't verify this */
+ SendMessage(hwndRichEdit, EM_SCROLLCARET, 0, 0);
+
+ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text);
+
+ /* Caret above visible window */
+ line_scroll(hwndRichEdit, 3);
+ prevY = get_scroll_pos_y(hwndRichEdit);
+ SendMessage(hwndRichEdit, EM_SCROLLCARET, 0, 0);
+ curY = get_scroll_pos_y(hwndRichEdit);
+ ok(prevY != curY, "%d == %d\n", prevY, curY);
+
+ /* Caret below visible window */
+ move_cursor(hwndRichEdit, sizeof(text) - 1);
+ line_scroll(hwndRichEdit, -3);
+ prevY = get_scroll_pos_y(hwndRichEdit);
+ SendMessage(hwndRichEdit, EM_SCROLLCARET, 0, 0);
+ curY = get_scroll_pos_y(hwndRichEdit);
+ ok(prevY != curY, "%d == %d\n", prevY, curY);
+
+ /* Caret in visible window */
+ move_cursor(hwndRichEdit, sizeof(text) - 2);
+ prevY = get_scroll_pos_y(hwndRichEdit);
+ SendMessage(hwndRichEdit, EM_SCROLLCARET, 0, 0);
+ curY = get_scroll_pos_y(hwndRichEdit);
+ ok(prevY == curY, "%d != %d\n", prevY, curY);
+
+ /* Caret still in visible window */
+ line_scroll(hwndRichEdit, -1);
+ prevY = get_scroll_pos_y(hwndRichEdit);
+ SendMessage(hwndRichEdit, EM_SCROLLCARET, 0, 0);
+ curY = get_scroll_pos_y(hwndRichEdit);
+ ok(prevY == curY, "%d != %d\n", prevY, curY);
+
+ DestroyWindow(hwndRichEdit);
+}
+
START_TEST( editor )
{
MSG msg;
@@ -194,6 +266,7 @@
ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
test_EM_FINDTEXT();
+ test_EM_SCROLLCARET();
/* Set the environment variable WINETEST_RICHED20 to keep windows
* responsive and open for 30 seconds. This is useful for debugging.
More information about the wine-patches
mailing list