diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 53cddd0b9d5..feb99c30eb8 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1313,7 +1313,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX) UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */ UNSUPPORTED_MSG(EM_PASTESPECIAL) - UNSUPPORTED_MSG(EM_SCROLL) UNSUPPORTED_MSG(EM_SELECTIONTYPE) UNSUPPORTED_MSG(EM_SETBIDIOPTIONS) UNSUPPORTED_MSG(EM_SETEDITSTYLE) @@ -2132,21 +2131,29 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP } return 0; } + case EM_SCROLL: /* fall through */ case WM_VSCROLL: { + int nEnd; int nPos = editor->nScrollPosY; + int origNPos = nPos; + int lineHeight = 24; si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_PAGE|SIF_POS|SIF_RANGE|SIF_TRACKPOS; GetScrollInfo(hWnd, SB_VERT, &si); + if (editor && editor->pBuffer && editor->pBuffer->pDefaultStyle) + lineHeight = editor->pBuffer->pDefaultStyle->tm.tmHeight; + if (lineHeight <= 0) lineHeight = 24; switch(LOWORD(wParam)) { case SB_LINEUP: - nPos -= 24; /* FIXME follow the original */ + nPos -= lineHeight; if (nPos<0) nPos = 0; break; case SB_LINEDOWN: { - int nEnd = editor->nTotalLength - editor->sizeWindow.cy; - nPos += 24; /* FIXME follow the original */ + nEnd = editor->nTotalLength - editor->sizeWindow.cy; + if (nEnd < 0) nEnd = 0; + nPos += lineHeight; if (nPos>=nEnd) nPos = nEnd; break; } @@ -2155,8 +2162,10 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP if (nPos<0) nPos = 0; break; case SB_PAGEDOWN: + nEnd = editor->nTotalLength - editor->sizeWindow.cy; + if (nEnd < 0) nEnd = 0; nPos += editor->sizeWindow.cy; - if (nPos>=editor->nTotalLength) nPos = editor->nTotalLength-1; + if (nPos>=nEnd) nPos = nEnd; break; case SB_THUMBTRACK: case SB_THUMBPOSITION: @@ -2173,6 +2182,8 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP UpdateWindow(hWnd); } } + if (msg == EM_SCROLL) + return 0x00010000 | (((nPos - origNPos)/lineHeight) & 0xffff); break; } case WM_MOUSEWHEEL: diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index aae34867eea..4f34a6620be 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -536,6 +536,147 @@ static void test_EM_SETOPTIONS() DestroyWindow(hwndRichEdit); } +static void test_EM_SCROLL() +{ + int i, j; + int r; /* return value */ + int expr; /* expected return value */ + HWND hwndRichEdit = new_richedit(NULL); + int y_before, y_after; /* units of lines of text */ + + /* test a richedit box containing a single line of text */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "a");/* one line of text */ + expr = 0x00010000; + for (i = 0; i < 4; i++) { + int cmd; + switch (i) { + case 0: cmd = SB_PAGEDOWN; break; + case 1: cmd = SB_PAGEUP; break; + case 2: cmd = SB_LINEDOWN; break; + case 3: cmd = SB_LINEUP; break; + } + + r = SendMessage(hwndRichEdit, EM_SCROLL, cmd, 0); + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + ok(expr == r, "EM_SCROLL improper return value returned (i == %d). " + "Got 0x%08x, expected 0x%08x\n", i, r, expr); + ok(y_after == 0, "EM_SCROLL improper scroll. scrolled to line %d, not 1 " + "(i == %d)\n", y_after, i); + } + + /* + * test a richedit box that will scroll. There are two general + * cases: the case without any long lines and the case with a long + * line. + */ + for (i = 0; i < 2; i++) { /* iterate through different bodies of text */ + if (i == 0) + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) "a\nb\nc\nd\ne"); + else + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) + "a LONG LINE LONG LINE LONG LINE LONG LINE LONG LINE " + "LONG LINE LONG LINE LONG LINE LONG LINE LONG LINE " + "LONG LINE \nb\nc\nd\ne"); + for (j = 0; j < 12; j++) /* reset scrol position to top */ + SendMessage(hwndRichEdit, EM_SCROLL, SB_PAGEUP, 0); + + /* get first visible line */ + y_before = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + r = SendMessage(hwndRichEdit, EM_SCROLL, SB_PAGEDOWN, 0); /* page down */ + + /* get new current first visible line */ + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(((r & 0xffffff00) == 0x00010000) && + ((r & 0x000000ff) != 0x00000000), + "EM_SCROLL page down didn't scroll by a small positive number of " + "lines (r == 0x%08x)\n", r); + ok(y_after > y_before, "EM_SCROLL page down not functioning " + "(line %d scrolled to line %d\n", y_before, y_after); + + y_before = y_after; + + r = SendMessage(hwndRichEdit, EM_SCROLL, SB_PAGEUP, 0); /* page up */ + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + ok(((r & 0xffffff00) == 0x0001ff00), + "EM_SCROLL page up didn't scroll by a small negative number of lines " + "(r == 0x%08x)\n", r); + ok(y_after < y_before, "EM_SCROLL page up not functioning (line " + "%d scrolled to line %d\n", y_before, y_after); + + y_before = y_after; + + r = SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEDOWN, 0); /* line down */ + + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(r == 0x00010001, "EM_SCROLL line down didn't scroll by one line " + "(r == 0x%08x)\n", r); + ok(y_after -1 == y_before, "EM_SCROLL line down didn't go down by " + "1 line (%d scrolled to %d)\n", y_before, y_after); + + y_before = y_after; + + r = SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEUP, 0); /* line up */ + + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(r == 0x0001ffff, "EM_SCROLL line up didn't scroll by one line " + "(r == 0x%08x)\n", r); + ok(y_after +1 == y_before, "EM_SCROLL line up didn't go up by 1 " + "line (%d scrolled to %d)\n", y_before, y_after); + + y_before = y_after; + + r = SendMessage(hwndRichEdit, EM_SCROLL, + SB_LINEUP, 0); /* lineup beyond top */ + + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(r == 0x00010000, + "EM_SCROLL line up returned indicating movement (0x%08x)\n", r); + ok(y_before == y_after, + "EM_SCROLL line up beyond top worked (%d)\n", y_after); + + y_before = y_after; + + r = SendMessage(hwndRichEdit, EM_SCROLL, + SB_PAGEUP, 0);/*page up beyond top */ + + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(r == 0x00010000, + "EM_SCROLL page up returned indicating movement (0x%08x)\n", r); + ok(y_before == y_after, + "EM_SCROLL page up beyond top worked (%d)\n", y_after); + + for (j = 0; j < 12; j++) /* page down all the way to the bottom */ + SendMessage(hwndRichEdit, EM_SCROLL, SB_PAGEDOWN, 0); + y_before = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + r = SendMessage(hwndRichEdit, EM_SCROLL, + SB_PAGEDOWN, 0); /* page down beyond bot */ + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(r == 0x00010000, + "EM_SCROLL page down returned indicating movement (0x%08x)\n", r); + ok(y_before == y_after, + "EM_SCROLL page down beyond bottom worked (%d -> %d)\n", + y_before, y_after); + + y_before = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + SendMessage(hwndRichEdit, EM_SCROLL, + SB_LINEDOWN, 0); /* line down beyond bot */ + y_after = SendMessage(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); + + ok(r == 0x00010000, + "EM_SCROLL line down returned indicating movement (0x%08x)\n", r); + ok(y_before == y_after, + "EM_SCROLL line down beyond bottom worked (%d -> %d)\n", + y_before, y_after); + } + DestroyWindow(hwndRichEdit); +} + START_TEST( editor ) { MSG msg; @@ -548,6 +689,7 @@ START_TEST( editor ) test_EM_FINDTEXT(); test_EM_SCROLLCARET(); + test_EM_SCROLL(); test_EM_SETTEXTMODE(); test_TM_PLAINTEXT(); test_EM_SETOPTIONS();