Click here to Skip to main content
15,893,622 members
Articles / Desktop Programming / MFC

Include File Hierarchy Viewer

Rate me:
Please Sign up or sign in to vote.
4.84/5 (108 votes)
29 Jul 2003CPOL8 min read 384.7K   4.5K   151  
A tool to view the include file hierarchy of your source code.
//====================================================================
// Although great care has gone into developing this software,
// it is provided without any guarantee of reliability, accuracy
// of information, or correctness of operation.  I am not responsible
// for any damages that may occur as a result of using this software.
// Use this software entirely at your own risk.
// Copyright 2003, Chris Richardson
//
// Description: View class.
//
//====================================================================

#include "stdafx.h"
#include "IncFinder.h"

#include "IncFinderDoc.h"
#include "IncFinderView.h"
#include "Settings.h"

#include "ParsedFile.h"

#include "FileIterator.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CIncFinderView

// Register the FINDMSGSTRING message
static WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);

IMPLEMENT_DYNCREATE(CIncFinderView, CFormView)

BEGIN_MESSAGE_MAP(CIncFinderView, CFormView)
	//{{AFX_MSG_MAP(CIncFinderView)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_START_STOP, OnStartStop)
	ON_WM_DESTROY()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_TREE_OPENFILE, OnTreeOpenfile)
	ON_UPDATE_COMMAND_UI(ID_TREE_OPENFILE, OnUpdateTreeOpenfile)
	ON_COMMAND(ID_VIEW_UNFOUND_FILES, OnViewUnfoundFiles)
	ON_UPDATE_COMMAND_UI(ID_VIEW_UNFOUND_FILES, OnUpdateViewUnfoundFiles)
	ON_COMMAND(ID_VIEW_RELATIVE_PATHS, OnViewRelativePaths)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RELATIVE_PATHS, OnUpdateViewRelativePaths)
	ON_NOTIFY(NM_DBLCLK, IDC_FILE_TREE, OnDblclkFileTree)
	ON_COMMAND(ID_EDIT_FIND, OnEditFind)
	ON_COMMAND(ID_EDIT_FIND_NEXT, OnEditFindNext)
	ON_UPDATE_COMMAND_UI(ID_EDIT_FIND_NEXT, OnUpdateEditFindNext)
	//}}AFX_MSG_MAP
   ON_MESSAGE( INC_FINDER_WM_FILE_START, OnFileStart )
   ON_MESSAGE( INC_FINDER_WM_FILE_FINISHED, OnFileFinished )
   ON_MESSAGE( INC_FINDER_WM_FINISHED, OnFinished )
   ON_REGISTERED_MESSAGE(WM_FINDREPLACE, OnFindReplace) 
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIncFinderView construction/destruction

CIncFinderView::CIncFinderView()
	: CFormView(CIncFinderView::IDD),
   c_bIsShowingOnlyUnfoundFiles( false ),
   c_bIsShowingRelativePaths( false ),
   c_bIsInitialized( false ),
   c_poCurrentSearchPage( NULL ),
   c_poFindDlg( NULL )
{
	//{{AFX_DATA_INIT(CIncFinderView)
	//}}AFX_DATA_INIT
	// TODO: add construction code here
}

CIncFinderView::~CIncFinderView()
{
   c_poCurrentSearchPage = NULL;
   ClearParsedFiles();
   
   if( c_poFindDlg )
   {
      delete c_poFindDlg;
      c_poFindDlg = NULL;
   }
}

void CIncFinderView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CIncFinderView)
	DDX_Control(pDX, IDC_PREPROCESS, c_oPreprocess);
	DDX_Control(pDX, IDC_PROCESSING_TIME, c_oProcessingTime);
	DDX_Control(pDX, IDC_FILES_PROCESSED, c_oFilesProcessed);
	DDX_Control(pDX, IDC_PROCESSING_ANIM, c_oProcessingAnim);
	DDX_Control(pDX, IDC_FILE_TREE, c_oFileTree);
	DDX_Control(pDX, IDC_START_STOP, c_oStartStop);
	DDX_Control(pDX, IDC_MIDDLE_BORDER, c_oMiddleBorder);
	DDX_Control(pDX, IDC_TOP_BORDER, c_oTopBorder);
	//}}AFX_DATA_MAP
}

BOOL CIncFinderView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFormView::PreCreateWindow(cs);
}

void CIncFinderView::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

   if( !c_bIsInitialized )
   {
      // Load the neat file search icon from shell32.dll.
      // I do this up here instead of with the rest of the init below, so that the control will be repositioned
      // properly in the WM_SIZE handler.
      HINSTANCE a_hInstance = (HINSTANCE)LoadLibrary( _T("Shell32.dll") );
      c_oProcessingAnim.SendMessage( ACM_OPEN, (WPARAM)a_hInstance, (LPARAM)MAKEINTRESOURCE( 151 ) );
      FreeLibrary( a_hInstance );
   }

	GetParentFrame()->RecalcLayout();
   
   if( !c_bIsInitialized )
   {
      CSettings & a_roSettings = CSettings::GetSettings();

      c_bIsInitialized = true;
      
      // Create our "Search Type" property sheet.
      c_oPropSheet.Create(this, WS_CHILD | WS_VISIBLE | WS_TABSTOP, WS_EX_CONTROLPARENT);
      c_oPropSheet.ModifyStyleEx(0, WS_EX_CONTROLPARENT|WS_EX_WINDOWEDGE);
      c_oPropSheet.ModifyStyle( WS_DLGFRAME, WS_TABSTOP );
      
      CRect a_oRect;
      c_oPropSheet.GetWindowRect( &a_oRect );
      c_iDefaultPropSheetHeight = a_oRect.Height();
      
      // Restore some GUI settings.
      a_roSettings.c_iActiveSearchTab = max( a_roSettings.c_iActiveSearchTab, 0 );
      a_roSettings.c_iActiveSearchTab = min( a_roSettings.c_iActiveSearchTab, c_oPropSheet.GetPageCount() );
      c_oPropSheet.SetActivePage( a_roSettings.c_iActiveSearchTab );

      if( a_roSettings.c_oMainRect.left == -1 ||
          a_roSettings.c_oMainRect.top == -1 ||
          a_roSettings.c_oMainRect.right == -1 ||
          a_roSettings.c_oMainRect.bottom == -1 )
         ResizeParentToFit(FALSE);
   
      // Remove the client edge.  I like the flat look a little more.
      ModifyStyleEx( WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME );
   
      // Set the initial text of the Start/Stop button.
      CString a_sTemp( (LPCTSTR)IDS_STR_START );
      c_oStartStop.SetWindowText( a_sTemp );

      c_oTreeImages.Create( IDB_TREE_ICONS, 16, 0, RGB( 255, 0, 255 ) );
      c_oFileTree.SetImageList( &c_oTreeImages, TVSIL_NORMAL );
   
      UpdateResultsControls( 0, COleDateTimeSpan( 0, 0, 0, 0 ) );
      
      c_oPreprocess.SetCheck( a_roSettings.c_bPreprocess != 0 );
   }
}

/////////////////////////////////////////////////////////////////////////////
// CIncFinderView diagnostics

#ifdef _DEBUG
void CIncFinderView::AssertValid() const
{
	CFormView::AssertValid();
}

void CIncFinderView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}

CIncFinderDoc* CIncFinderView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIncFinderDoc)));
	return (CIncFinderDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CIncFinderView non-message functions
/////////////////////////////////////////////////////////////////////////////

//
// ------------------------------------------------------------------
//
void CIncFinderView::OnFinished()
{
   PostMessage( INC_FINDER_WM_FINISHED, 0, 0 );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnFileStart( CParsedFile * p_poFile )
{
   PostMessage( INC_FINDER_WM_FILE_START, 0, (LPARAM)p_poFile );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnFileComplete( CParsedFile * p_poResults )
{
   PostMessage( INC_FINDER_WM_FILE_FINISHED, 0, (LPARAM)p_poResults );
}
//
// ------------------------------------------------------------------
//
HTREEITEM CIncFinderView::InsertFile( HTREEITEM p_hParent, CParsedFile * p_poFile, BOOL & p_rbHasMultipleIncluded )
{
   BOOL a_bRecurse = TRUE;
   
   // Determine the image we will use for the file.
   int a_iImage = TREE_IMAGE_FILE;
   if( p_poFile->GetNotFoundFlag() )
      a_iImage = TREE_IMAGE_NOT_FOUND;
   else
   if( p_poFile->GetAlreadyIncluded() )
   {
      a_iImage = TREE_IMAGE_MULTIPLE;
      
      // The file was already included.  We don't want to recurse because
      // we might infinitely recurse (i.e, "rpc.h" includes "windows.h", which includes "rpc.h").
      a_bRecurse = FALSE;

      p_rbHasMultipleIncluded = TRUE;
   }
   
   if( !p_poFile->GetNotFoundFlag() && c_bIsShowingOnlyUnfoundFiles && p_hParent != TVI_ROOT )
      // We don't want to insert this item.
      return NULL;

   CTCharString a_sFileName = GetDisplayFileName( p_poFile, p_hParent );
   
   // Insert the file into the tree.
   HTREEITEM a_hFileRootItem = c_oFileTree.InsertItem( a_sFileName.c_str(), a_iImage, a_iImage, p_hParent );
   c_oFileTree.SetItemData( a_hFileRootItem, (DWORD)p_poFile );
   p_poFile->SetAlreadyIncluded( true );

   if( a_bRecurse )
   {
      // Now recursively insert all the file's included files.
      CParsedFileArray & a_roIncludedFiles = p_poFile->GetIncludedFiles();
      HTREEITEM a_hFileItem = a_hFileRootItem;
      for( int i = 0; i<a_roIncludedFiles.size(); ++i )
      {
         if( a_roIncludedFiles[i] == p_poFile )
         {
            // The current file included itself.  Insert it, with a special icon.
            a_sFileName = GetDisplayFileName( a_roIncludedFiles[i], p_hParent );
            HTREEITEM a_hRecursiveItem = c_oFileTree.InsertItem( a_sFileName.c_str(), TREE_IMAGE_RECURSE, TREE_IMAGE_RECURSE, a_hFileRootItem );
            c_oFileTree.SetItemData( a_hRecursiveItem, (DWORD)a_roIncludedFiles[i] );
            continue;
         }
         a_hFileItem = InsertFile( a_hFileRootItem, a_roIncludedFiles[i], p_rbHasMultipleIncluded );
      }
   }
   
   // Check if p_poFile has any files which are included more than once so we can change it's icon.
   if( p_hParent == TVI_ROOT && p_rbHasMultipleIncluded )
      c_oFileTree.SetItem( a_hFileRootItem, TVIF_IMAGE|TVIF_SELECTEDIMAGE, NULL, TREE_IMAGE_MULTIPLE, TREE_IMAGE_MULTIPLE, 0, 0, 0 );

   return a_hFileRootItem;
}
//
// ------------------------------------------------------------------
//
CTCharString CIncFinderView::GetDisplayFileName( CParsedFile * p_poFile, HTREEITEM p_hParentLevel )
{
   if( !c_bIsShowingRelativePaths )
      return p_poFile->GetFileName();

   const CTCharString & a_rsTemp = p_poFile->GetFileName();
   TCHAR a_szFileExt[MAX_PATH + 1] = {0};
   TCHAR a_szFileName[MAX_PATH + 1] = {0};
   TCHAR a_szFileDir[MAX_PATH + 1] = {0};
   _tsplitpath( a_rsTemp.c_str(), NULL, a_szFileDir, a_szFileName, a_szFileExt );
   
   CTCharString a_sFinal;
   a_sFinal = a_szFileName;
   a_sFinal += a_szFileExt;
   return a_sFinal;
   
   // Well, this was an attempt at showing the relative path names...but it's not completed yet.
   /*
   if( p_hParentLevel == TVI_ROOT )
   {
      a_sFinal = a_szFileName;
      a_sFinal += a_szFileExt;
   }
   else
   {
      CParsedFile * a_poParentFile = (CParsedFile*)c_oFileTree.GetItemData( p_hParentLevel );
      const CTCharString & a_rsParentPath = a_poParentFile->GetFileName();
   
      const TCHAR * a_pszFileBase = _tcsstr( a_rsParentPath.c_str(), a_szFileDir );
      if( !a_pszFileBase )
      {
         a_sFinal = a_rsTemp.c_str();
      }
      else
      {
         a_pszFileBase += _tcslen( a_szFileDir );
         a_sFinal = a_pszFileBase;
         a_sFinal += a_szFileName;
         a_sFinal += a_szFileExt;
      }
   }

   return a_sFinal;
   */
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::ClearParsedFiles()
{
   if( IsWindow( c_oFileTree ) )
   {
      c_oFileTree.SetRedraw( FALSE );

      // Clear the data from the tree.
      c_oFileTree.DeleteAllItems();

      c_oFileTree.SetRedraw( TRUE );
   }
   
   // Have the doc clear it's data as well.
   GetDocument()->ClearResults();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::UpdateResultsControls( unsigned long p_ulFiles, COleDateTimeSpan & p_roProcessTime )
{
   TCHAR a_szTemp[64] = {0};
   _stprintf( a_szTemp, _T("%d"), p_ulFiles );
   c_oFilesProcessed.SetWindowText( a_szTemp );
   c_oProcessingTime.SetWindowText( p_roProcessTime.Format( _T("%H:%M:%S") ) );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::RepopulateTree()
{
   CWaitCursor a_oWait;

   c_oFileTree.SetRedraw( FALSE );

   // Clear the tree.
   c_oFileTree.DeleteAllItems();
   
   // Repopulate the tree now.
   CParsedFileArray & a_roFiles = GetDocument()->GetTopLevelFiles();
   CParsedFileArray::iterator a_oIter;
   int i = 0;
   for( a_oIter = a_roFiles.begin(); a_oIter != a_roFiles.end(); ++a_oIter )
   {
      CParsedFile * a_poFile = *a_oIter;
      
      BOOL a_bHasMultipleIncluded = FALSE;
      InsertFile( TVI_ROOT, a_poFile, a_bHasMultipleIncluded );

      // Clear the "already included" flag so the file can be recursed next time.
      a_poFile->SetAlreadyIncluded( false );

      ++i;
   }

   c_oFileTree.SetRedraw( TRUE );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::LaunchFile( CParsedFile * p_poFile )
{
   CSettings & a_roSettings = CSettings::GetSettings();
   CString a_sFilename;
   a_sFilename.Format( _T("\"%s\""), p_poFile->GetFileName().c_str() );
   if( a_roSettings.c_bViewWithAssociatedViewer )
   {
      // ShellExecute the selected file, with the associated program.
      ShellExecute( NULL, _T("Open"), a_sFilename, NULL, NULL, SW_SHOWNORMAL );
   }
   else
   {
      // ShellExecute the selected file, with the custom command.
      CString a_sCommand = a_roSettings.c_sCustomSourceViewerCommand.c_str();
      ShellExecute( NULL, _T("Open"), a_sCommand, a_sFilename, NULL, SW_SHOWNORMAL );
   }
}
//
// ------------------------------------------------------------------
//
HTREEITEM CIncFinderView::SearchTree( BOOL p_bStart, HTREEITEM p_hCur, const TCHAR * p_pszText )
{
   HTREEITEM a_hCurrent = NULL;

   if( p_hCur && !p_bStart )
   {
      // Test the current item.
      CParsedFile * a_poFile = (CParsedFile*)c_oFileTree.GetItemData( p_hCur );
      //if( WildcardCompare( a_poFile->GetFileName().c_str(), p_pszText ) )
      if( _tcsstr( a_poFile->GetFileName().c_str(), p_pszText ) )
      {
         return p_hCur;
      }
   }

   // Check the item's children first.
   a_hCurrent = c_oFileTree.GetChildItem( p_hCur );
   if( a_hCurrent )
   {
      a_hCurrent = SearchTree( FALSE, a_hCurrent, p_pszText );
      if( a_hCurrent )
         return a_hCurrent;
   }
   
   // Now check siblings.
   a_hCurrent = p_hCur;
   while( 1 )
   {
      a_hCurrent = c_oFileTree.GetNextSiblingItem( a_hCurrent );
      if( !a_hCurrent )
         break;
      
      // We found one to search, so search it...
      HTREEITEM a_hItem = SearchTree( FALSE, a_hCurrent, p_pszText );
      if( a_hItem )
         return a_hItem;
      else
         break;
   }
   
   if( p_bStart )
   {
      // Try to work our way back to another branch above us, that has more unchecked siblings.
      a_hCurrent = p_hCur;
      while( 1 )
      {
         a_hCurrent = c_oFileTree.GetParentItem( a_hCurrent );
         if( !a_hCurrent )
            break;

         HTREEITEM a_hSibling = c_oFileTree.GetNextSiblingItem( a_hCurrent );
         if( a_hSibling )
         {
            // We found a sibling of a parent to search.
            HTREEITEM a_hTest = SearchTree( FALSE, a_hSibling, p_pszText );
            if( a_hTest )
               return a_hTest;
         }
      }
   }

   return NULL;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::DoSearch( const TCHAR * p_pszText )
{
   HTREEITEM a_hSelection = c_oFileTree.GetSelectedItem();
   if( !a_hSelection )
      a_hSelection = c_oFileTree.GetRootItem();

   if( a_hSelection )
   {
      // Search the tree for the next suitable item.
      HTREEITEM a_hNewItem = SearchTree( TRUE, a_hSelection, p_pszText );
   
      if( a_hNewItem )
      {
         c_oFileTree.SelectItem( a_hNewItem );
      }
   }
}
//
// ------------------------------------------------------------------
//


/////////////////////////////////////////////////////////////////////////////
// CIncFinderView message handlers
/////////////////////////////////////////////////////////////////////////////

void CIncFinderView::OnSize(UINT nType, int cx, int cy) 
{
	if( !IsWindow( c_oPropSheet ) )
      // Our controls haven't been subclassed yet.
      return;

   // Resize our controls.
   //
   
   int a_iBigBorder = 0;
   CRect a_oRect;

   c_oFileTree.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   a_iBigBorder = a_oRect.left;

   c_oTopBorder.GetWindowRect( &a_oRect );
   c_oTopBorder.MoveWindow( 0,
                            0,
                            cx,
                            a_oRect.Height() );
   
   CRect a_oButtonRect;
   c_oStartStop.GetWindowRect( &a_oButtonRect );
   ScreenToClient( &a_oButtonRect );

   c_oPropSheet.GetWindowRect( &a_oRect );
   c_oPropSheet.MoveWindow( a_iBigBorder / 2,
                            a_iBigBorder / 2,
                            cx - a_oButtonRect.Width() - a_iBigBorder * 2,
                            c_iDefaultPropSheetHeight );

   
   c_oStartStop.MoveWindow( cx - a_oButtonRect.Width() - a_iBigBorder,
                            a_oButtonRect.top,
                            a_oButtonRect.Width(),
                            a_oButtonRect.Height() );
   
   c_oProcessingAnim.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oProcessingAnim.MoveWindow( cx - a_oButtonRect.Width() - a_iBigBorder + (abs(a_oButtonRect.Width()-a_oRect.Width()))/2,
                                 a_oRect.top,
                                 a_oRect.Width(),
                                 a_oRect.Height() );

   c_oMiddleBorder.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oMiddleBorder.MoveWindow( a_oRect.left,
                               a_oRect.top,
                               cx - a_oRect.left * 2,
                               a_oRect.Height() );
   c_oFileTree.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oFileTree.MoveWindow( a_oRect.left,
                           a_oRect.top,
                           cx - a_iBigBorder * 2,
                           cy - a_oRect.top - a_iBigBorder );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnStartStop() 
{
   UINT a_uiTextID = 0;
   CIncludeFinder & a_roFinder = GetDocument()->GetIncludeFinder();
   CIncludeFinderInfo & a_roFindInfo = GetDocument()->GetFindInfo();
   if( a_roFinder.IsRunning() )
   {
      CWaitCursor a_oWait;
      
      // Stop the include finder thread.
      a_roFinder.Stop();
      
      a_uiTextID = IDS_STR_START;
   }
   else
   {
      CWaitCursor a_oWait;

      c_poCurrentSearchPage = static_cast<CSearchPropertyPage*>(c_oPropSheet.GetPage( c_oPropSheet.GetActiveIndex() ));
      
      CFileIterator * a_poIter = c_poCurrentSearchPage->PrepareToStart();

      if( !a_poIter )
      {
         // The page doesn't want us to start.
         return;
      }
      
      ((CFrameWnd*)AfxGetMainWnd())->SetMessageText( IDS_STR_STARTING_UP );

      c_oProcessingAnim.Play( 0, -1, -1 );
      
      // Clear the current data.
      ClearParsedFiles();
      
      a_roFindInfo.SetOptions( a_poIter, (c_oPreprocess.GetCheck() == 1) );

      UpdateResultsControls( 0, COleDateTimeSpan( 0, 0, 0, 0 ) );

      // Start the parsing.
      a_roFinder.Start();

      a_uiTextID = IDS_STR_STOP;
   }
   
   // Change the text of the start/stop button.
   CString a_sText( (LPCTSTR)a_uiTextID );
   c_oStartStop.SetWindowText( a_sText );
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFileFinished( WPARAM wParam, LPARAM lParam )
{
   // Add the file to the doc's top level file list.
   CParsedFile * a_poFile = (CParsedFile*)lParam;
   GetDocument()->AddTopLevelFile( a_poFile );
   
   // Add the file into the tree, recursively.
   BOOL a_bHasMultipleIncluded = FALSE;
   InsertFile( TVI_ROOT, a_poFile, a_bHasMultipleIncluded );

   // Set the 'already included' flag back to false, so the file's included files will show up recursively
   // in the next file they may be included in.
   a_poFile->SetAlreadyIncluded( false );
   return 0;
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFileStart( WPARAM wParam, LPARAM lParam )
{
   CParsedFile * a_poFile = (CParsedFile*)lParam;
   
   // Set the text of the status bar to the path of the file we are parsing.
   CString a_sTemp;
   a_sTemp.Format( IDS_STR_PROCESSING, a_poFile->GetFileName().c_str() );
   ((CFrameWnd*)AfxGetMainWnd())->SetMessageText( a_sTemp );
   
   // Update the two static controls which show the number of files processed and the amount of time it took so far.
   CIncludeFinderInfo & a_roFindInfo = GetDocument()->GetFindInfo();
   a_roFindInfo.c_ulFilesProcessed++;
   UpdateResultsControls( a_roFindInfo.c_ulFilesProcessed, COleDateTime::GetCurrentTime() - a_roFindInfo.c_oStartTime );

   return 0;
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFinished( WPARAM wParam, LPARAM lParam )
{
   // Set the text of the start/stop button to "Start"
   CString a_sText( (LPCTSTR)IDS_STR_START );
   c_oStartStop.SetWindowText( a_sText );

   // Set the status bar text to the idle msg.
   ((CFrameWnd*)AfxGetMainWnd())->SetMessageText( AFX_IDS_IDLEMESSAGE );
   
   // Update the two static controls which show the number of files processed and the amount of time it took.
   CIncludeFinderInfo & a_roFindInfo = GetDocument()->GetFindInfo();
   UpdateResultsControls( a_roFindInfo.c_ulFilesProcessed, a_roFindInfo.c_oStopTime - a_roFindInfo.c_oStartTime );
   
   c_oFileTree.SetRedraw( TRUE );
   
   if( c_poCurrentSearchPage )
      c_poCurrentSearchPage->SearchStopped();

   // Stop the animation control.
   c_oProcessingAnim.Stop();
   return 0;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnDestroy() 
{
   CIncludeFinder & a_roFinder = GetDocument()->GetIncludeFinder();
   // Stop the include finder thread if it's running.
   if( a_roFinder.IsRunning() )
   {
      CWaitCursor a_oWait;
      a_roFinder.Stop();
   }

   // Save settings.
   CSettings & a_roSettings = CSettings::GetSettings();
   a_roSettings.c_bPreprocess = c_oPreprocess.GetCheck() != 0;

   a_roSettings.c_iActiveSearchTab = c_oPropSheet.GetActiveIndex();
	
   CFormView::OnDestroy();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
   BOOL a_bKeyStroke = FALSE;
   CWnd * a_poFocus = GetFocus();
   if (point.x == -1 && point.y == -1)
   {
      // Keystroke invocation.
      CRect rect;
      a_poFocus->GetClientRect(rect);
      a_poFocus->ClientToScreen(rect);

      point = rect.TopLeft();
      point.Offset(5, 5);

      a_bKeyStroke = TRUE;
   }

   // Determine which menu to show.
   CRect a_oRect;
   c_oFileTree.GetWindowRect( &a_oRect );
   UINT a_uiMenu = 0;
   if( a_oRect.PtInRect( point ) || (a_bKeyStroke && a_poFocus == &c_oFileTree) )
      a_uiMenu = IDR_TREE_CONTEXT;
   else
      return;

   // Load and show the context menu.
	CMenu menu;
   VERIFY(menu.LoadMenu(a_uiMenu));

   CMenu* pPopup = menu.GetSubMenu(0);
   ASSERT(pPopup != NULL);
	
   CWnd* pWndPopupOwner = this;

   while (pWndPopupOwner->GetStyle() & WS_CHILD)
	   pWndPopupOwner = pWndPopupOwner->GetParent();

   pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, 
                          point.x, 
                          point.y,
                          pWndPopupOwner);
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnTreeOpenfile() 
{
	HTREEITEM a_hItem = c_oFileTree.GetSelectedItem();
   CParsedFile * a_poFile = (CParsedFile*)c_oFileTree.GetItemData( a_hItem );

   LaunchFile( a_poFile );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateTreeOpenfile(CCmdUI* pCmdUI) 
{
	HTREEITEM a_hItem = c_oFileTree.GetSelectedItem();
   pCmdUI->Enable( a_hItem != NULL );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnViewUnfoundFiles() 
{
   // Toggle the flag.
   c_bIsShowingOnlyUnfoundFiles = !c_bIsShowingOnlyUnfoundFiles;
   
   // Repopulate the tree.
   RepopulateTree();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateViewUnfoundFiles(CCmdUI* pCmdUI) 
{
   pCmdUI->Enable( !GetDocument()->GetIncludeFinder().IsRunning() );
   pCmdUI->SetCheck( c_bIsShowingOnlyUnfoundFiles );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnViewRelativePaths() 
{
   // Toggle the flag.
   c_bIsShowingRelativePaths = !c_bIsShowingRelativePaths;
   
   // Repopulate the tree.
   RepopulateTree();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateViewRelativePaths(CCmdUI* pCmdUI) 
{
   pCmdUI->Enable( !GetDocument()->GetIncludeFinder().IsRunning() );
   pCmdUI->SetCheck( c_bIsShowingRelativePaths );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
   RepopulateTree();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnDblclkFileTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CPoint a_oPoint( 0, 0 );
   GetCursorPos( &a_oPoint );
   c_oFileTree.ScreenToClient( &a_oPoint );

   // If they double-clicked on a leaf item, we'll open the file.
   HTREEITEM a_hItem = c_oFileTree.HitTest( a_oPoint );
   if( a_hItem != NULL && c_oFileTree.GetChildItem( a_hItem ) == NULL )
   {
      CParsedFile * a_poFile = (CParsedFile*)c_oFileTree.GetItemData( a_hItem );
      LaunchFile( a_poFile );
   }

   *pResult = 0;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnEditFind() 
{
   if( !c_poFindDlg )
   {
      CFindReplaceDialog * c_poFindDlg = new CFindReplaceDialog;
      c_poFindDlg->m_fr.Flags |= FR_HIDEUPDOWN|FR_HIDEMATCHCASE|FR_HIDEWHOLEWORD;

      c_poFindDlg->Create( TRUE, c_sLastSearchText.c_str(), NULL, FR_DOWN, this );
   }
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
   CFindReplaceDialog * a_poDlg = CFindReplaceDialog::GetNotifier( lParam );

   if( NULL != a_poDlg )
   {
      if( a_poDlg->FindNext() )
      {
         c_sLastSearchText = a_poDlg->GetFindString();
         DoSearch( c_sLastSearchText.c_str() );
      }
   }
   
   return 0;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnEditFindNext() 
{
   DoSearch( c_sLastSearchText.c_str() );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateEditFindNext(CCmdUI* pCmdUI) 
{
   pCmdUI->Enable( c_sLastSearchText.length() != 0 );
}
//
// ------------------------------------------------------------------
//

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I like to program, I like to sail.

Comments and Discussions