2 * Unit tests for scrollbar
4 * Copyright 2008 Lyutin Anatoly (Etersoft)
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.
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.
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
26 #include "wine/test.h"
29 static BOOL bThemeActive
= FALSE
;
31 static LRESULT CALLBACK
MyWndProc( HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
38 hScroll
= CreateWindowA( "SCROLLBAR", "", WS_CHILD
| WS_VISIBLE
, 0, 0, 120, 100, hWnd
, (HMENU
)100, GetModuleHandleA(0), 0 );
51 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
56 static HWND
create_main_test_wnd(void)
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");
70 static void scrollbar_test_track(void)
74 mainwnd
= create_main_test_wnd();
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");
83 DestroyWindow(hScroll
);
84 DestroyWindow(mainwnd
);
87 static void test_EnableScrollBar(void)
92 mainwnd
= create_main_test_wnd();
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" );
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" );
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" );
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" );
117 SetLastError( 0xdeadbeef );
118 ret
= EnableScrollBar( mainwnd
, SB_CTL
, ESB_ENABLE_BOTH
);
119 ok( !ret
, "EnableScrollBar should fail.\n" );
121 ok( GetLastError() == ERROR_INVALID_PARAMETER
122 || broken(GetLastError() == 0xdeadbeef), /* winxp */
123 "GetLastError() = %u\n", GetLastError() );
125 /* disable window, try to re-enable */
126 ret
= EnableWindow( hScroll
, FALSE
);
127 ok( !ret
, "got %d\n", ret
);
128 ok( !IsWindowEnabled( hScroll
), "The scrollbar window should be disabled.\n" );
130 ret
= EnableScrollBar( hScroll
, SB_CTL
, ESB_ENABLE_BOTH
);
131 ok( ret
, "got %d\n", ret
);
132 ok( IsWindowEnabled( hScroll
), "The scrollbar window should be disabled.\n" );
134 DestroyWindow(hScroll
);
135 DestroyWindow(mainwnd
);
138 static void test_SetScrollPos(void)
143 mainwnd
= create_main_test_wnd();
145 EnableWindow( hScroll
, FALSE
);
146 ok( !IsWindowEnabled( hScroll
), "The scroll should be disabled.\n" );
148 ret
= SetScrollPos( hScroll
, SB_CTL
, 30, TRUE
);
149 ok( !ret
, "The position should not be set.\n" );
151 ret
= GetScrollPos( hScroll
, SB_CTL
);
152 ok( !ret
, "The position should be equal to zero\n");
154 ret
= SetScrollRange( hScroll
, SB_CTL
, 0, 100, TRUE
);
155 ok( ret
, "The range should be set.\n" );
157 ret
= SetScrollPos( hScroll
, SB_CTL
, 30, TRUE
);
158 ok( !ret
, "The position should not be set.\n" );
160 ret
= GetScrollPos( hScroll
, SB_CTL
);
161 ok( ret
== 30, "The position should be set!!!\n");
163 EnableWindow( hScroll
, TRUE
);
164 ok( IsWindowEnabled( hScroll
), "The scroll should be enabled.\n" );
166 ret
= SetScrollPos( hScroll
, SB_CTL
, 30, TRUE
);
167 ok( ret
== 30, "The position should be set.\n" );
169 ret
= GetScrollPos( hScroll
, SB_CTL
);
170 ok( ret
== 30, "The position should not be equal to zero\n");
172 ret
= SetScrollRange( hScroll
, SB_CTL
, 0, 100, TRUE
);
173 ok( ret
, "The range should be set.\n" );
175 ret
= SetScrollPos( hScroll
, SB_CTL
, 30, TRUE
);
176 ok( ret
== 30, "The position should be set.\n" );
178 ret
= GetScrollPos( hScroll
, SB_CTL
);
179 ok( ret
== 30, "The position should not be equal to zero\n");
181 SetLastError( 0xdeadbeef );
182 ret
= SetScrollPos( mainwnd
, SB_CTL
, 30, TRUE
);
183 ok( !ret
, "The position should not be set.\n" );
184 ok( GetLastError() == 0xdeadbeef, "GetLastError() = %u\n", GetLastError() );
186 SetLastError( 0xdeadbeef );
187 ret
= GetScrollPos( mainwnd
, SB_CTL
);
188 ok( !ret
, "The position should be equal to zero\n");
189 ok( GetLastError() == 0xdeadbeef, "GetLastError() = %u\n", GetLastError() );
191 DestroyWindow(hScroll
);
192 DestroyWindow(mainwnd
);
195 static void test_ShowScrollBar(void)
200 mainwnd
= create_main_test_wnd();
202 ret
= ShowScrollBar( hScroll
, SB_CTL
, FALSE
);
203 ok( ret
, "The ShowScrollBar() should not failed.\n" );
204 ok( !IsWindowVisible( hScroll
), "The scrollbar window should not be visible\n" );
206 ret
= ShowScrollBar( hScroll
, SB_CTL
, TRUE
);
207 ok( ret
, "The ShowScrollBar() should not failed.\n" );
208 ok( !IsWindowVisible( hScroll
), "The scrollbar window should be visible\n" );
210 ret
= ShowScrollBar( NULL
, SB_CTL
, TRUE
);
211 ok( !ret
, "The ShowScrollBar() should failed.\n" );
213 ret
= ShowScrollBar( mainwnd
, SB_CTL
, TRUE
);
214 ok( ret
, "The ShowScrollBar() should not fail.\n" );
216 DestroyWindow(hScroll
);
217 DestroyWindow(mainwnd
);
220 static void test_GetScrollBarInfo(void)
226 BOOL (WINAPI
*pGetScrollBarInfo
)(HWND
, LONG
, LPSCROLLBARINFO
);
228 pGetScrollBarInfo
= (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetScrollBarInfo");
229 if (!pGetScrollBarInfo
)
231 win_skip("GetScrollBarInfo is not available\n");
235 hMainWnd
= create_main_test_wnd();
237 /* Test GetScrollBarInfo to make sure it returns rcScrollBar in screen
239 sbi
.cbSize
= sizeof(sbi
);
240 ret
= pGetScrollBarInfo( hScroll
, OBJID_CLIENT
, &sbi
);
241 ok( ret
, "The GetScrollBarInfo() call should not fail.\n" );
242 GetWindowRect( hScroll
, &rect
);
243 ok( ret
, "The GetWindowRect() call should not fail.\n" );
244 ok( !(sbi
.rgstate
[0] & (STATE_SYSTEM_INVISIBLE
|STATE_SYSTEM_OFFSCREEN
)),
245 "unexpected rgstate(0x%x)\n", sbi
.rgstate
[0]);
246 ok(EqualRect(&rect
, &sbi
.rcScrollBar
), "WindowRect %s != rcScrollBar %s\n",
247 wine_dbgstr_rect(&rect
), wine_dbgstr_rect(&sbi
.rcScrollBar
));
249 /* Test windows horizontal and vertical scrollbar to make sure rcScrollBar
250 * is still returned in screen coordinates by moving the window, and
251 * making sure that it shifts the rcScrollBar value. */
252 ShowWindow( hMainWnd
, SW_SHOW
);
253 sbi
.cbSize
= sizeof(sbi
);
254 ret
= pGetScrollBarInfo( hMainWnd
, OBJID_HSCROLL
, &sbi
);
255 ok( ret
, "The GetScrollBarInfo() call should not fail.\n" );
256 GetWindowRect( hMainWnd
, &rect
);
257 ok( ret
, "The GetWindowRect() call should not fail.\n" );
258 MoveWindow( hMainWnd
, rect
.left
+5, rect
.top
+5,
259 rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
260 rect
= sbi
.rcScrollBar
;
261 OffsetRect(&rect
, 5, 5);
262 ret
= pGetScrollBarInfo( hMainWnd
, OBJID_HSCROLL
, &sbi
);
263 ok( ret
, "The GetScrollBarInfo() call should not fail.\n" );
264 ok(EqualRect(&rect
, &sbi
.rcScrollBar
), "PreviousRect %s != CurrentRect %s\n",
265 wine_dbgstr_rect(&rect
), wine_dbgstr_rect(&sbi
.rcScrollBar
));
267 sbi
.cbSize
= sizeof(sbi
);
268 ret
= pGetScrollBarInfo( hMainWnd
, OBJID_VSCROLL
, &sbi
);
269 ok( ret
, "The GetScrollBarInfo() call should not fail.\n" );
270 GetWindowRect( hMainWnd
, &rect
);
271 ok( ret
, "The GetWindowRect() call should not fail.\n" );
272 MoveWindow( hMainWnd
, rect
.left
+5, rect
.top
+5,
273 rect
.right
-rect
.left
, rect
.bottom
-rect
.top
, TRUE
);
274 rect
= sbi
.rcScrollBar
;
275 OffsetRect(&rect
, 5, 5);
276 ret
= pGetScrollBarInfo( hMainWnd
, OBJID_VSCROLL
, &sbi
);
277 ok( ret
, "The GetScrollBarInfo() call should not fail.\n" );
278 ok(EqualRect(&rect
, &sbi
.rcScrollBar
), "PreviousRect %s != CurrentRect %s\n",
279 wine_dbgstr_rect(&rect
), wine_dbgstr_rect(&sbi
.rcScrollBar
));
281 DestroyWindow(hScroll
);
282 DestroyWindow(hMainWnd
);
285 /* some tests designed to show that Horizontal and Vertical
286 * window scroll bar info are not created independently */
287 static void scrollbar_test_default( DWORD style
)
292 SCROLLINFO si
= { sizeof( SCROLLINFO
), SIF_TRACKPOS
};
294 hwnd
= CreateWindowExA( 0, "static", "", WS_POPUP
| style
,
295 0, 0, 10, 10, 0, 0, 0, NULL
);
298 ret
= GetScrollRange( hwnd
, SB_VERT
, &min
, &max
);
300 broken( !ret
) /* Win 9x/ME */ , "GetScrollRange failed.\n");
301 /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */
302 if( !( style
& ( WS_VSCROLL
| WS_HSCROLL
)))
303 ok( min
== 0 && max
== 0,
304 "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min
, max
, style
);
306 ok(( min
== 0 && max
== 100) ||
307 broken( min
== 0 && max
== 0), /* Win 9x/ME */
308 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min
, max
, style
);
309 ret
= GetScrollRange( hwnd
, SB_HORZ
, &min
, &max
);
311 broken( !ret
) /* Win 9x/ME */ , "GetScrollRange failed.\n");
312 /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */
313 if( !( style
& ( WS_VSCROLL
| WS_HSCROLL
)))
314 ok( min
== 0 && max
== 0,
315 "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min
, max
, style
);
317 ok(( min
== 0 && max
== 100) ||
318 broken( min
== 0 && max
== 0), /* Win 9x/ME */
319 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min
, max
, style
);
320 /* test GetScrollInfo, vist for vertical SB */
321 ret
= GetScrollInfo( hwnd
, SB_VERT
, &si
);
322 /* should fail if no H or V scroll bar styles are present. Succeed otherwise */
323 if( !( style
& ( WS_VSCROLL
| WS_HSCROLL
)))
324 ok( !ret
, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style
);
327 broken( !ret
), /* Win 9x/ME */
328 "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
329 /* Same for Horizontal SB */
330 ret
= GetScrollInfo( hwnd
, SB_HORZ
, &si
);
331 /* should fail if no H or V scroll bar styles are present. Succeed otherwise */
332 if( !( style
& ( WS_VSCROLL
| WS_HSCROLL
)))
333 ok( !ret
, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style
);
336 broken( !ret
), /* Win 9x/ME */
337 "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
338 /* now set the Vertical Scroll range to something that could be the default value it
340 ret
= SetScrollRange( hwnd
, SB_VERT
, 0, 100, FALSE
);
341 ok( ret
, "SetScrollRange failed.\n");
342 /* and request the Horizontal range */
343 ret
= GetScrollRange( hwnd
, SB_HORZ
, &min
, &max
);
344 ok( ret
, "GetScrollRange failed.\n");
345 /* now the range should be 0,100 in ALL cases */
346 ok( min
== 0 && max
== 100,
347 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min
, max
, style
);
348 /* See what is different now for GetScrollRange */
349 ret
= GetScrollInfo( hwnd
, SB_HORZ
, &si
);
350 /* should succeed in ALL cases */
351 ok( ret
, "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
352 ret
= GetScrollInfo( hwnd
, SB_VERT
, &si
);
353 /* should succeed in ALL cases */
354 ok( ret
, "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
355 /* report the windows style */
356 winstyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
357 /* WS_VSCROLL added to the window style */
358 if( !(style
& WS_VSCROLL
))
360 if (bThemeActive
|| style
!= WS_HSCROLL
)
362 ok( (winstyle
& (WS_HSCROLL
|WS_VSCROLL
)) == ( style
| WS_VSCROLL
),
363 "unexpected style change %08x/%08x\n", winstyle
, style
);
365 ok( (winstyle
& (WS_HSCROLL
|WS_VSCROLL
)) == style
,
366 "unexpected style change %08x/%08x\n", winstyle
, style
);
368 /* do the test again with H and V reversed.
369 * Start with a clean window */
370 DestroyWindow( hwnd
);
371 hwnd
= CreateWindowExA( 0, "static", "", WS_POPUP
| style
,
372 0, 0, 10, 10, 0, 0, 0, NULL
);
374 /* Set Horizontal Scroll range to something that could be the default value it
376 ret
= SetScrollRange( hwnd
, SB_HORZ
, 0, 100, FALSE
);
377 ok( ret
, "SetScrollRange failed.\n");
378 /* and request the Vertical range */
379 ret
= GetScrollRange( hwnd
, SB_VERT
, &min
, &max
);
380 ok( ret
, "GetScrollRange failed.\n");
381 /* now the range should be 0,100 in ALL cases */
382 ok( min
== 0 && max
== 100,
383 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min
, max
, style
);
384 /* See what is different now for GetScrollRange */
385 ret
= GetScrollInfo( hwnd
, SB_HORZ
, &si
);
386 /* should succeed in ALL cases */
387 ok( ret
, "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
388 ret
= GetScrollInfo( hwnd
, SB_VERT
, &si
);
389 /* should succeed in ALL cases */
390 ok( ret
, "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
391 /* report the windows style */
392 winstyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
393 /* WS_HSCROLL added to the window style */
394 if( !(style
& WS_HSCROLL
))
396 if (bThemeActive
|| style
!= WS_VSCROLL
)
398 ok( (winstyle
& (WS_HSCROLL
|WS_VSCROLL
)) == ( style
| WS_HSCROLL
),
399 "unexpected style change %08x/%08x\n", winstyle
, style
);
401 ok( (winstyle
& (WS_HSCROLL
|WS_VSCROLL
)) == style
,
402 "unexpected style change %08x/%08x\n", winstyle
, style
);
404 /* Slightly change the test to use SetScrollInfo
405 * Start with a clean window */
406 DestroyWindow( hwnd
);
407 hwnd
= CreateWindowExA( 0, "static", "", WS_POPUP
| style
,
408 0, 0, 10, 10, 0, 0, 0, NULL
);
410 /* set Horizontal position with SetScrollInfo */
414 si
.fMask
|= SIF_RANGE
;
415 ret
= SetScrollInfo( hwnd
, SB_HORZ
, &si
, FALSE
);
416 ok( ret
, "SetScrollInfo failed. Style is %08x\n", style
);
417 /* and request the Vertical range */
418 ret
= GetScrollRange( hwnd
, SB_VERT
, &min
, &max
);
419 ok( ret
, "GetScrollRange failed.\n");
420 /* now the range should be 0,100 in ALL cases */
421 ok( min
== 0 && max
== 100,
422 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min
, max
, style
);
423 /* See what is different now for GetScrollRange */
424 ret
= GetScrollInfo( hwnd
, SB_HORZ
, &si
);
425 /* should succeed in ALL cases */
426 ok( ret
, "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
427 ret
= GetScrollInfo( hwnd
, SB_VERT
, &si
);
428 /* should succeed in ALL cases */
429 ok( ret
, "GetScrollInfo failed unexpectedly. Style is %08x\n", style
);
430 /* also test if the window scroll bars are enabled */
431 ret
= EnableScrollBar( hwnd
, SB_VERT
, ESB_ENABLE_BOTH
);
432 ok( !ret
, "Vertical window scroll bar was not enabled\n");
433 ret
= EnableScrollBar( hwnd
, SB_HORZ
, ESB_ENABLE_BOTH
);
434 ok( !ret
, "Horizontal window scroll bar was not enabled\n");
435 DestroyWindow( hwnd
);
436 /* finally, check if adding a WS_[HV]SCROLL style of a window makes the scroll info
438 if( style
& (WS_HSCROLL
| WS_VSCROLL
)) return;/* only test if not yet set */
439 /* Start with a clean window */
440 DestroyWindow( hwnd
);
441 hwnd
= CreateWindowExA( 0, "static", "", WS_POPUP
,
442 0, 0, 10, 10, 0, 0, 0, NULL
);
444 ret
= GetScrollInfo( hwnd
, SB_VERT
, &si
);
446 ok( !ret
, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style
);
447 /* add scroll styles */
448 winstyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
449 SetWindowLongW( hwnd
, GWL_STYLE
, winstyle
| WS_VSCROLL
| WS_HSCROLL
);
450 ret
= GetScrollInfo( hwnd
, SB_VERT
, &si
);
451 /* should still fail */
452 ok( !ret
, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style
);
454 DestroyWindow( hwnd
);
457 static LRESULT CALLBACK
scroll_init_proc(HWND hwnd
, UINT msg
,
458 WPARAM wparam
, LPARAM lparam
)
460 SCROLLINFO horz
, vert
;
461 CREATESTRUCTA
*cs
= (CREATESTRUCTA
*)lparam
;
467 return cs
->lpCreateParams
? DefWindowProcA(hwnd
, msg
, wparam
, lparam
) :
471 horz
.cbSize
= sizeof horz
;
472 horz
.fMask
= SIF_ALL
;
473 horz
.nMin
= 0xdeadbeaf;
474 horz
.nMax
= 0xbaadc0de;
476 h_ret
= GetScrollInfo(hwnd
, SB_HORZ
, &horz
);
477 v_ret
= GetScrollInfo(hwnd
, SB_VERT
, &vert
);
479 if(cs
->lpCreateParams
)
481 /* WM_NCCREATE was passed to DefWindowProc */
482 if(cs
->style
& (WS_VSCROLL
| WS_HSCROLL
))
484 ok(h_ret
&& v_ret
, "GetScrollInfo() should return NON-zero "
485 "but got h_ret=%d v_ret=%d\n", h_ret
, v_ret
);
486 ok(vert
.nMin
== 0 && vert
.nMax
== 100,
487 "unexpected init values(SB_VERT): min=%d max=%d\n",
488 vert
.nMin
, vert
.nMax
);
489 ok(horz
.nMin
== 0 && horz
.nMax
== 100,
490 "unexpected init values(SB_HORZ): min=%d max=%d\n",
491 horz
.nMin
, horz
.nMax
);
495 ok(!h_ret
&& !v_ret
, "GetScrollInfo() should return zeru, "
496 "but got h_ret=%d v_ret=%d\n", h_ret
, v_ret
);
497 ok(vert
.nMin
== 0xdeadbeaf && vert
.nMax
== 0xbaadc0de,
498 "unexpected initialization(SB_VERT): min=%d max=%d\n",
499 vert
.nMin
, vert
.nMax
);
500 ok(horz
.nMin
== 0xdeadbeaf && horz
.nMax
== 0xbaadc0de,
501 "unexpected initialization(SB_HORZ): min=%d max=%d\n",
502 horz
.nMin
, horz
.nMax
);
507 ok(!h_ret
&& !v_ret
, "GetScrollInfo() should return zeru, "
508 "but got h_ret=%d v_ret=%d\n", h_ret
, v_ret
);
509 ok(horz
.nMin
== 0xdeadbeaf && horz
.nMax
== 0xbaadc0de &&
510 vert
.nMin
== 0xdeadbeaf && vert
.nMax
== 0xbaadc0de,
511 "unexpected initialization\n");
513 return FALSE
; /* abort creation */
516 /* need for WM_GETMINMAXINFO, which precedes WM_NCCREATE */
521 static void scrollbar_test_init(void)
524 CHAR cls_name
[] = "scroll_test_class";
525 LONG style
[] = {WS_VSCROLL
, WS_HSCROLL
, WS_VSCROLL
| WS_HSCROLL
, 0};
528 memset( &wc
, 0, sizeof wc
);
529 wc
.cbSize
= sizeof wc
;
530 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
531 wc
.hInstance
= GetModuleHandleA(0);
532 wc
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
533 wc
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
534 wc
.lpszClassName
= cls_name
;
535 wc
.lpfnWndProc
= scroll_init_proc
;
536 RegisterClassExA(&wc
);
538 for(i
= 0; i
< ARRAY_SIZE(style
); i
++)
540 /* need not to destroy these windows due creation abort */
541 CreateWindowExA(0, cls_name
, NULL
, style
[i
],
542 100, 100, 100, 100, NULL
, NULL
, wc
.hInstance
, (LPVOID
)TRUE
);
543 CreateWindowExA(0, cls_name
, NULL
, style
[i
],
544 100, 100, 100, 100, NULL
, NULL
, wc
.hInstance
, (LPVOID
)FALSE
);
546 UnregisterClassA(cls_name
, wc
.hInstance
);
549 static void test_SetScrollInfo(void)
555 mainwnd
= create_main_test_wnd();
557 ret
= IsWindowEnabled(hScroll
);
558 ok(ret
, "scroll bar disabled\n");
560 EnableScrollBar(hScroll
, SB_CTL
, ESB_DISABLE_BOTH
);
562 ret
= IsWindowEnabled(hScroll
);
563 ok(!ret
, "scroll bar enabled\n");
564 ret
= IsWindowVisible(hScroll
);
565 ok(!ret
, "Unexpected visible state.\n");
567 memset(&si
, 0, sizeof(si
));
568 si
.cbSize
= sizeof(si
);
570 ret
= GetScrollInfo(hScroll
, SB_CTL
, &si
);
571 ok(ret
, "got %d\n", ret
);
574 memset(&si
, 0, sizeof(si
));
575 si
.cbSize
= sizeof(si
);
576 ret
= IsWindowEnabled(hScroll
);
577 ok(!ret
, "scroll bar enabled\n");
578 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
583 SetScrollInfo(hScroll
, SB_CTL
, &si
, TRUE
);
584 ret
= IsWindowEnabled(hScroll
);
585 ok(!ret
, "scroll bar enabled\n");
586 ret
= IsWindowVisible(hScroll
);
587 ok(!ret
, "Unexpected visible state.\n");
590 ret
= GetScrollInfo(hScroll
, SB_CTL
, &si
);
591 ok(ret
, "got %d\n", ret
);
593 EnableScrollBar(hScroll
, SB_CTL
, ESB_ENABLE_BOTH
);
594 ok(IsWindowEnabled(hScroll
), "expected enabled scrollbar\n");
595 ret
= IsWindowVisible(hScroll
);
596 ok(!ret
, "Unexpected visible state.\n");
598 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
603 SetScrollInfo(hScroll
, SB_CTL
, &si
, TRUE
);
604 ret
= IsWindowEnabled(hScroll
);
605 ok(ret
, "scroll bar disabled\n");
606 ret
= IsWindowVisible(hScroll
);
607 ok(!ret
, "Unexpected visible state.\n");
609 /* With visible window. */
610 ShowWindow(mainwnd
, SW_SHOW
);
612 ret
= IsWindowVisible(hScroll
);
613 ok(ret
, "Unexpected visible state.\n");
615 EnableScrollBar(hScroll
, SB_CTL
, ESB_DISABLE_BOTH
);
616 ret
= IsWindowEnabled(hScroll
);
617 ok(!ret
, "Unexpected enabled state.\n");
619 /* Enabled state is changed only for visible windows, and only with redraw flag. */
620 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
625 SetScrollInfo(hScroll
, SB_CTL
, &si
, FALSE
);
626 ret
= IsWindowEnabled(hScroll
);
627 ok(!ret
, "Unexpected enabled state.\n");
629 /* State changes when called with same arguments too. */
630 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
635 SetScrollInfo(hScroll
, SB_CTL
, &si
, TRUE
);
636 ret
= IsWindowEnabled(hScroll
);
637 ok(ret
, "Unexpected enabled state.\n");
639 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
644 SetScrollInfo(hScroll
, SB_CTL
, &si
, TRUE
);
645 ret
= IsWindowEnabled(hScroll
);
646 ok(!ret
, "Unexpected enabled state.\n");
648 EnableScrollBar(hScroll
, SB_CTL
, ESB_ENABLE_BOTH
);
649 ret
= IsWindowEnabled(hScroll
);
650 ok(ret
, "Unexpected enabled state.\n");
652 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
657 SetScrollInfo(hScroll
, SB_CTL
, &si
, TRUE
);
658 ret
= IsWindowEnabled(hScroll
);
659 ok(!ret
, "Unexpected enabled state.\n");
661 EnableScrollBar(hScroll
, SB_CTL
, ESB_DISABLE_BOTH
);
662 ret
= IsWindowEnabled(hScroll
);
663 ok(!ret
, "Unexpected enabled state.\n");
665 si
.fMask
= SIF_POS
|SIF_RANGE
|SIF_PAGE
|SIF_DISABLENOSCROLL
;
670 SetScrollInfo(hScroll
, SB_CTL
, &si
, TRUE
);
671 ret
= IsWindowEnabled(hScroll
);
672 ok(ret
, "Unexpected enabled state.\n");
674 DestroyWindow(hScroll
);
675 DestroyWindow(mainwnd
);
678 static WNDPROC scrollbar_wndproc
;
680 static SCROLLINFO set_scrollinfo
;
682 static LRESULT CALLBACK
subclass_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
684 if (msg
== WM_CREATE
&& ((CREATESTRUCTA
*)lparam
)->lpCreateParams
)
685 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
687 if (msg
== SBM_SETSCROLLINFO
)
688 set_scrollinfo
= *(SCROLLINFO
*)lparam
;
690 return CallWindowProcA(scrollbar_wndproc
, hwnd
, msg
, wparam
, lparam
);
693 static void test_subclass(void)
695 SCROLLBARINFO scroll_info
;
696 WNDCLASSEXA class_info
;
702 r
= GetClassInfoExA(GetModuleHandleA(NULL
), "SCROLLBAR", &class_info
);
703 ok(r
, "GetClassInfoEx failed: %u\n", GetLastError());
704 scrollbar_wndproc
= class_info
.lpfnWndProc
;
706 memset(&wc
, 0, sizeof(wc
));
707 wc
.cbWndExtra
= class_info
.cbWndExtra
+ 3; /* more space than needed works */
708 wc
.hInstance
= GetModuleHandleA(NULL
);
709 wc
.lpszClassName
= "MyTestSubclass";
710 wc
.lpfnWndProc
= subclass_proc
;
711 r
= RegisterClassA(&wc
);
712 ok(r
, "RegisterClass failed: %u\n", GetLastError());
714 hwnd
= CreateWindowExA( 0, "MyTestSubclass", "Scroll", WS_OVERLAPPEDWINDOW
,
715 CW_USEDEFAULT
, CW_USEDEFAULT
, 100, 100, NULL
, NULL
, GetModuleHandleA(NULL
), 0 );
716 ok(hwnd
!= NULL
, "Failed to create window: %u\n", GetLastError());
718 r
= SetScrollRange(hwnd
, SB_CTL
, 0, 100, TRUE
);
719 ok(r
, "SetScrollRange failed: %u\n", GetLastError());
721 res
= SetScrollPos(hwnd
, SB_CTL
, 2, FALSE
);
722 ok(!res
, "SetScrollPos returned %lu\n", res
);
724 memset(&set_scrollinfo
, 0xcc, sizeof(set_scrollinfo
));
725 res
= SetScrollPos(hwnd
, SB_CTL
, 1, FALSE
);
726 ok(res
== 2, "SetScrollPos returned %lu\n", res
);
727 ok(set_scrollinfo
.cbSize
== sizeof(SCROLLINFO
), "cbSize = %u\n", set_scrollinfo
.cbSize
);
729 ok(set_scrollinfo
.fMask
== (0x1000 | SIF_POS
), "fMask = %x\n", set_scrollinfo
.fMask
);
730 ok(set_scrollinfo
.nPos
== 1, "nPos = %x\n", set_scrollinfo
.nPos
);
732 memset(&scroll_info
, 0xcc, sizeof(scroll_info
));
733 scroll_info
.cbSize
= sizeof(scroll_info
);
734 res
= SendMessageA(hwnd
, SBM_GETSCROLLBARINFO
, 0, (LPARAM
)&scroll_info
);
735 ok(res
== 1, "SBM_GETSCROLLBARINFO returned %lu\n", res
);
739 /* if we skip calling wndproc for WM_CREATE, window is not considered a scrollbar */
740 hwnd
= CreateWindowExA( 0, "MyTestSubclass", "Scroll", WS_OVERLAPPEDWINDOW
,
741 CW_USEDEFAULT
, CW_USEDEFAULT
, 100, 100, NULL
, NULL
, GetModuleHandleA(NULL
), (void *)1 );
742 ok(hwnd
!= NULL
, "Failed to create window: %u\n", GetLastError());
744 memset(&scroll_info
, 0xcc, sizeof(scroll_info
));
745 scroll_info
.cbSize
= sizeof(scroll_info
);
746 res
= SendMessageA(hwnd
, SBM_GETSCROLLBARINFO
, 0, (LPARAM
)&scroll_info
);
747 ok(!res
, "SBM_GETSCROLLBARINFO returned %lu\n", res
);
751 /* not enough space in extra data */
752 wc
.cbWndExtra
= class_info
.cbWndExtra
- 1;
753 wc
.lpszClassName
= "MyTestSubclass2";
754 r
= RegisterClassA(&wc
);
755 ok(r
, "RegisterClass failed: %u\n", GetLastError());
757 hwnd
= CreateWindowExA( 0, "MyTestSubclass2", "Scroll", WS_OVERLAPPEDWINDOW
,
758 CW_USEDEFAULT
, CW_USEDEFAULT
, 100, 100, NULL
, NULL
, GetModuleHandleA(NULL
), 0 );
759 ok(hwnd
!= NULL
, "Failed to create window: %u\n", GetLastError());
761 memset(&scroll_info
, 0xcc, sizeof(scroll_info
));
762 scroll_info
.cbSize
= sizeof(scroll_info
);
763 res
= SendMessageA(hwnd
, SBM_GETSCROLLBARINFO
, 0, (LPARAM
)&scroll_info
);
764 ok(!res
, "SBM_GETSCROLLBARINFO returned %lu\n", res
);
766 memset(&set_scrollinfo
, 0xcc, sizeof(set_scrollinfo
));
767 res
= SetScrollPos(hwnd
, SB_CTL
, 1, FALSE
);
768 ok(res
== 0, "SetScrollPos returned %lu\n", res
);
769 ok(set_scrollinfo
.cbSize
== sizeof(SCROLLINFO
), "cbSize = %u\n", set_scrollinfo
.cbSize
);
771 ok(set_scrollinfo
.fMask
== (0x1000 | SIF_POS
), "fMask = %x\n", set_scrollinfo
.fMask
);
772 ok(set_scrollinfo
.nPos
== 1, "nPos = %x\n", set_scrollinfo
.nPos
);
777 START_TEST ( scroll
)
781 BOOL (WINAPI
* pIsThemeActive
)(VOID
);
783 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
786 wc
.hInstance
= GetModuleHandleA(NULL
);
788 wc
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_IBEAM
);
789 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
790 wc
.lpszMenuName
= NULL
;
791 wc
.lpszClassName
= "MyTestWnd";
792 wc
.lpfnWndProc
= MyWndProc
;
795 test_EnableScrollBar();
797 test_ShowScrollBar();
798 test_GetScrollBarInfo();
799 scrollbar_test_track();
800 test_SetScrollInfo();
803 /* Some test results vary depending of theming being active or not */
804 hUxtheme
= LoadLibraryA("uxtheme.dll");
807 pIsThemeActive
= (void*)GetProcAddress(hUxtheme
, "IsThemeActive");
809 bThemeActive
= pIsThemeActive();
810 FreeLibrary(hUxtheme
);
813 scrollbar_test_default( 0);
814 scrollbar_test_default( WS_HSCROLL
);
815 scrollbar_test_default( WS_VSCROLL
);
816 scrollbar_test_default( WS_HSCROLL
| WS_VSCROLL
);
818 scrollbar_test_init();