My Project
Loading...
Searching...
No Matches
Win32Gui.h
Go to the documentation of this file.
1#ifndef __cxxtest__Win32Gui_h__
2#define __cxxtest__Win32Gui_h__
3
4//
5// The Win32Gui displays a simple progress bar using the Win32 API.
6//
7// It accepts the following command line options:
8// -minimized Start minimized, pop up on error
9// -keep Don't close the window at the end
10// -title TITLE Set the window caption
11//
12// If both -minimized and -keep are specified, GUI will only keep the
13// window if it's in focus.
14//
15// N.B. If you're wondering why this class doesn't use any standard
16// library or STL (<string> would have been nice) it's because it only
17// uses "straight" Win32 API.
18//
19
20#include <cxxtest/Gui.h>
21
22#include <windows.h>
23#include <commctrl.h>
24
25namespace CxxTest
26{
27 class Win32Gui : public GuiListener
28 {
29 public:
30 void enterGui( int &argc, char **argv )
31 {
32 parseCommandLine( argc, argv );
33 }
34
35 void enterWorld( const WorldDescription &wd )
36 {
37 getTotalTests( wd );
38 _testsDone = 0;
40 }
41
42 void guiEnterSuite( const char *suiteName )
43 {
44 showSuiteName( suiteName );
46 }
47
48 void guiEnterTest( const char *suiteName, const char *testName )
49 {
50 ++ _testsDone;
51 setTestCaption( suiteName, testName );
52 showTestName( testName );
54 progressBarMessage( PBM_STEPIT );
56 }
57
58 void yellowBar()
59 {
60 setColor( 255, 255, 0 );
61 setIcon( IDI_WARNING );
63 }
64
65 void redBar()
66 {
67 if ( _startMinimized )
68 showMainWindow( SW_SHOWNORMAL );
69 setColor( 255, 0, 0 );
70 setIcon( IDI_ERROR );
72 }
73
74 void leaveGui()
75 {
76 if ( keep() )
77 {
79 WaitForSingleObject( _gui, INFINITE );
80 }
81 DestroyWindow( _mainWindow );
82 }
83
84 private:
85 const char *_title;
87 HANDLE _gui;
88 WNDCLASSEX _windowClass;
93 enum {
98 };
101 unsigned _statusTotal;
102 char _statusTestsDone[sizeof("1000000000 of (100%)") + WorldDescription::MAX_STRLEN_TOTAL_TESTS];
104 char _timeString[sizeof("00:00:00")];
105
106 void parseCommandLine( int argc, char **argv )
107 {
108 _startMinimized = _keep = false;
109 _title = argv[0];
110
111 for ( int i = 1; i < argc; ++ i )
112 {
113 if ( !lstrcmpA( argv[i], "-minimized" ) )
114 _startMinimized = true;
115 else if ( !lstrcmpA( argv[i], "-keep" ) )
116 _keep = true;
117 else if ( !lstrcmpA( argv[i], "-title" ) && (i + 1 < argc) )
118 _title = argv[++i];
119 }
120 }
121
123 {
124 getTotalTests( tracker().world() );
125 }
126
128 {
131 }
132
134 {
135 _canStartTests = CreateEvent( NULL, TRUE, FALSE, NULL );
136 DWORD threadId;
137 _gui = CreateThread( NULL, 0, &(Win32Gui::guiThread), (LPVOID)this, 0, &threadId );
138 WaitForSingleObject( _canStartTests, INFINITE );
139 }
140
141 static DWORD WINAPI guiThread( LPVOID parameter )
142 {
143 ((Win32Gui *)parameter)->gui();
144 return 0;
145 }
146
147 void gui()
148 {
156 startTimer();
157 startTests();
158
159 messageLoop();
160 }
161
163 {
164 _windowClass.cbSize = sizeof(_windowClass);
165 _windowClass.style = CS_HREDRAW | CS_VREDRAW;
167 _windowClass.cbClsExtra = 0;
168 _windowClass.cbWndExtra = sizeof(LONG);
169 _windowClass.hInstance = (HINSTANCE)NULL;
170 _windowClass.hIcon = (HICON)NULL;
171 _windowClass.hCursor = (HCURSOR)NULL;
172 _windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
173 _windowClass.lpszMenuName = NULL;
174 _windowClass.lpszClassName = TEXT("CxxTest Window Class");
175 _windowClass.hIconSm = (HICON)NULL;
176
177 RegisterClassEx( &_windowClass );
178 }
179
181 {
182 _mainWindow = createWindow( _windowClass.lpszClassName, WS_OVERLAPPEDWINDOW );
183 }
184
186 {
187 HMODULE dll = LoadLibraryA( "comctl32.dll" );
188 if ( !dll )
189 return;
190
191 typedef void (WINAPI *FUNC)( void );
192 FUNC func = (FUNC)GetProcAddress( dll, "InitCommonControls" );
193 if ( !func )
194 return;
195
196 func();
197 }
198
200 {
201 _progressBar = createWindow( PROGRESS_CLASS, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, _mainWindow );
202
203#ifdef PBM_SETRANGE32
204 progressBarMessage( PBM_SETRANGE32, 0, _numTotalTests );
205#else // No PBM_SETRANGE32, use PBM_SETRANGE
206 progressBarMessage( PBM_SETRANGE, 0, MAKELPARAM( 0, (WORD)_numTotalTests ) );
207#endif // PBM_SETRANGE32
208 progressBarMessage( PBM_SETPOS, 0 );
209 progressBarMessage( PBM_SETSTEP, 1 );
210 greenBar();
211 UpdateWindow( _progressBar );
212 }
213
215 {
216 _statusBar = createWindow( STATUSCLASSNAME, WS_CHILD | WS_VISIBLE, _mainWindow );
217 setRatios( 4, 1, 3, 1, 3, 1 );
218 }
219
220 void setRatios( unsigned suiteNameRatio, unsigned suiteTimeRatio,
221 unsigned testNameRatio, unsigned testTimeRatio,
222 unsigned testsDoneRatio, unsigned worldTimeRatio )
223 {
224 _statusTotal = 0;
225 _statusOffsets[STATUS_SUITE_NAME] = (_statusTotal += suiteNameRatio);
226 _statusOffsets[STATUS_SUITE_TIME] = (_statusTotal += suiteTimeRatio);
227 _statusOffsets[STATUS_TEST_NAME] = (_statusTotal += testNameRatio);
228 _statusOffsets[STATUS_TEST_TIME] = (_statusTotal += testTimeRatio);
229 _statusOffsets[STATUS_TESTS_DONE] = (_statusTotal += testsDoneRatio);
230 _statusOffsets[STATUS_WORLD_TIME] = (_statusTotal += worldTimeRatio);
231 }
232
233 HWND createWindow( LPCTSTR className, DWORD style, HWND parent = (HWND)NULL )
234 {
235 return CreateWindow( className, NULL, style, 0, 0, 0, 0, parent,
236 (HMENU)NULL, (HINSTANCE)NULL, (LPVOID)this );
237 }
238
239 void progressBarMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 )
240 {
241 SendMessage( _progressBar, message, wParam, lParam );
242 }
243
245 {
246 RECT screen;
247 getScreenArea( screen );
248
249 LONG screenWidth = screen.right - screen.left;
250 LONG screenHeight = screen.bottom - screen.top;
251
252 LONG xCenter = (screen.right + screen.left) / 2;
253 LONG yCenter = (screen.bottom + screen.top) / 2;
254
255 LONG windowWidth = (screenWidth * 4) / 5;
256 LONG windowHeight = screenHeight / 10;
257 LONG minimumHeight = 2 * (GetSystemMetrics( SM_CYCAPTION ) + GetSystemMetrics( SM_CYFRAME ));
258 if ( windowHeight < minimumHeight )
259 windowHeight = minimumHeight;
260
261 SetWindowPos( _mainWindow, HWND_TOP,
262 xCenter - (windowWidth / 2), yCenter - (windowHeight / 2),
263 windowWidth, windowHeight, 0 );
264 }
265
266 void getScreenArea( RECT &area )
267 {
268 if ( !getScreenAreaWithoutTaskbar( area ) )
269 getWholeScreenArea( area );
270 }
271
273 {
274 return (SystemParametersInfo( SPI_GETWORKAREA, sizeof(RECT), &area, 0 ) != 0);
275 }
276
277 void getWholeScreenArea( RECT &area )
278 {
279 area.left = area.top = 0;
280 area.right = GetSystemMetrics( SM_CXSCREEN );
281 area.bottom = GetSystemMetrics( SM_CYSCREEN );
282 }
283
285 {
286 showMainWindow( _startMinimized ? SW_MINIMIZE : SW_SHOWNORMAL );
287 UpdateWindow( _mainWindow );
288 }
289
290 void showMainWindow( int mode )
291 {
292 ShowWindow( _mainWindow, mode );
293 }
294
295 enum { TIMER_ID = 1, TIMER_DELAY = 1000 };
296
298 {
301 reset( _testStart );
302 SetTimer( _mainWindow, TIMER_ID, TIMER_DELAY, 0 );
303 }
304
305 void reset( DWORD &tick )
306 {
307 tick = GetTickCount();
308 }
309
311 {
312 SetEvent( _canStartTests );
313 }
314
316 {
317 MSG message;
318 while ( BOOL haveMessage = GetMessage( &message, NULL, 0, 0 ) )
319 if ( haveMessage != -1 )
320 DispatchMessage( &message );
321 }
322
323 static LRESULT CALLBACK windowProcedure( HWND window, UINT message, WPARAM wParam, LPARAM lParam )
324 {
325 if ( message == WM_CREATE )
326 setUp( window, (LPCREATESTRUCT)lParam );
327
328 Win32Gui *that = (Win32Gui *)GetWindowLong( window, GWL_USERDATA );
329 return that->handle( window, message, wParam, lParam );
330 }
331
332 static void setUp( HWND window, LPCREATESTRUCT create )
333 {
334 SetWindowLong( window, GWL_USERDATA, (LONG)create->lpCreateParams );
335 }
336
337 LRESULT handle( HWND window, UINT message, WPARAM wParam, LPARAM lParam )
338 {
339 switch ( message )
340 {
341 case WM_SIZE: resizeControls(); break;
342
343 case WM_TIMER: updateTime(); break;
344
345 case WM_CLOSE:
346 case WM_DESTROY:
347 case WM_QUIT:
348 ExitProcess( 0 );
349
350 default: return DefWindowProc( window, message, wParam, lParam );
351 }
352 return 0;
353 }
354
356 {
357 RECT r;
358 GetClientRect( _mainWindow, &r );
359 LONG width = r.right - r.left;
360 LONG height = r.bottom - r.top;
361
362 GetClientRect( _statusBar, &r );
363 LONG statusHeight = r.bottom - r.top;
364 LONG resizeGripWidth = statusHeight;
365 LONG progressHeight = height - statusHeight;
366
367 SetWindowPos( _progressBar, HWND_TOP, 0, 0, width, progressHeight, 0 );
368 SetWindowPos( _statusBar, HWND_TOP, 0, progressHeight, width, statusHeight, 0 );
369 setStatusParts( width - resizeGripWidth );
370 }
371
372 void setStatusParts( LONG width )
373 {
374 for ( unsigned i = 0; i < STATUS_TOTAL_PARTS; ++ i )
376
378 }
379
380 void statusBarMessage( UINT message, WPARAM wParam = 0, const void *lParam = 0 )
381 {
382 SendMessage( _statusBar, message, wParam, (LPARAM)lParam );
383 }
384
385 void greenBar()
386 {
387 setColor( 0, 255, 0 );
388 setIcon( IDI_INFORMATION );
389 }
390
391#ifdef PBM_SETBARCOLOR
392 void setColor( BYTE red, BYTE green, BYTE blue )
393 {
394 progressBarMessage( PBM_SETBARCOLOR, 0, RGB( red, green, blue ) );
395 }
396#else // !PBM_SETBARCOLOR
397 void setColor( BYTE, BYTE, BYTE )
398 {
399 }
400#endif // PBM_SETBARCOLOR
401
402 void setIcon( LPCTSTR icon )
403 {
404 SendMessage( _mainWindow, WM_SETICON, ICON_BIG, (LPARAM)loadStandardIcon( icon ) );
405 }
406
407 HICON loadStandardIcon( LPCTSTR icon )
408 {
409 return LoadIcon( (HINSTANCE)NULL, icon );
410 }
411
412 void setTestCaption( const char *suiteName, const char *testName )
413 {
414 setCaption( suiteName, "::", testName, "()" );
415 }
416
417 void setCaption( const char *a = "", const char *b = "", const char *c = "", const char *d = "" )
418 {
419 unsigned length = lstrlenA( _title ) + sizeof( " - " ) +
420 lstrlenA( a ) + lstrlenA( b ) + lstrlenA( c ) + lstrlenA( d );
421 char *name = allocate( length );
422 lstrcpyA( name, _title );
423 lstrcatA( name, " - " );
424 lstrcatA( name, a );
425 lstrcatA( name, b );
426 lstrcatA( name, c );
427 lstrcatA( name, d );
428 SetWindowTextA( _mainWindow, name );
429 deallocate( name );
430 }
431
432 void showSuiteName( const char *suiteName )
433 {
434 setStatusPart( STATUS_SUITE_NAME, suiteName );
435 }
436
437 void showTestName( const char *testName )
438 {
439 setStatusPart( STATUS_TEST_NAME, testName );
440 }
441
443 {
444 wsprintfA( _statusTestsDone, "%u of %s (%u%%)",
446 (_testsDone * 100) / _numTotalTests );
448 }
449
451 {
455 }
456
457 void setStatusTime( unsigned part, DWORD start )
458 {
459 unsigned total = (GetTickCount() - start) / 1000;
460 unsigned hours = total / 3600;
461 unsigned minutes = (total / 60) % 60;
462 unsigned seconds = total % 60;
463
464 if ( hours )
465 wsprintfA( _timeString, "%u:%02u:%02u", hours, minutes, seconds );
466 else
467 wsprintfA( _timeString, "%02u:%02u", minutes, seconds );
468
469 setStatusPart( part, _timeString );
470 }
471
472 bool keep()
473 {
474 if ( !_keep )
475 return false;
476 if ( !_startMinimized )
477 return true;
478 return (_mainWindow == GetForegroundWindow());
479 }
480
482 {
483 stopTimer();
486 }
487
488 void setStatusPart( unsigned part, const char *text )
489 {
490 statusBarMessage( SB_SETTEXTA, part, text );
491 }
492
494 {
495 KillTimer( _mainWindow, TIMER_ID );
497 }
498
500 {
501 setRatios( 0, 0, 0, 0, 1, 1 );
503
504 const char *tests = (_numTotalTests == 1) ? "test" : "tests";
505 if ( tracker().failedTests() )
506 wsprintfA( _statusTestsDone, "Failed %u of %s %s",
507 tracker().failedTests(), _strTotalTests, tests );
508 else
509 wsprintfA( _statusTestsDone, "%s %s passed", _strTotalTests, tests );
510
512 }
513
515 {
517 }
518
519 char *allocate( unsigned length )
520 {
521 return (char *)HeapAlloc( GetProcessHeap(), 0, length );
522 }
523
524 void deallocate( char *data )
525 {
526 HeapFree( GetProcessHeap(), 0, data );
527 }
528 };
529};
530
531#endif // __cxxtest__Win32Gui_h__
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
int i
Definition: cfEzgcd.cc:132
CanonicalForm b
Definition: cfModGcd.cc:4103
unsigned failedTests() const
Definition: TestTracker.h:37
void setCaption(const char *a="", const char *b="", const char *c="", const char *d="")
Definition: Win32Gui.h:417
static LRESULT CALLBACK windowProcedure(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
Definition: Win32Gui.h:323
void progressBarMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0)
Definition: Win32Gui.h:239
void centerMainWindow()
Definition: Win32Gui.h:244
void getTotalTests()
Definition: Win32Gui.h:122
void createProgressBar()
Definition: Win32Gui.h:199
int _statusWidths[STATUS_TOTAL_PARTS]
Definition: Win32Gui.h:99
unsigned _statusTotal
Definition: Win32Gui.h:101
void setSummaryStatusBar()
Definition: Win32Gui.h:499
void statusBarMessage(UINT message, WPARAM wParam=0, const void *lParam=0)
Definition: Win32Gui.h:380
void setStatusTime(unsigned part, DWORD start)
Definition: Win32Gui.h:457
HWND createWindow(LPCTSTR className, DWORD style, HWND parent=(HWND) NULL)
Definition: Win32Gui.h:233
unsigned _statusOffsets[STATUS_TOTAL_PARTS]
Definition: Win32Gui.h:100
void startTimer()
Definition: Win32Gui.h:297
char _strTotalTests[WorldDescription::MAX_STRLEN_TOTAL_TESTS]
Definition: Win32Gui.h:92
HANDLE _canStartTests
Definition: Win32Gui.h:90
char * allocate(unsigned length)
Definition: Win32Gui.h:519
void leaveGui()
Definition: Win32Gui.h:74
void setStatusParts(LONG width)
Definition: Win32Gui.h:372
void getTotalTests(const WorldDescription &wd)
Definition: Win32Gui.h:127
void setIcon(LPCTSTR icon)
Definition: Win32Gui.h:402
void reset(DWORD &tick)
Definition: Win32Gui.h:305
void setRatios(unsigned suiteNameRatio, unsigned suiteTimeRatio, unsigned testNameRatio, unsigned testTimeRatio, unsigned testsDoneRatio, unsigned worldTimeRatio)
Definition: Win32Gui.h:220
void messageLoop()
Definition: Win32Gui.h:315
void showSuiteName(const char *suiteName)
Definition: Win32Gui.h:432
void enterWorld(const WorldDescription &wd)
Definition: Win32Gui.h:35
void enterGui(int &argc, char **argv)
Definition: Win32Gui.h:30
void getScreenArea(RECT &area)
Definition: Win32Gui.h:266
static void setUp(HWND window, LPCREATESTRUCT create)
Definition: Win32Gui.h:332
const char * _title
Definition: Win32Gui.h:85
void startGuiThread()
Definition: Win32Gui.h:133
void showTestName(const char *testName)
Definition: Win32Gui.h:437
bool _startMinimized
Definition: Win32Gui.h:86
void updateTime()
Definition: Win32Gui.h:450
void guiEnterSuite(const char *suiteName)
Definition: Win32Gui.h:42
void initCommonControls()
Definition: Win32Gui.h:185
void parseCommandLine(int argc, char **argv)
Definition: Win32Gui.h:106
void resizeControls()
Definition: Win32Gui.h:355
void guiEnterTest(const char *suiteName, const char *testName)
Definition: Win32Gui.h:48
void showMainWindow(int mode)
Definition: Win32Gui.h:290
unsigned _numTotalTests
Definition: Win32Gui.h:91
static DWORD WINAPI guiThread(LPVOID parameter)
Definition: Win32Gui.h:141
WNDCLASSEX _windowClass
Definition: Win32Gui.h:88
void getWholeScreenArea(RECT &area)
Definition: Win32Gui.h:277
void deallocate(char *data)
Definition: Win32Gui.h:524
unsigned _testsDone
Definition: Win32Gui.h:91
LRESULT handle(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
Definition: Win32Gui.h:337
bool getScreenAreaWithoutTaskbar(RECT &area)
Definition: Win32Gui.h:272
void createMainWindow()
Definition: Win32Gui.h:180
void showTestsDone()
Definition: Win32Gui.h:442
void setColor(BYTE, BYTE, BYTE)
Definition: Win32Gui.h:397
char _statusTestsDone[sizeof("1000000000 of (100%)")+WorldDescription::MAX_STRLEN_TOTAL_TESTS]
Definition: Win32Gui.h:102
void showSummary()
Definition: Win32Gui.h:481
void createStatusBar()
Definition: Win32Gui.h:214
void setSummaryCaption()
Definition: Win32Gui.h:514
void setTestCaption(const char *suiteName, const char *testName)
Definition: Win32Gui.h:412
char _timeString[sizeof("00:00:00")]
Definition: Win32Gui.h:104
void registerWindowClass()
Definition: Win32Gui.h:162
void setStatusPart(unsigned part, const char *text)
Definition: Win32Gui.h:488
void stopTimer()
Definition: Win32Gui.h:493
void yellowBar()
Definition: Win32Gui.h:58
HICON loadStandardIcon(LPCTSTR icon)
Definition: Win32Gui.h:407
void startTests()
Definition: Win32Gui.h:310
void showMainWindow()
Definition: Win32Gui.h:284
char * strTotalTests(char *) const
virtual unsigned numTotalTests(void) const =0
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:257
NodeM * create()
Definition: janet.cc:757
void message(int i, int *reduc, int *olddeg, kStrategy strat, int red_result)
Definition: kutil.cc:7512
#define LONG
Definition: longrat.cc:105
TestTracker & tracker()
Definition: TestTracker.h:111
#define NULL
Definition: omList.c:12
int name
New type name for int.
Definition: templateForC.h:21