1 /* Unit tests for the track bar control.
2  *
3  * Copyright 2007 Keith Stevens
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include "precomp.h"
21 
22 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
23 #define NUM_MSG_SEQUENCE 2
24 #define PARENT_SEQ_INDEX 0
25 #define TRACKBAR_SEQ_INDEX 1
26 
27 static const DWORD defaultstyle = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS;
28 static HWND hWndParent;
29 
30 static LRESULT WINAPI trackbar_no_wmpaint_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
31 {
32     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
33 
34     if (message == WM_PAINT)
35         return 0;
36 
37     return CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
38 }
39 
40 static struct msg_sequence *sequences[NUM_MSG_SEQUENCE];
41 
42 static const struct message empty_seq[] = {
43     {0}
44 };
45 
46 static const struct message parent_create_trackbar_wnd_seq[] = {
47     { WM_NOTIFYFORMAT, sent},
48     { WM_QUERYUISTATE, sent|optional},
49     { WM_WINDOWPOSCHANGING, sent},
50     { WM_NCACTIVATE, sent},
51     { PBT_APMRESUMECRITICAL, sent},
52     { WM_WINDOWPOSCHANGING, sent},
53     { PBT_APMRESUMESTANDBY, sent},
54     { WM_IME_SETCONTEXT, sent|optional},
55     { WM_IME_NOTIFY, sent|optional},
56     { WM_CTLCOLORSTATIC, sent},
57     { WM_NOTIFY, sent},
58     {0}
59 };
60 
61 static const struct message parent_new_window_test_seq[] = {
62     { WM_QUERYNEWPALETTE, sent|optional },
63     { WM_WINDOWPOSCHANGING, sent|optional},
64     { WM_NCACTIVATE, sent|optional},
65     { PBT_APMRESUMECRITICAL, sent|optional},
66     { WM_IME_SETCONTEXT, sent|defwinproc|optional},
67     { WM_IME_NOTIFY, sent|defwinproc|optional},
68     { WM_SETFOCUS, sent|defwinproc|optional},
69     { WM_NOTIFYFORMAT, sent},
70     { WM_QUERYUISTATE, sent|optional},
71     {0}
72 };
73 
74 static const struct message buddy_window_test_seq[] = {
75     { TBM_GETBUDDY, sent|wparam, TRUE},
76     { TBM_SETBUDDY, sent|wparam, FALSE},
77     { WM_PAINT, sent|defwinproc},
78     { TBM_SETBUDDY, sent|wparam, FALSE},
79     { WM_PAINT, sent|defwinproc},
80     { TBM_GETBUDDY, sent|wparam, TRUE},
81     { TBM_SETBUDDY, sent|wparam, TRUE},
82     { WM_PAINT, sent|defwinproc},
83     { TBM_SETBUDDY, sent|wparam, TRUE},
84     { WM_PAINT, sent|defwinproc},
85     { TBM_GETBUDDY, sent|wparam, FALSE},
86     { TBM_GETBUDDY, sent|wparam, TRUE},
87     {0}
88 };
89 
90 static const struct message parent_buddy_window_test_seq[] = {
91     { WM_CTLCOLORSTATIC, sent},
92     { WM_NOTIFY, sent},
93     { WM_CTLCOLORSTATIC, sent},
94     { WM_NOTIFY, sent},
95     { WM_CTLCOLORSTATIC, sent},
96     { WM_NOTIFY, sent},
97     { WM_CTLCOLORSTATIC, sent},
98     { WM_NOTIFY, sent},
99     {0}
100 };
101 
102 static const struct message line_size_test_seq[] = {
103     { TBM_SETLINESIZE, sent|lparam, 0, 10},
104     { TBM_SETLINESIZE, sent|lparam, 0, 4},
105     { TBM_GETLINESIZE, sent},
106     {0}
107 };
108 
109 static const struct message page_size_test_seq[] = {
110     { TBM_SETPAGESIZE, sent|lparam, 0, 10},
111     { TBM_SETPAGESIZE, sent|lparam, 0, -1},
112     { TBM_GETPAGESIZE, sent},
113     {0}
114 };
115 
116 static const struct message position_test_seq[] = {
117     { TBM_SETPOS, sent|wparam|lparam, TRUE, -1},
118     { WM_PAINT, sent|defwinproc},
119     { TBM_GETPOS, sent},
120     { TBM_SETPOS, sent|wparam|lparam, TRUE, 5},
121     { WM_PAINT, sent|defwinproc},
122     { TBM_GETPOS, sent},
123     { TBM_SETPOS, sent|wparam|lparam, TRUE, 5},
124     { TBM_SETPOS, sent|wparam|lparam, TRUE, 1000},
125     { WM_PAINT, sent|defwinproc},
126     { TBM_GETPOS, sent},
127     { TBM_SETPOS, sent|wparam|lparam, FALSE, 20},
128     { TBM_GETPOS, sent},
129     { TBM_SETPOS, sent|wparam|lparam, TRUE, 20},
130     { TBM_GETPOS, sent},
131     {0}
132 };
133 
134 static const struct message parent_position_test_seq[] = {
135     { WM_CTLCOLORSTATIC, sent},
136     { WM_NOTIFY, sent},
137     { WM_CTLCOLORSTATIC, sent},
138     { WM_NOTIFY, sent},
139     { WM_CTLCOLORSTATIC, sent},
140     { WM_NOTIFY, sent},
141     {0}
142 };
143 
144 static const struct message range_test_seq[] = {
145     { TBM_SETRANGE, sent|wparam|lparam, TRUE, MAKELONG(0, 10)},
146     { WM_PAINT, sent|defwinproc},
147     { TBM_GETRANGEMAX, sent},
148     { TBM_GETRANGEMIN, sent},
149     { TBM_SETRANGE, sent|wparam|lparam, TRUE, MAKELONG(-1, 1000)},
150     { WM_PAINT, sent|defwinproc},
151     { TBM_GETRANGEMAX, sent},
152     { TBM_GETRANGEMIN, sent},
153     { TBM_SETRANGE, sent|wparam|lparam, TRUE, MAKELONG(10, 0)},
154     { WM_PAINT, sent|defwinproc},
155     { TBM_GETRANGEMAX, sent},
156     { TBM_GETRANGEMIN, sent},
157     { TBM_SETRANGE, sent|wparam|lparam, FALSE, MAKELONG(0, 10)},
158     { TBM_GETRANGEMAX, sent},
159     { TBM_GETRANGEMIN, sent},
160     { TBM_SETRANGEMAX, sent|wparam|lparam, TRUE, 10},
161     { WM_PAINT, sent|defwinproc},
162     { TBM_GETRANGEMAX, sent},
163     { TBM_SETRANGEMAX, sent|wparam|lparam, TRUE, -1},
164     { WM_PAINT, sent|defwinproc},
165     { TBM_GETRANGEMAX, sent},
166     { TBM_SETRANGEMAX, sent|wparam|lparam, FALSE, 10},
167     { TBM_GETRANGEMAX, sent},
168     { TBM_SETRANGEMIN, sent|wparam|lparam, TRUE, 0},
169     { WM_PAINT, sent|defwinproc},
170     { TBM_GETRANGEMIN, sent},
171     { TBM_SETRANGEMIN, sent|wparam|lparam, TRUE, 10},
172     { WM_PAINT, sent|defwinproc},
173     { TBM_GETRANGEMIN, sent},
174     { TBM_SETRANGEMIN, sent|wparam|lparam, TRUE, -10},
175     { WM_PAINT, sent|defwinproc},
176     { TBM_GETRANGEMIN, sent},
177     { TBM_SETRANGEMIN, sent|wparam|lparam, FALSE, 5},
178     { TBM_GETRANGEMIN, sent},
179     { TBM_GETRANGEMAX, sent},
180     { TBM_GETRANGEMIN, sent},
181     {0}
182 };
183 
184 static const struct message parent_range_test_seq[] = {
185     { WM_CTLCOLORSTATIC, sent},
186     { WM_NOTIFY, sent},
187     { WM_CTLCOLORSTATIC, sent},
188     { WM_NOTIFY, sent},
189     { WM_CTLCOLORSTATIC, sent},
190     { WM_NOTIFY, sent},
191     { WM_CTLCOLORSTATIC, sent},
192     { WM_NOTIFY, sent},
193     { WM_CTLCOLORSTATIC, sent},
194     { WM_NOTIFY, sent},
195     { WM_CTLCOLORSTATIC, sent},
196     { WM_NOTIFY, sent},
197     { WM_CTLCOLORSTATIC, sent},
198     { WM_NOTIFY, sent},
199     { WM_CTLCOLORSTATIC, sent},
200     { WM_NOTIFY, sent},
201     {0}
202 };
203 
204 static const struct message selection_test_seq[] = {
205     { TBM_SETSEL, sent|wparam|lparam, TRUE, MAKELONG(0, 10)},
206     { WM_PAINT, sent|defwinproc},
207     { TBM_GETSELEND, sent},
208     { TBM_GETSELSTART, sent},
209     { TBM_SETSEL, sent|wparam|lparam, TRUE, MAKELONG(5, 20)},
210     { WM_PAINT, sent|defwinproc},
211     { TBM_GETSELEND, sent},
212     { TBM_GETSELSTART, sent},
213     { TBM_SETSEL, sent|wparam|lparam, FALSE, MAKELONG(5, 10)},
214     { TBM_GETSELEND, sent},
215     { TBM_GETSELSTART, sent},
216     { TBM_SETSELEND, sent|wparam|lparam, TRUE, 10},
217     { WM_PAINT, sent|defwinproc},
218     { TBM_GETSELEND, sent},
219     { TBM_SETSELEND, sent|wparam|lparam, TRUE, 20},
220     { WM_PAINT, sent|defwinproc},
221     { TBM_GETSELEND, sent},
222     { TBM_SETSELEND, sent|wparam|lparam, TRUE, 4},
223     { WM_PAINT, sent|defwinproc},
224     { TBM_GETSELEND, sent},
225     { TBM_SETSELEND, sent|wparam|lparam, FALSE, 2},
226     { TBM_GETSELEND, sent},
227     { TBM_GETSELEND, sent},
228     { TBM_SETSELSTART, sent|wparam|lparam, TRUE, 5},
229     { WM_PAINT, sent|defwinproc},
230     { TBM_GETSELSTART, sent},
231     { TBM_SETSELSTART, sent|wparam|lparam, TRUE, 0},
232     { WM_PAINT, sent|defwinproc},
233     { TBM_GETSELSTART, sent},
234     { TBM_SETSELSTART, sent|wparam|lparam, TRUE, 20},
235     { WM_PAINT, sent|defwinproc},
236     { TBM_GETSELSTART, sent},
237     { TBM_SETSELSTART, sent|wparam|lparam, FALSE, 8},
238     { TBM_GETSELSTART, sent},
239     { TBM_GETSELSTART, sent},
240     {0}
241 };
242 
243 static const struct message parent_selection_test_seq[] = {
244     { WM_CTLCOLORSTATIC, sent},
245     { WM_NOTIFY, sent},
246     { WM_CTLCOLORSTATIC, sent},
247     { WM_NOTIFY, sent},
248     { WM_CTLCOLORSTATIC, sent},
249     { WM_NOTIFY, sent},
250     { WM_CTLCOLORSTATIC, sent},
251     { WM_NOTIFY, sent},
252     { WM_CTLCOLORSTATIC, sent},
253     { WM_NOTIFY, sent},
254     { WM_CTLCOLORSTATIC, sent},
255     { WM_NOTIFY, sent},
256     { WM_CTLCOLORSTATIC, sent},
257     { WM_NOTIFY, sent},
258     { WM_CTLCOLORSTATIC, sent},
259     { WM_NOTIFY, sent},
260     {0}
261 };
262 
263 static const struct message tic_settings_test_seq[] = {
264     { TBM_SETTIC, sent|lparam, 0, 0},
265     { TBM_SETTIC, sent|lparam, 0, 5},
266     { TBM_SETTIC, sent|lparam, 0, 10},
267     { TBM_SETTIC, sent|lparam, 0, 20},
268     { TBM_SETRANGE, sent|wparam|lparam, TRUE, MAKELONG(0,10)},
269     { WM_PAINT, sent|defwinproc},
270     { TBM_SETTICFREQ, sent|wparam, 2},
271     { WM_PAINT, sent|defwinproc},
272     { TBM_GETNUMTICS, sent},
273     { TBM_SETTICFREQ, sent|wparam, 5},
274     { WM_PAINT, sent|defwinproc},
275     { TBM_GETNUMTICS, sent},
276     { TBM_SETTICFREQ, sent|wparam, 15},
277     { WM_PAINT, sent|defwinproc},
278     { TBM_GETNUMTICS, sent},
279     { TBM_GETNUMTICS, sent},
280     {0}
281 };
282 
283 static const struct message parent_tic_settings_test_seq[] = {
284     { WM_CTLCOLORSTATIC, sent},
285     { WM_NOTIFY, sent},
286     { WM_CTLCOLORSTATIC, sent},
287     { WM_NOTIFY, sent},
288     { WM_CTLCOLORSTATIC, sent},
289     { WM_NOTIFY, sent},
290     { WM_CTLCOLORSTATIC, sent},
291     { WM_NOTIFY, sent},
292     {0}
293 };
294 
295 static const struct message thumb_length_test_seq[] = {
296     { TBM_SETTHUMBLENGTH, sent|wparam|lparam, 15, 0},
297     { WM_PAINT, sent|defwinproc},
298     { TBM_GETTHUMBLENGTH, sent},
299     { TBM_SETTHUMBLENGTH, sent|wparam|lparam, 20, 0},
300     { WM_PAINT, sent|defwinproc},
301     { TBM_GETTHUMBLENGTH, sent},
302     { TBM_GETTHUMBLENGTH, sent},
303     { WM_SIZE, sent},
304     { WM_PAINT, sent|defwinproc},
305     { TBM_GETTHUMBLENGTH, sent},
306     { WM_SIZE, sent},
307     { WM_PAINT, sent|defwinproc},
308     { TBM_GETTHUMBLENGTH, sent},
309     {0}
310 };
311 
312 static const struct message parent_thumb_length_test_seq[] = {
313     { WM_CTLCOLORSTATIC, sent},
314     { WM_NOTIFY, sent},
315     { WM_CTLCOLORSTATIC, sent},
316     { WM_NOTIFY, sent},
317     { WM_CTLCOLORSTATIC, sent},
318     { WM_NOTIFY, sent},
319     { WM_CTLCOLORSTATIC, sent},
320     { WM_NOTIFY, sent},
321     {0}
322 };
323 
324 static const struct message tic_placement_test_seq[] = {
325     { TBM_GETPTICS, sent},
326     { TBM_GETTIC, sent|wparam, 0},
327     { TBM_GETTIC, sent|wparam, 2},
328     { TBM_GETTIC, sent|wparam, 4},
329     { TBM_GETTICPOS, sent|wparam, 0},
330     { TBM_GETTICPOS, sent|wparam, 2},
331     {0}
332 };
333 
334 static const struct message tool_tips_test_seq[] = {
335     { TBM_SETTIPSIDE, sent|wparam, TBTS_TOP},
336     { TBM_SETTIPSIDE, sent|wparam, TBTS_LEFT},
337     { TBM_SETTIPSIDE, sent|wparam, TBTS_BOTTOM},
338     { TBM_SETTIPSIDE, sent|wparam, TBTS_RIGHT},
339     { TBM_SETTOOLTIPS, sent},
340     { TBM_GETTOOLTIPS, sent},
341     { TBM_SETTOOLTIPS, sent},
342     { TBM_GETTOOLTIPS, sent},
343     { TBM_SETTOOLTIPS, sent},
344     { TBM_GETTOOLTIPS, sent},
345     { TBM_GETTOOLTIPS, sent},
346     {0}
347 };
348 
349 static const struct message unicode_test_seq[] = {
350     { TBM_SETUNICODEFORMAT, sent|wparam, TRUE},
351     { TBM_SETUNICODEFORMAT, sent|wparam, FALSE},
352     { TBM_GETUNICODEFORMAT, sent},
353     {0}
354 };
355 
356 static const struct message ignore_selection_test_seq[] = {
357     { TBM_SETSEL, sent|wparam|lparam, TRUE, MAKELONG(0,10)},
358     { TBM_GETSELEND, sent},
359     { TBM_GETSELSTART, sent},
360     { TBM_SETSEL, sent|wparam|lparam, FALSE, MAKELONG(0,10)},
361     { TBM_GETSELEND, sent},
362     { TBM_GETSELSTART, sent},
363     { TBM_SETSELEND, sent|wparam|lparam, TRUE,0},
364     { TBM_GETSELEND, sent},
365     { TBM_SETSELEND, sent|wparam|lparam, TRUE, 10},
366     { TBM_GETSELEND, sent},
367     { TBM_SETSELEND, sent|wparam|lparam, FALSE,0},
368     { TBM_GETSELEND, sent},
369     { TBM_SETSELSTART, sent|wparam|lparam, TRUE,0},
370     { TBM_GETSELSTART, sent},
371     { TBM_SETSELSTART, sent|wparam|lparam, TRUE, 10},
372     { TBM_GETSELSTART, sent},
373     { TBM_SETSELSTART, sent|wparam|lparam, FALSE,0},
374     { TBM_GETSELSTART, sent},
375     {0}
376 };
377 
378 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
379     static LONG defwndproc_counter = 0;
380     LRESULT ret;
381     struct message msg;
382 
383     /* log system messages, except for painting */
384     if (message < WM_USER &&
385         message != WM_PAINT &&
386         message != WM_ERASEBKGND &&
387         message != WM_NCPAINT &&
388         message != WM_NCHITTEST &&
389         message != WM_GETTEXT &&
390         message != WM_GETICON &&
391         message != WM_DEVICECHANGE)
392     {
393         msg.message = message;
394         msg.flags = sent|wparam|lparam;
395         if (defwndproc_counter) msg.flags |= defwinproc;
396         msg.wParam = wParam;
397         msg.lParam = lParam;
398         msg.id = 0;
399         add_message(sequences, PARENT_SEQ_INDEX, &msg);
400     }
401 
402     defwndproc_counter++;
403     ret = DefWindowProcA(hwnd, message, wParam, lParam);
404     defwndproc_counter--;
405 
406     return ret;
407 }
408 
409 static BOOL register_parent_wnd_class(void){
410     WNDCLASSA cls;
411 
412     cls.style = 0;
413     cls.lpfnWndProc = parent_wnd_proc;
414     cls.cbClsExtra = 0;
415     cls.cbWndExtra = 0;
416     cls.hInstance = GetModuleHandleA(NULL);
417     cls.hIcon = 0;
418     cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
419     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
420     cls.lpszMenuName = NULL;
421     cls.lpszClassName = "Trackbar test parent class";
422     return RegisterClassA(&cls);
423 }
424 
425 static HWND create_parent_window(void){
426     if (!register_parent_wnd_class())
427         return NULL;
428 
429     return CreateWindowA("Trackbar test parent class", "Trackbar test parent window",
430                          WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE,
431                          0, 0, 100, 100, GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
432 }
433 
434 static LRESULT WINAPI trackbar_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
435     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
436     static LONG defwndproc_counter = 0;
437     struct message msg = { 0 };
438     LRESULT ret;
439 
440     msg.message = message;
441     msg.flags = sent|wparam|lparam;
442     if (defwndproc_counter) msg.flags |= defwinproc;
443     msg.wParam = wParam;
444     msg.lParam = lParam;
445     add_message(sequences, TRACKBAR_SEQ_INDEX, &msg);
446 
447     defwndproc_counter++;
448     ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
449     defwndproc_counter--;
450 
451     return ret;
452 }
453 
454 static HWND create_trackbar(DWORD style, HWND parent){
455     HWND hWndTrack;
456     WNDPROC oldproc;
457     RECT rect;
458 
459     GetClientRect(parent, &rect);
460     hWndTrack = CreateWindowA(TRACKBAR_CLASSA, "Trackbar Control", style,
461                               rect.right, rect.bottom, 100, 50,
462                               parent, NULL, GetModuleHandleA(NULL), NULL);
463 
464     if (!hWndTrack) return NULL;
465 
466     oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrack, GWLP_WNDPROC, (LONG_PTR)trackbar_subclass_proc);
467     SetWindowLongPtrA(hWndTrack, GWLP_USERDATA, (LONG_PTR)oldproc);
468 
469     return hWndTrack;
470 }
471 
472 static HWND create_trackbar2(DWORD style, HWND parent)
473 {
474     RECT rect;
475     GetClientRect(parent, &rect);
476     return CreateWindowA(TRACKBAR_CLASSA, "Trackbar Control", style,
477                               rect.right, rect.bottom, 100, 50,
478                               parent, NULL, GetModuleHandleA(NULL), NULL);
479 }
480 
481 /* test functions for setters, getters, and sequences */
482 
483 static void test_trackbar_buddy(void)
484 {
485     HWND hWndLeftBuddy, hWndTrackbar;
486     HWND hWndRightBuddy;
487     HWND hWndCurrentBuddy;
488     HWND rTest;
489 
490     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
491     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
492 
493     flush_sequences(sequences, NUM_MSG_SEQUENCE);
494 
495     hWndLeftBuddy = CreateWindowA(STATUSCLASSNAMEA, NULL, 0, 0, 0, 300, 20, NULL, NULL, NULL, NULL);
496     ok(hWndLeftBuddy != NULL, "Expected non NULL value\n");
497 
498     if (hWndLeftBuddy != NULL){
499         hWndCurrentBuddy = (HWND) SendMessageA(hWndTrackbar, TBM_GETBUDDY, TRUE, 0);
500         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_SETBUDDY, FALSE, (LPARAM) hWndLeftBuddy);
501         ok(rTest == hWndCurrentBuddy, "Expected hWndCurrentBuddy\n");
502         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_SETBUDDY, FALSE, (LPARAM) hWndLeftBuddy);
503         ok(rTest == hWndLeftBuddy, "Expected hWndLeftBuddy\n");
504     } else
505         skip ("left buddy control not present?\n");
506 
507     hWndRightBuddy = CreateWindowA(STATUSCLASSNAMEA, NULL, 0, 0, 0, 300, 20, NULL, NULL, NULL, NULL);
508 
509     ok(hWndRightBuddy != NULL, "expected non NULL value\n");
510 
511     /* test TBM_SETBUDDY */
512     if (hWndRightBuddy != NULL){
513         hWndCurrentBuddy = (HWND) SendMessageA(hWndTrackbar, TBM_GETBUDDY, TRUE, 0);
514         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_SETBUDDY, TRUE, (LPARAM) hWndRightBuddy);
515         ok(rTest == hWndCurrentBuddy, "Expected hWndCurrentBuddy\n");
516         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_SETBUDDY, TRUE, (LPARAM) hWndRightBuddy);
517         ok(rTest == hWndRightBuddy, "Expected hWndRightbuddy\n");
518      } else
519        skip("Right buddy control not present?\n");
520 
521     /* test TBM_GETBUDDY */
522     if (hWndLeftBuddy != NULL){
523         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_GETBUDDY, FALSE, 0);
524         ok(rTest == hWndLeftBuddy, "Expected hWndLeftBuddy\n");
525         DestroyWindow(hWndLeftBuddy);
526     }
527     if (hWndRightBuddy != NULL){
528         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_GETBUDDY, TRUE,0);
529         ok(rTest == hWndRightBuddy, "Expected hWndRightBuddy\n");
530         DestroyWindow(hWndRightBuddy);
531     }
532 
533     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, buddy_window_test_seq, "buddy test sequence", TRUE);
534     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_buddy_window_test_seq, "parent buddy test seq", TRUE);
535 
536     DestroyWindow(hWndTrackbar);
537 }
538 
539 static void test_line_size(void)
540 {
541     HWND hWndTrackbar;
542     int r;
543 
544     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
545     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
546 
547     flush_sequences(sequences, NUM_MSG_SEQUENCE);
548 
549     /* test TBM_SETLINESIZE */
550     r = SendMessageA(hWndTrackbar, TBM_SETLINESIZE, 0, 10);
551     expect(1,r);
552     r = SendMessageA(hWndTrackbar, TBM_SETLINESIZE, 0, 4);
553     expect(10, r);
554 
555     /* test TBM_GETLINESIZE */
556     r = SendMessageA(hWndTrackbar, TBM_GETLINESIZE, 0,0);
557     expect(4, r);
558 
559     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, line_size_test_seq, "linesize test sequence", FALSE);
560     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent line test sequence", FALSE);
561 
562     DestroyWindow(hWndTrackbar);
563 }
564 
565 
566 static void test_page_size(void)
567 {
568     HWND hWndTrackbar;
569     int r;
570 
571     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
572     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
573 
574     flush_sequences(sequences, NUM_MSG_SEQUENCE);
575 
576     /* test TBM_SETPAGESIZE */
577     r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, 10);
578     expect(20, r);
579     r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, -1);
580     expect(10, r);
581 
582     /* test TBM_GETPAGESIZE */
583     r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0,0);
584     expect(20, r);
585 
586     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, page_size_test_seq, "page size test sequence", FALSE);
587     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent page size test sequence", FALSE);
588 
589     /* check for zero page size */
590     r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, 0);
591     expect(20, r);
592     r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
593     expect(0, r);
594     /* revert to default */
595     r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, -1);
596     expect(0, r);
597     r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
598     expect(20, r);
599     /* < -1 */
600     r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, -2);
601     expect(20, r);
602     r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
603     expect(-2, r);
604 
605     DestroyWindow(hWndTrackbar);
606 }
607 
608 static void test_position(void)
609 {
610     HWND hWndTrackbar;
611     RECT rect, rect2;
612     WNDPROC oldproc;
613     int r;
614 
615     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
616     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
617 
618     flush_sequences(sequences, NUM_MSG_SEQUENCE);
619 
620     /* test TBM_SETPOS */
621     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, -1);
622     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
623     expect(0, r);
624     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 5);
625     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0,0);
626     expect(5, r);
627     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 5);
628     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 1000);
629     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0,0);
630     expect(100, r);
631     SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 20);
632     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0,0);
633     expect(20, r);
634     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 20);
635 
636     /* test TBM_GETPOS */
637     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0,0);
638     expect(20, r);
639 
640     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, position_test_seq, "position test sequence", TRUE);
641     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_position_test_seq, "parent position test sequence", TRUE);
642 
643     DestroyWindow(hWndTrackbar);
644 
645     hWndTrackbar = create_trackbar2(defaultstyle, hWndParent);
646     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
647 
648     /* subclassing procedure blocks WM_PAINT */
649     oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrackbar, GWLP_WNDPROC, (LONG_PTR)trackbar_no_wmpaint_proc);
650     SetWindowLongPtrA(hWndTrackbar, GWLP_USERDATA, (LONG_PTR)oldproc);
651 
652     SetRectEmpty(&rect);
653     SetRectEmpty(&rect2);
654 
655     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect);
656 
657     /* without repaint */
658     SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 25);
659     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
660     ok(r == 25, "got %d\n", r);
661     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2);
662     ok(rect.left == rect2.left, "got %d\n", rect.left);
663 
664     /* with repaint */
665     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 30);
666     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
667     ok(r == 30, "got %d\n", r);
668     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2);
669     ok(rect.left != rect2.left, "got %d, expected %d\n", rect2.left, rect.left);
670 
671     /* now move it with keys */
672     SendMessageA(hWndTrackbar, WM_KEYDOWN, VK_END, 0);
673     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
674     ok(r == 100, "got %d\n", r);
675     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect);
676     ok(rect.left != rect2.left, "got %d, expected %d\n", rect.left, rect2.left);
677 
678     DestroyWindow(hWndTrackbar);
679 }
680 
681 static void test_range(void)
682 {
683     HWND hWndTrackbar;
684     RECT rect1, rect2;
685     int r;
686 
687     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
688     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
689 
690     flush_sequences(sequences, NUM_MSG_SEQUENCE);
691 
692     /* test TBM_SETRANGE */
693     SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10));
694     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
695     expect(10, r);
696     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
697     expect(0, r);
698     SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(-1, 1000));
699     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
700     expect(1000, r);
701     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
702     expect(-1, r);
703     SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(10, 0));
704     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
705     expect(0, r);
706     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
707     expect(10, r);
708     SendMessageA(hWndTrackbar, TBM_SETRANGE, FALSE, MAKELONG(0,10));
709     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
710     expect(10, r);
711     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
712     expect(0, r);
713 
714     /*test TBM_SETRANGEMAX */
715     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 10);
716     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
717     expect(10, r);
718     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, TRUE, -1);
719     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
720     expect(-1, r);
721     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10);
722     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
723     expect(10, r);
724 
725     /* testing TBM_SETRANGEMIN */
726     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
727     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
728     expect(0, r);
729     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 10);
730     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
731     expect(10, r);
732     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, TRUE, -10);
733     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
734     expect(-10, r);
735     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5);
736     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
737     expect(5, r);
738 
739     /* test TBM_GETRANGEMAX */
740     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0);
741     expect(10, r);
742 
743     /* test TBM_GETRANGEMIN */
744     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0,0);
745     expect(5, r);
746 
747     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, range_test_seq, "range test sequence", TRUE);
748     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_range_test_seq, "parent range test sequence", TRUE);
749 
750     /* TBM_SETRANGE updates thumb visual position (rectangle) if needed */
751     r = SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(-10, 0));
752     ok(r == 0, "got %d\n", r);
753     SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 0);
754 
755     RedrawWindow(hWndTrackbar, NULL, 0, RDW_UPDATENOW);
756     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect1);
757 
758     r = SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(-10, 10));
759     ok(r == 0, "got %d\n", r);
760     RedrawWindow(hWndTrackbar, NULL, 0, RDW_UPDATENOW);
761 
762     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2);
763     ok(!EqualRect(&rect1, &rect2), "thumb rectangle not updated\n");
764 
765     /* change range back, don't force repaint */
766     r = SendMessageA(hWndTrackbar, TBM_SETRANGE, FALSE, MAKELONG(-10, 0));
767     ok(r == 0, "got %d\n", r);
768 
769     SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect1);
770     ok(EqualRect(&rect1, &rect2), "thumb rectangle not updated\n");
771 
772     /* test position update on range change */
773 
774     /* set to [20, 50], position at 30, reduce range to [20,25] */
775     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 20);
776     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 50);
777     SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 30);
778     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 25);
779     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
780     ok(r == 25, "Unexpected position %d\n", r);
781 
782     /* set to [20, 50], position at 30, flip max to 10 */
783     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 20);
784     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 50);
785     SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 30);
786     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10);
787     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
788     ok(r == 20, "Unexpected position %d\n", r);
789 
790     /* set to [20, 50], position at 30, flip min to 70 */
791     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 20);
792     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 50);
793     SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 30);
794     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 70);
795     r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0);
796     ok(r == 70, "Unexpected position %d\n", r);
797 
798     DestroyWindow(hWndTrackbar);
799 }
800 
801 static void test_selection(void)
802 {
803     HWND hWndTrackbar;
804     int r;
805 
806     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
807     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
808 
809     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5);
810     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10);
811 
812     flush_sequences(sequences, NUM_MSG_SEQUENCE);
813 
814     /* test TBM_SETSEL */
815     SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(0,10));
816     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
817     expect(10, r);
818     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
819     expect(5, r);
820     SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(5, 20));
821     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
822     expect(10, r);
823     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
824     expect(5, r);
825     SendMessageA(hWndTrackbar, TBM_SETSEL, FALSE, MAKELONG(5, 10));
826     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
827     expect(10, r);
828     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
829     expect(5, r);
830 
831     /* test TBM_SETSELEND */
832     SendMessageA(hWndTrackbar, TBM_SETSELEND, TRUE, 10);
833     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
834     expect(10, r);
835     SendMessageA(hWndTrackbar, TBM_SETSELEND, TRUE, 20);
836     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
837     expect(10, r);
838     SendMessageA(hWndTrackbar, TBM_SETSELEND, TRUE, 4);
839     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
840     expect(4, r);
841     SendMessageA(hWndTrackbar, TBM_SETSELEND, FALSE, 2);
842     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
843     expect(2, r);
844 
845     /* test TBM_GETSELEND */
846     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
847     expect(2, r);
848 
849     /* testing TBM_SETSELSTART */
850     SendMessageA(hWndTrackbar, TBM_SETSELSTART, TRUE, 5);
851     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
852     expect(5, r);
853     SendMessageA(hWndTrackbar, TBM_SETSELSTART, TRUE, 0);
854     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
855     expect(5, r);
856     SendMessageA(hWndTrackbar, TBM_SETSELSTART, TRUE, 20);
857     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
858     expect(20, r);
859     SendMessageA(hWndTrackbar, TBM_SETSELSTART, FALSE, 8);
860     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
861     expect(8, r);
862 
863     /* test TBM_GETSELSTART */
864     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
865     expect(8, r);
866 
867     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, selection_test_seq, "selection test sequence", TRUE);
868     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_selection_test_seq, "parent selection test sequence", TRUE);
869 
870     DestroyWindow(hWndTrackbar);
871 }
872 
873 static void test_thumb_length(void)
874 {
875     HWND hWndTrackbar;
876     int r;
877 
878     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
879     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
880 
881     flush_sequences(sequences, NUM_MSG_SEQUENCE);
882 
883     /* testing TBM_SETTHUMBLENGTH */
884     SendMessageA(hWndTrackbar, TBM_SETTHUMBLENGTH, 15, 0);
885     r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0);
886     expect(15, r);
887     SendMessageA(hWndTrackbar, TBM_SETTHUMBLENGTH, 20, 0);
888     r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0);
889     expect(20, r);
890 
891     /* test TBM_GETTHUMBLENGTH */
892     r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0);
893     expect(20, r);
894 
895     r = SendMessageA(hWndTrackbar, WM_SIZE, 0,0);
896     expect(0, r);
897     r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0);
898     expect(20, r);
899     r = SendMessageA(hWndTrackbar, WM_SIZE, 0, MAKELPARAM(50, 50) );
900     expect(0, r);
901     r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0);
902     expect(20, r);
903 
904     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, thumb_length_test_seq, "thumb length test sequence", TRUE);
905     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_thumb_length_test_seq, "parent thumb length test sequence", TRUE);
906 
907     DestroyWindow(hWndTrackbar);
908 }
909 
910 static void test_tic_settings(void)
911 {
912     HWND hWndTrackbar;
913     int r, i;
914 
915     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
916     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
917 
918     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5);
919     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10);
920 
921     /* testing TBM_SETTIC */
922     /* Set tics at 5 and 10 */
923     /* 0 and 20 are out of range and should not be set */
924     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0, 0);
925     expect(10, r);
926     r = SendMessageA(hWndTrackbar, TBM_GETRANGEMIN, 0, 0);
927     expect(5, r);
928 
929     flush_sequences(sequences, NUM_MSG_SEQUENCE);
930     r = SendMessageA(hWndTrackbar, TBM_SETTIC, 0, 0);
931     ok(r == FALSE, "Expected FALSE, got %d\n", r);
932     r = SendMessageA(hWndTrackbar, TBM_SETTIC, 0, 5);
933     ok(r == TRUE, "Expected TRUE, got %d\n", r);
934     r = SendMessageA(hWndTrackbar, TBM_SETTIC, 0, 10);
935     ok(r == TRUE, "Expected TRUE, got %d\n", r);
936 
937     r = SendMessageA(hWndTrackbar, TBM_SETTIC, 0, 20);
938     ok(r == FALSE, "Expected FALSE, got %d\n", r);
939 
940     /* test TBM_SETTICFREQ */
941     SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10));
942     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 2, 0);
943     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
944     expect(6, r);
945     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 5, 0);
946     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
947     expect(3, r);
948     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 15, 0);
949     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
950     expect(2, r);
951 
952     /* test TBM_GETNUMTICS */
953     /* since TIC FREQ is 15, there should be only 2 tics now */
954     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
955     expect(2, r);
956 
957     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_settings_test_seq, "tic settings test sequence", TRUE);
958     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_tic_settings_test_seq, "parent tic settings test sequence", TRUE);
959 
960     /* range [0,0], freq = 1 */
961     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 0);
962     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
963     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
964     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
965     expect(2, r);
966     /* range [0,1], freq = 1 */
967     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 1);
968     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
969     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
970     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
971     expect(2, r);
972     /* range [0,2], freq = 1 */
973     SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 2);
974     SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
975     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
976     r = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
977     expect(3, r);
978 
979     DestroyWindow(hWndTrackbar);
980 
981     /* Test to show that TBM_SETTICFREQ updates thumb */
982     for (i = 0; i < 2; i++)
983     {
984         DWORD style = i ? defaultstyle : defaultstyle & ~TBS_AUTOTICKS;
985         RECT rect, rect1;
986         WNDPROC oldproc;
987 
988         hWndTrackbar = create_trackbar2(style, hWndParent);
989         ok(hWndTrackbar != NULL, "Expected non NULL value\n");
990 
991         oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrackbar, GWLP_WNDPROC, (LONG_PTR)trackbar_no_wmpaint_proc);
992         SetWindowLongPtrA(hWndTrackbar, GWLP_USERDATA, (LONG_PTR)oldproc);
993 
994         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect);
995         SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 0);
996         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect1);
997         ok(EqualRect(&rect, &rect1), "Unexpected thumb rectangle %s, previous %s\n",
998             wine_dbgstr_rect(&rect1), wine_dbgstr_rect(&rect));
999 
1000         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect);
1001         SendMessageA(hWndTrackbar, TBM_SETRANGE, FALSE, MAKELONG(-100, 100));
1002         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect1);
1003         ok(EqualRect(&rect, &rect1), "Unexpected thumb rectangle %s, previous %s\n",
1004             wine_dbgstr_rect(&rect1), wine_dbgstr_rect(&rect));
1005         /* Old position is also 0, but thumb position will be different after range change */
1006         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect);
1007         SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 0);
1008         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect1);
1009         ok(EqualRect(&rect, &rect1), "Unexpected thumb rectangle %s, previous %s\n",
1010             wine_dbgstr_rect(&rect1), wine_dbgstr_rect(&rect));
1011         /* Previous frequency is also 1, yet thumb is updated */
1012         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect);
1013         SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
1014         SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect1);
1015         ok(!EqualRect(&rect, &rect1), "Unexpected thumb rectangle %s, previous %s\n",
1016             wine_dbgstr_rect(&rect1), wine_dbgstr_rect(&rect));
1017 
1018         SetWindowLongPtrA(hWndTrackbar, GWLP_WNDPROC, (LONG_PTR)oldproc);
1019 
1020         DestroyWindow(hWndTrackbar);
1021     }
1022 }
1023 
1024 static void test_tic_placement(void)
1025 {
1026     HWND hWndTrackbar;
1027     int r;
1028     DWORD *rPTics;
1029     DWORD numtics;
1030 
1031     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
1032     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
1033 
1034     SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(1, 6));
1035     SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
1036 
1037     numtics = SendMessageA(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
1038     ok(numtics == 6, "Expected 6, got %d\n", numtics);
1039 
1040     flush_sequences(sequences, NUM_MSG_SEQUENCE);
1041     /* test TBM_GETPTICS */
1042     rPTics = (DWORD *) SendMessageA(hWndTrackbar, TBM_GETPTICS, 0,0);
1043     expect(2, rPTics[0]);
1044     expect(3, rPTics[1]);
1045     expect(4, rPTics[2]);
1046     expect(5, rPTics[3]);
1047 
1048     /* test TBM_GETTIC */
1049     r = SendMessageA(hWndTrackbar, TBM_GETTIC, 0,0);
1050     expect(2, r);
1051     r = SendMessageA(hWndTrackbar, TBM_GETTIC, 2,0);
1052     expect(4, r);
1053     r = SendMessageA(hWndTrackbar, TBM_GETTIC, 4,0);
1054     expect(-1, r);
1055 
1056     /* test TBM_GETTICPIC */
1057     r = SendMessageA(hWndTrackbar, TBM_GETTICPOS, 0, 0);
1058     ok(r > 0, "Expected r > 0, got %d\n", r);
1059     r = SendMessageA(hWndTrackbar, TBM_GETTICPOS, 2, 0);
1060     ok(r > 0, "Expected r > 0, got %d\n", r);
1061 
1062     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_placement_test_seq, "get tic placement test sequence", FALSE);
1063     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent get tic placement test sequence", FALSE);
1064 
1065     DestroyWindow(hWndTrackbar);
1066 }
1067 
1068 static void test_tool_tips(void)
1069 {
1070     HWND hWndTooltip, hWndTrackbar;
1071     HWND rTest;
1072     int r;
1073 
1074     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
1075     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
1076 
1077     flush_sequences(sequences, NUM_MSG_SEQUENCE);
1078 
1079     /* testing TBM_SETTIPSIDE */
1080     r = SendMessageA(hWndTrackbar, TBM_SETTIPSIDE, TBTS_TOP, 0);
1081     expect(TBTS_TOP, r);
1082     r = SendMessageA(hWndTrackbar, TBM_SETTIPSIDE, TBTS_LEFT, 0);
1083     expect(TBTS_TOP, r);
1084     r = SendMessageA(hWndTrackbar, TBM_SETTIPSIDE, TBTS_BOTTOM, 0);
1085     expect(TBTS_LEFT, r);
1086     r = SendMessageA(hWndTrackbar, TBM_SETTIPSIDE, TBTS_RIGHT, 0);
1087     expect(TBTS_BOTTOM, r);
1088 
1089     /* testing TBM_SETTOOLTIPS */
1090     hWndTooltip = CreateWindowExA(WS_EX_TOPMOST, TOOLTIPS_CLASSA, NULL, 0,
1091                                   CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1092                                   NULL, NULL, NULL, NULL);
1093 
1094     ok(hWndTooltip != NULL, "Expected non NULL value\n");
1095     if (hWndTooltip != NULL){
1096         SendMessageA(hWndTrackbar, TBM_SETTOOLTIPS, (LPARAM) hWndTooltip, 0);
1097         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_GETTOOLTIPS, 0,0);
1098         ok(rTest == hWndTooltip, "Expected hWndToolTip, got\n");
1099         SendMessageA(hWndTrackbar, TBM_SETTOOLTIPS, 0, 0);
1100         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_GETTOOLTIPS, 0,0);
1101         ok(rTest == NULL, "Expected NULL\n");
1102         SendMessageA(hWndTrackbar, TBM_SETTOOLTIPS, (LPARAM) hWndTooltip, 5);
1103         rTest = (HWND) SendMessageA(hWndTrackbar, TBM_GETTOOLTIPS, 0,0);
1104         ok(rTest == hWndTooltip, "Expected hWndTooltip, got\n");
1105     } else
1106         skip("tool tip control not present?\n");
1107 
1108     /* test TBM_GETTOOLTIPS */
1109     rTest = (HWND) SendMessageA(hWndTrackbar, TBM_GETTOOLTIPS, 0,0);
1110     ok(rTest == hWndTooltip, "Expected hWndTooltip\n");
1111 
1112     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tool_tips_test_seq, "tool tips test sequence", FALSE);
1113     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent tool tips test sequence", FALSE);
1114 
1115     DestroyWindow(hWndTrackbar);
1116 }
1117 
1118 
1119 static void test_unicode(void)
1120 {
1121     HWND hWndTrackbar;
1122     int r;
1123 
1124     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
1125     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
1126 
1127     flush_sequences(sequences, NUM_MSG_SEQUENCE);
1128 
1129     /* testing TBM_SETUNICODEFORMAT */
1130     r = SendMessageA(hWndTrackbar, TBM_SETUNICODEFORMAT, TRUE, 0);
1131     ok(r == FALSE, "Expected FALSE, got %d\n",r);
1132     r = SendMessageA(hWndTrackbar, TBM_SETUNICODEFORMAT, FALSE, 0);
1133     ok(r == TRUE, "Expected TRUE, got %d\n",r);
1134 
1135     /* test TBM_GETUNICODEFORMAT */
1136     r = SendMessageA(hWndTrackbar, TBM_GETUNICODEFORMAT, 0,0);
1137     ok(r == FALSE, "Expected FALSE, got %d\n",r);
1138 
1139     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, unicode_test_seq, "unicode test sequence", FALSE);
1140     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent unicode test sequence", FALSE);
1141 
1142     DestroyWindow(hWndTrackbar);
1143 }
1144 
1145 static void test_ignore_selection(void)
1146 {
1147     HWND hWndTrackbar;
1148     int r;
1149 
1150     hWndTrackbar = create_trackbar(0, hWndParent);
1151     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
1152 
1153     flush_sequences(sequences, NUM_MSG_SEQUENCE);
1154     /* test TBM_SETSEL  ensure that it is ignored */
1155     SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(0,10));
1156     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
1157     expect(0, r);
1158     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
1159     expect(0, r);
1160     SendMessageA(hWndTrackbar, TBM_SETSEL, FALSE, MAKELONG(0,10));
1161     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
1162     expect(0, r);
1163     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
1164     expect(0, r);
1165 
1166     /* test TBM_SETSELEND, ensure that it is ignored */
1167     SendMessageA(hWndTrackbar, TBM_SETSELEND, TRUE, 0);
1168     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
1169     expect(0, r);
1170     SendMessageA(hWndTrackbar, TBM_SETSELEND, TRUE, 10);
1171     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
1172     expect(0,r);
1173     SendMessageA(hWndTrackbar, TBM_SETSELEND, FALSE, 0);
1174     r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0);
1175     expect(0, r);
1176 
1177     /* test TBM_SETSELSTART, ensure that it is ignored */
1178     SendMessageA(hWndTrackbar, TBM_SETSELSTART, TRUE, 0);
1179     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
1180     expect(0, r);
1181     SendMessageA(hWndTrackbar, TBM_SETSELSTART, TRUE, 10);
1182     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
1183     expect(0,r);
1184     SendMessageA(hWndTrackbar, TBM_SETSELSTART, FALSE, 0);
1185     r = SendMessageA(hWndTrackbar, TBM_GETSELSTART, 0,0);
1186     expect(0, r);
1187 
1188     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, ignore_selection_test_seq, "ignore selection setting test sequence", FALSE);
1189     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent ignore selection setting test sequence", FALSE);
1190 
1191     DestroyWindow(hWndTrackbar);
1192 }
1193 
1194 static void test_initial_state(void)
1195 {
1196     HWND hWnd;
1197     int ret;
1198 
1199     hWnd = create_trackbar(0, hWndParent);
1200 
1201     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1202     expect(2, ret);
1203     ret = SendMessageA(hWnd, TBM_GETTIC, 0, 0);
1204     expect(-1, ret);
1205     ret = SendMessageA(hWnd, TBM_GETTICPOS, 0, 0);
1206     expect(-1, ret);
1207     ret = SendMessageA(hWnd, TBM_GETRANGEMIN, 0, 0);
1208     expect(0, ret);
1209     ret = SendMessageA(hWnd, TBM_GETRANGEMAX, 0, 0);
1210     expect(100, ret);
1211 
1212     ret = SendMessageA(hWnd, TBM_SETRANGEMAX, TRUE, 200);
1213     expect(0, ret);
1214 
1215     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1216     expect(2, ret);
1217 
1218     ret = SendMessageA(hWnd, TBM_SETRANGEMIN, TRUE, 10);
1219     expect(0, ret);
1220 
1221     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1222     expect(2, ret);
1223 
1224     DestroyWindow(hWnd);
1225 }
1226 
1227 static void test_TBS_AUTOTICKS(void)
1228 {
1229     HWND hWnd;
1230     int ret;
1231 
1232     hWnd = create_trackbar(TBS_AUTOTICKS, hWndParent);
1233 
1234     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1235     expect(2, ret);
1236     ret = SendMessageA(hWnd, TBM_GETTIC, 0, 0);
1237     expect(-1, ret);
1238     ret = SendMessageA(hWnd, TBM_GETTICPOS, 0, 0);
1239     expect(-1, ret);
1240     ret = SendMessageA(hWnd, TBM_GETRANGEMIN, 0, 0);
1241     expect(0, ret);
1242     ret = SendMessageA(hWnd, TBM_GETRANGEMAX, 0, 0);
1243     expect(100, ret);
1244 
1245     /* TBM_SETRANGEMAX rebuilds tics */
1246     ret = SendMessageA(hWnd, TBM_SETRANGEMAX, TRUE, 200);
1247     expect(0, ret);
1248     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1249     expect(201, ret);
1250 
1251     /* TBM_SETRANGEMIN rebuilds tics */
1252     ret = SendMessageA(hWnd, TBM_SETRANGEMAX, TRUE, 100);
1253     expect(0, ret);
1254     ret = SendMessageA(hWnd, TBM_SETRANGEMIN, TRUE, 10);
1255     expect(0, ret);
1256     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1257     expect(91, ret);
1258 
1259     ret = SendMessageA(hWnd, TBM_SETRANGEMIN, TRUE, 0);
1260     expect(0, ret);
1261 
1262     /* TBM_SETRANGE rebuilds tics */
1263     ret = SendMessageA(hWnd, TBM_SETRANGE, TRUE, MAKELONG(10, 200));
1264     expect(0, ret);
1265     ret = SendMessageA(hWnd, TBM_GETNUMTICS, 0, 0);
1266     expect(191, ret);
1267 
1268     DestroyWindow(hWnd);
1269 }
1270 
1271 static void test_create(void)
1272 {
1273     HWND hWndTrackbar;
1274 
1275     flush_sequences(sequences, NUM_MSG_SEQUENCE);
1276 
1277     hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
1278     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
1279     ok_sequence(sequences, TRACKBAR_SEQ_INDEX, empty_seq, "create Trackbar Window", FALSE);
1280     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_trackbar_wnd_seq, "parent trackbar window", TRUE);
1281 
1282     DestroyWindow(hWndTrackbar);
1283 
1284     /* no style bits */
1285     flush_sequences(sequences, NUM_MSG_SEQUENCE);
1286     hWndTrackbar = create_trackbar(0, hWndParent);
1287     ok(hWndTrackbar != NULL, "Expected non NULL value\n");
1288     ok_sequence(sequences, PARENT_SEQ_INDEX, parent_new_window_test_seq, "new trackbar window test sequence", TRUE);
1289     DestroyWindow(hWndTrackbar);
1290 }
1291 
1292 START_TEST(trackbar)
1293 {
1294     init_msg_sequences(sequences, NUM_MSG_SEQUENCE);
1295     InitCommonControls();
1296 
1297     /* create parent window */
1298     hWndParent = create_parent_window();
1299     ok(hWndParent != NULL, "Failed to create parent Window!\n");
1300 
1301     if(!hWndParent){
1302         skip("parent window not present\n");
1303         return;
1304     }
1305 
1306     test_create();
1307     test_trackbar_buddy();
1308     test_line_size();
1309     test_page_size();
1310     test_position();
1311     test_range();
1312     test_selection();
1313     test_thumb_length();
1314     test_tic_settings();
1315     test_tic_placement();
1316     test_tool_tips();
1317     test_unicode();
1318     test_TBS_AUTOTICKS();
1319     test_ignore_selection();
1320     test_initial_state();
1321 
1322     DestroyWindow(hWndParent);
1323 }
1324