home *** CD-ROM | disk | FTP | other *** search
/ Mastering Visual Basic 6 / mastvb6.iso / numega / sc501.exe / data1.cab / Examples / BUGBENCH.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-25  |  32.8 KB  |  1,095 lines

  1. /*
  2.  * BugBench.cpp
  3.  * $Header: /BoundsChecker/Examples/BUGBNCHX/BUGBENCH.CPP 6     4/09/97 9:26a Bob $
  4.  *
  5.  * Description:
  6.  *  Defines the behavior for the application and the main dialog box.
  7.  *
  8.  * Notes:
  9.  *  <implementation notes go here>
  10.  *
  11.  ***********************************************************************
  12.  *
  13.  * Nu-Mega Technologies, Inc.
  14.  * P.O. Box 7780
  15.  * Nashua, NH 03060
  16.  *
  17.  * (c) Copyright 1994, 1995 Nu-Mega Technologies, Inc.
  18.  * ALL RIGHTS RESERVED.
  19.  *
  20.  ***********************************************************************
  21.  *
  22.  **********************************************************************/
  23. #include "stdafx.h"
  24. #include <time.h>
  25. #include <ctl3d.h>
  26. #ifndef BCBVER
  27. #include <crtdbg.h>
  28. #endif
  29.  
  30. #include "bcerrtyp.h"
  31.  
  32. #include "cstatbmp.h"
  33. #include "BCTree.h"
  34. #include "aboutbox.h"
  35. #include "RegIface.h"
  36.  
  37. #include "BugBench.h"
  38. #include "resource.h"
  39.  
  40. ////////////////////////////////////////////////////////////////////////
  41. // Types
  42. typedef void (*PFUNC_POPTREE) ( HWND hWndTree ) ;
  43. typedef void (*PFUNC_DEPOPTREE) ( HWND hWndTree ) ;
  44. typedef void (*PFUNC_DORANDOM) ( ) ;
  45. typedef void (*PFUNC_DOALL) ( ) ;
  46.  
  47.  
  48. ////////////////////////////////////////////////////////////////////////
  49. // Constants that we need.
  50. // The application name.
  51. #ifndef BCBVER
  52. const TCHAR * constAPPNAME = _T ( "BugBench" ) ;
  53. #else
  54. const TCHAR * constAPPNAME = _T ( "BugBcb" ) ;
  55. #endif
  56. const constMaxBugModules = 255 ;
  57.  
  58. ////////////////////////////////////////////////////////////////////////
  59. // Globals
  60. HINSTANCE g_hInstance              ;
  61. HICON     g_hIcon                  ;
  62. BOOL      g_fDoRealizationInActive ;
  63. BOOL      g_fSkipMsgBox            ;
  64. HWND      g_hwndTree               ;
  65. HWND      g_hwndStaticBmp          ;
  66. HINSTANCE g_hBugModArray [ constMaxBugModules ]   ;
  67. int       g_nBugModules ;
  68. int          g_nRunError;
  69.  
  70. ////////////////////////////////////////////////////////////////////////
  71.  
  72.  
  73. void MainDlg_FreeBugModules ( ) 
  74. {
  75.     for ( int i = 0; i < g_nBugModules ; i++ )
  76.     {
  77.         PFUNC_DEPOPTREE pFreeFunc = ( PFUNC_DEPOPTREE ) GetProcAddress ( g_hBugModArray [ i ], _T ( "DePopulateTree" ) ) ;
  78.         if ( NULL == pFreeFunc )
  79.         {
  80.             pFreeFunc = ( PFUNC_DEPOPTREE ) GetProcAddress ( g_hBugModArray [ i ], _T ( "_DePopulateTree" ));
  81.         }
  82.         if ( NULL != pFreeFunc )
  83.         {
  84. #ifndef BCBVER
  85.             __try
  86.             {
  87. #else
  88.             try
  89.             {
  90. #endif
  91.                 pFreeFunc ( g_hwndTree );
  92.             }
  93.             __except ( EXCEPTION_EXECUTE_HANDLER )
  94.             {
  95.             } 
  96.         }
  97.  
  98.         FreeLibrary ( g_hBugModArray [ i ] ) ;
  99.     }
  100. }
  101.  
  102. void MainDlg_CleanUpAndShutDown ( HWND hWnd )
  103. {
  104.    // Cleans up all allocations.  It doesn't really look good
  105.    //  if Nu-Mega's own demo applications show all sorts of problems
  106.    //  and leaks.
  107.    ASSERT ( NULL != g_hwndTree ) ;
  108.    ASSERT ( NULL != g_hwndStaticBmp ) ;
  109.  
  110.    // Hide the window so we don't see every single tree node deleted.
  111.    ShowWindow ( hWnd , SW_HIDE ) ;
  112.  
  113.    // Delete all items in the tree control.
  114.    //TreeCtrl_DeleteAllItems ( g_hwndTree ) ;
  115.    MainDlg_FreeBugModules ( ) ;
  116.  
  117.    StaticBitmap_CleanUp ( g_hwndStaticBmp ) ;
  118.  
  119.    // End it.
  120.    EndDialog ( hWnd , 0 ) ;
  121. }
  122.  
  123. // Bring up the AboutBox.
  124. void MainDlg_OnAbout ( HWND hWnd )
  125. {
  126.    DialogBox ( g_hInstance                      ,
  127.                MAKEINTRESOURCE ( IDD_ABOUTBOX ) ,
  128.                hWnd                             ,
  129.                ( DLGPROC ) AboutBox_DlgProc      ) ;
  130. }
  131.  
  132. // Execute a error check testing function.
  133. BOOL MainDlg_IsItemExecutable ( HWND hwndDlg )
  134. {
  135.    BOOL  executable = FALSE;
  136.    LParamInfo * pInfo = 
  137.                ( LParamInfo * ) TreeCtrl_GetSelectedLParam ( g_hwndTree ) ;
  138.  
  139.    // The only items that have functions are the leaf nodes.
  140.    if ( 2 == pInfo->iType )
  141.    {
  142.       // Since some of the functions might not be done yet, we
  143.       //  need to do some sanity check before setting EIP to NULL
  144.       //  and executing it.
  145.       if ( NULL != pInfo->stEO.pFunc )
  146.       {
  147.          executable = TRUE;
  148.       }
  149.    }
  150.    return executable;
  151. }
  152. // Execute a error check testing function.
  153. void MainDlg_ExecuteFunction ( HWND hwndDlg )
  154. {
  155.    if ( MainDlg_IsItemExecutable ( hwndDlg ) == TRUE )
  156.    {
  157.       LParamInfo * pInfo = 
  158.             ( LParamInfo * ) TreeCtrl_GetSelectedLParam ( g_hwndTree ) ;
  159.       pInfo->stEO.pFunc ( ) ;
  160.    }
  161. }
  162.  
  163. // Handle the double click event on the tree control.
  164. void MainDlg_OnDblClkTreeList ( HWND hwndDlg      ,
  165.                                 NMHDR   *         ,
  166.                                 LRESULT * pResult  )
  167. {
  168.    MainDlg_ExecuteFunction ( hwndDlg ) ;
  169.    *pResult = 0 ;
  170. }
  171.  
  172. // Handle the test button or the test menu item.
  173. void MainDlg_OnTest ( HWND hwndDlg )
  174. {
  175.    MainDlg_ExecuteFunction ( hwndDlg ) ;
  176. }
  177.  
  178. // Handle the 5 random button.
  179. void MainDlg_OnFiveRandom ( HWND hwndDlg )
  180. {
  181.    // reseed each time through.
  182.    srand( (unsigned) time( NULL ) ) ;
  183.  
  184.    // Pick a random bug module.
  185.    int iMod = rand ( ) % g_nBugModules ;
  186.    PFUNC_DORANDOM pDoRandomFunc = ( PFUNC_DORANDOM ) GetProcAddress ( g_hBugModArray [ iMod ], _T ( "DoRandomErrors" ) ) ;
  187.    if ( NULL == pDoRandomFunc )
  188.    {
  189.       pDoRandomFunc = ( PFUNC_DORANDOM ) GetProcAddress ( g_hBugModArray [ iMod ], _T ( "_DoRandomErrors" ) );
  190.    }
  191.    if ( NULL != pDoRandomFunc )
  192.    {
  193. #ifndef BCBVER
  194.       __try
  195.       {
  196. #else
  197.       try
  198.       {
  199. #endif      
  200.           // Call its random func.
  201.           pDoRandomFunc ( );
  202.       }
  203.       __except ( EXCEPTION_EXECUTE_HANDLER )
  204.       {
  205.       } 
  206.    }
  207. }
  208.  
  209. // Handle the hidden button (or Ctrl-P).
  210. void MainDlg_OnAllDo ( HWND hwndDlg )
  211. {
  212.    // Do all the errors in all the bug modules
  213.    for ( int i = 0; i < g_nBugModules ; i++ )
  214.    {
  215.       PFUNC_DOALL pDoAllFunc = ( PFUNC_DOALL ) GetProcAddress ( g_hBugModArray [ i ], _T ( "DoAllErrors" ) ) ;
  216.       if ( NULL == pDoAllFunc )
  217.       {
  218.           pDoAllFunc = ( PFUNC_DOALL ) GetProcAddress ( g_hBugModArray [ i ], _T ( "_DoAllErrors" ) );
  219.       }
  220.       if ( NULL != pDoAllFunc )
  221.       {
  222. #ifndef BCBVER
  223.           __try
  224.           {
  225. #else
  226.           try
  227.           {
  228. #endif
  229.               pDoAllFunc ( );
  230.           }
  231.           __except ( EXCEPTION_EXECUTE_HANDLER )
  232.           {
  233.           } 
  234.       }
  235.    }
  236. }
  237.  
  238. // Handle the expand all menu item.
  239. void MainDlg_OnExpandAll ( HWND hwndDlg )
  240. {
  241.    ASSERT ( NULL != g_hwndTree ) ;
  242.    TreeCtrl_ExpandAll ( g_hwndTree , TVE_EXPAND ) ;
  243.    TreeCtrl_EnsureVisible ( g_hwndTree , TreeCtrl_GetSelectedItem ( g_hwndTree ) ) ;
  244. }
  245.  
  246. // Handle the collapse all menu item.
  247. void MainDlg_OnCollapseAll ( HWND hwndDlg )
  248. {
  249.    ASSERT ( NULL != g_hwndTree ) ;
  250.  
  251.    TreeCtrl_ExpandAll ( g_hwndTree , TVE_COLLAPSE ) ;
  252.    TreeCtrl_EnsureVisible ( g_hwndTree , TreeCtrl_GetSelectedItem ( g_hwndTree ) ) ;
  253. }
  254.  
  255. BOOL MainDlg_InitBugModule ( LPCTSTR szModName )
  256. {
  257.     BOOL fReturn = FALSE ;
  258.  
  259.     if ( NULL != szModName )
  260.     {
  261.         // Attempt to load the DLL.  The assumption is made that
  262.         // LoadLibrary will prevent any serious errors in the 
  263.         // DLLs DllMain function from hosing our memory.  
  264.         HINSTANCE hExtension = LoadLibrary ( szModName ) ;
  265.         if ( NULL != hExtension )
  266.         {
  267.             PFUNC_POPTREE pInitFunc = ( PFUNC_POPTREE ) GetProcAddress ( hExtension , _T ( "PopulateTree" ) ) ;
  268.             if ( NULL == pInitFunc )
  269.             {
  270.                 pInitFunc = ( PFUNC_POPTREE ) GetProcAddress ( hExtension, _T ("_PopulateTree" ));
  271.             }
  272.             DWORD dwError = GetLastError ( ) ;
  273.             if ( NULL != pInitFunc )
  274.             {
  275.                 // Before we try calling the initialization function,
  276.                 // setup the exception handler, so if the export isn't
  277.                 // setup right by the DLL, we won't blow up.
  278. #ifndef BCBVER
  279.                 __try
  280.                 {
  281. #else
  282.                 try
  283.                 {
  284. #endif                
  285.                     pInitFunc ( g_hwndTree );
  286.                     g_hBugModArray [ g_nBugModules++ ] = hExtension;
  287.  
  288.                     fReturn = TRUE ;
  289.                 }
  290.                 __except ( EXCEPTION_EXECUTE_HANDLER )
  291.                 {
  292.                 } 
  293.             }  // if valid function pointer
  294.             else
  295.                 FreeLibrary ( hExtension ) ;
  296.  
  297.         }  // if valid extension DLL instance handle
  298.     }
  299.  
  300.     return fReturn ;
  301.  
  302. }
  303.  
  304. void MainDlg_LoadBugModules ( )
  305. {
  306.     // Begin enumerating the DLLs
  307.     HANDLE hFind ;
  308.     WIN32_FIND_DATA findData = { 0 } ;
  309.  
  310.     g_nBugModules = 0;
  311.  
  312.     hFind = FindFirstFile ( "*.bug", &findData ) ;
  313.  
  314.     if ( hFind == INVALID_HANDLE_VALUE )
  315.         TRACE ( _T ( "No BugModules Found.\n" ) ) ;
  316.     else
  317.     {
  318.         do
  319.         {
  320.             // Pass it to the InitExtension routine. Using the
  321.             // full path prevents other DLLs in the path with
  322.             // the same name from being loaded.
  323.             if ( MainDlg_InitBugModule ( findData.cFileName ) )
  324.             {
  325.                 TRACE1 ( _T ( "BugModule Loaded: %s\n" ) , findData.cFileName ) ;
  326.             }
  327.             else
  328.                 TRACE1 ( _T ( "Unable to load BugModule: %s\n" ) , findData.cFileName ) ;
  329.         }
  330.         while ( FindNextFile ( hFind , &findData ) ) ;
  331.  
  332.         FindClose ( hFind ) ;
  333.     }
  334.  
  335.     // Return the selected item to be the first item in the tree control.
  336.     HTREEITEM hitemFirst = TreeView_GetNextItem ( g_hwndTree , NULL , TVGN_ROOT ) ;
  337.     if ( NULL != hitemFirst )
  338.         TreeView_SelectItem ( g_hwndTree , hitemFirst ) ;
  339.  
  340. }
  341.  
  342. BOOL MainDlg_SelectError( HWND hwndDlg, HTREEITEM item, UINT code, int & errorValue )
  343. {
  344.     BOOL    found = FALSE;
  345.  
  346.     item = TreeView_GetNextItem ( g_hwndTree , item , code ) ;
  347.     if ( item == NULL )
  348.         return found;
  349.  
  350.     TreeCtrl_Select ( g_hwndTree, item, TVGN_CARET ) ;
  351.     if ( MainDlg_IsItemExecutable( hwndDlg ) == TRUE )
  352.     {
  353.         if( ++errorValue == g_nRunError )
  354.         {
  355.             found = TRUE;
  356.         }
  357.         else
  358.         {
  359.             found = MainDlg_SelectError( hwndDlg, item, TVGN_NEXT, errorValue );
  360.         }
  361.     }
  362.     else
  363.     {
  364.         found = MainDlg_SelectError( hwndDlg, item, TVGN_CHILD, errorValue );
  365.         if( found != TRUE )
  366.             found = MainDlg_SelectError( hwndDlg, item, TVGN_NEXT, errorValue );
  367.     }
  368.     return found;
  369. }
  370.  
  371. void MainDlg_RunError( HWND hwndDlg )
  372. {
  373.     int currentError = 0;
  374.     if( MainDlg_SelectError( hwndDlg, NULL, TVGN_ROOT, currentError ) == TRUE )
  375.     {
  376.         MainDlg_ExecuteFunction( hwndDlg );
  377.     }
  378. }
  379.  
  380. ///////////////////////////////////////////////////////////
  381. // Handles the WM_INITDIALOG message for the main dialog.
  382. BOOL MainDlg_OnInitDialog ( HWND hWnd , HWND hwndFocus , LPARAM lParam )
  383. {
  384.    TCHAR szBuff[ 1024 ] ;
  385.    BOOL fRetVal = TRUE ;
  386.    HMENU hSysMenu ;
  387.    int nSysMenuItems ;
  388.    DWORD dwStyle ;
  389.  
  390.    // Initialize globals
  391.    g_hIcon                  = NULL  ;
  392.    g_fDoRealizationInActive = FALSE ;
  393.    g_hwndTree               = NULL  ;
  394.    g_hwndStaticBmp          = NULL  ;
  395.    g_hIcon = LoadIcon ( g_hInstance , MAKEINTRESOURCE ( IDR_MAINFRAME ) ) ;
  396.    ASSERT ( NULL != g_hIcon ) ;
  397.  
  398.    // Set the icon of the dialog to be the mainframe icon.
  399.    SendMessage(hWnd, WM_SETICON, FALSE, (LPARAM)g_hIcon);
  400.    SendMessage(hWnd, WM_SETICON, TRUE, (LPARAM)g_hIcon);
  401.  
  402.  
  403.    dwStyle = GetWindowLong ( hWnd , GWL_STYLE ) ;
  404.    dwStyle |= DS_3DLOOK ;
  405.    SetWindowLong ( hWnd , GWL_STYLE , dwStyle ) ;
  406.  
  407.    // Add "About..." menu item to system men
  408.    // IDM_ABOUTBOX must be in the system command range.
  409.    ASSERT ( ( IDM_ABOUTBOX & 0xFFF0 ) == IDM_ABOUTBOX ) ;
  410.    ASSERT ( IDM_ABOUTBOX < 0xF000 ) ;
  411.  
  412.    hSysMenu = GetSystemMenu ( hWnd , FALSE ) ;
  413.  
  414.    VERIFY ( LoadString ( GetModuleHandle ( NULL )   ,
  415.                            IDS_ABOUTBOX             ,
  416.                            szBuff                   ,
  417.                            sizeof ( szBuff )         ) ) ;
  418.  
  419.    nSysMenuItems = GetMenuItemCount ( hSysMenu ) ;
  420.    if ( ( nSysMenuItems != 0 ) && ( nSysMenuItems != -1 ) )
  421.    {
  422.       if ( ! AppendMenu ( hSysMenu , MF_SEPARATOR , 0 , NULL ) )
  423.          fRetVal = FALSE ;
  424.       if ( ! AppendMenu ( hSysMenu , MF_STRING , IDM_ABOUTBOX , szBuff ) )
  425.          fRetVal = FALSE ;
  426.    }
  427.  
  428.    // Get the HWNDs for the tree control and the static
  429.    //  bitmap.
  430.    g_hwndTree = GetDlgItem ( hWnd , IDC_TREELIST ) ;
  431.    ASSERT ( NULL != g_hwndTree ) ;
  432.    if ( NULL == g_hwndTree ) 
  433.       fRetVal = FALSE ;
  434.  
  435.    g_hwndStaticBmp = GetDlgItem ( hWnd , IDC_BCBITMAP ) ;
  436.    ASSERT ( NULL != g_hwndStaticBmp ) ;
  437.    if ( NULL == g_hwndStaticBmp ) 
  438.       fRetVal = FALSE ;
  439.       
  440.    // Center the window.
  441.    CenterWindow ( hWnd ) ;
  442.  
  443.    // Initialize the bitmap
  444.    if ( ! StaticBitmap_Init ( g_hwndStaticBmp ) )
  445.       fRetVal = FALSE ;
  446.    
  447.    // Fill the tree control with data.
  448.    //FillTree ( g_hwndTree ) ; 
  449.    MainDlg_LoadBugModules ( ) ;
  450.  
  451.    if( g_nRunError != 0 )
  452.    {
  453.        // Run error
  454.         MainDlg_RunError( hWnd );
  455.       // Shut bugbench down without ever having displayed it.
  456.       MainDlg_CleanUpAndShutDown ( hWnd );
  457.    }
  458.  
  459.    // Show the "Danger Will Robinson" message.
  460.    TCHAR * szMsg = _T ( "All efforts have been made to make BugBench\n"\
  461.                         "as failsafe as possible. However, wild pointer\n"\
  462.                         "writes can always bring down the best programs.\n"\
  463.                         "Additionally, it is possible to corrupt the heap\n"\
  464.                         "with certain combinations of errors that stop\n"
  465.                         "BugBench. While BugBench might end,\n"\
  466.                         "BoundsChecker will always show you where\n"
  467.                         "the errors are!" ) ;
  468.    if ( FALSE == g_fSkipMsgBox )
  469.    {
  470.       MessageBox ( NULL          ,
  471.                    szMsg         ,
  472.                    constAPPNAME  ,
  473.                    MB_APPLMODAL | MB_OK ) ;
  474.    }
  475.  
  476.    return ( fRetVal ) ;
  477. }
  478.  
  479. ///////////////////////////////////////////////////////////
  480. // Handles WM_COMMAND messages for the main dialog.
  481. void MainDlg_OnCommand ( HWND  hWnd         ,
  482.                          int   idCmd        ,
  483.                          HWND  hWndCtl      ,
  484.                          UINT  uiCodeNotify  )
  485. {
  486.    switch ( idCmd )
  487.    {
  488.       // If it is one of the bugbench buttons.
  489.       case IDC_TEST        :
  490.       case IDM_TEST        :
  491.          MainDlg_OnTest ( hWnd ) ;
  492.          break ;
  493.       case IDC_FIVERANDOM  :
  494.          MainDlg_OnFiveRandom ( hWnd ) ;
  495.          break ;
  496.       case IDC_ABOUT       :
  497.          MainDlg_OnAbout ( hWnd ) ;
  498.          break ;
  499.       case IDC_CLOSE       :
  500.          MainDlg_CleanUpAndShutDown ( hWnd ) ;
  501.          break ;
  502.       case IDC_ALLDO       :
  503.          MainDlg_OnAllDo ( hWnd ) ;
  504.          break ;
  505.       case IDM_EXPANDALL   :
  506.          MainDlg_OnExpandAll ( hWnd ) ;
  507.          break ;
  508.       case IDM_COLLAPSEALL :
  509.          MainDlg_OnCollapseAll ( hWnd ) ;
  510.          break ;
  511.          
  512.    }
  513. }
  514.  
  515. // Handle the system menu ( for close and about ).
  516. void MainDlg_OnSysCommand ( HWND  hWnd         ,
  517.                             UINT  idCmd        ,
  518.                             int   xPos         ,
  519.                             int   yPos          )
  520. {
  521.    // Handle About.
  522.    if ( ( idCmd & 0xFFF0 ) == IDM_ABOUTBOX )
  523.    {
  524.       MainDlg_OnAbout ( hWnd ) ;
  525.    }
  526.    
  527.    // Handle Close
  528.    if ( SC_CLOSE == idCmd )
  529.    {
  530.       MainDlg_CleanUpAndShutDown ( hWnd ) ;
  531.    }
  532. }
  533.  
  534. void MainDlg_OnPaint ( HWND hWnd )
  535. {
  536.    PAINTSTRUCT ps ;
  537.    HDC hDC ;
  538.    int cxIcon, cyIcon ;
  539.  
  540.    if ( IsIconic ( hWnd ) )
  541.    {
  542.       // The device context for painting
  543.       hDC = BeginPaint ( hWnd , &ps ) ;
  544.       ASSERT ( NULL != hDC ) ;
  545.  
  546.       SendMessage( hWnd               , 
  547.                    WM_ICONERASEBKGND  ,
  548.                    ( WPARAM ) hDC     ,
  549.                    0                   );
  550.  
  551.       // Center icon in client rectangle
  552.       cxIcon = GetSystemMetrics ( SM_CXICON ) ;
  553.       cyIcon = GetSystemMetrics ( SM_CYICON ) ;
  554.       RECT rect ;
  555.       GetClientRect ( hWnd , &rect ) ;
  556.       int x = ( RECTWIDTH ( &rect ) - cxIcon + 1 ) / 2 ;
  557.       int y = ( RECTHEIGHT ( &rect ) - cyIcon + 1 ) / 2 ;
  558.  
  559.       // Draw the icon
  560.       DrawIcon ( hDC , x , y , g_hIcon ) ;
  561.    }
  562. }
  563.  
  564. HCURSOR MainDlg_OnQueryDragIcon ( HWND hWnd ) 
  565. {
  566.    return ( (HCURSOR) g_hIcon ) ;
  567. }
  568.  
  569. void MainDlg_OnPaletteChanged ( HWND hWnd , HWND hwndPaletteChange )
  570. {
  571.    // If we are not the window recieving the focus, call the
  572.    //  CStaticBitmap control to realize the palette.
  573.    if ( ( hwndPaletteChange != hWnd ) && ( FALSE == IsIconic ( hWnd ) ) )
  574.    {
  575.       ASSERT ( NULL != g_hwndStaticBmp ) ;
  576.       if ( NULL == g_hwndStaticBmp ) 
  577.          return ;
  578.       
  579.       StaticBitmap_RealizeDIBPalette ( g_hwndStaticBmp ) ;
  580.    }
  581. }
  582.  
  583. BOOL MainDlg_OnQueryNewPalette ( HWND hWnd ) 
  584. {   
  585.    BOOL fReturn = FALSE ;
  586.    // Sometimes the WM_QUERYNEWPALETTE message gets sent with the
  587.    //  before it should so we must then handle the palette realization
  588.    //  in the WM_ACTIVATE.
  589.    if ( GetActiveWindow ( ) != hWnd )
  590.    {
  591.       g_fDoRealizationInActive = TRUE ;
  592.       // Return TRUE here so that Windows knows we are an appl with
  593.       //  a palette to realize.
  594.       fReturn = TRUE  ;
  595.    }
  596.  
  597.    if ( ( ! fReturn ) && ( FALSE == IsIconic ( hWnd ) ) )
  598.    {
  599.       // Pass this off to the CStaticBitmap control.
  600.       ASSERT ( NULL != g_hwndStaticBmp ) ;
  601.       if ( NULL != g_hwndStaticBmp ) 
  602.          fReturn = StaticBitmap_RealizeDIBPalette ( g_hwndStaticBmp ) ;
  603.    }
  604.  
  605.    return ( fReturn ) ;
  606. }
  607.  
  608. void MainDlg_OnActivate ( HWND hWnd , UINT nState , HWND hwndActDeact, BOOL fMinimized )
  609. {
  610.    // Do we need to do the palette realization?
  611.    if ( TRUE == g_fDoRealizationInActive )
  612.    {
  613.       ASSERT ( NULL != g_hwndStaticBmp ) ;
  614.       if ( NULL != g_hwndStaticBmp ) 
  615.          StaticBitmap_RealizeDIBPalette ( g_hwndStaticBmp ) ;
  616.  
  617.       g_fDoRealizationInActive = FALSE ;
  618.    }
  619. }
  620.  
  621. void MainDlg_OnDeleteItemTreeList ( HWND hwndDlg , NMHDR* pNMHDR  , LRESULT* pResult )
  622. {
  623.    NM_TREEVIEW * pNMTreeView = (NM_TREEVIEW*)pNMHDR ;
  624.  
  625.    // Free the memory associated with the lParam.
  626. //   if ( 0 != pNMTreeView->itemOld.lParam )
  627. //      delete (LParamInfo*)pNMTreeView->itemOld.lParam ;
  628.    *pResult = 0;
  629. }
  630.  
  631. void MainDlg_OnSelChangedTreeList ( HWND hwndDlg , NMHDR* pNMHDR  , LRESULT* pResult )
  632. {
  633.    NM_TREEVIEW * pNMTreeView = (NM_TREEVIEW*)pNMHDR ;
  634.    // The buffer we load strings into.
  635.    TCHAR szBuff[ 1024 ] ;
  636.    // The current tree item we are working with.
  637.    HTREEITEM hItem ;
  638.    // The structure used to get information about specific items.
  639.    TV_ITEM stTI ;
  640.    // The flag we use to determine if we are supposed to enable
  641.    //  or disable the Test button.  It is only enabled if it is a
  642.    //  leaf node, which has the function in the lParam.
  643.    BOOL bEnableTestButton = FALSE ;
  644.    // The flag that we use to determine which LED to show next to the
  645.    //  BC Personal product.
  646.    BOOL bShowPersonalLEDON = FALSE ;
  647.    // The flag that tells us we need to show the product LEDs and
  648.    //  descriptions.
  649.    BOOL bShowLEDs = FALSE ;
  650.    // Depending on the item that gets the focus will determine what we
  651.    //  show in the description.  If it is a leaf node, then that is
  652.    //  what we show, otherwise we will show the root node text.
  653.    BOOL bShowRootNodeDescription = TRUE ;
  654.    // Icon used to show if standard edition supports the error
  655.    // check or not.
  656.    HICON hIcon ;
  657.    // Whether or not to show the LED windows
  658.    int iProductLEDsShow ;
  659.    // An HWND of IDC_DESCRIPTION static text.
  660.    HWND hwndDescription = NULL ;
  661.    // A standard HWND which we use to get the individual product
  662.    //  description controls.
  663.    HWND hWnd ;
  664.  
  665.    ASSERT ( NULL != g_hwndTree ) ;
  666.  
  667.    // Get the description's HWND
  668.    hwndDescription = GetDlgItem ( hwndDlg , IDC_DESCRIPTION ) ;
  669.    ASSERT ( NULL != hwndDescription ) ;
  670.  
  671.    *pResult = 0;
  672.  
  673.    // Get the new selected item's lParam.
  674.    LParamInfo * pLPI = (LParamInfo *)pNMTreeView->itemNew.lParam ;
  675.    ASSERT ( NULL != pLPI ) ;
  676.  
  677.    hItem = pNMTreeView->itemNew.hItem ;
  678.  
  679.    // If this is a leaf node, set the description, detected by, and
  680.    //  instance text.
  681.    if ( 2 == pLPI->iType )
  682.    {
  683.       // Get the description string.
  684.       VERIFY ( ::LoadString ( pLPI->hModule              ,
  685.                               pLPI->stEO.uiDescription ,
  686.                               szBuff                     ,
  687.                               sizeof ( szBuff )           ) ) ;
  688.  
  689.       // We just filled out the description so we don't need to do the
  690.       //  root node description.
  691.       bShowRootNodeDescription = FALSE ;
  692.  
  693.       // A leaf node is selected, enable the test button if it has
  694.       //  a function to call.
  695.       if ( NULL != pLPI->stEO.pFunc )
  696.       {
  697.          bEnableTestButton = TRUE ;
  698.       }
  699.       // For leaf nodes, we want to show the product LEDs.
  700.       bShowLEDs = TRUE ;
  701.  
  702.       // Now get the parent and change the pLPI to the second
  703.       //  level.
  704.       hItem = TreeCtrl_GetParentItem ( g_hwndTree , hItem ) ;
  705.       ASSERT ( NULL != hItem ) ;
  706.       stTI.hItem = hItem ;
  707.       stTI.mask = TVIF_PARAM ;
  708.  
  709.       VERIFY ( TreeCtrl_GetItem ( g_hwndTree , &stTI ) ) ;
  710.       pLPI = (LParamInfo *)stTI.lParam ;
  711.       ASSERT ( NULL != pLPI ) ;
  712.       if ( NULL == pLPI )
  713.       {
  714.          SetWindowText ( hwndDescription , szBuff ) ;
  715.          return ;
  716.       }
  717.    }
  718.    // Is this a first level item?
  719.    if ( 1 == pLPI->iType )
  720.    {
  721.       // The first level item tells us if we are supposed to show
  722.       //  the product descriptions.
  723.       if ( TRUE == pLPI->stET.bPersonalDoes )
  724.       {
  725.          // We are supposed to show the ON LED next to the BC Product
  726.          //  description.
  727.          bShowPersonalLEDON = TRUE ;
  728.       }
  729.       // For the individual error decriptions, we want to show the
  730.       //  LEDs.
  731.       bShowLEDs = TRUE ;
  732.       // Now get the parent and change the pLPI to the root level.
  733.       hItem = TreeCtrl_GetParentItem ( g_hwndTree , hItem ) ;
  734.       ASSERT ( NULL != hItem ) ;
  735.       stTI.hItem = hItem ;
  736.       stTI.mask = TVIF_PARAM ;
  737.  
  738.       VERIFY ( TreeCtrl_GetItem ( g_hwndTree , &stTI ) ) ;
  739.       pLPI = (LParamInfo *)stTI.lParam ;
  740.       ASSERT ( NULL != pLPI ) ;
  741.       if ( NULL == pLPI )
  742.       {
  743.          SetWindowText ( hwndDescription , szBuff ) ;
  744.          return ;
  745.       }
  746.    }
  747.    // Is this a root object?
  748.    if ( 0 == pLPI->iType )
  749.    {
  750.       // If the leaf node did not fill out the description, we need
  751.       //  to use the root node.
  752.       if ( TRUE == bShowRootNodeDescription )
  753.       {
  754.          VERIFY ( ::LoadString ( pLPI->hModule              ,
  755.                                  pLPI->stEC.uiDescription ,
  756.                                  szBuff                     ,
  757.                                  sizeof ( szBuff )           ) ) ;
  758.       }
  759.    }
  760.    // Show the text.
  761.    SetWindowText ( hwndDescription , szBuff ) ;
  762.  
  763.    // Enable or disable the Test Button based on the bEnableTestButton.
  764.    hWnd = GetDlgItem ( hwndDlg , IDC_TEST ) ;
  765.    ASSERT ( NULL != hWnd ) ;
  766.    EnableWindow ( hWnd , bEnableTestButton ) ;
  767.    hWnd = NULL ;
  768.  
  769.    // Always enable the 5 random button.
  770.    hWnd = GetDlgItem ( hwndDlg , IDC_FIVERANDOM ) ;
  771.    ASSERT ( NULL != hWnd ) ;
  772.    EnableWindow ( hWnd , TRUE ) ;
  773.    hWnd = NULL ;
  774.  
  775.    // Always turn on the Pro LED.
  776.    hWnd = GetDlgItem ( hwndDlg , IDC_PROLED ) ;
  777.    ASSERT ( NULL != hWnd ) ;
  778.    hIcon = LoadIcon ( g_hInstance , MAKEINTRESOURCE ( IDI_LEDON ) ) ;
  779.    ASSERT ( NULL != hIcon ) ;
  780.    ::SendMessage( hWnd, STM_SETICON , ( WPARAM ) hIcon , 0L );
  781.  
  782.    // If this is an error that BC Personal supports, set the LED
  783.    //  for it to ON.
  784.    hWnd = GetDlgItem ( hwndDlg , IDC_PERSLED ) ;
  785.    ASSERT ( NULL != hWnd ) ;
  786.  
  787.    if ( TRUE == bShowPersonalLEDON )
  788.       hIcon = LoadIcon ( g_hInstance , MAKEINTRESOURCE ( IDI_LEDON ) ) ;
  789.    else
  790.       hIcon = LoadIcon ( g_hInstance , MAKEINTRESOURCE ( IDI_LEDOFF ) ) ;
  791.    ASSERT ( NULL != hIcon ) ;
  792.    ::SendMessage( hWnd, STM_SETICON , ( WPARAM ) hIcon , 0L );
  793.    //((CStatic*)pWnd)->SetIcon ( hIcon ) ;
  794.  
  795.    // Hide or show the product description text and LEDs.
  796.    if ( TRUE == bShowLEDs )
  797.       iProductLEDsShow = SW_SHOW ;
  798.    else
  799.       iProductLEDsShow = SW_HIDE ;
  800.  
  801.    hWnd = GetDlgItem ( hwndDlg , IDC_PRODSTR ) ;
  802.    ASSERT ( NULL != hWnd ) ;
  803.    ShowWindow ( hWnd , iProductLEDsShow ) ;
  804.    hWnd = GetDlgItem ( hwndDlg ,IDC_PROSTR ) ;
  805.    ASSERT ( NULL != hWnd ) ;
  806.    ShowWindow ( hWnd , iProductLEDsShow ) ;
  807.    hWnd = GetDlgItem ( hwndDlg ,IDC_PERSSTR ) ;
  808.    ASSERT ( NULL != hWnd ) ;
  809.    ShowWindow ( hWnd , iProductLEDsShow ) ;
  810.    hWnd = GetDlgItem ( hwndDlg , IDC_PROLED ) ;
  811.    ASSERT ( NULL != hWnd ) ;
  812.    ShowWindow ( hWnd , iProductLEDsShow ) ;
  813.    hWnd = GetDlgItem ( hwndDlg , IDC_PERSLED ) ;
  814.    ASSERT ( NULL != hWnd ) ;
  815.    ShowWindow ( hWnd , iProductLEDsShow ) ;
  816. }
  817.  
  818.  
  819. LRESULT MainDlg_OnNotify ( HWND hWnd , int nIdCtrl , LPNMHDR pnmh ) 
  820. {
  821.    LRESULT nRes = 0 ;
  822.  
  823.    switch ( nIdCtrl )
  824.    {
  825.       // If it is the dialog's tree control.
  826.       case IDC_TREELIST :
  827.       {
  828.          switch ( pnmh->code )
  829.          {
  830.             // When a tree control item is being
  831.             // deleted, handle the notification.
  832.             case TVN_DELETEITEM :
  833.             {
  834.                MainDlg_OnDeleteItemTreeList ( hWnd , pnmh  , &nRes ) ;
  835.                break ;
  836.             }
  837.             
  838.             // When the tree control selection 
  839.             // has changed, update the data
  840.             // on the dialog.
  841.             case TVN_SELCHANGED :
  842.             {
  843.                MainDlg_OnSelChangedTreeList ( hWnd , pnmh , &nRes ) ;
  844.                break ;
  845.             }
  846.  
  847.             // When an item in the tree control
  848.             // has been double-clicked.
  849.             case NM_DBLCLK      :
  850.             {
  851.                MainDlg_OnDblClkTreeList ( hWnd , pnmh , &nRes ) ;
  852.                break ;
  853.             }
  854.  
  855.          }  // End switch on notification type
  856.          
  857.          break ;
  858.       
  859.       }  // End tree control case
  860.  
  861.    }  // End switch on the control
  862.  
  863.    return nRes ;
  864. }
  865.  
  866. LRESULT MainDlg_OnContextMenu ( HWND hWnd , WPARAM wParam , LPARAM lParam )
  867. {
  868.    // We want to only allow the popup menu to show up in the Tree
  869.    //  control client rect.
  870.    RECT  cTreeRect ;
  871.    POINT cPoint ;
  872.    cPoint.x = LOWORD ( lParam ) ;
  873.    cPoint.y = HIWORD ( lParam ) ;
  874.  
  875.    // Get the area that the Tree is in.
  876.    GetClientRect ( g_hwndTree , &cTreeRect ) ;
  877.    // Convert the mouse coordinates from screen coordinates to the
  878.    //  client coordinates of the Tree window.
  879.    ScreenToClient ( g_hwndTree , &cPoint ) ;
  880.    // If the right click is not in the Tree window, don't do anything.
  881.    if ( FALSE == PtInRect ( &cTreeRect , cPoint ) )
  882.       return ( FALSE ) ;
  883.  
  884.    // Load the menu from the resource.
  885.    HMENU hLoadMenu ;
  886.    hLoadMenu = LoadMenu ( g_hInstance , MAKEINTRESOURCE ( IDR_TRACKMENU ) ) ;
  887.    VERIFY ( hLoadMenu != NULL ) ;
  888.  
  889.    // Now get the first popup because we use it to be the actual popup.
  890.    HMENU hPopupMenu = GetSubMenu ( hLoadMenu , 0 ) ;
  891.    ASSERT ( NULL != hPopupMenu ) ;
  892.    if ( NULL == hPopupMenu )
  893.    {
  894.       return ( 0 ) ;
  895.    }
  896.  
  897.    // We need to get the currently selected item in the Tree Control.
  898.    //  If it is a leaf node, then we can enable the Test item on the
  899.    //  menu provided that there is a function that the leaf node
  900.    //  can execute.
  901.    LParamInfo * pInfo =
  902.                     (LParamInfo *)TreeCtrl_GetSelectedLParam ( g_hwndTree ) ;
  903.    if ( ( 2 == pInfo->iType ) && ( NULL != pInfo->stEO.pFunc ) )
  904.    {
  905.       EnableMenuItem ( hPopupMenu , IDM_TEST , MF_BYCOMMAND ) ;
  906.    }
  907.  
  908.    // Do the tracking.
  909.    TrackPopupMenu ( hPopupMenu ,
  910.                     TPM_LEFTALIGN | TPM_LEFTBUTTON  ,
  911.                     LOWORD(lParam)                  ,
  912.                     HIWORD(lParam)                  ,
  913.                     0                               ,
  914.                     hWnd                            ,
  915.                     NULL                             ) ;
  916.  
  917.    // If you load a menu, you must destroy it.
  918.    DestroyMenu ( hLoadMenu ) ;
  919.  
  920.    return ( 0 ) ;
  921. }
  922.  
  923. ///////////////////////////////////////////////////////////
  924. // The main dialog proc.
  925. BOOL CALLBACK Main_DlgProc ( HWND    hDlg   ,
  926.                              UINT    uMsg   ,
  927.                              WPARAM  wParam ,
  928.                              LPARAM  lParam  )
  929. {
  930.    BOOL fProcessed = TRUE;
  931.  
  932.    switch ( uMsg )
  933.    {
  934.       HANDLE_MSG ( hDlg , WM_INITDIALOG      , MainDlg_OnInitDialog      ) ;
  935.       HANDLE_MSG ( hDlg , WM_COMMAND         , MainDlg_OnCommand         ) ;
  936.       HANDLE_MSG ( hDlg , WM_SYSCOMMAND      , MainDlg_OnSysCommand      ) ;
  937.       HANDLE_MSG ( hDlg , WM_NOTIFY          , MainDlg_OnNotify          ) ;
  938.       HANDLE_MSG ( hDlg , WM_PAINT           , MainDlg_OnPaint           ) ;
  939.       HANDLE_MSG ( hDlg , WM_QUERYDRAGICON   , MainDlg_OnQueryDragIcon   ) ;
  940.       HANDLE_MSG ( hDlg , WM_PALETTECHANGED  , MainDlg_OnPaletteChanged  ) ;
  941.       HANDLE_MSG ( hDlg , WM_QUERYNEWPALETTE , MainDlg_OnQueryNewPalette ) ;
  942.       HANDLE_MSG ( hDlg , WM_ACTIVATE        , MainDlg_OnActivate        ) ;
  943.       HANDLE_MSG ( hDlg , WM_CONTEXTMENU     , MainDlg_OnContextMenu     ) ;
  944.  
  945.       default  :
  946.          fProcessed = FALSE ;
  947.          break ;
  948.    }
  949.    return ( fProcessed ) ;
  950. }
  951.  
  952.  
  953. // Utility function used to check what operating system we are running from.
  954. BOOL IsWinNT ( ) 
  955. {
  956.     DWORD dwVersion;
  957.  
  958.     dwVersion = GetVersion();
  959.  
  960.     if (dwVersion < 0x80000000) 
  961.     {
  962.         return ( TRUE ) ;
  963.     }
  964.     else 
  965.     {
  966.         return( FALSE ) ;
  967.     }    
  968. }
  969.  
  970.  
  971. ///////////////////////////////////////////////////////////
  972. // Parse the command line 
  973. void ParseCmdLine( LPSTR    lpszCmdLine )
  974. {
  975.    char * cmdLineCopy = new char[strlen( lpszCmdLine ) + 1];
  976.    strcpy( cmdLineCopy, lpszCmdLine );
  977.    char seps[]   = " -";
  978.  
  979.    /* Establish string and get the first token: */
  980.    char * token = strtok( cmdLineCopy, seps );
  981.    while( token != NULL )
  982.    {
  983.         // -s means skip the initial message box
  984.         if( token[0] == 's' )
  985.             g_fSkipMsgBox = TRUE ;
  986.  
  987.         // -cxxx means execute the the specified error and return without
  988.         //        ever displaying any part of the GUI including the info msg box.
  989.         else if( token[0] == 'c' )
  990.       {
  991.             g_nRunError = atoi( &token[1] );
  992.             g_fSkipMsgBox = TRUE ;
  993.       }
  994.  
  995.        /* Get next token: */
  996.         token = strtok( NULL, seps );
  997.    }
  998.    delete [] cmdLineCopy;
  999. }
  1000.  
  1001. ///////////////////////////////////////////////////////////
  1002. // The trusty ol' WinMain.
  1003. int APIENTRY WinMain ( HINSTANCE hInstance      ,
  1004.                        HINSTANCE hPrevInstance  ,
  1005.                        LPSTR     lpszCmdLine    ,
  1006.                        int       nCmdShow        )
  1007. {
  1008. #ifndef BCBVER
  1009.    // Turn off new CRT library assertion message boxes.
  1010.    _CrtSetReportMode ( _CRT_ASSERT , _CRTDBG_MODE_DEBUG ) ;
  1011.    _CrtSetReportMode ( _CRT_ERROR , _CRTDBG_MODE_DEBUG ) ;
  1012.    _CrtSetReportMode ( _CRT_WARN , _CRTDBG_MODE_DEBUG ) ;
  1013.    
  1014. #endif
  1015.  
  1016.    g_hInstance = hInstance ;
  1017.  
  1018.    ParseCmdLine( lpszCmdLine );
  1019.  
  1020.    // Initialize OLE.
  1021.    HRESULT hRes = OleInitialize ( NULL ) ;
  1022.    if ( FAILED ( hRes ) )
  1023.    {
  1024.       MessageBox ( NULL , "OLE could not be initialized." , "BugBench Initialization Error" , MB_APPLMODAL | MB_OK ) ;
  1025.       return -1 ;
  1026.    }
  1027.  
  1028.    InitCommonControls ( ) ;
  1029.  
  1030.    // Register 3D Controls
  1031.    if ( IsWinNT ( ) )
  1032.    {
  1033.       Ctl3dRegister ( hInstance ) ;
  1034.       Ctl3dAutoSubclass ( hInstance ) ;
  1035.    }
  1036.  
  1037.    // Dynamically register the Interface Test Object that will be used by the 
  1038.    // error generating OLE code.
  1039.    if ( ! RegisterInterfaceTestObject ( ) )
  1040.    {
  1041.       TCHAR * szMsg = _T ( "Unable to register the Interface Test Object.\n"
  1042.                            "OLE errors will not be generated.\n"
  1043.                            "Please re-install the BoundsChecker samples." ) ;
  1044.       MessageBox ( NULL ,  szMsg , constAPPNAME , MB_APPLMODAL | MB_OK ) ;
  1045.    }
  1046.  
  1047.    DialogBox ( hInstance      ,
  1048.                MAKEINTRESOURCE ( DLG_BBENCH ) ,
  1049.                NULL           ,
  1050.                ( DLGPROC ) Main_DlgProc    ) ;
  1051.  
  1052.    // Unregister the 3D Controls
  1053.    if ( IsWinNT ( ) )
  1054.    {
  1055.       Ctl3dUnregister ( hInstance ) ;
  1056.    }
  1057.  
  1058.    // Let's be polite and clean-up the registry entries we made.
  1059.    UnregisterInterfaceTestObject ( ) ;
  1060.       
  1061.    return ( 0 ) ;
  1062. }
  1063.  
  1064.  
  1065. ///////////////////////////////////////////////////////////
  1066. // Center a window.
  1067. void CenterWindow ( HWND hWnd )
  1068. {
  1069.    RECT rect    ;
  1070.    WORD wWidth  ;
  1071.    WORD wHeight ;
  1072.  
  1073.    GetWindowRect ( hWnd , &rect ) ;
  1074.  
  1075.    wWidth  = GetSystemMetrics ( SM_CXSCREEN ) ;
  1076.    wHeight = GetSystemMetrics ( SM_CYSCREEN ) ;
  1077.  
  1078.    MoveWindow( hWnd  ,
  1079.                (wWidth/2) - ((rect.right -  rect.left)/2) ,
  1080.                (wHeight/2) - ((rect.bottom - rect.top) /2) ,
  1081.                rect.right - rect.left  ,
  1082.                rect.bottom - rect.top  ,
  1083.                FALSE ) ;
  1084. }
  1085.  
  1086.  
  1087. // Get the application name
  1088. LPCTSTR GetAppName ( )
  1089. {
  1090.    return constAPPNAME ;
  1091. }
  1092.  
  1093.  
  1094.  
  1095.