[COMCTL32_WINETEST] Add a PCH.
[reactos.git] / modules / rostests / winetests / comctl32 / progress.c
1 /* Unit tests for the progress bar control.
2 *
3 * Copyright 2005 Michael Kaufmann
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 static HWND hProgressParentWnd, hProgressWnd;
23 static const char progressTestClass[] = "ProgressBarTestClass";
24
25 static HWND create_progress(DWORD style)
26 {
27 return CreateWindowExA(0, PROGRESS_CLASSA, "", WS_VISIBLE | style,
28 0, 0, 100, 20, NULL, NULL, GetModuleHandleA(NULL), 0);
29 }
30
31 /* try to make sure pending X events have been processed before continuing */
32 static void flush_events(void)
33 {
34 MSG msg;
35 int diff = 100;
36 DWORD time = GetTickCount() + diff;
37
38 while (diff > 0)
39 {
40 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min(10,diff), QS_ALLINPUT ) == WAIT_TIMEOUT) break;
41 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
42 diff = time - GetTickCount();
43 }
44 }
45
46 static LRESULT CALLBACK progress_test_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
47 {
48 switch(msg) {
49
50 case WM_DESTROY:
51 PostQuitMessage(0);
52 break;
53
54 default:
55 return DefWindowProcA(hWnd, msg, wParam, lParam);
56 }
57
58 return 0L;
59 }
60
61 static WNDPROC progress_wndproc;
62 static BOOL erased;
63 static RECT last_paint_rect;
64
65 static LRESULT CALLBACK progress_subclass_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
66 {
67 if (msg == WM_PAINT)
68 {
69 GetUpdateRect(hWnd, &last_paint_rect, FALSE);
70 }
71 else if (msg == WM_ERASEBKGND)
72 {
73 erased = TRUE;
74 }
75 return CallWindowProcA(progress_wndproc, hWnd, msg, wParam, lParam);
76 }
77
78
79 static void update_window(HWND hWnd)
80 {
81 UpdateWindow(hWnd);
82 ok(!GetUpdateRect(hWnd, NULL, FALSE), "GetUpdateRect must return zero after UpdateWindow\n");
83 }
84
85
86 static void init(void)
87 {
88 HMODULE hComctl32;
89 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
90 WNDCLASSA wc;
91 RECT rect;
92 BOOL ret;
93
94 hComctl32 = GetModuleHandleA("comctl32.dll");
95 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
96 if (pInitCommonControlsEx)
97 {
98 INITCOMMONCONTROLSEX iccex;
99 iccex.dwSize = sizeof(iccex);
100 iccex.dwICC = ICC_PROGRESS_CLASS;
101 pInitCommonControlsEx(&iccex);
102 }
103 else
104 InitCommonControls();
105
106 wc.style = CS_HREDRAW | CS_VREDRAW;
107 wc.cbClsExtra = 0;
108 wc.cbWndExtra = 0;
109 wc.hInstance = GetModuleHandleA(NULL);
110 wc.hIcon = NULL;
111 wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
112 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
113 wc.lpszMenuName = NULL;
114 wc.lpszClassName = progressTestClass;
115 wc.lpfnWndProc = progress_test_wnd_proc;
116 RegisterClassA(&wc);
117
118 SetRect(&rect, 0, 0, 400, 20);
119 ret = AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
120 ok(ret, "got %d\n", ret);
121
122 hProgressParentWnd = CreateWindowExA(0, progressTestClass, "Progress Bar Test", WS_OVERLAPPEDWINDOW,
123 CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, GetModuleHandleA(NULL), 0);
124 ok(hProgressParentWnd != NULL, "failed to create parent wnd\n");
125
126 GetClientRect(hProgressParentWnd, &rect);
127 hProgressWnd = CreateWindowExA(0, PROGRESS_CLASSA, "", WS_CHILD | WS_VISIBLE,
128 0, 0, rect.right, rect.bottom, hProgressParentWnd, NULL, GetModuleHandleA(NULL), 0);
129 ok(hProgressWnd != NULL, "failed to create parent wnd\n");
130 progress_wndproc = (WNDPROC)SetWindowLongPtrA(hProgressWnd, GWLP_WNDPROC, (LPARAM)progress_subclass_proc);
131
132 ShowWindow(hProgressParentWnd, SW_SHOWNORMAL);
133 ok(GetUpdateRect(hProgressParentWnd, NULL, FALSE), "GetUpdateRect: There should be a region that needs to be updated\n");
134 flush_events();
135 update_window(hProgressParentWnd);
136 }
137
138 static void cleanup(void)
139 {
140 MSG msg;
141
142 PostMessageA(hProgressParentWnd, WM_CLOSE, 0, 0);
143 while (GetMessageA(&msg,0,0,0)) {
144 TranslateMessage(&msg);
145 DispatchMessageA(&msg);
146 }
147
148 UnregisterClassA(progressTestClass, GetModuleHandleA(NULL));
149 }
150
151
152 /*
153 * Tests if a progress bar repaints itself immediately when it receives
154 * some specific messages.
155 */
156 static void test_redraw(void)
157 {
158 RECT client_rect;
159 LRESULT ret;
160
161 SendMessageA(hProgressWnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
162 SendMessageA(hProgressWnd, PBM_SETPOS, 10, 0);
163 SendMessageA(hProgressWnd, PBM_SETSTEP, 20, 0);
164 update_window(hProgressWnd);
165
166 /* PBM_SETPOS */
167 ok(SendMessageA(hProgressWnd, PBM_SETPOS, 50, 0) == 10, "PBM_SETPOS must return the previous position\n");
168 ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_SETPOS: The progress bar should be redrawn immediately\n");
169
170 /* PBM_DELTAPOS */
171 ok(SendMessageA(hProgressWnd, PBM_DELTAPOS, 15, 0) == 50, "PBM_DELTAPOS must return the previous position\n");
172 ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_DELTAPOS: The progress bar should be redrawn immediately\n");
173
174 /* PBM_SETPOS */
175 ok(SendMessageA(hProgressWnd, PBM_SETPOS, 80, 0) == 65, "PBM_SETPOS must return the previous position\n");
176 ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_SETPOS: The progress bar should be redrawn immediately\n");
177
178 /* PBM_STEPIT */
179 ok(SendMessageA(hProgressWnd, PBM_STEPIT, 0, 0) == 80, "PBM_STEPIT must return the previous position\n");
180 ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_STEPIT: The progress bar should be redrawn immediately\n");
181 ret = SendMessageA(hProgressWnd, PBM_GETPOS, 0, 0);
182 if (ret == 0)
183 win_skip("PBM_GETPOS needs comctl32 > 4.70\n");
184 else
185 ok(ret == 100, "PBM_GETPOS returned a wrong position : %d\n", (UINT)ret);
186
187 /* PBM_SETRANGE and PBM_SETRANGE32:
188 Usually the progress bar doesn't repaint itself immediately. If the
189 position is not in the new range, it does.
190 Don't test this, it may change in future Windows versions. */
191
192 SendMessageA(hProgressWnd, PBM_SETPOS, 0, 0);
193 update_window(hProgressWnd);
194
195 /* increase to 10 - no background erase required */
196 erased = FALSE;
197 SetRectEmpty(&last_paint_rect);
198 SendMessageA(hProgressWnd, PBM_SETPOS, 10, 0);
199 GetClientRect(hProgressWnd, &client_rect);
200 ok(EqualRect(&last_paint_rect, &client_rect), "last_paint_rect was %s instead of %s\n",
201 wine_dbgstr_rect(&last_paint_rect), wine_dbgstr_rect(&client_rect));
202 update_window(hProgressWnd);
203 ok(!erased, "Progress bar shouldn't have erased the background\n");
204
205 /* decrease to 0 - background erase will be required */
206 erased = FALSE;
207 SetRectEmpty(&last_paint_rect);
208 SendMessageA(hProgressWnd, PBM_SETPOS, 0, 0);
209 GetClientRect(hProgressWnd, &client_rect);
210 ok(EqualRect(&last_paint_rect, &client_rect), "last_paint_rect was %s instead of %s\n",
211 wine_dbgstr_rect(&last_paint_rect), wine_dbgstr_rect(&client_rect));
212 update_window(hProgressWnd);
213 ok(erased, "Progress bar should have erased the background\n");
214 }
215
216 static void test_setcolors(void)
217 {
218 HWND progress;
219 COLORREF clr;
220
221 progress = create_progress(PBS_SMOOTH);
222
223 clr = SendMessageA(progress, PBM_SETBARCOLOR, 0, 0);
224 ok(clr == CLR_DEFAULT, "got %x\n", clr);
225
226 clr = SendMessageA(progress, PBM_SETBARCOLOR, 0, RGB(0, 255, 0));
227 ok(clr == 0, "got %x\n", clr);
228
229 clr = SendMessageA(progress, PBM_SETBARCOLOR, 0, CLR_DEFAULT);
230 ok(clr == RGB(0, 255, 0), "got %x\n", clr);
231
232 clr = SendMessageA(progress, PBM_SETBKCOLOR, 0, 0);
233 ok(clr == CLR_DEFAULT, "got %x\n", clr);
234
235 clr = SendMessageA(progress, PBM_SETBKCOLOR, 0, RGB(255, 0, 0));
236 ok(clr == 0, "got %x\n", clr);
237
238 clr = SendMessageA(progress, PBM_SETBKCOLOR, 0, CLR_DEFAULT);
239 ok(clr == RGB(255, 0, 0), "got %x\n", clr);
240
241 DestroyWindow(progress);
242 }
243
244 START_TEST(progress)
245 {
246 init();
247
248 test_redraw();
249 test_setcolors();
250
251 cleanup();
252 }