diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index e3ec37c46d..bf30c97478 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -406,9 +406,8 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa if (!wndPtr) return 0; HeapFree( GetProcessHeap(), 0, wndPtr->text ); wndPtr->text = NULL; - HeapFree( GetProcessHeap(), 0, wndPtr->pVScroll ); - HeapFree( GetProcessHeap(), 0, wndPtr->pHScroll ); - wndPtr->pVScroll = wndPtr->pHScroll = NULL; + HeapFree( GetProcessHeap(), 0, wndPtr->pScroll ); + wndPtr->pScroll = NULL; WIN_ReleasePtr( wndPtr ); return 0; } diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 93f85f2bb8..52c350cdff 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -41,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll); +/* data for a single scroll bar */ typedef struct { INT curVal; /* Current scroll-bar value */ @@ -50,6 +51,12 @@ typedef struct UINT flags; /* EnableScrollBar flags */ } SCROLLBAR_INFO, *LPSCROLLBAR_INFO; +/* data for window that has (one or two) scroll bars */ +typedef struct +{ + SCROLLBAR_INFO horz; + SCROLLBAR_INFO vert; +} WINSCROLLBAR_INFO, *LPWINSCROLLBAR_INFO; /* Minimum size of the rectangle between the arrows */ #define SCROLL_MIN_RECT 4 @@ -156,26 +163,39 @@ static SCROLLBAR_INFO *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc ) if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return NULL; switch(nBar) { - case SB_HORZ: infoPtr = wndPtr->pHScroll; break; - case SB_VERT: infoPtr = wndPtr->pVScroll; break; - case SB_CTL: infoPtr = (SCROLLBAR_INFO *)wndPtr->wExtra; break; - case SB_BOTH: WARN("with SB_BOTH\n"); break; + case SB_HORZ: + if (wndPtr->pScroll) infoPtr = &((LPWINSCROLLBAR_INFO)wndPtr->pScroll)->horz; + break; + case SB_VERT: + if (wndPtr->pScroll) infoPtr = &((LPWINSCROLLBAR_INFO)wndPtr->pScroll)->vert; + break; + case SB_CTL: + infoPtr = (SCROLLBAR_INFO *)wndPtr->wExtra; + break; + case SB_BOTH: + WARN("with SB_BOTH\n"); + break; } if (!infoPtr && alloc) { + WINSCROLLBAR_INFO *winInfoPtr; + if (nBar != SB_HORZ && nBar != SB_VERT) WARN("Cannot initialize nBar=%d\n",nBar); - else if ((infoPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(SCROLLBAR_INFO) ))) + else if ((winInfoPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(WINSCROLLBAR_INFO) ))) { /* Set default values */ - infoPtr->minVal = infoPtr->curVal = infoPtr->page = 0; - /* From MSDN: max for a standard scroll bar is 100 by default. */ - infoPtr->maxVal = 100; - /* Scroll bar is enabled by default after create */ - infoPtr->flags = ESB_ENABLE_BOTH; - if (nBar == SB_HORZ) wndPtr->pHScroll = infoPtr; - else wndPtr->pVScroll = infoPtr; + winInfoPtr->horz.minVal = 0; + winInfoPtr->horz.curVal = 0; + winInfoPtr->horz.page = 0; + /* From MSDN and our own tests: + * max for a standard scroll bar is 100 by default. */ + winInfoPtr->horz.maxVal = 100; + winInfoPtr->horz.flags = ESB_ENABLE_BOTH; + winInfoPtr->vert = winInfoPtr->horz; + wndPtr->pScroll = winInfoPtr; + infoPtr = nBar == SB_HORZ ? &winInfoPtr->horz : &winInfoPtr->vert; } } WIN_ReleasePtr( wndPtr ); diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 0c36ff82bd..6082d6f298 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -211,6 +211,7 @@ static void scrollbar_test4(void) static void scrollbar_test_default( DWORD style) { INT min, max, ret; + DWORD winstyle; HWND hwnd; SCROLLINFO si = { sizeof( SCROLLINFO), SIF_TRACKPOS }; @@ -226,6 +227,7 @@ static void scrollbar_test_default( DWORD style) ok( min == 0 && max == 0, "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style); else +todo_wine ok( min == 0 && max == 100, "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); ret = GetScrollRange( hwnd, SB_HORZ, &min, &max); @@ -236,6 +238,7 @@ static void scrollbar_test_default( DWORD style) ok( min == 0 && max == 0, "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style); else +todo_wine ok( min == 0 && max == 100, "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); /* test GetScrollInfo, vist for vertical SB */ @@ -244,6 +247,7 @@ static void scrollbar_test_default( DWORD style) if( !( style & ( WS_VSCROLL | WS_HSCROLL))) ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); else +todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); /* Same for Horizontal SB */ ret = GetScrollInfo( hwnd, SB_HORZ, &si); @@ -251,6 +255,7 @@ static void scrollbar_test_default( DWORD style) if( !( style & ( WS_VSCROLL | WS_HSCROLL))) ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); else +todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); /* now set the Vertical Scroll range to something that could be the default value it * already has */; @@ -260,17 +265,23 @@ static void scrollbar_test_default( DWORD style) ret = GetScrollRange( hwnd, SB_HORZ, &min, &max); ok( ret, "GetScrollRange failed.\n"); /* now the range should be 0,100 in ALL cases */ -todo_wine ok( min == 0 && max == 100, "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); /* See what is different now for GetScrollRange */ ret = GetScrollInfo( hwnd, SB_HORZ, &si); /* should succeed in ALL cases */ -todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); ret = GetScrollInfo( hwnd, SB_VERT, &si); /* should succeed in ALL cases */ ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + /* report the windows style */ + winstyle = GetWindowLongW( hwnd, GWL_STYLE ); + /* WS_VSCROLL added to the window style */ +todo_wine + if( !(style & WS_VSCROLL)) + ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == ( style | WS_VSCROLL), + "unexpected style change %8lx expected %8lx\n", + (winstyle & (WS_HSCROLL|WS_VSCROLL)), style | WS_VSCROLL); /* do the test again with H and V reversed. * Start with a clean window */ DestroyWindow( hwnd); @@ -285,7 +296,6 @@ todo_wine ret = GetScrollRange( hwnd, SB_VERT, &min, &max); ok( ret, "GetScrollRange failed.\n"); /* now the range should be 0,100 in ALL cases */ -todo_wine ok( min == 0 && max == 100, "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); /* See what is different now for GetScrollRange */ @@ -294,9 +304,16 @@ todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); ret = GetScrollInfo( hwnd, SB_VERT, &si); /* should succeed in ALL cases */ -todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); - /* Slightly change the test to muse SetScrollInfo + /* report the windows style */ + winstyle = GetWindowLongW( hwnd, GWL_STYLE ); + /* WS_HSCROLL added to the window style */ +todo_wine + if( !(style & WS_HSCROLL)) + ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == ( style | WS_HSCROLL), + "unexpected style change %8lx expected %8lx\n", + (winstyle & (WS_HSCROLL|WS_VSCROLL)), style | WS_HSCROLL); + /* Slightly change the test to use SetScrollInfo * Start with a clean window */ DestroyWindow( hwnd); hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style, @@ -313,7 +330,6 @@ todo_wine ret = GetScrollRange( hwnd, SB_VERT, &min, &max); ok( ret, "GetScrollRange failed.\n"); /* now the range should be 0,100 in ALL cases */ -todo_wine ok( min == 0 && max == 100, "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); /* See what is different now for GetScrollRange */ @@ -322,9 +338,31 @@ todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); ret = GetScrollInfo( hwnd, SB_VERT, &si); /* should succeed in ALL cases */ -todo_wine ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); - /* clean up */ + /* also test if the window scroll bars are enabled */ + ret = EnableScrollBar( hwnd, SB_VERT, ESB_ENABLE_BOTH); + ok( !ret, "Vertical window scroll bar was not enabled\n"); + ret = EnableScrollBar( hwnd, SB_HORZ, ESB_ENABLE_BOTH); + ok( !ret, "Horizontal window scroll bar was not enabled\n"); + DestroyWindow( hwnd); + /* finally, check if adding a WS_[HV]SColl style of a window makes the scroll info + * available */ + if( style & (WS_HSCROLL | WS_VSCROLL)) return;/* only test if not yet set */ + /* Start with a clean window */ + DestroyWindow( hwnd); + hwnd = CreateWindowExA( 0, "static", "", WS_POPUP , + 0, 0, 10, 10, 0, 0, 0, NULL); + assert( hwnd != 0); + ret = GetScrollInfo( hwnd, SB_VERT, &si); + /* should fail */ + ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); + /* add scroll styles */ + winstyle = GetWindowLongW( hwnd, GWL_STYLE ); + SetWindowLongW( hwnd, GWL_STYLE, winstyle | WS_VSCROLL | WS_HSCROLL); + ret = GetScrollInfo( hwnd, SB_VERT, &si); + /* should still fail */ + ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); + /* clean up */ DestroyWindow( hwnd); } @@ -359,11 +397,10 @@ START_TEST ( scroll ) scrollbar_test4(); scrollbar_test_default( 0); -if( 0) { /* enable this when the todo's in scrollbar_test_default are fixed */ scrollbar_test_default( WS_HSCROLL); scrollbar_test_default( WS_VSCROLL); scrollbar_test_default( WS_HSCROLL | WS_VSCROLL); -} + DestroyWindow(hScroll); DestroyWindow(hMainWnd); } diff --git a/dlls/user32/win.c b/dlls/user32/win.c index ab0ab59405..7e599baa05 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -1073,8 +1073,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags wndPtr->dwExStyle = cs->dwExStyle; wndPtr->wIDmenu = 0; wndPtr->helpContext = 0; - wndPtr->pVScroll = NULL; - wndPtr->pHScroll = NULL; + wndPtr->pScroll = NULL; wndPtr->userdata = 0; wndPtr->hIcon = 0; wndPtr->hIconSmall = 0; diff --git a/dlls/user32/win.h b/dlls/user32/win.h index 447f4fd24d..5cd879ab5f 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -51,8 +51,7 @@ typedef struct tagWND POINT max_pos; /* Position for maximized window */ HWND icon_title; /* Icon title window */ LPWSTR text; /* Window text */ - void *pVScroll; /* Vertical scroll-bar info */ - void *pHScroll; /* Horizontal scroll-bar info */ + void *pScroll; /* Scroll-bar info */ DWORD dwStyle; /* Window style (from CreateWindow) */ DWORD dwExStyle; /* Extended style (from CreateWindowEx) */ UINT_PTR wIDmenu; /* ID or hmenu (from CreateWindow) */