My Project  debian-1:4.1.2-p1+ds-2
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 
25 namespace 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 );
45  reset( _suiteStart );
46  }
47 
48  void guiEnterTest( const char *suiteName, const char *testName )
49  {
50  ++ _testsDone;
51  setTestCaption( suiteName, testName );
52  showTestName( testName );
53  showTestsDone();
54  progressBarMessage( PBM_STEPIT );
55  reset( _testStart );
56  }
57 
58  void yellowBar()
59  {
60  setColor( 255, 255, 0 );
61  setIcon( IDI_WARNING );
62  getTotalTests();
63  }
64 
65  void redBar()
66  {
67  if ( _startMinimized )
68  showMainWindow( SW_SHOWNORMAL );
69  setColor( 255, 0, 0 );
70  setIcon( IDI_ERROR );
71  getTotalTests();
72  }
73 
74  void leaveGui()
75  {
76  if ( keep() )
77  {
78  showSummary();
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 
127  void getTotalTests( const WorldDescription &wd )
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  {
153  createStatusBar();
155  showMainWindow();
156  startTimer();
157  startTests();
158 
159  messageLoop();
160  }
161 
163  {
164  _windowClass.cbSize = sizeof(_windowClass);
165  _windowClass.style = CS_HREDRAW | CS_VREDRAW;
166  _windowClass.lpfnWndProc = &(Win32Gui::windowProcedure);
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 
272  bool getScreenAreaWithoutTaskbar( RECT &area )
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 
297  void startTimer()
298  {
299  reset( _worldStart );
300  reset( _suiteStart );
301  reset( _testStart );
302  SetTimer( _mainWindow, TIMER_ID, TIMER_DELAY, 0 );
303  }
304 
305  void reset( DWORD &tick )
306  {
307  tick = GetTickCount();
308  }
309 
310  void startTests()
311  {
312  SetEvent( _canStartTests );
313  }
314 
315  void messageLoop()
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 )
375  _statusWidths[i] = (width * _statusOffsets[i]) / _statusTotal;
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 
450  void updateTime()
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 
481  void showSummary()
482  {
483  stopTimer();
486  }
487 
488  void setStatusPart( unsigned part, const char *text )
489  {
490  statusBarMessage( SB_SETTEXTA, part, text );
491  }
492 
493  void stopTimer()
494  {
495  KillTimer( _mainWindow, TIMER_ID );
497  }
498 
500  {
501  setRatios( 0, 0, 0, 0, 1, 1 );
502  resizeControls();
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:125
CanonicalForm b
Definition: cfModGcd.cc:4044
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
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
char * allocate(unsigned length)
Definition: Win32Gui.h:519
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
char name(const Variable &v)
Definition: factory.h:180
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:263
NodeM * create()
Definition: janet.cc:757
void message(int i, int *reduc, int *olddeg, kStrategy strat, int red_result)
Definition: kutil.cc:7954
#define LONG
Definition: longrat.cc:110
TestTracker & tracker()
Definition: TestTracker.h:111
#define NULL
Definition: omList.c:12