Thomas Kho : riched20: Implement EM_SCROLLCARET and EM_GETSCROLLPOS.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Feb 16 14:05:55 CST 2006


Module: wine
Branch: refs/heads/master
Commit: bfb3c756eb5f956904e5f3154eb09be34aa63e94
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=bfb3c756eb5f956904e5f3154eb09be34aa63e94

Author: Thomas Kho <tkho at ucla.edu>
Date:   Thu Feb 16 19:33:19 2006 +0100

riched20: Implement EM_SCROLLCARET and EM_GETSCROLLPOS.

---

 dlls/riched20/editor.c       |   48 +++++++++++++++++++++++++---
 dlls/riched20/tests/editor.c |   73 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 4 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index a9e6937..fd3137a 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -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 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
   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 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
   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 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
     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 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
     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 --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index 7eb24ac..908bb90 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -183,6 +183,78 @@ static void test_EM_FINDTEXT(void)
   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 @@ START_TEST( editor )
   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-cvs mailing list