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