riched20: implement EM_SCROLLCARET and EM_GETSCROLLPOS

tkho at ucla.edu tkho at ucla.edu
Thu Feb 9 21:19:11 CST 2006


Hi,

This patch both implements and adds conformance tests for EM_SCROLLCARET and
EM_GETSCROLLPOS. It applies on top of the patch that adds EM_FINDTEXT
conformance tests

2006-02-09 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_GETSCROLPOS 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>
diff -Naur ../patch1/dlls/riched20/editor.c ./dlls/riched20/editor.c
--- ../patch1/dlls/riched20/editor.c	2006-02-09 11:53:57.000000000 -0800
+++ ./dlls/riched20/editor.c	2006-02-09 11:54:16.000000000 -0800
@@ -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
@@ -1284,7 +1284,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)
@@ -1293,7 +1292,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)
@@ -1594,6 +1592,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));
@@ -1754,6 +1787,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;
diff -Naur ../patch1/dlls/riched20/tests/editor.c ./dlls/riched20/tests/editor.c
--- ../patch1/dlls/riched20/tests/editor.c	2006-02-09 11:53:10.000000000 -0800
+++ ./dlls/riched20/tests/editor.c	2006-02-09 11:54:16.000000000 -0800
@@ -181,6 +181,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;
@@ -192,6 +264,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