diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 5556315..7b7818b 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -1237,6 +1237,7 @@ static BOOL SCROLL_GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO in INT nDummy; DWORD style = GetWindowLongW(hwnd, GWL_STYLE); BOOL pressed; + RECT rect; switch (idObject) { @@ -1252,6 +1253,9 @@ static BOOL SCROLL_GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO in SCROLL_GetScrollBarRect(hwnd, nBar, &info->rcScrollBar, &nDummy, &info->dxyLineButton, &info->xyThumbTop); + /* rcScrollBar needs to be in screen coordinates */ + GetWindowRect(hwnd, &rect); + OffsetRect(&info->rcScrollBar, rect.left, rect.top); info->xyThumbBottom = info->xyThumbTop + info->dxyLineButton; diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 3bc407a..62513fa 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -127,6 +127,66 @@ static void scrollbar_test3(void) } +static void scrollbar_test4(void) +{ + BOOL ret; + SCROLLBARINFO sbi; + RECT rect; + + /* Test GetScrollBarInfo to make sure it returns rcScrollBar in screen + * coordinates. */ + sbi.cbSize = sizeof(sbi); + ret = GetScrollBarInfo( hScroll, OBJID_CLIENT, &sbi); + ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); + GetWindowRect( hScroll, &rect ); + ok( ret, "The GetWindowRect() call should not fail.\n" ); + ok( !(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)), + "unexpected rgstate(0x%x)\n", sbi.rgstate[0]); + ok( EqualRect(&rect, &sbi.rcScrollBar), + "WindowRect(%d, %d, %d, %d) != rcScrollBar(%d, %d, %d, %d)\n", + rect.top, rect.left, rect.bottom, rect.right, + sbi.rcScrollBar.top, sbi.rcScrollBar.left, + sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); + + /* Test windows horizontal and vertical scrollbar to make sure rcScrollBar + * is still returned in screen coordinates by moving the window, and + * making sure that it shifts the rcScrollBar value. */ + ShowWindow( hMainWnd, SW_SHOW ); + sbi.cbSize = sizeof(sbi); + ret = GetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi); + ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); + GetWindowRect( hMainWnd, &rect ); + ok( ret, "The GetWindowRect() call should not fail.\n" ); + MoveWindow( hMainWnd, rect.left+5, rect.top+5, + rect.right-rect.left, rect.bottom-rect.top, TRUE ); + rect = sbi.rcScrollBar; + OffsetRect(&rect, 5, 5); + ret = GetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi); + ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); + ok( EqualRect(&rect, &sbi.rcScrollBar), + "PreviousRect(%d, %d, %d, %d) != CurrentRect(%d, %d, %d, %d)\n", + rect.top, rect.left, rect.bottom, rect.right, + sbi.rcScrollBar.top, sbi.rcScrollBar.left, + sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); + + sbi.cbSize = sizeof(sbi); + ret = GetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi); + ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); + GetWindowRect( hMainWnd, &rect ); + ok( ret, "The GetWindowRect() call should not fail.\n" ); + MoveWindow( hMainWnd, rect.left+5, rect.top+5, + rect.right-rect.left, rect.bottom-rect.top, TRUE ); + rect = sbi.rcScrollBar; + OffsetRect(&rect, 5, 5); + ret = GetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi); + ok( ret, "The GetScrollBarInfo() call should not fail.\n" ); + ok( EqualRect(&rect, &sbi.rcScrollBar), + "PreviousRect(%d, %d, %d, %d) != CurrentRect(%d, %d, %d, %d)\n", + rect.top, rect.left, rect.bottom, rect.right, + sbi.rcScrollBar.top, sbi.rcScrollBar.left, + sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); +} + START_TEST ( scroll ) { WNDCLASSA wc; @@ -143,7 +203,8 @@ START_TEST ( scroll ) wc.lpfnWndProc = MyWndProc; RegisterClassA(&wc); - hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll", WS_OVERLAPPEDWINDOW, + hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll", + WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0 ); if ( !ok( hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n" ) ) @@ -154,6 +215,7 @@ START_TEST ( scroll ) scrollbar_test1(); scrollbar_test2(); scrollbar_test3(); + scrollbar_test4(); DestroyWindow(hScroll); DestroyWindow(hMainWnd);