www.pudn.com > SectorEdit2000.rar > DrvListBox.cpp


// ========================================================================== 
// DrvListBox.cpp : implementation file 
// ========================================================================== 
 
#include "stdafx.h" 
#include "DrvListBox.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
// ========================================================================== 
// Construction/Destruction 
// ========================================================================== 
CDrvListBox::CDrvListBox() : 
  m_pDriveStrings( NULL ), 
	m_pImageList( NULL ) 
	{ 
	} 
CDrvListBox::~CDrvListBox() 
	{ 
  // detach system image list before deleting it: otherwise when I delete the  
	// list I'd be deallocating the system-wide image list 
 
	if( m_pImageList != NULL ) 
		{ 
		m_pImageList->Detach(); 
		delete m_pImageList; 
		} 
 
	// this should be safe since all pointers into that buffer are destroyed 
	// at the "same" time 
 
	if( m_pDriveStrings != NULL ) 
		delete[] m_pDriveStrings; 
	} 
// ========================================================================== 
// Message Map 
// ========================================================================== 
 
BEGIN_MESSAGE_MAP(CDrvListBox, CComboBoxEx) 
	//{{AFX_MSG_MAP(CDrvListBox) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
// ========================================================================== 
// Load Items - collects all drive information and place it into the listbox, 
// return number of items added to the list: a negative value is an error; 
// ========================================================================== 
int CDrvListBox::LoadItems( const bool bLargeIcons ) 
{ 
	if( m_pDriveStrings != NULL ) 
		return -1; // duplicate calls are not implemented 
 
	// allocate buffer for the drive strings: GetLogicalDriveStrings will tell 
	// me how much is needed (minus the trailing zero-byte) 
 
	size_t lAllDriveStrings = GetLogicalDriveStrings( 0, NULL ); 
 
	_ASSERT( m_pDriveStrings == NULL ); 
		m_pDriveStrings = new _TCHAR[ lAllDriveStrings + sizeof( _T("")) ]; // + for trailer 
		if( GetLogicalDriveStrings( lAllDriveStrings, m_pDriveStrings ) != lAllDriveStrings - 1 ) 
			return -2; 
	_ASSERT( m_pDriveStrings != NULL ); 
 
	// this structure is used to enter items into the CComboBoxEx, preset 
	// some parts before loop to fill box starts; I need to set both  
	// standard and selected images or I won't see an icon when an entry 
	// is selected; the lParam is set so I can have direct access to the 
	// selected root path. 
 
	COMBOBOXEXITEM CBEItem; 
	CBEItem.mask		= CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM; 
	CBEItem.cchTextMax	= 0;	// is ignored 
	CBEItem.iItem		= -1; // insert at end 
   
	// now loop over each drive (string) 
 
	_TCHAR *pDriveString = m_pDriveStrings; 
	size_t  lDriveString = strlen( pDriveString ); 
	DWORD		dIconSize    = bLargeIcons ? SHGFI_LARGEICON : SHGFI_SMALLICON; 
 
	while( lDriveString > 0 ) 
	{ 
    // retrieve display string and icon handle 
 
		SHFILEINFO FileInfo; 
		DWORD r = SHGetFileInfo( pDriveString, 0, &FileInfo, sizeof( FileInfo ), 
			SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX | dIconSize ); 
		if( r == 0 ) // failure - which can be ignored  
		{ 
			TRACE0( "SHGetFileInfo failed, no more details available\n" ); 
		} 
		else 
		{ 
			// insert icon and string into list box 
 
			CBEItem.pszText = FileInfo.szDisplayName; 
			CBEItem.lParam  = ( LPARAM )pDriveString; 
 
			CBEItem.iSelectedImage	= 
			CBEItem.iImage			= FileInfo.iIcon; // index into system image list 
 
			if(GetDriveType(pDriveString)==DRIVE_FIXED || GetDriveType(pDriveString)==DRIVE_REMOVABLE) 
				VERIFY( InsertItem( &CBEItem ) >= 0 ); 
			} 
 
		// setup for next drive string (next round in loop) 
 
		pDriveString += lDriveString + 1; 
		lDriveString = strlen( pDriveString ); 
	} 
 
	// have items in list, now provide image list: it seems I cannot just 
	// pass the system image list (see notes on System Image List by Marc 
	// Otway) so I create a copy on the fly (code based also on Marc's) 
 
	_ASSERT( m_pImageList == NULL ); 
	m_pImageList = new CImageList; 
 
	// load the system image list - use an arbitrary file extension for the 
	// call to SHGetFileInfo (we don't want to touch the disk, so use 
	// FILE_ATTRIBUTE_NORMAL && SHGFI_USEFILEATTRIBUTES) 
 
	SHFILEINFO FileInfo; 
	VERIFY( m_pImageList->Attach(( HIMAGELIST )SHGetFileInfo( _T(".txt"), 
		FILE_ATTRIBUTE_NORMAL, &FileInfo, sizeof( FileInfo ), 
		SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | dIconSize ))); 
	 
	// make the background colour transparent, works better for lists etc. 
 
	m_pImageList->SetBkColor( CLR_NONE ); 
 
	// don't forget to set it up! 
 
	VERIFY( SetImageList( m_pImageList ) == NULL ); 
 
	// done. 
 
	return GetCount(); 
}