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