DrvListBox.cpp
上传用户:davidcaozc
上传日期:2007-01-01
资源大小:13k
文件大小:5k
- // ==========================================================================
- // 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 availablen" );
- }
- 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
- 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();
- }