gusucode.com > VC_C++源码,界面编程,网页爬虫源码程序 > VC_C++源码,界面编程,网页爬虫源码程序/code/webpageloader_SourceCode/LogView.cpp

    // FileView.cpp : implementation of the CLogView class
//

#include "stdafx.h"
#include "WebPageLoader.h"

#include "Doc.h"
#include "LogView.h"
#include "MainFrm.h"

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


/////////////////////////////////////////////////////////////////////////////
// CSetRedraw helper class

class CSetRedraw
{
public:
   CSetRedraw(HWND hWnd) { m_hWnd = hWnd; ::SendMessage(m_hWnd, WM_SETREDRAW,FALSE,0); };
   ~CSetRedraw() { ::SendMessage(m_hWnd, WM_SETREDRAW,TRUE,0); ::InvalidateRect(m_hWnd,NULL,TRUE); };
private:
   HWND m_hWnd;
};


/////////////////////////////////////////////////////////////////////////////
// CLogView

IMPLEMENT_DYNCREATE(CLogView, CListView)

BEGIN_MESSAGE_MAP(CLogView, CListView)
   //{{AFX_MSG_MAP(CLogView)
   ON_COMMAND(ID_EDIT_REFRESH, OnEditRefresh)
   ON_COMMAND(ID_EDIT_DELETE, OnDelete)
   ON_COMMAND(ID_EDIT_MOVEUP, OnMoveUp)
   ON_COMMAND(ID_EDIT_MOVEDOWN, OnMoveDown)
   ON_COMMAND(ID_EDIT_COPY, OnCopy)   
   ON_COMMAND(ID_EDIT_OPENBROWSE, OnOpenBrowser)   
   ON_COMMAND(ID_EDIT_RANDOMIZE, OnRandomize)   
   ON_COMMAND(ID_EDIT_GOTOACTIVE, OnGotoActive)   
   ON_COMMAND(ID_EDIT_IGNORE_FILENAME, OnIgnoreFilename)   
   ON_COMMAND(ID_EDIT_IGNORE_DOMAIN, OnIgnoreDomain)   
   ON_WM_CONTEXTMENU()
   ON_WM_SIZE()
   ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, OnUpdateDelete)
   ON_UPDATE_COMMAND_UI(ID_EDIT_MOVEUP, OnUpdateMoveUp)
   ON_UPDATE_COMMAND_UI(ID_EDIT_MOVEDOWN, OnUpdateMoveDown)
   ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateCopy)
   ON_UPDATE_COMMAND_UI(ID_EDIT_OPENBROWSE, OnUpdateOpenBrowser)
   ON_UPDATE_COMMAND_UI(ID_EDIT_RANDOMIZE, OnUpdateRandomize)
   ON_UPDATE_COMMAND_UI(ID_EDIT_GOTOACTIVE, OnUpdateGotoActive)
   ON_UPDATE_COMMAND_UI(ID_EDIT_IGNORE_FILENAME, OnUpdateIgnoreFilename)
   ON_UPDATE_COMMAND_UI(ID_EDIT_IGNORE_DOMAIN, OnUpdateIgnoreDomain)
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLogView construction/destruction

CLogView::CLogView()
{
   m_dwStyle = ID_VIEW_LOG;
   m_iLastActive = -1;
   ::srand(::time(NULL));
}

CLogView::~CLogView()
{
}

BOOL CLogView::PreCreateWindow(CREATESTRUCT& cs)
{
   return CListView::PreCreateWindow(cs);
}


/////////////////////////////////////////////////////////////////////////////
// CLogView drawing

void CLogView::OnDraw(CDC* pDC)
{
}

void CLogView::OnInitialUpdate()
{
   CListCtrl& ctlList = GetListCtrl();

   // Create the image list for the tree control
   m_ImageList.Create(IDR_IMAGES, 16, 1, RGB(0,0,255));
   ctlList.SetImageList(&m_ImageList, LVSIL_SMALL);

   // Set style and add columns
   ctlList.ModifyStyle(LVS_TYPEMASK, LVS_REPORT|LVS_NOCOLUMNHEADER);
   CString s;
   s.LoadString(IDS_COL_ITEM);
   ctlList.InsertColumn(0, s, LVCFMT_LEFT);

   // Set reasonable widths for our columns
   ctlList.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);

   CListView::OnInitialUpdate();
}


/////////////////////////////////////////////////////////////////////////////
// CLogView diagnostics

#ifdef _DEBUG
void CLogView::AssertValid() const
{
   CListView::AssertValid();
}

void CLogView::Dump(CDumpContext& dc) const
{
   CListView::Dump(dc);
}

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


/////////////////////////////////////////////////////////////////////////////
// CLogView message handlers

void CLogView::CreateItems()
{
   CListCtrl& ctlList = GetListCtrl();
   CWaitCursor wait;
   CSetRedraw redraw(ctlList);
   int old_index = ctlList.GetNextItem(-1, LVNI_SELECTED);
   ctlList.DeleteAllItems();
   RefreshItems();
   if( old_index != -1 ) {
      ctlList.SetItemState(old_index, LVNI_SELECTED, LVNI_SELECTED);
      ctlList.EnsureVisible(old_index, FALSE);
   }
};

void CLogView::RefreshItems()
{
   switch( m_dwStyle ) {
   case ID_VIEW_LOG:
   default:
      RefreshLogs();
      break;
   case ID_VIEW_STATUS:
      RefreshStatus();
      break;
   case ID_VIEW_FILES:
      RefreshFiles();
      break;
   };
};

void CLogView::RefreshLogs()
// The log display shows a bunch of text messages
{
   CSession *pSession = GetDocument()->GetSelectedSession();
   if( pSession==NULL ) return;
   ASSERT_VALID(pSession);

   CListCtrl& ctlList = GetListCtrl();
   CSingleLock lock( *pSession, TRUE );

   int session_size = pSession->m_Info.m_Log.GetSize();
   int list_size = ctlList.GetItemCount();
   if( list_size < session_size ) {
      for( int i=list_size; i<session_size; i++ ) {
         LV_ITEM itm = { 0 };
         itm.mask = LVIF_IMAGE | LVIF_TEXT;
         itm.pszText = (LPTSTR)(LPCTSTR) pSession->m_Info.m_Log[ i ];
         itm.cchTextMax = _tcslen(itm.pszText);
         itm.iImage = 12;
         ctlList.InsertItem(&itm);
      };
   };
};


void CLogView::RefreshFiles()
// The files display should show the status of each file in
// the selected session
{
   CSession *pSession = GetDocument()->GetSelectedSession();
   if( pSession==NULL ) return;
   ASSERT_VALID(pSession);

   CListCtrl& ctlList = GetListCtrl();
   CSingleLock lock( *pSession, TRUE );

   int session_size = pSession->m_Files.GetCount();
   int list_size = ctlList.GetItemCount();
   int idx;
   // If logs have been added/deleted then refresh the whole list
   if( session_size != list_size ) {
      // Delete all items
      if( list_size > session_size ) {
         ctlList.DeleteAllItems();
         list_size = 0;
         m_iLastActive = -1;
      }
      // and re-insert them...
      POSITION pos = pSession->m_Files.GetHeadPosition();
      LV_ITEM itm = { 0 };
      itm.mask = LVIF_TEXT;
      idx = 0;
      while( pos!=NULL ) {
         CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
         ASSERT_VALID(pFile);
         itm.iItem = idx++;
         if( idx <= list_size ) continue;
         itm.pszText = (LPTSTR) (LPCTSTR) pFile->m_sURL;
         int iItem = ctlList.InsertItem(&itm);
         pFile->m_iLastImage = -1;
         if( pFile->m_State == FILESTATE_DOWNLOADING ) m_iLastActive = iItem;
      }
   }

   // Update images on all file-items
   POSITION pos = pSession->m_Files.GetHeadPosition();
   LV_ITEM itm = { 0 };
   idx = 0;
   while( pos!=NULL ) {
      CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
      ASSERT_VALID(pFile);
      itm.iItem = idx++;
      itm.mask = LVIF_IMAGE;
      int iImage = 1;
      switch( pFile->m_State ) {
      case FILESTATE_CONNECTING:
         iImage = 17;
         break;
      case FILESTATE_DOWNLOADING:
         iImage = 3;
         break;
      case FILESTATE_SKIPPED:
      case FILESTATE_BROKEN:
         iImage = 15;
         break;
      case FILESTATE_ERROR:
         iImage = 16;
         break;
      case FILESTATE_DONE:
         iImage = 4;
         break;
      case FILESTATE_WAITING:
         iImage = 1;
         break;
      case FILESTATE_ALREADYTHERE:
         iImage = 21;
         break;
      }
      if( pFile->m_iLastImage == iImage ) continue;
      itm.iImage = iImage;
      ctlList.SetItem(&itm);
      pFile->m_iLastImage = iImage;
   };
};


void CLogView::RefreshStatus()
// The status display is supposed to display all files
// currently in download progress. Currently it just
// show the active file download as a single entry in the list.
{
   CSession *pSession = GetDocument()->GetSelectedSession();
   if( pSession==NULL ) return;
   ASSERT_VALID(pSession);

   CListCtrl& ctlList = GetListCtrl();
   CSingleLock lock( *pSession, TRUE );

   bool bInsert = false;

   int session_size = 0;
   POSITION pos = pSession->m_Files.GetHeadPosition();
   while( pos!=NULL ) {
      const CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
      if( pFile->m_State==FILESTATE_CONNECTING ) session_size++;
      if( pFile->m_State==FILESTATE_DOWNLOADING ) session_size++;
   }
   int list_size = ctlList.GetItemCount();
   int old_index = ctlList.GetNextItem(-1, LVNI_SELECTED);
   if( session_size != list_size ) {
      ctlList.DeleteAllItems();
      bInsert = true;
   }

   pos = pSession->m_Files.GetHeadPosition();
   int idx = 0;
   while( pos!=NULL ) {
      const CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
      ASSERT_VALID(pFile);
      if( pFile->m_State == FILESTATE_DOWNLOADING || pFile->m_State == FILESTATE_CONNECTING ) {
         LV_ITEM itm = { 0 };
         itm.iItem = idx++;
         itm.mask = LVIF_TEXT | LVIF_IMAGE;
         itm.iImage = pFile->m_bIsImage ? 9 : 0;
         if( itm.iImage == 0 && pFile->m_State == FILESTATE_CONNECTING ) itm.iImage = 19;
         if( itm.iImage == 9 && pFile->m_State == FILESTATE_CONNECTING ) itm.iImage = 18;
         CString s;
         s.Format(pFile->m_State == FILESTATE_CONNECTING ? IDS_COL_CONNECTING : IDS_COL_STATUS, 
            (LPCTSTR)pFile->m_sURL, 
            pFile->m_lBytesDownloaded);
         itm.pszText = (LPTSTR)(LPCTSTR)s;
         if( bInsert ) {
            ctlList.InsertItem(&itm);
         }
         else {
            ctlList.SetItem(&itm);
         }
      }
   }

   if( bInsert && old_index != -1 ) {
      ctlList.SetItemState(old_index, LVNI_SELECTED, LVNI_SELECTED);
      ctlList.EnsureVisible(old_index, FALSE);
   }
};

void CLogView::OnEditRefresh() 
{
   CreateItems();
}

void CLogView::OnSize(UINT nType, int cx, int cy)
{ 
   CListCtrl& ctlList = GetListCtrl();
   ctlList.SetColumnWidth(0, cx - 30);
}

void CLogView::OnContextMenu(CWnd* pWnd, CPoint point)
{ 
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
   case ID_VIEW_STATUS:
      break;
   case ID_VIEW_LOG:
      return;
   };

   CMainFrame *frm = (CMainFrame *)::AfxGetMainWnd();
   ASSERT_VALID(frm);
   if( frm==NULL ) return;
   CMenu menu;
   menu.LoadMenu(IDR_POPUP);
   if( menu==NULL ) return;
   CMenu *editmenu = menu.GetSubMenu(0);
   if( editmenu==NULL ) return;
   editmenu->TrackPopupMenu(TPM_LEFTALIGN, 
      point.x, point.y,
      frm,
      NULL);
}

void CLogView::OnDelete()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );

   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         CArray< CDownloadFile*, CDownloadFile*& > aDeleted;
         POSITION pos = pSession->m_Files.GetHeadPosition();
         int idx = 0;
         while( pos!=NULL ) {
            CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            ASSERT_VALID(pFile);
            LV_ITEM itm = { 0 };
            itm.iItem = idx;
            itm.mask = LVIF_STATE;
            itm.stateMask = LVIS_SELECTED;
            ctlList.GetItem(&itm);
            if( itm.state & LVIS_SELECTED ) {
               if( pFile->m_State != FILESTATE_DOWNLOADING && pFile->m_State != FILESTATE_CONNECTING ) {
                  aDeleted.Add( pFile );
               }
            }
            idx++;
         }
         for( int i=0; i<aDeleted.GetSize(); i++ ) {
            POSITION pos = pSession->m_Files.Find( aDeleted[i] );
            pSession->m_Files.RemoveAt( pos );
            delete aDeleted[i];
         }
      }
      break;
   case ID_VIEW_STATUS:
      {
         int idx = 0;
         POSITION pos = pSession->m_Files.GetHeadPosition();
         while( pos!=NULL ) {
            CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            ASSERT_VALID(pFile);
            if( pFile->m_State == FILESTATE_DOWNLOADING || pFile->m_State == FILESTATE_CONNECTING ) {
               pFile->m_bSkipRequest = TRUE;
               TRY
               {
                  TRACE("Trying to abort file...\n");
                  if( pFile->m_pFile ) pFile->m_pFile->Abort();
               }
               CATCH_ALL( e )
               {
                  TRACE("File abort failed!\n");
               }
               END_CATCH_ALL
            }
         }
      }
      break;
   }

   ::AfxGetMainWnd()->PostMessage(WM_SCHEDULE);

   OnEditRefresh();
}

void CLogView::OnIgnoreFilename()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );
   
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         POSITION pos = pSession->m_Files.GetHeadPosition();
         int idx = 0;
         while( pos!=NULL ) {
            const CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            ASSERT_VALID(pFile);
            LV_ITEM itm = { 0 };
            itm.iItem = idx;
            itm.mask = LVIF_STATE;
            itm.stateMask = LVIS_SELECTED;
            ctlList.GetItem(&itm);
            if( itm.state & LVIS_SELECTED ) {
               CString sServer, sPage;
               DWORD dwType;
               INTERNET_PORT nPort;
               if( AfxParseURL( pFile->m_sURL, dwType, sServer, sPage, nPort ) ) {
                  pSession->m_Preferences->m_aBannerProviders.Add(sPage);
               }
            }
            idx++;
         }
      }
      break;
   }

   OnEditRefresh();
}

void CLogView::OnIgnoreDomain()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );
   
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         POSITION pos = pSession->m_Files.GetHeadPosition();
         int idx = 0;
         while( pos!=NULL ) {
            const CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            ASSERT_VALID(pFile);
            LV_ITEM itm = { 0 };
            itm.iItem = idx;
            itm.mask = LVIF_STATE;
            itm.stateMask = LVIS_SELECTED;
            ctlList.GetItem(&itm);
            if( itm.state & LVIS_SELECTED ) {
               CString sServer, sPage;
               DWORD dwType;
               INTERNET_PORT nPort;
               if( AfxParseURL( pFile->m_sURL, dwType, sServer, sPage, nPort ) ) {
                  pSession->m_Preferences->m_aBannerProviders.Add(sServer);
               }
            }
            idx++;
         }
      }
      break;
   }

   OnEditRefresh();
}

void CLogView::OnMoveUp()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );
   
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         CArray< CDownloadFile*, CDownloadFile*& > aDeleted;
         POSITION pos = pSession->m_Files.GetHeadPosition();
         int idx = 0;
         while( pos!=NULL ) {
            CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            ASSERT_VALID(pFile);
            LV_ITEM itm = { 0 };
            itm.iItem = idx;
            itm.mask = LVIF_STATE;
            itm.stateMask = LVIS_SELECTED;
            ctlList.GetItem(&itm);
            if( itm.state & LVIS_SELECTED ) {
               if( pFile->m_State != FILESTATE_DOWNLOADING && pFile->m_State != FILESTATE_CONNECTING ) {
                  aDeleted.Add( pFile );
               }
            }
            idx++;
         }
         for( int i=0; i<aDeleted.GetSize(); i++ ) {
            POSITION pos = pSession->m_Files.Find( aDeleted[i] );
            pSession->m_Files.RemoveAt( pos );
            pSession->m_Files.AddHead( aDeleted[i] );
         }
      }
      break;
   }

   OnEditRefresh();
}

void CLogView::OnMoveDown()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );
   
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         CArray< CDownloadFile*, CDownloadFile*& > aDeleted;
         POSITION pos = pSession->m_Files.GetHeadPosition();
         int idx = 0;
         while( pos!=NULL ) {
            CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            ASSERT_VALID(pFile);
            LV_ITEM itm = { 0 };
            itm.iItem = idx;
            itm.mask = LVIF_STATE;
            itm.stateMask = LVIS_SELECTED;
            ctlList.GetItem(&itm);
            if( itm.state & LVIS_SELECTED ) {
               if( pFile->m_State != FILESTATE_DOWNLOADING && pFile->m_State != FILESTATE_CONNECTING ) {
                  aDeleted.Add( pFile );
               }
            }
            idx++;
         }
         for( int i=0; i<aDeleted.GetSize(); i++ ) {
            POSITION pos = pSession->m_Files.Find( aDeleted[i] );
            pSession->m_Files.RemoveAt( pos );
            pSession->m_Files.AddTail( aDeleted[i] );
         }
      }
      break;
   }

   OnEditRefresh();
}

void CLogView::OnRandomize()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );

   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         DWORD dwTick = ::GetTickCount();
         int iStart = pSession->m_Info.m_nFilesDownloaded + pSession->m_Info.m_nFilesSkipped;
         int nCount = pSession->m_Files.GetCount() - iStart;
         while( true ) {
            POSITION pos = pSession->m_Files.GetHeadPosition();
            int n = (::rand() % nCount) + iStart;
            while( pos!=NULL ) {
               CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
               if( n-- == 0 ) {
                  if( pos != NULL && pFile->m_State == FILESTATE_WAITING) {
                     pSession->m_Files.RemoveAt( pSession->m_Files.Find(pFile) );
                     pSession->m_Files.AddTail(pFile);
                  }
                  break;
               }
            }
            DWORD dwNow = ::GetTickCount();
            if( (long)(dwNow - dwTick) < 0 ) break;
            if( dwNow - dwTick > 1500 ) break;
         }
      }
      break;
   }

   OnEditRefresh();
}

void CLogView::OnCopy()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );

   CListCtrl& ctlList = GetListCtrl();

   POSITION pos = ctlList.GetFirstSelectedItemPosition();
   if( pos == NULL ) return;

   CString sText = ctlList.GetItemText(ctlList.GetNextSelectedItem(pos), 0);

   if( !OpenClipboard() ) return;
   EmptyClipboard();
   HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, sText.GetLength()+1);
   if( hGlobal != NULL )  {
      strcpy( (char *)GlobalLock(hGlobal), static_cast<const char*>(sText));
      GlobalUnlock(hGlobal);
      SetClipboardData(CF_TEXT, hGlobal);
   }
   CloseClipboard();
}

void CLogView::OnOpenBrowser()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );

   CListCtrl& ctlList = GetListCtrl();

   POSITION pos = ctlList.GetFirstSelectedItemPosition();
   if( pos == NULL ) return;

   CString sText = ctlList.GetItemText(ctlList.GetNextSelectedItem(pos), 0);
   ::ShellExecute(m_hWnd, "open", sText, NULL, NULL, SW_SHOW);
}

void CLogView::OnGotoActive()
{
   CDoc *pDoc = GetDocument();
   ASSERT_KINDOF(CDoc,pDoc);
   if( pDoc==NULL ) return;
   CSession *pSession = pDoc->GetSelectedSession();
   ASSERT_VALID(pSession);
   if( pSession==NULL ) return;

   CWaitCursor wait;
   CSingleLock lock( *pSession, TRUE );

   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      {
         POSITION pos = pSession->m_Files.GetHeadPosition();
         int iIndex = 0;
         while( pos!=NULL ) {
            const CDownloadFile *pFile = pSession->m_Files.GetNext(pos);
            if( pos != NULL 
                && (pFile->m_State == FILESTATE_CONNECTING
                    || pFile->m_State == FILESTATE_DOWNLOADING) ) 
            {
               ctlList.SetItemState(-1, 0, LVNI_SELECTED);
               ctlList.SetItemState(iIndex, LVNI_SELECTED, LVNI_SELECTED);
               ctlList.EnsureVisible(iIndex, FALSE);
               return;
            }
            iIndex++;
         }
      }
      if( m_iLastActive > 0 ) {
         ctlList.SetItemState(-1, 0, LVNI_SELECTED);
         ctlList.SetItemState(m_iLastActive, LVNI_SELECTED, LVNI_SELECTED);
         ctlList.EnsureVisible(m_iLastActive, FALSE);
         return;
      }
      ::MessageBeep((UINT)-1);
      break;
   }
}

void CLogView::OnUpdateDelete(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateIgnoreFilename(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateIgnoreDomain(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateMoveUp(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateMoveDown(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateRandomize(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateCopy(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateOpenBrowser(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( ctlList.GetSelectedCount()>0 );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}

void CLogView::OnUpdateGotoActive(CCmdUI* pCmdUI) 
{
   CListCtrl& ctlList = GetListCtrl();
   switch( m_dwStyle ) {
   case ID_VIEW_FILES:
      pCmdUI->Enable( TRUE );
      break;
   case ID_VIEW_LOG:
   case ID_VIEW_STATUS:
      pCmdUI->Enable( FALSE );
      return;
   };
}