dirlistview.threads.cpp

来自「c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++」· C++ 代码 · 共 244 行

CPP
244
字号
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
//       http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////

// DirListView.Threads.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"

#include "Oscar.h"
#include "DirListView.h"
#include "DirTreeView.h"
#include "DirSplitter.h"

#include "MainFrm.h"
#include "ChildFrm.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

static HANDLE handleThread = NULL;

UINT PASCAL CDirListView::UpdateIcons_Thread(LPVOID *Param)
{
	CDirListView *pThis;

	// Set the wait cursor.
	CWaitCursor waitCursor;

	// Jump into the object itself
	pThis = (CDirListView *)Param;
	if(!pThis)
	{
		handleThread = NULL;     // Clear the global handle
		return 0;
	}

	// Add whatever information is required for sorting.
	for(int i = 0; 
		i < (int)pThis->m_cFileArray.GetNumEntries() && pThis->m_bUpdateContinue; i++)
	{
		// Extract the item's path.
		CString cszPath = pThis->m_cFileArray.GetFullName(i);
		if(cszPath.GetLength() == 0)
			continue;

		switch(pThis->m_iSortType)
		{
		case 0: default:                                          // Sort by name
			pThis->m_cFileArray.SetFriendlyName(i, 
				pThis->m_pFileSystem->GetFileDisplayName( cszPath ));
			break;

		case 1:                                                   // Sort by type
			pThis->m_cFileArray.SetType(i, pThis->m_pFileSystem->GetFileType(cszPath));
			break;

		case 2:                                                   // Sort by size
			pThis->m_cFileArray.SetSize(i, pThis->m_pFileSystem->GetFileSize(cszPath));
			break;

		case 3:                                                   // Sort by date
			pThis->m_cFileArray.SetModTime(i, 
				pThis->m_pFileSystem->GetFileModificationTime(cszPath));
			break;
		}

		// Always need this.
		pThis->m_cFileArray.SetDirectory(i, pThis->m_pFileSystem->IsDirectory(cszPath));
	}

	// Sort the items, in memory.
	pThis->m_cFileArray.SortItems(TRUE, pThis->m_iSortType);

	// Get a handle to the list view.
	CListCtrl *pList = &(pThis->m_List);
	ASSERT(pList);

	// Get a handle to the file system.
	CFileSystem *pFS = pThis->m_pFileSystem;
	ASSERT(pFS);

	// Iterate over the list, adding icons.
	// TODO: Mutexing?
	for(i = 0; 
		i < (int)pThis->m_cFileArray.GetNumEntries() && pThis->m_bUpdateContinue; i++)
	{
		// Extract the item's path.
		CString cszPath = pThis->m_cFileArray.GetFullName(i);
		if(cszPath.GetLength() == 0)
			continue;

		// Add the item to the ListCtrl with the current Icons
		SHFILEINFO shFinfo;
		int iIcon, iIndex;
		LPCTSTR strFileName;

		// Get the security filter.
		COscarApp *pApp = (COscarApp *)AfxGetApp();
		ASSERT(pApp);
		CSecurityFilter *pSecFilter = pApp->GetArchive()->m_pSecurityFilter;

		// Hold the security filter (not really necessary; the app isn't going
		// anywhere).
		pSecFilter->Reference();

		// Check to see if this is a shared directory.
		BOOL bIsShared = pSecFilter->IsShared(cszPath);

		// Let go the security filter.
		pSecFilter->Dereference();

		// Get the file information, minus the icon.
		if ( !pThis->m_pFileSystem->FillFileInfo( cszPath, &shFinfo, 
			SHGFI_ICON | pThis->m_iIconStyle | SHGFI_DISPLAYNAME | SHGFI_TYPENAME) )
		{
			continue;
		}

		iIcon = shFinfo.iIcon;

		// If the file is a shared directory, set the icon.
		if(pThis->m_pFileSystem->IsDirectory(cszPath) && bIsShared && 
			pThis->m_pFileSystem->GetFSType() == 0)
		{
			// First, back-up the normal icon (thread problems?).
			if(pThis->m_iViewType == 0)                    // Large icon.
				pApp->m_nNormalFolderIcon[SFI_LARGE] = shFinfo.iIcon;
			else
				pApp->m_nNormalFolderIcon[SFI_CLOSED] = shFinfo.iIcon;

			// Now set the shared icon.
			if(pThis->m_iViewType == 0)                    // Large icon.
				iIcon = pApp->m_nShareFolderIcon[SFI_LARGE];
			else
				iIcon = pApp->m_nShareFolderIcon[SFI_CLOSED];
		}

		strFileName = 
			pThis->m_pFileSystem->GetSubPath(pThis->m_pFileSystem->GetFileDisplayName( shFinfo ));

		int nLastItem;
		if(pThis->m_bUpdateContinue) nLastItem = pThis->m_List.GetItemCount();
		if(nLastItem > 0)
			nLastItem += 1;

		if(pThis->m_bUpdateContinue)
			iIndex = pThis->m_List.InsertItem( nLastItem, strFileName, iIcon );

		if(pThis->m_bUpdateContinue) 
			pThis->m_List.SetItemData(iIndex, (DWORD)i);

		pThis->m_cFileArray.SetIcon(i, iIcon);
		pThis->m_cFileArray.SetDirectory(i, pThis->m_pFileSystem->IsDirectory(cszPath));
		pThis->m_cFileArray.SetSize(i, pThis->m_pFileSystem->GetFileSize(cszPath));
		pThis->m_cFileArray.SetType(i, pThis->m_pFileSystem->GetFileType(shFinfo));
		pThis->m_cFileArray.SetModTime(i, 
			pThis->m_pFileSystem->GetFileModificationTime(cszPath));

		if(pThis->m_iViewType == 3)
		{
			if(pThis->m_bUpdateContinue)
				pThis->m_List.SetItemText( iIndex, 1, pThis->m_cFileArray.GetSize(i) );
			if(pThis->m_bUpdateContinue)
				pThis->m_List.SetItemText( iIndex, 2, pThis->m_cFileArray.GetType(i) );

			CTime ctTime = pThis->m_cFileArray.GetModTime(i);
			pThis->m_List.SetItemText( iIndex, 3, ctTime.Format("%m/%d/%y %I:%M:%S %p") );
		}
	}

	// Clean up
	handleThread = NULL;
	return 1;
}

BOOL CDirListView::UpdateIcons()
{
	CWinThread *pThread;

	if(handleThread)
		return FALSE;

	m_bUpdateContinue = TRUE;

	pThread = AfxBeginThread((AFX_THREADPROC)(CDirListView::UpdateIcons_Thread),
		(LPVOID)this, THREAD_PRIORITY_NORMAL);

	ASSERT(pThread);
	if(!pThread) return FALSE;

	handleThread = pThread->m_hThread;

	return TRUE;
}

BOOL CDirListView::StopUpdateIcons(BOOL bWait)
{
	DWORD dwExitCode = STILL_ACTIVE;

	if(!handleThread)
		return FALSE;

	m_bUpdateContinue = FALSE;

	while(dwExitCode == STILL_ACTIVE && bWait && handleThread)
	{
		if(!GetExitCodeThread(handleThread, &dwExitCode))
			return FALSE;

		if(dwExitCode == STILL_ACTIVE)
		{
			// Process any unhandled messages
			
			MSG msg;
			while ( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) 
			{ 
				CWinThread *pThisThread = AfxGetThread();
				ASSERT(pThisThread);

				if ( !pThisThread->PumpMessage( ) ) 
					break;
			}
    
			Sleep(THREAD_DIE_WAIT);
		}
	}

	return TRUE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?