1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * Unit tests for scrollbar
3*c2c66affSColin Finck  *
4*c2c66affSColin Finck  * Copyright 2008 Lyutin Anatoly (Etersoft)
5*c2c66affSColin Finck  *
6*c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7*c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8*c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9*c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10*c2c66affSColin Finck  *
11*c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12*c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*c2c66affSColin Finck  * Lesser General Public License for more details.
15*c2c66affSColin Finck  *
16*c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17*c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18*c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19*c2c66affSColin Finck  */
20*c2c66affSColin Finck 
21*c2c66affSColin Finck #include <assert.h>
22*c2c66affSColin Finck #include <stdarg.h>
23*c2c66affSColin Finck #include <stdio.h>
24*c2c66affSColin Finck #include <windows.h>
25*c2c66affSColin Finck 
26*c2c66affSColin Finck #include "wine/test.h"
27*c2c66affSColin Finck 
28*c2c66affSColin Finck static HWND hScroll;
29*c2c66affSColin Finck static BOOL bThemeActive = FALSE;
30*c2c66affSColin Finck 
31*c2c66affSColin Finck static LRESULT CALLBACK MyWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
32*c2c66affSColin Finck {
33*c2c66affSColin Finck     switch(msg)
34*c2c66affSColin Finck     {
35*c2c66affSColin Finck 
36*c2c66affSColin Finck     case WM_CREATE:
37*c2c66affSColin Finck     {
38*c2c66affSColin Finck         hScroll = CreateWindowA( "SCROLLBAR", "", WS_CHILD | WS_VISIBLE, 0, 0, 120, 100, hWnd, (HMENU)100, GetModuleHandleA(0), 0 );
39*c2c66affSColin Finck 
40*c2c66affSColin Finck         return 0;
41*c2c66affSColin Finck     }
42*c2c66affSColin Finck     case WM_DESTROY:
43*c2c66affSColin Finck         PostQuitMessage(0);
44*c2c66affSColin Finck         break;
45*c2c66affSColin Finck     case WM_HSCROLL:
46*c2c66affSColin Finck     case WM_VSCROLL:
47*c2c66affSColin Finck         /* stop tracking */
48*c2c66affSColin Finck         ReleaseCapture();
49*c2c66affSColin Finck         return 0;
50*c2c66affSColin Finck     default:
51*c2c66affSColin Finck         return DefWindowProcA(hWnd, msg, wParam, lParam);
52*c2c66affSColin Finck     }
53*c2c66affSColin Finck     return 0;
54*c2c66affSColin Finck }
55*c2c66affSColin Finck 
56*c2c66affSColin Finck static HWND create_main_test_wnd(void)
57*c2c66affSColin Finck {
58*c2c66affSColin Finck     HWND hMainWnd;
59*c2c66affSColin Finck 
60*c2c66affSColin Finck     hScroll = NULL;
61*c2c66affSColin Finck     hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll",
62*c2c66affSColin Finck       WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
63*c2c66affSColin Finck       CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0 );
64*c2c66affSColin Finck     ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
65*c2c66affSColin Finck     ok(hScroll != NULL, "got NULL scroll bar handle\n");
66*c2c66affSColin Finck 
67*c2c66affSColin Finck     return hMainWnd;
68*c2c66affSColin Finck }
69*c2c66affSColin Finck 
70*c2c66affSColin Finck static void scrollbar_test_track(void)
71*c2c66affSColin Finck {
72*c2c66affSColin Finck     HWND mainwnd;
73*c2c66affSColin Finck 
74*c2c66affSColin Finck     mainwnd = create_main_test_wnd();
75*c2c66affSColin Finck 
76*c2c66affSColin Finck     /* test that scrollbar tracking is terminated when
77*c2c66affSColin Finck      * the control loses mouse capture */
78*c2c66affSColin Finck     SendMessageA( hScroll, WM_LBUTTONDOWN, 0, MAKELPARAM( 1, 1));
79*c2c66affSColin Finck     /* a normal return from SendMessage */
80*c2c66affSColin Finck     /* not normal for instances such as closing the window */
81*c2c66affSColin Finck     ok( IsWindow( hScroll), "Scrollbar has gone!\n");
82*c2c66affSColin Finck 
83*c2c66affSColin Finck     DestroyWindow(hScroll);
84*c2c66affSColin Finck     DestroyWindow(mainwnd);
85*c2c66affSColin Finck }
86*c2c66affSColin Finck 
87*c2c66affSColin Finck static void test_EnableScrollBar(void)
88*c2c66affSColin Finck {
89*c2c66affSColin Finck     HWND mainwnd;
90*c2c66affSColin Finck     BOOL ret;
91*c2c66affSColin Finck 
92*c2c66affSColin Finck     mainwnd = create_main_test_wnd();
93*c2c66affSColin Finck 
94*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_BOTH );
95*c2c66affSColin Finck     ok( ret, "The scrollbar should be disabled.\n" );
96*c2c66affSColin Finck     ok( !IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" );
97*c2c66affSColin Finck 
98*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH );
99*c2c66affSColin Finck     ok( ret, "The scrollbar should be enabled.\n" );
100*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" );
101*c2c66affSColin Finck 
102*c2c66affSColin Finck     /* test buttons separately */
103*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_LTUP );
104*c2c66affSColin Finck     ok( ret, "The scrollbar LTUP button should be disabled.\n" );
105*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" );
106*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH );
107*c2c66affSColin Finck     ok( ret, "The scrollbar should be enabled.\n" );
108*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" );
109*c2c66affSColin Finck 
110*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_RTDN );
111*c2c66affSColin Finck     ok( ret, "The scrollbar RTDN button should be disabled.\n" );
112*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" );
113*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH );
114*c2c66affSColin Finck     ok( ret, "The scrollbar should be enabled.\n" );
115*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" );
116*c2c66affSColin Finck 
117*c2c66affSColin Finck     /* disable window, try to re-enable */
118*c2c66affSColin Finck     ret = EnableWindow( hScroll, FALSE );
119*c2c66affSColin Finck     ok( !ret, "got %d\n", ret );
120*c2c66affSColin Finck     ok( !IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" );
121*c2c66affSColin Finck 
122*c2c66affSColin Finck     ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH );
123*c2c66affSColin Finck     ok( ret, "got %d\n", ret );
124*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" );
125*c2c66affSColin Finck 
126*c2c66affSColin Finck     DestroyWindow(hScroll);
127*c2c66affSColin Finck     DestroyWindow(mainwnd);
128*c2c66affSColin Finck }
129*c2c66affSColin Finck 
130*c2c66affSColin Finck static void test_SetScrollPos(void)
131*c2c66affSColin Finck {
132*c2c66affSColin Finck     HWND mainwnd;
133*c2c66affSColin Finck     int ret;
134*c2c66affSColin Finck 
135*c2c66affSColin Finck     mainwnd = create_main_test_wnd();
136*c2c66affSColin Finck 
137*c2c66affSColin Finck     EnableWindow( hScroll, FALSE );
138*c2c66affSColin Finck     ok( !IsWindowEnabled( hScroll ), "The scroll should be disabled.\n" );
139*c2c66affSColin Finck 
140*c2c66affSColin Finck     ret = SetScrollPos( hScroll, SB_CTL, 30, TRUE);
141*c2c66affSColin Finck     ok( !ret, "The position should not be set.\n" );
142*c2c66affSColin Finck 
143*c2c66affSColin Finck     ret = GetScrollPos( hScroll, SB_CTL);
144*c2c66affSColin Finck     ok( !ret, "The position should be equal to zero\n");
145*c2c66affSColin Finck 
146*c2c66affSColin Finck     ret = SetScrollRange( hScroll, SB_CTL, 0, 100, TRUE );
147*c2c66affSColin Finck     ok( ret, "The range should be set.\n" );
148*c2c66affSColin Finck 
149*c2c66affSColin Finck     ret = SetScrollPos( hScroll, SB_CTL, 30, TRUE);
150*c2c66affSColin Finck     ok( !ret , "The position should not be set.\n" );
151*c2c66affSColin Finck 
152*c2c66affSColin Finck     ret = GetScrollPos( hScroll, SB_CTL);
153*c2c66affSColin Finck     ok( ret == 30, "The position should be set!!!\n");
154*c2c66affSColin Finck 
155*c2c66affSColin Finck     EnableWindow( hScroll, TRUE );
156*c2c66affSColin Finck     ok( IsWindowEnabled( hScroll ), "The scroll should be enabled.\n" );
157*c2c66affSColin Finck 
158*c2c66affSColin Finck     ret = SetScrollPos( hScroll, SB_CTL, 30, TRUE);
159*c2c66affSColin Finck     ok( ret == 30, "The position should be set.\n" );
160*c2c66affSColin Finck 
161*c2c66affSColin Finck     ret = GetScrollPos( hScroll, SB_CTL);
162*c2c66affSColin Finck     ok( ret == 30, "The position should not be equal to zero\n");
163*c2c66affSColin Finck 
164*c2c66affSColin Finck     ret = SetScrollRange( hScroll, SB_CTL, 0, 100, TRUE );
165*c2c66affSColin Finck     ok( ret, "The range should be set.\n" );
166*c2c66affSColin Finck 
167*c2c66affSColin Finck     ret = SetScrollPos( hScroll, SB_CTL, 30, TRUE);
168*c2c66affSColin Finck     ok( ret == 30, "The position should be set.\n" );
169*c2c66affSColin Finck 
170*c2c66affSColin Finck     ret = GetScrollPos( hScroll, SB_CTL);
171*c2c66affSColin Finck     ok( ret == 30, "The position should not be equal to zero\n");
172*c2c66affSColin Finck 
173*c2c66affSColin Finck     DestroyWindow(hScroll);
174*c2c66affSColin Finck     DestroyWindow(mainwnd);
175*c2c66affSColin Finck }
176*c2c66affSColin Finck 
177*c2c66affSColin Finck static void test_ShowScrollBar(void)
178*c2c66affSColin Finck {
179*c2c66affSColin Finck     HWND mainwnd;
180*c2c66affSColin Finck     BOOL    ret;
181*c2c66affSColin Finck 
182*c2c66affSColin Finck     mainwnd = create_main_test_wnd();
183*c2c66affSColin Finck 
184*c2c66affSColin Finck     ret = ShowScrollBar( hScroll, SB_CTL, FALSE );
185*c2c66affSColin Finck     ok( ret, "The ShowScrollBar() should not failed.\n" );
186*c2c66affSColin Finck     ok( !IsWindowVisible( hScroll ), "The scrollbar window should not be visible\n" );
187*c2c66affSColin Finck 
188*c2c66affSColin Finck     ret = ShowScrollBar( hScroll, SB_CTL, TRUE );
189*c2c66affSColin Finck     ok( ret, "The ShowScrollBar() should not failed.\n" );
190*c2c66affSColin Finck     ok( !IsWindowVisible( hScroll ), "The scrollbar window should be visible\n" );
191*c2c66affSColin Finck 
192*c2c66affSColin Finck     ret = ShowScrollBar( NULL, SB_CTL, TRUE );
193*c2c66affSColin Finck     ok( !ret, "The ShowScrollBar() should failed.\n" );
194*c2c66affSColin Finck 
195*c2c66affSColin Finck     DestroyWindow(hScroll);
196*c2c66affSColin Finck     DestroyWindow(mainwnd);
197*c2c66affSColin Finck }
198*c2c66affSColin Finck 
199*c2c66affSColin Finck static void test_GetScrollBarInfo(void)
200*c2c66affSColin Finck {
201*c2c66affSColin Finck     HWND hMainWnd;
202*c2c66affSColin Finck     BOOL ret;
203*c2c66affSColin Finck     SCROLLBARINFO sbi;
204*c2c66affSColin Finck     RECT rect;
205*c2c66affSColin Finck     BOOL (WINAPI *pGetScrollBarInfo)(HWND, LONG, LPSCROLLBARINFO);
206*c2c66affSColin Finck 
207*c2c66affSColin Finck     pGetScrollBarInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetScrollBarInfo");
208*c2c66affSColin Finck     if (!pGetScrollBarInfo)
209*c2c66affSColin Finck     {
210*c2c66affSColin Finck         win_skip("GetScrollBarInfo is not available\n");
211*c2c66affSColin Finck         return;
212*c2c66affSColin Finck     }
213*c2c66affSColin Finck 
214*c2c66affSColin Finck     hMainWnd = create_main_test_wnd();
215*c2c66affSColin Finck 
216*c2c66affSColin Finck     /* Test GetScrollBarInfo to make sure it returns rcScrollBar in screen
217*c2c66affSColin Finck      * coordinates. */
218*c2c66affSColin Finck     sbi.cbSize = sizeof(sbi);
219*c2c66affSColin Finck     ret = pGetScrollBarInfo( hScroll, OBJID_CLIENT, &sbi);
220*c2c66affSColin Finck     ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
221*c2c66affSColin Finck     GetWindowRect( hScroll, &rect );
222*c2c66affSColin Finck     ok( ret, "The GetWindowRect() call should not fail.\n" );
223*c2c66affSColin Finck     ok( !(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)),
224*c2c66affSColin Finck         "unexpected rgstate(0x%x)\n", sbi.rgstate[0]);
225*c2c66affSColin Finck     ok(EqualRect(&rect, &sbi.rcScrollBar), "WindowRect %s != rcScrollBar %s\n",
226*c2c66affSColin Finck        wine_dbgstr_rect(&rect), wine_dbgstr_rect(&sbi.rcScrollBar));
227*c2c66affSColin Finck 
228*c2c66affSColin Finck     /* Test windows horizontal and vertical scrollbar to make sure rcScrollBar
229*c2c66affSColin Finck      * is still returned in screen coordinates by moving the window, and
230*c2c66affSColin Finck      * making sure that it shifts the rcScrollBar value. */
231*c2c66affSColin Finck     ShowWindow( hMainWnd, SW_SHOW );
232*c2c66affSColin Finck     sbi.cbSize = sizeof(sbi);
233*c2c66affSColin Finck     ret = pGetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi);
234*c2c66affSColin Finck     ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
235*c2c66affSColin Finck     GetWindowRect( hMainWnd, &rect );
236*c2c66affSColin Finck     ok( ret, "The GetWindowRect() call should not fail.\n" );
237*c2c66affSColin Finck     MoveWindow( hMainWnd, rect.left+5, rect.top+5,
238*c2c66affSColin Finck                 rect.right-rect.left, rect.bottom-rect.top, TRUE );
239*c2c66affSColin Finck     rect = sbi.rcScrollBar;
240*c2c66affSColin Finck     OffsetRect(&rect, 5, 5);
241*c2c66affSColin Finck     ret = pGetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi);
242*c2c66affSColin Finck     ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
243*c2c66affSColin Finck     ok(EqualRect(&rect, &sbi.rcScrollBar), "PreviousRect %s != CurrentRect %s\n",
244*c2c66affSColin Finck        wine_dbgstr_rect(&rect), wine_dbgstr_rect(&sbi.rcScrollBar));
245*c2c66affSColin Finck 
246*c2c66affSColin Finck     sbi.cbSize = sizeof(sbi);
247*c2c66affSColin Finck     ret = pGetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi);
248*c2c66affSColin Finck     ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
249*c2c66affSColin Finck     GetWindowRect( hMainWnd, &rect );
250*c2c66affSColin Finck     ok( ret, "The GetWindowRect() call should not fail.\n" );
251*c2c66affSColin Finck     MoveWindow( hMainWnd, rect.left+5, rect.top+5,
252*c2c66affSColin Finck                 rect.right-rect.left, rect.bottom-rect.top, TRUE );
253*c2c66affSColin Finck     rect = sbi.rcScrollBar;
254*c2c66affSColin Finck     OffsetRect(&rect, 5, 5);
255*c2c66affSColin Finck     ret = pGetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi);
256*c2c66affSColin Finck     ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
257*c2c66affSColin Finck     ok(EqualRect(&rect, &sbi.rcScrollBar), "PreviousRect %s != CurrentRect %s\n",
258*c2c66affSColin Finck        wine_dbgstr_rect(&rect), wine_dbgstr_rect(&sbi.rcScrollBar));
259*c2c66affSColin Finck 
260*c2c66affSColin Finck     DestroyWindow(hScroll);
261*c2c66affSColin Finck     DestroyWindow(hMainWnd);
262*c2c66affSColin Finck }
263*c2c66affSColin Finck 
264*c2c66affSColin Finck /* some tests designed to show that Horizontal and Vertical
265*c2c66affSColin Finck  * window scroll bar info are not created independently */
266*c2c66affSColin Finck static void scrollbar_test_default( DWORD style)
267*c2c66affSColin Finck {
268*c2c66affSColin Finck     INT min, max, ret;
269*c2c66affSColin Finck     DWORD winstyle;
270*c2c66affSColin Finck     HWND hwnd;
271*c2c66affSColin Finck     SCROLLINFO si = { sizeof( SCROLLINFO), SIF_TRACKPOS };
272*c2c66affSColin Finck 
273*c2c66affSColin Finck     hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style,
274*c2c66affSColin Finck                 0, 0, 10, 10, 0, 0, 0, NULL);
275*c2c66affSColin Finck     assert( hwnd != 0);
276*c2c66affSColin Finck 
277*c2c66affSColin Finck     ret = GetScrollRange( hwnd, SB_VERT, &min, &max);
278*c2c66affSColin Finck     ok( ret ||
279*c2c66affSColin Finck             broken( !ret) /* Win 9x/ME */ , "GetScrollRange failed.\n");
280*c2c66affSColin Finck     /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */
281*c2c66affSColin Finck     if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
282*c2c66affSColin Finck         ok( min == 0 && max == 0,
283*c2c66affSColin Finck                 "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style);
284*c2c66affSColin Finck     else
285*c2c66affSColin Finck         ok(( min == 0 && max == 100) ||
286*c2c66affSColin Finck                 broken( min == 0 && max == 0), /* Win 9x/ME */
287*c2c66affSColin Finck                 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
288*c2c66affSColin Finck     ret = GetScrollRange( hwnd, SB_HORZ, &min, &max);
289*c2c66affSColin Finck     ok( ret ||
290*c2c66affSColin Finck             broken( !ret) /* Win 9x/ME */ , "GetScrollRange failed.\n");
291*c2c66affSColin Finck     /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */
292*c2c66affSColin Finck     if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
293*c2c66affSColin Finck         ok( min == 0 && max == 0,
294*c2c66affSColin Finck                 "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style);
295*c2c66affSColin Finck     else
296*c2c66affSColin Finck         ok(( min == 0 && max == 100) ||
297*c2c66affSColin Finck                 broken( min == 0 && max == 0), /* Win 9x/ME */
298*c2c66affSColin Finck                 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
299*c2c66affSColin Finck     /* test GetScrollInfo, vist for vertical SB */
300*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_VERT, &si);
301*c2c66affSColin Finck     /* should fail if no H or V scroll bar styles are present. Succeed otherwise */
302*c2c66affSColin Finck     if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
303*c2c66affSColin Finck         ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
304*c2c66affSColin Finck     else
305*c2c66affSColin Finck         ok( ret ||
306*c2c66affSColin Finck                 broken( !ret), /* Win 9x/ME */
307*c2c66affSColin Finck                 "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
308*c2c66affSColin Finck     /* Same for Horizontal SB */
309*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_HORZ, &si);
310*c2c66affSColin Finck     /* should fail if no H or V scroll bar styles are present. Succeed otherwise */
311*c2c66affSColin Finck     if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
312*c2c66affSColin Finck         ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
313*c2c66affSColin Finck     else
314*c2c66affSColin Finck         ok( ret ||
315*c2c66affSColin Finck                 broken( !ret), /* Win 9x/ME */
316*c2c66affSColin Finck                 "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
317*c2c66affSColin Finck     /* now set the Vertical Scroll range to something that could be the default value it
318*c2c66affSColin Finck      * already has */;
319*c2c66affSColin Finck     ret = SetScrollRange( hwnd, SB_VERT, 0, 100, FALSE);
320*c2c66affSColin Finck     ok( ret, "SetScrollRange failed.\n");
321*c2c66affSColin Finck     /* and request the Horizontal range */
322*c2c66affSColin Finck     ret = GetScrollRange( hwnd, SB_HORZ, &min, &max);
323*c2c66affSColin Finck     ok( ret, "GetScrollRange failed.\n");
324*c2c66affSColin Finck     /* now the range should be 0,100 in ALL cases */
325*c2c66affSColin Finck     ok( min == 0 && max == 100,
326*c2c66affSColin Finck             "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
327*c2c66affSColin Finck     /* See what is different now for GetScrollRange */
328*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_HORZ, &si);
329*c2c66affSColin Finck     /* should succeed in ALL cases */
330*c2c66affSColin Finck     ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
331*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_VERT, &si);
332*c2c66affSColin Finck     /* should succeed in ALL cases */
333*c2c66affSColin Finck     ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
334*c2c66affSColin Finck     /* report the windows style */
335*c2c66affSColin Finck     winstyle = GetWindowLongA( hwnd, GWL_STYLE );
336*c2c66affSColin Finck     /* WS_VSCROLL added to the window style */
337*c2c66affSColin Finck     if( !(style & WS_VSCROLL))
338*c2c66affSColin Finck     {
339*c2c66affSColin Finck         if (bThemeActive || style != WS_HSCROLL)
340*c2c66affSColin Finck todo_wine
341*c2c66affSColin Finck             ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == ( style | WS_VSCROLL),
342*c2c66affSColin Finck                 "unexpected style change %08x/%08x\n", winstyle, style);
343*c2c66affSColin Finck         else
344*c2c66affSColin Finck             ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == style,
345*c2c66affSColin Finck                 "unexpected style change %08x/%08x\n", winstyle, style);
346*c2c66affSColin Finck     }
347*c2c66affSColin Finck     /* do the test again with H and V reversed.
348*c2c66affSColin Finck      * Start with a clean window */
349*c2c66affSColin Finck     DestroyWindow( hwnd);
350*c2c66affSColin Finck     hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style,
351*c2c66affSColin Finck                 0, 0, 10, 10, 0, 0, 0, NULL);
352*c2c66affSColin Finck     assert( hwnd != 0);
353*c2c66affSColin Finck     /* Set Horizontal Scroll range to something that could be the default value it
354*c2c66affSColin Finck      * already has */;
355*c2c66affSColin Finck     ret = SetScrollRange( hwnd, SB_HORZ, 0, 100, FALSE);
356*c2c66affSColin Finck     ok( ret, "SetScrollRange failed.\n");
357*c2c66affSColin Finck     /* and request the Vertical range */
358*c2c66affSColin Finck     ret = GetScrollRange( hwnd, SB_VERT, &min, &max);
359*c2c66affSColin Finck     ok( ret, "GetScrollRange failed.\n");
360*c2c66affSColin Finck     /* now the range should be 0,100 in ALL cases */
361*c2c66affSColin Finck     ok( min == 0 && max == 100,
362*c2c66affSColin Finck             "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
363*c2c66affSColin Finck     /* See what is different now for GetScrollRange */
364*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_HORZ, &si);
365*c2c66affSColin Finck     /* should succeed in ALL cases */
366*c2c66affSColin Finck     ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
367*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_VERT, &si);
368*c2c66affSColin Finck     /* should succeed in ALL cases */
369*c2c66affSColin Finck     ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
370*c2c66affSColin Finck     /* report the windows style */
371*c2c66affSColin Finck     winstyle = GetWindowLongA( hwnd, GWL_STYLE );
372*c2c66affSColin Finck     /* WS_HSCROLL added to the window style */
373*c2c66affSColin Finck     if( !(style & WS_HSCROLL))
374*c2c66affSColin Finck     {
375*c2c66affSColin Finck         if (bThemeActive || style != WS_VSCROLL)
376*c2c66affSColin Finck todo_wine
377*c2c66affSColin Finck             ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == ( style | WS_HSCROLL),
378*c2c66affSColin Finck                 "unexpected style change %08x/%08x\n", winstyle, style);
379*c2c66affSColin Finck         else
380*c2c66affSColin Finck             ok( (winstyle & (WS_HSCROLL|WS_VSCROLL)) == style,
381*c2c66affSColin Finck                 "unexpected style change %08x/%08x\n", winstyle, style);
382*c2c66affSColin Finck     }
383*c2c66affSColin Finck     /* Slightly change the test to use SetScrollInfo
384*c2c66affSColin Finck      * Start with a clean window */
385*c2c66affSColin Finck     DestroyWindow( hwnd);
386*c2c66affSColin Finck     hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style,
387*c2c66affSColin Finck                 0, 0, 10, 10, 0, 0, 0, NULL);
388*c2c66affSColin Finck     assert( hwnd != 0);
389*c2c66affSColin Finck     /* set Horizontal position with SetScrollInfo */
390*c2c66affSColin Finck     si.nPos = 0;
391*c2c66affSColin Finck     si.nMin = 11;
392*c2c66affSColin Finck     si.nMax = 22;
393*c2c66affSColin Finck     si.fMask |= SIF_RANGE;
394*c2c66affSColin Finck     ret = SetScrollInfo( hwnd, SB_HORZ, &si, FALSE);
395*c2c66affSColin Finck     ok( ret, "SetScrollInfo failed. Style is %08x\n", style);
396*c2c66affSColin Finck     /* and request the Vertical range */
397*c2c66affSColin Finck     ret = GetScrollRange( hwnd, SB_VERT, &min, &max);
398*c2c66affSColin Finck     ok( ret, "GetScrollRange failed.\n");
399*c2c66affSColin Finck     /* now the range should be 0,100 in ALL cases */
400*c2c66affSColin Finck     ok( min == 0 && max == 100,
401*c2c66affSColin Finck             "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
402*c2c66affSColin Finck     /* See what is different now for GetScrollRange */
403*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_HORZ, &si);
404*c2c66affSColin Finck     /* should succeed in ALL cases */
405*c2c66affSColin Finck     ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
406*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_VERT, &si);
407*c2c66affSColin Finck     /* should succeed in ALL cases */
408*c2c66affSColin Finck     ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
409*c2c66affSColin Finck     /* also test if the window scroll bars are enabled */
410*c2c66affSColin Finck     ret = EnableScrollBar( hwnd, SB_VERT, ESB_ENABLE_BOTH);
411*c2c66affSColin Finck     ok( !ret, "Vertical window scroll bar was not enabled\n");
412*c2c66affSColin Finck     ret = EnableScrollBar( hwnd, SB_HORZ, ESB_ENABLE_BOTH);
413*c2c66affSColin Finck     ok( !ret, "Horizontal window scroll bar was not enabled\n");
414*c2c66affSColin Finck     DestroyWindow( hwnd);
415*c2c66affSColin Finck     /* finally, check if adding a WS_[HV]SCROLL style of a window makes the scroll info
416*c2c66affSColin Finck      * available */
417*c2c66affSColin Finck     if( style & (WS_HSCROLL | WS_VSCROLL)) return;/* only test if not yet set */
418*c2c66affSColin Finck     /* Start with a clean window */
419*c2c66affSColin Finck     DestroyWindow( hwnd);
420*c2c66affSColin Finck     hwnd = CreateWindowExA( 0, "static", "", WS_POPUP ,
421*c2c66affSColin Finck                 0, 0, 10, 10, 0, 0, 0, NULL);
422*c2c66affSColin Finck     assert( hwnd != 0);
423*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_VERT, &si);
424*c2c66affSColin Finck     /* should fail */
425*c2c66affSColin Finck     ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
426*c2c66affSColin Finck     /* add scroll styles */
427*c2c66affSColin Finck     winstyle = GetWindowLongA( hwnd, GWL_STYLE );
428*c2c66affSColin Finck     SetWindowLongW( hwnd, GWL_STYLE, winstyle | WS_VSCROLL | WS_HSCROLL);
429*c2c66affSColin Finck     ret = GetScrollInfo( hwnd, SB_VERT, &si);
430*c2c66affSColin Finck     /* should still fail */
431*c2c66affSColin Finck     ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
432*c2c66affSColin Finck     /* clean up */
433*c2c66affSColin Finck     DestroyWindow( hwnd);
434*c2c66affSColin Finck }
435*c2c66affSColin Finck 
436*c2c66affSColin Finck static LRESULT CALLBACK scroll_init_proc(HWND hwnd, UINT msg,
437*c2c66affSColin Finck                                         WPARAM wparam, LPARAM lparam)
438*c2c66affSColin Finck {
439*c2c66affSColin Finck     SCROLLINFO horz, vert;
440*c2c66affSColin Finck     CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
441*c2c66affSColin Finck     BOOL h_ret, v_ret;
442*c2c66affSColin Finck 
443*c2c66affSColin Finck     switch(msg)
444*c2c66affSColin Finck     {
445*c2c66affSColin Finck         case WM_NCCREATE:
446*c2c66affSColin Finck             return cs->lpCreateParams ? DefWindowProcA(hwnd, msg, wparam, lparam) :
447*c2c66affSColin Finck                                         TRUE;
448*c2c66affSColin Finck 
449*c2c66affSColin Finck         case WM_CREATE:
450*c2c66affSColin Finck             horz.cbSize = sizeof horz;
451*c2c66affSColin Finck             horz.fMask  = SIF_ALL;
452*c2c66affSColin Finck             horz.nMin   = 0xdeadbeaf;
453*c2c66affSColin Finck             horz.nMax   = 0xbaadc0de;
454*c2c66affSColin Finck             vert = horz;
455*c2c66affSColin Finck             h_ret = GetScrollInfo(hwnd, SB_HORZ, &horz);
456*c2c66affSColin Finck             v_ret = GetScrollInfo(hwnd, SB_VERT, &vert);
457*c2c66affSColin Finck 
458*c2c66affSColin Finck             if(cs->lpCreateParams)
459*c2c66affSColin Finck             {
460*c2c66affSColin Finck                 /* WM_NCCREATE was passed to DefWindowProc */
461*c2c66affSColin Finck                 if(cs->style & (WS_VSCROLL | WS_HSCROLL))
462*c2c66affSColin Finck                 {
463*c2c66affSColin Finck                     ok(h_ret && v_ret, "GetScrollInfo() should return NON-zero "
464*c2c66affSColin Finck                             "but got h_ret=%d v_ret=%d\n", h_ret, v_ret);
465*c2c66affSColin Finck                     ok(vert.nMin == 0 && vert.nMax == 100,
466*c2c66affSColin Finck                             "unexpected init values(SB_VERT): min=%d max=%d\n",
467*c2c66affSColin Finck                             vert.nMin, vert.nMax);
468*c2c66affSColin Finck                     ok(horz.nMin == 0 && horz.nMax == 100,
469*c2c66affSColin Finck                             "unexpected init values(SB_HORZ): min=%d max=%d\n",
470*c2c66affSColin Finck                             horz.nMin, horz.nMax);
471*c2c66affSColin Finck                 }
472*c2c66affSColin Finck                 else
473*c2c66affSColin Finck                 {
474*c2c66affSColin Finck                     ok(!h_ret && !v_ret, "GetScrollInfo() should return zeru, "
475*c2c66affSColin Finck                             "but got h_ret=%d v_ret=%d\n", h_ret, v_ret);
476*c2c66affSColin Finck                     ok(vert.nMin == 0xdeadbeaf && vert.nMax == 0xbaadc0de,
477*c2c66affSColin Finck                             "unexpected  initialization(SB_VERT): min=%d max=%d\n",
478*c2c66affSColin Finck                             vert.nMin, vert.nMax);
479*c2c66affSColin Finck                     ok(horz.nMin == 0xdeadbeaf && horz.nMax == 0xbaadc0de,
480*c2c66affSColin Finck                             "unexpected  initialization(SB_HORZ): min=%d max=%d\n",
481*c2c66affSColin Finck                             horz.nMin, horz.nMax);
482*c2c66affSColin Finck                 }
483*c2c66affSColin Finck             }
484*c2c66affSColin Finck             else
485*c2c66affSColin Finck             {
486*c2c66affSColin Finck                 ok(!h_ret && !v_ret, "GetScrollInfo() should return zeru, "
487*c2c66affSColin Finck                     "but got h_ret=%d v_ret=%d\n", h_ret, v_ret);
488*c2c66affSColin Finck                 ok(horz.nMin == 0xdeadbeaf && horz.nMax == 0xbaadc0de &&
489*c2c66affSColin Finck                     vert.nMin == 0xdeadbeaf && vert.nMax == 0xbaadc0de,
490*c2c66affSColin Finck                         "unexpected initialization\n");
491*c2c66affSColin Finck             }
492*c2c66affSColin Finck             return FALSE; /* abort creation */
493*c2c66affSColin Finck 
494*c2c66affSColin Finck         default:
495*c2c66affSColin Finck             /* need for WM_GETMINMAXINFO, which precedes WM_NCCREATE */
496*c2c66affSColin Finck             return 0;
497*c2c66affSColin Finck     }
498*c2c66affSColin Finck }
499*c2c66affSColin Finck 
500*c2c66affSColin Finck static void scrollbar_test_init(void)
501*c2c66affSColin Finck {
502*c2c66affSColin Finck     WNDCLASSEXA wc;
503*c2c66affSColin Finck     CHAR cls_name[] = "scroll_test_class";
504*c2c66affSColin Finck     LONG style[] = {WS_VSCROLL, WS_HSCROLL, WS_VSCROLL | WS_HSCROLL, 0};
505*c2c66affSColin Finck     int i;
506*c2c66affSColin Finck 
507*c2c66affSColin Finck     memset( &wc, 0, sizeof wc );
508*c2c66affSColin Finck     wc.cbSize        = sizeof wc;
509*c2c66affSColin Finck     wc.style         = CS_VREDRAW | CS_HREDRAW;
510*c2c66affSColin Finck     wc.hInstance     = GetModuleHandleA(0);
511*c2c66affSColin Finck     wc.hCursor       = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
512*c2c66affSColin Finck     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
513*c2c66affSColin Finck     wc.lpszClassName = cls_name;
514*c2c66affSColin Finck     wc.lpfnWndProc   = scroll_init_proc;
515*c2c66affSColin Finck     RegisterClassExA(&wc);
516*c2c66affSColin Finck 
517*c2c66affSColin Finck     for(i = 0; i < sizeof style / sizeof style[0]; i++)
518*c2c66affSColin Finck     {
519*c2c66affSColin Finck         /* need not to destroy these windows due creation abort */
520*c2c66affSColin Finck         CreateWindowExA(0, cls_name, NULL, style[i],
521*c2c66affSColin Finck                 100, 100, 100, 100, NULL, NULL, wc.hInstance, (LPVOID)TRUE);
522*c2c66affSColin Finck         CreateWindowExA(0, cls_name, NULL, style[i],
523*c2c66affSColin Finck                 100, 100, 100, 100, NULL, NULL, wc.hInstance, (LPVOID)FALSE);
524*c2c66affSColin Finck     }
525*c2c66affSColin Finck     UnregisterClassA(cls_name, wc.hInstance);
526*c2c66affSColin Finck }
527*c2c66affSColin Finck 
528*c2c66affSColin Finck static void test_SetScrollInfo(void)
529*c2c66affSColin Finck {
530*c2c66affSColin Finck     SCROLLINFO si;
531*c2c66affSColin Finck     HWND mainwnd;
532*c2c66affSColin Finck     BOOL ret;
533*c2c66affSColin Finck 
534*c2c66affSColin Finck     mainwnd = create_main_test_wnd();
535*c2c66affSColin Finck 
536*c2c66affSColin Finck     ret = IsWindowEnabled(hScroll);
537*c2c66affSColin Finck     ok(ret, "scroll bar disabled\n");
538*c2c66affSColin Finck 
539*c2c66affSColin Finck     EnableScrollBar(hScroll, SB_CTL, ESB_DISABLE_BOTH);
540*c2c66affSColin Finck 
541*c2c66affSColin Finck     ret = IsWindowEnabled(hScroll);
542*c2c66affSColin Finck     ok(!ret, "scroll bar enabled\n");
543*c2c66affSColin Finck 
544*c2c66affSColin Finck     memset(&si, 0, sizeof(si));
545*c2c66affSColin Finck     si.cbSize = sizeof(si);
546*c2c66affSColin Finck     si.fMask = 0xf;
547*c2c66affSColin Finck     ret = GetScrollInfo(hScroll, SB_CTL, &si);
548*c2c66affSColin Finck     ok(ret, "got %d\n", ret);
549*c2c66affSColin Finck 
550*c2c66affSColin Finck     /* SetScrollInfo */
551*c2c66affSColin Finck     memset(&si, 0, sizeof(si));
552*c2c66affSColin Finck     si.cbSize = sizeof(si);
553*c2c66affSColin Finck     ret = IsWindowEnabled(hScroll);
554*c2c66affSColin Finck     ok(!ret, "scroll bar enabled\n");
555*c2c66affSColin Finck     si.fMask = SIF_POS|SIF_RANGE|SIF_PAGE|SIF_DISABLENOSCROLL;
556*c2c66affSColin Finck     si.nMax = 100;
557*c2c66affSColin Finck     si.nMin = 10;
558*c2c66affSColin Finck     si.nPos = 0;
559*c2c66affSColin Finck     si.nPage = 100;
560*c2c66affSColin Finck     SetScrollInfo(hScroll, SB_CTL, &si, TRUE);
561*c2c66affSColin Finck     ret = IsWindowEnabled(hScroll);
562*c2c66affSColin Finck     ok(!ret, "scroll bar enabled\n");
563*c2c66affSColin Finck 
564*c2c66affSColin Finck     si.fMask = 0xf;
565*c2c66affSColin Finck     ret = GetScrollInfo(hScroll, SB_CTL, &si);
566*c2c66affSColin Finck     ok(ret, "got %d\n", ret);
567*c2c66affSColin Finck 
568*c2c66affSColin Finck     EnableScrollBar(hScroll, SB_CTL, ESB_ENABLE_BOTH);
569*c2c66affSColin Finck     ok(IsWindowEnabled(hScroll), "expected enabled scrollbar\n");
570*c2c66affSColin Finck 
571*c2c66affSColin Finck     si.fMask = SIF_POS|SIF_RANGE|SIF_PAGE|SIF_DISABLENOSCROLL;
572*c2c66affSColin Finck     si.nMax = 10;
573*c2c66affSColin Finck     si.nMin = 100;
574*c2c66affSColin Finck     si.nPos = 0;
575*c2c66affSColin Finck     si.nPage = 100;
576*c2c66affSColin Finck     SetScrollInfo(hScroll, SB_CTL, &si, TRUE);
577*c2c66affSColin Finck     ret = IsWindowEnabled(hScroll);
578*c2c66affSColin Finck     ok(ret, "scroll bar disabled\n");
579*c2c66affSColin Finck 
580*c2c66affSColin Finck     DestroyWindow(hScroll);
581*c2c66affSColin Finck     DestroyWindow(mainwnd);
582*c2c66affSColin Finck }
583*c2c66affSColin Finck 
584*c2c66affSColin Finck START_TEST ( scroll )
585*c2c66affSColin Finck {
586*c2c66affSColin Finck     WNDCLASSA wc;
587*c2c66affSColin Finck     HMODULE hUxtheme;
588*c2c66affSColin Finck     BOOL (WINAPI * pIsThemeActive)(VOID);
589*c2c66affSColin Finck 
590*c2c66affSColin Finck     wc.style = CS_HREDRAW | CS_VREDRAW;
591*c2c66affSColin Finck     wc.cbClsExtra = 0;
592*c2c66affSColin Finck     wc.cbWndExtra = 0;
593*c2c66affSColin Finck     wc.hInstance = GetModuleHandleA(NULL);
594*c2c66affSColin Finck     wc.hIcon = NULL;
595*c2c66affSColin Finck     wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_IBEAM);
596*c2c66affSColin Finck     wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
597*c2c66affSColin Finck     wc.lpszMenuName = NULL;
598*c2c66affSColin Finck     wc.lpszClassName = "MyTestWnd";
599*c2c66affSColin Finck     wc.lpfnWndProc = MyWndProc;
600*c2c66affSColin Finck     RegisterClassA(&wc);
601*c2c66affSColin Finck 
602*c2c66affSColin Finck     test_EnableScrollBar();
603*c2c66affSColin Finck     test_SetScrollPos();
604*c2c66affSColin Finck     test_ShowScrollBar();
605*c2c66affSColin Finck     test_GetScrollBarInfo();
606*c2c66affSColin Finck     scrollbar_test_track();
607*c2c66affSColin Finck     test_SetScrollInfo();
608*c2c66affSColin Finck 
609*c2c66affSColin Finck     /* Some test results vary depending of theming being active or not */
610*c2c66affSColin Finck     hUxtheme = LoadLibraryA("uxtheme.dll");
611*c2c66affSColin Finck     if (hUxtheme)
612*c2c66affSColin Finck     {
613*c2c66affSColin Finck         pIsThemeActive = (void*)GetProcAddress(hUxtheme, "IsThemeActive");
614*c2c66affSColin Finck         if (pIsThemeActive)
615*c2c66affSColin Finck             bThemeActive = pIsThemeActive();
616*c2c66affSColin Finck         FreeLibrary(hUxtheme);
617*c2c66affSColin Finck     }
618*c2c66affSColin Finck 
619*c2c66affSColin Finck     scrollbar_test_default( 0);
620*c2c66affSColin Finck     scrollbar_test_default( WS_HSCROLL);
621*c2c66affSColin Finck     scrollbar_test_default( WS_VSCROLL);
622*c2c66affSColin Finck     scrollbar_test_default( WS_HSCROLL | WS_VSCROLL);
623*c2c66affSColin Finck 
624*c2c66affSColin Finck     scrollbar_test_init();
625*c2c66affSColin Finck }
626