diff --git a/WinDirStat/windirstat/SelectDrivesDlg.cpp b/WinDirStat/windirstat/SelectDrivesDlg.cpp index f63e08a..b04f190 100644 --- a/WinDirStat/windirstat/SelectDrivesDlg.cpp +++ b/WinDirStat/windirstat/SelectDrivesDlg.cpp @@ -19,6 +19,10 @@ namespace { UINT WMU_THREADFINISHED = RegisterWindowMessageW( _T( "{F03D3293-86E0-4c87-B559-5FD103F5AF58}" ) ); const rsize_t volume_name_size = ( MAX_PATH + 1u ); + const rsize_t max_number_of_named_drives = 32u; + const rsize_t volume_name_pool_size = ( volume_name_size * max_number_of_named_drives ); + + std::tuple RetrieveDriveInformation_GetVolumeName_succeeded( _In_ const std::wstring path, _In_ _Null_terminated_ wchar_t( &volume_name )[ volume_name_size ], _Inout_ _Pre_writable_size_( volume_name_size ) PWSTR formatted_volume_name ) { std::uint64_t total = 0; std::uint64_t free = 0; @@ -50,21 +54,25 @@ namespace { thisDriveItem->m_used = 0; } - void SetDriveInformation_copy_name_and_set_m_used( _In_ CDriveItem* const thisDriveItem, _In_ const std::wstring name ) { + void SetDriveInformation_copy_name_and_set_m_used( _In_ CDriveItem* const thisDriveItem, _In_ const std::wstring name, _In_ Children_String_Heap_Manager* name_pool ) { ASSERT( name.length( ) < UINT16_MAX ); const auto new_name_length = static_cast( name.length( ) ); PWSTR new_name_ptr_temp = nullptr; - const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr_temp, new_name_length, name ); + //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr_temp, new_name_length, name ); + const HRESULT copy_res = name_pool->copy_name_str_into_buffer( new_name_ptr_temp, ( new_name_length + 1u ), name ); + + ASSERT( SUCCEEDED( copy_res ) ); if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy name str! (SetDriveInformation, success)(aborting!)" ); displayWindowsMsgBoxWithMessage( name.c_str( ) ); std::terminate( ); } + PCWSTR const new_name_ptr = new_name_ptr_temp; - thisDriveItem->m_name.reset( new_name_ptr ); + thisDriveItem->m_name = new_name_ptr; thisDriveItem->m_name_length = new_name_length; if ( thisDriveItem->m_totalBytes == 0 ) { return; @@ -74,19 +82,19 @@ namespace { thisDriveItem->m_used = static_cast( thisDriveItem->m_totalBytes - thisDriveItem->m_freeBytes ) / static_cast( thisDriveItem->m_totalBytes ); } - void SetDriveInformation_failure( _In_ CDriveItem* thisDriveItem, _In_ const std::wstring name ) { + void SetDriveInformation_failure( _In_ CDriveItem* const thisDriveItem ) { thisDriveItem->m_totalBytes = UINT64_MAX; thisDriveItem->m_freeBytes = UINT64_MAX; thisDriveItem->m_used = -1; } - void SetDriveInformation( _In_ CDriveItem* thisDriveItem, _In_ const bool success, _In_ const std::wstring name, _In_ const std::uint64_t total, _In_ const std::uint64_t free ) { + void SetDriveInformation( _In_ CDriveItem* const thisDriveItem, _In_ const bool success, _In_ const std::wstring name, _In_ const std::uint64_t total, _In_ const std::uint64_t free, _In_ Children_String_Heap_Manager* const name_pool ) { if ( success ) { SetDriveInformation_set_valid_info( thisDriveItem, name, total, free ); - return SetDriveInformation_copy_name_and_set_m_used( thisDriveItem, name ); + return SetDriveInformation_copy_name_and_set_m_used( thisDriveItem, name, name_pool ); } - SetDriveInformation_failure( thisDriveItem, name ); - SetDriveInformation_copy_name_and_set_m_used( thisDriveItem, name ); + SetDriveInformation_failure( thisDriveItem ); + SetDriveInformation_copy_name_and_set_m_used( thisDriveItem, name, name_pool ); return; } @@ -300,8 +308,9 @@ IMPLEMENT_DYNAMIC(CSelectDrivesDlg, CDialog) UINT CSelectDrivesDlg::_serial; + #pragma warning(suppress:4355) -CSelectDrivesDlg::CSelectDrivesDlg( CWnd* pParent /*=NULL*/ ) : CDialog( CSelectDrivesDlg::IDD, pParent ), m_radio( RADIO_ALLLOCALDRIVES ), m_layout( static_cast( this ), global_strings::select_drives_dialog_layout ) { +CSelectDrivesDlg::CSelectDrivesDlg( CWnd* pParent /*=NULL*/ ) : CDialog( CSelectDrivesDlg::IDD, pParent ), m_radio( RADIO_ALLLOCALDRIVES ), m_layout( static_cast( this ), global_strings::select_drives_dialog_layout ), m_name_pool( volume_name_pool_size ) { _serial++; //InitializeCriticalSection_wrapper( _csRunningThreads ); InitializeCriticalSection_wrapper( m_running_threads_CRITICAL_SECTION ); @@ -395,9 +404,9 @@ void CSelectDrivesDlg::buildSelectList( ) { const auto drives = GetLogicalDrives( ); INT i = 0; DWORD mask = 0x00000001; - m_list.m_drives.reset( new CDriveItem[ 32 ] ); + m_list.m_drives.reset( new CDriveItem[ max_number_of_named_drives ] ); m_list.m_drives_count = 0; - for ( i = 0; i < 32; i++, mask <<= 1 ) { + for ( i = 0; i < static_cast( max_number_of_named_drives ); i++, mask <<= 1 ) { if ( ( drives bitand mask ) == 0 ) { continue; } @@ -414,6 +423,7 @@ void CSelectDrivesDlg::buildSelectList( ) { } const rsize_t drive_name_length = ( drive_name_buffer_size - chars_remaining ); + ASSERT( wcslen( drive_name_buffer ) == drive_name_length ); const auto type = GetDriveTypeW( drive_name_buffer ); if ( ( type == DRIVE_UNKNOWN ) || ( type == DRIVE_NO_ROOT_DIR ) ) { @@ -435,8 +445,9 @@ void CSelectDrivesDlg::buildSelectList( ) { ASSERT( drive_name_length < UINT16_MAX ); PWSTR new_name_ptr = nullptr; - //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, s.GetString( ) ); - const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, drive_name_length, drive_name_buffer ); + //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, drive_name_length, drive_name_buffer ); + const HRESULT copy_res = m_name_pool.copy_name_str_into_buffer( new_name_ptr, ( drive_name_length + 1u ), drive_name_buffer ); + ASSERT( SUCCEEDED( copy_res ) ); if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy name str! (buildSelectList)(aborting!)" ); @@ -702,7 +713,7 @@ LRESULT _Function_class_( "GUI_THREAD" ) CSelectDrivesDlg::OnWmuThreadFinished( //EnterCriticalSection( &_csRunningThreads ); EnterCriticalSection( &m_running_threads_CRITICAL_SECTION ); - SetDriveInformation( item, success, std::move( name ), total, free ); + SetDriveInformation( item, success, std::move( name ), total, free, &m_name_pool ); LeaveCriticalSection( &m_running_threads_CRITICAL_SECTION ); //LeaveCriticalSection( &_csRunningThreads ); diff --git a/WinDirStat/windirstat/SelectDrivesDlg.h b/WinDirStat/windirstat/SelectDrivesDlg.h index 13834dc..94711aa 100644 --- a/WinDirStat/windirstat/SelectDrivesDlg.h +++ b/WinDirStat/windirstat/SelectDrivesDlg.h @@ -272,6 +272,7 @@ class CSelectDrivesDlg final : public CDialog { std::vector m_drives; // out. Valid if m_radio != RADIO_AFOLDER CRITICAL_SECTION m_running_threads_CRITICAL_SECTION; _Guarded_by_( m_running_threads_CRITICAL_SECTION ) std::vector m_running_threads; + Children_String_Heap_Manager m_name_pool; protected: static UINT _serial; // Each Instance of this dialog gets a serial number CDrivesList m_list; diff --git a/WinDirStat/windirstat/TreeListControl.cpp b/WinDirStat/windirstat/TreeListControl.cpp index 3b1d0e3..d1e8151 100644 --- a/WinDirStat/windirstat/TreeListControl.cpp +++ b/WinDirStat/windirstat/TreeListControl.cpp @@ -103,7 +103,7 @@ namespace { } while ( ( steps_from_target > 0 ) && ( child != static_cast< const CItemBranch* >( item ) ) ); - TRACE( _T( "halted at: %s\r\n" ), child->m_name.get( ) ); + TRACE( _T( "halted at: %s\r\n" ), child->m_name ); //END new algorithm } @@ -205,7 +205,7 @@ void CTreeListItem::childNotNull( _In_ CItemBranch* const aTreeListChild, const //TRACE( _T( "aTreeListChild: %s\r\n" ), aTreeListChild->GetText( column::COL_NAME ).c_str( ) ); ASSERT( m_vi->cache_sortedChildren.at( i ) == aTreeListChild ); //ASSERT( m_vi->cache_sortedChildren.at( i )->GetText( column::COL_NAME ).compare( aTreeListChild->GetText( column::COL_NAME ) ) == 0 ); - ASSERT( wcscmp( m_vi->cache_sortedChildren.at( i )->m_name.get( ), aTreeListChild->m_name.get( ) ) == 0u ); + ASSERT( wcscmp( m_vi->cache_sortedChildren.at( i )->m_name, aTreeListChild->m_name ) == 0u ); m_vi->cache_sortedChildren.at( i ) = aTreeListChild; } } @@ -388,7 +388,7 @@ void CTreeListControl::adjustColumnSize( _In_ const CTreeListItem* const item_at static_assert( std::is_convertible::type, int>::value, "we're gonna need to do this!" ); const auto w = GetSubItemWidth( item_at_index, column::COL_NAME ) + 5; - ASSERT( w == ( GetStringWidth( item_at_index->m_name.get( ) ) + 15 ) ); + ASSERT( w == ( GetStringWidth( item_at_index->m_name ) + 15 ) ); const auto colWidth = GetColumnWidth( static_cast( column::COL_NAME ) ); if ( colWidth < w ) { VERIFY( SetColumnWidth( 0, w + colWidth ) ); @@ -425,7 +425,7 @@ void CTreeListControl::expand_item_then_scroll_to_it( _In_ const CTreeListItem* } INT CTreeListControl::find_item_then_show_first_try_failed( _In_ const CTreeListItem* const thisPath, const int i ) { - TRACE( _T( "Searching %s ( this path element ) for next path element...not found! Expanding %I64d...\r\n" ), thisPath->m_name.get( ), i ); + TRACE( _T( "Searching %s ( this path element ) for next path element...not found! Expanding %I64d...\r\n" ), thisPath->m_name, i ); ExpandItemNoScroll( i ); //we expect to find the item on the second try. @@ -449,7 +449,7 @@ void CTreeListControl::find_item_then_show( _In_ const CTreeListItem* const this } else { //if we've found the item, then we should close anything that we opened in the process? - TRACE( _T( "Searching %s for next path element...found! path.at( %I64d ), index: %i\r\n" ), thisPath->m_name.get( ), std::int64_t( i ), index ); + TRACE( _T( "Searching %s for next path element...found! path.at( %I64d ), index: %i\r\n" ), thisPath->m_name, std::int64_t( i ), index ); index = collapse_parent_plus_one_through_index( thisPath, index, parent ); TRACE( _T( "Collapsing items [%i, %i), new index %i. Item count: %i\r\n" ), ( parent + 1 ), index, index, GetItemCount( ) ); } @@ -600,8 +600,8 @@ void CTreeListControl::SelectAndShowItem( _In_ const CTreeListItem* const item, #ifdef DEBUG for ( size_t inner = 0; inner < path.size( ); ++inner ) { - ASSERT( path.at( inner )->m_name.get( ) != NULL ); - TRACE( _T( "path component %I64u: `%s` (%p)\r\n" ), std::uint64_t( inner ), path.at( inner )->m_name.get( ), path.at( inner ) ); + ASSERT( path.at( inner )->m_name != NULL ); + TRACE( _T( "path component %I64u: `%s` (%p)\r\n" ), std::uint64_t( inner ), path.at( inner )->m_name, path.at( inner ) ); } #endif @@ -971,7 +971,7 @@ int CTreeListControl::countItemsToDelete( _In_ const CTreeListItem* const item, } todelete++; } - TRACE( _T( "Need to delete %i items from %s\r\n" ), todelete, item->m_name.get( ) ); + TRACE( _T( "Need to delete %i items from %s\r\n" ), todelete, item->m_name ); return todelete; } @@ -983,10 +983,10 @@ _Success_( return == true ) bool CTreeListControl::CollapseItem( _In_ _In_range_ return false; } if ( !item->IsExpanded( ) ) { - TRACE( _T( "ERROR: Collapsing item %i: %s...it's not expanded!\r\n" ), i, item->m_name.get( ) ); + TRACE( _T( "ERROR: Collapsing item %i: %s...it's not expanded!\r\n" ), i, item->m_name ); return false; } - TRACE( _T( "Collapsing item %i: %s\r\n" ), i, item->m_name.get( ) ); + TRACE( _T( "Collapsing item %i: %s\r\n" ), i, item->m_name ); //WTL::CWaitCursor wc; SetRedraw( FALSE ); @@ -1000,7 +1000,7 @@ _Success_( return == true ) bool CTreeListControl::CollapseItem( _In_ _In_range_ ASSERT( local_var != NULL ); if ( local_var != NULL ) { ASSERT( item_number_to_delete == FindListItem( local_var ) ); - TRACE( _T( "deleting item %i (%i/%i), %s\r\n" ), ( item_number_to_delete ), m, todelete, local_var->m_name.get( ) ); + TRACE( _T( "deleting item %i (%i/%i), %s\r\n" ), ( item_number_to_delete ), m, todelete, local_var->m_name ); } else { TRACE( _T( "deleting item %i (%i/%i), %s\r\n" ), ( item_number_to_delete ), m, todelete, L"ERROR: NULL POINTER!" ); @@ -1018,7 +1018,7 @@ _Success_( return == true ) bool CTreeListControl::CollapseItem( _In_ _In_range_ const auto item_count = GetItemCount( ); #ifdef DEBUG const auto local_var = GetItem( i ); - TRACE( _T( "Redrawing items %i (`%s`) to %i....\r\n" ), i, ( ( local_var != NULL ) ? local_var->m_name.get( ) : L"" ), ( item_count ) ); + TRACE( _T( "Redrawing items %i (`%s`) to %i....\r\n" ), i, ( ( local_var != NULL ) ? local_var->m_name : L"" ), ( item_count ) ); #endif VERIFY( RedrawItems( i, item_count ) ); @@ -1102,14 +1102,14 @@ void CTreeListControl::ExpandItemInsertChildren( _In_ const CTreeListItem* const static_assert( column::COL_NAME == 0, "GetSubItemWidth used to accept an INT as the second parameter. The value of zero, I believe, should be COL_NAME" ); //static_assert( COL_NAME__ == 0, "GetSubItemWidth used to accept an INT as the second parameter. The value of zero, I believe, should be COL_NAME" ); auto maxwidth = GetSubItemWidth( item, column::COL_NAME ); - ASSERT( maxwidth == ( GetStringWidth( item->m_name.get( ) ) + 10 ) ); + ASSERT( maxwidth == ( GetStringWidth( item->m_name ) + 10 ) ); const auto count = item->GetChildrenCount_( ); if ( count == 0 ) { - TRACE( _T( "item `%s` has a child count of ZERO! Not expanding! \r\n" ), item->m_name.get( ) ); + TRACE( _T( "item `%s` has a child count of ZERO! Not expanding! \r\n" ), item->m_name ); return; } const auto myCount = static_cast( GetItemCount( ) ); - TRACE( _T( "Expanding %s! Must insert %i items!\r\n" ), item->m_name.get( ), count ); + TRACE( _T( "Expanding %s! Must insert %i items!\r\n" ), item->m_name, count ); SetItemCount( static_cast( ( count >= myCount) ? ( count + 1 ) : ( myCount + 1 ) ) ); insertItemsAdjustWidths( item, count, maxwidth, scroll, i ); diff --git a/WinDirStat/windirstat/TreeListControl.h b/WinDirStat/windirstat/TreeListControl.h index ec9e32e..ada2200 100644 --- a/WinDirStat/windirstat/TreeListControl.h +++ b/WinDirStat/windirstat/TreeListControl.h @@ -137,7 +137,7 @@ class CTreeListItem : public COwnerDrawnListItem { public: const CTreeListItem* m_parent; - + Children_String_Heap_Manager m_name_pool; // Data needed to display the item. mutable std::unique_ptr m_vi = nullptr; }; diff --git a/WinDirStat/windirstat/colorbutton.cpp b/WinDirStat/windirstat/colorbutton.cpp index a8694dc..17f2afe 100644 --- a/WinDirStat/windirstat/colorbutton.cpp +++ b/WinDirStat/windirstat/colorbutton.cpp @@ -11,10 +11,10 @@ #include "colorbutton.h" -BEGIN_MESSAGE_MAP(CColorButton::CPreview, CWnd) - ON_WM_PAINT() - ON_WM_LBUTTONDOWN() -END_MESSAGE_MAP() +//BEGIN_MESSAGE_MAP(CColorButton::CPreview, CWnd) +// ON_WM_PAINT() +// ON_WM_LBUTTONDOWN() +//END_MESSAGE_MAP() BEGIN_MESSAGE_MAP( CColorButton, CButton ) ON_WM_PAINT( ) diff --git a/WinDirStat/windirstat/colorbutton.h b/WinDirStat/windirstat/colorbutton.h index b29b40d..fc8bf70 100644 --- a/WinDirStat/windirstat/colorbutton.h +++ b/WinDirStat/windirstat/colorbutton.h @@ -9,6 +9,7 @@ #include "stdafx.h" +#include "globalhelpers.h" #define COLBN_CHANGED 0x87 // this is a value, I hope, that is nowhere used as notification code. @@ -23,8 +24,9 @@ class CColorButton final : public CButton { CColorButton( ) = default; CColorButton& operator=( const CColorButton& in ) = delete; CColorButton( const CColorButton& in ) = delete; + // The color preview is an own little child window of the button. - class CPreview final : public CWnd { + class CPreview final : public ATL::CWindowImpl { public: COLORREF m_color; @@ -34,34 +36,97 @@ class CColorButton final : public CButton { CPreview( ) : m_color{ 0u } { } void SetColor( _In_ const COLORREF color ) { m_color = color; - if ( IsWindow( m_hWnd ) ) { + if ( IsWindow( ) ) { //"Return value: If the function succeeds, the return value is nonzero. If the function fails, the return value is zero." VERIFY( ::InvalidateRect( m_hWnd, NULL, TRUE ) ); //InvalidateRect( NULL ); } } - DECLARE_MESSAGE_MAP() - afx_msg void OnPaint( ) { - CPaintDC dc( this ); +#pragma warning( push ) +#pragma warning( disable: 4365 ) + BEGIN_MSG_MAP(CPreview) + MESSAGE_HANDLER( static_cast( WM_PAINT ), ( CPreview::OnPaint ) ) + MESSAGE_HANDLER( static_cast( WM_LBUTTONDOWN ), ( CPreview::OnLButtonDown ) ) + DEFAULT_REFLECTION_HANDLER( ) + END_MSG_MAP() +#pragma warning( pop ) + + LRESULT OnPaint( UINT /*nMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ ) { + //CPaintDC dc( this ); + PAINTSTRUCT ps; + HDC hDC = BeginPaint( &ps ); + RECT rc; ASSERT( ::IsWindow( m_hWnd ) ); //"Return value: If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError." VERIFY( ::GetClientRect( m_hWnd, &rc ) ); //GetClientRect( &rc ); + //VERIFY( dc.DrawEdge( &rc, EDGE_BUMP, BF_RECT bitor BF_ADJUST ) ); + /* +_AFXWIN_INLINE BOOL CDC::DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags) + { ASSERT(m_hDC != NULL); return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags); } + */ - VERIFY( dc.DrawEdge( &rc, EDGE_BUMP, BF_RECT bitor BF_ADJUST ) ); + VERIFY( DrawEdge( hDC, &rc, EDGE_BUMP, BF_RECT bitor BF_ADJUST ) ); auto color_scope_holder = m_color; - if ( ( GetParent( )->GetStyle( ) bitand WS_DISABLED ) != 0 ) { + const HWND parent = GetParent( ); + + auto window_info = zero_init_struct( ); + window_info.cbSize = sizeof( WINDOWINFO ); + + + //If [GetWindowInfo] succeeds, the return value is nonzero. + const BOOL window_info_res = ::GetWindowInfo( parent, &window_info ); + if ( window_info_res == 0 ) { + const DWORD err = GetLastError( ); + TRACE( _T( "GetWindowInfo failed! Error: %u\r\n" ), unsigned( err ) ); + displayWindowsMsgBoxWithError( err ); + const auto color = color_scope_holder; + + //dc.FillSolidRect( &rc, color ); + /* +void CDC::FillSolidRect(LPCRECT lpRect, COLORREF clr) +{ + ENSURE_VALID(this); + ENSURE(m_hDC != NULL); + ENSURE(lpRect); + + ::SetBkColor(m_hDC, clr); + ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); +} + */ + + ::SetBkColor( hDC, color ); + ::ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + + EndPaint( &ps ); + return 0; + } + + if ( ( window_info.dwStyle bitand WS_DISABLED ) != 0 ) { color_scope_holder = GetSysColor( COLOR_BTNFACE ); } const auto color = color_scope_holder; - dc.FillSolidRect( &rc, color ); + //dc.FillSolidRect( &rc, color ); + ::SetBkColor( hDC, color ); + ::ExtTextOutW( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL ); + + EndPaint( &ps ); + return 0; } - afx_msg void OnLButtonDown( UINT nFlags, CPoint point ) { + //UINT /*nMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ + //UINT nFlags, CPoint point + LRESULT OnLButtonDown( UINT /*nMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/ ) { + const UINT nFlags = static_cast< UINT >( wParam ); + //const POINT point = static_cast< POINT >( lParam ); + POINT point_temp; + point_temp.x = GET_X_LPARAM( lParam ); + point_temp.y = GET_Y_LPARAM( lParam ); + POINT point = point_temp; ASSERT( ::IsWindow( m_hWnd ) ); //"Return value: If the function succeeds, the return value is nonzero. If the function fails, the return value is zero." VERIFY( ::ClientToScreen( m_hWnd, &point ) ); @@ -70,7 +135,8 @@ class CColorButton final : public CButton { const auto this_parent = GetParent( ); //"Return value: If the function succeeds, the return value is nonzero. If the function fails, the return value is zero." - VERIFY( ::ScreenToClient( this_parent->m_hWnd, &point ) ); + VERIFY( ::ScreenToClient( this_parent.m_hWnd, &point ) ); + //this_parent->ScreenToClient( &point ); TRACE( _T( "User clicked x:%ld, y:%ld! Sending WM_LBUTTONDOWN!\r\n" ), point.x, point.y ); @@ -79,7 +145,21 @@ class CColorButton final : public CButton { _AFXWIN_INLINE CWnd* CWnd::GetParent() const { ASSERT(::IsWindow(m_hWnd)); return CWnd::FromHandle(::GetParent(m_hWnd)); } */ - this_parent->SendMessageW( WM_LBUTTONDOWN, nFlags, MAKELPARAM( point.x, point.y ) ); + /* +_AFXWIN_INLINE LRESULT CWnd::_AFX_FUNCNAME(SendMessage)(UINT message, WPARAM wParam, LPARAM lParam) const + { ASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, message, wParam, lParam); } +#pragma push_macro("SendMessage") +#undef SendMessage +_AFXWIN_INLINE LRESULT CWnd::SendMessage(UINT message, WPARAM wParam, LPARAM lParam) const + { return _AFX_FUNCNAME(SendMessage)(message, wParam, lParam); } +#pragma pop_macro("SendMessage") + + */ + //this_parent->SendMessageW( WM_LBUTTONDOWN, nFlags, MAKELPARAM( point.x, point.y ) ); + + const HWND parent = GetParent( ); + ::SendMessageW( parent, WM_LBUTTONDOWN, nFlags, MAKELPARAM( point.x, point.y ) ); + return 0; } }; @@ -100,7 +180,7 @@ class CColorButton final : public CButton { //rc.DeflateRect( 4, 4 ); VERIFY( ::InflateRect( &rc, -4, -4 ) ); - VERIFY( m_preview.Create( AfxRegisterWndClass( 0, 0, 0, 0 ), _T( "" ), WS_CHILD | WS_VISIBLE, rc, this, 4711 ) ); + VERIFY( m_preview.Create( m_hWnd, rc, _T( "" ), WS_CHILD | WS_VISIBLE, 0, 4711, NULL ) ); VERIFY( ModifyStyle( 0, WS_CLIPCHILDREN ) ); } diff --git a/WinDirStat/windirstat/directory_enumeration.cpp b/WinDirStat/windirstat/directory_enumeration.cpp index 618a7cc..d9d8d1e 100644 --- a/WinDirStat/windirstat/directory_enumeration.cpp +++ b/WinDirStat/windirstat/directory_enumeration.cpp @@ -74,7 +74,7 @@ namespace { } } else { - TRACE( _T( "ERROR returned by GetCompressedFileSize! file: %s\r\n" ), child->m_name.get( ) ); + TRACE( _T( "ERROR returned by GetCompressedFileSize! file: %s\r\n" ), child->m_name ); child->m_attr.invalid = true; } } @@ -174,7 +174,10 @@ std::vector> addFiles_returnSizesToWorkOn( ASSERT( new_name_length < UINT16_MAX ); PWSTR new_name_ptr = nullptr; - const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, aFile.name ); + //ThisCItem->m_name_pool.copy_name_str_into_buffer + //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, aFile.name ); + const HRESULT copy_res = ThisCItem->m_name_pool.copy_name_str_into_buffer( new_name_ptr, ( new_name_length + 1u ), aFile.name ); + if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy (compressed) name str! (addFiles_returnSizesToWorkOn)(aborting!)" ); displayWindowsMsgBoxWithMessage( aFile.name.c_str( ) ); @@ -191,7 +194,10 @@ std::vector> addFiles_returnSizesToWorkOn( const auto new_name_length = aFile.name.length( ); ASSERT( new_name_length < UINT16_MAX ); PWSTR new_name_ptr = nullptr; - const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, aFile.name ); + + //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, aFile.name ); + const HRESULT copy_res = ThisCItem->m_name_pool.copy_name_str_into_buffer( new_name_ptr, ( new_name_length + 1u ), aFile.name ); + if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy (uncompressed) name str! (addFiles_returnSizesToWorkOn)(aborting!)" ); displayWindowsMsgBoxWithMessage( aFile.name.c_str( ) ); @@ -230,8 +236,8 @@ _Pre_satisfies_( !ThisCItem->m_attr.m_done ) std::pair( aFile.name.length( ) ); @@ -246,13 +252,17 @@ _Pre_satisfies_( !ThisCItem->m_attr.m_done ) std::pairm_name_pool.reset( total_size_alloc ); + + ASSERT( ThisCItem->m_name_pool.m_buffer_filled == 0 ); + //ASSERT( path.back( ) != _T( '\\' ) ); //sizesToWorkOn_ CANNOT BE CONST!! auto sizesToWorkOn_ = addFiles_returnSizesToWorkOn( ThisCItem, vecFiles, path ); @@ -267,7 +277,9 @@ _Pre_satisfies_( !ThisCItem->m_attr.m_done ) std::pairm_name_pool.copy_name_str_into_buffer( new_name_ptr, ( new_name_length + 1u ), dir.name ); + if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy (directory) name str! (readJobNotDoneWork)(aborting!)" ); displayWindowsMsgBoxWithMessage( dir.name.c_str( ) ); @@ -292,6 +304,7 @@ _Pre_satisfies_( !ThisCItem->m_attr.m_done ) std::pairm_name_pool.m_buffer_filled == ( total_size_alloc - 1 ) ); ASSERT( ( fileCount + dirCount ) == ThisCItem->m_childCount ); //ThisCItem->m_children_vector.shrink_to_fit( ); return std::make_pair( std::move( dirsToWorkOn ), std::move( sizesToWorkOn_ ) ); diff --git a/WinDirStat/windirstat/dirstatdoc.cpp b/WinDirStat/windirstat/dirstatdoc.cpp index 1cd8514..8b217e9 100644 --- a/WinDirStat/windirstat/dirstatdoc.cpp +++ b/WinDirStat/windirstat/dirstatdoc.cpp @@ -321,14 +321,21 @@ void CDirstatDoc::buildDriveItems( _In_ const std::vector& rootFol FILETIME t; //zeroDate( t ); memset_zero_struct( t ); - const auto new_name_length = rootFolders.at( 0 ).length( ); + const auto new_name_length = rootFolders.at( 0u ).length( ); ASSERT( new_name_length < UINT16_MAX ); + m_rootItem.reset( ); + + //TODO: BUGBUG: for some reason, we need +2u here! ASSERT fails if we don't! + m_name_pool.reset( ( new_name_length + 2u ) ); + PWSTR new_name_ptr = nullptr; - const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, rootFolders.at( 0 ) ); + //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, rootFolders.at( 0 ) ); + const HRESULT copy_res = m_name_pool.copy_name_str_into_buffer( new_name_ptr, ( new_name_length + 1u ), rootFolders.at( 0u ) ); + if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy name str! (CDirstatDoc::buildDriveItems)(aborting!)" ); - displayWindowsMsgBoxWithMessage( rootFolders.at( 0 ) ); + displayWindowsMsgBoxWithMessage( rootFolders.at( 0u ) ); } // IT_DIRECTORY diff --git a/WinDirStat/windirstat/dirstatdoc.h b/WinDirStat/windirstat/dirstatdoc.h index a1e484e..c4645c5 100644 --- a/WinDirStat/windirstat/dirstatdoc.h +++ b/WinDirStat/windirstat/dirstatdoc.h @@ -5,6 +5,7 @@ #pragma once #include "stdafx.h" +#include "globalhelpers.h" #ifndef WDS_DIRSTATDOC_H #define WDS_DIRSTATDOC_H @@ -88,7 +89,8 @@ class CDirstatDoc final : public CDocument { CItemBranch const* m_selectedItem; // Currently selected item, or NULL CItemBranch const* m_workingItem; // Current item we are working on. For progress indication //C4820: 'CDirstatDoc' : '6' bytes padding added after data member 'CDirstatDoc::m_iterations' (dirstatdoc.cpp) - + Children_String_Heap_Manager m_name_pool; + protected: std::vector m_extensionRecords; std::unordered_mapm_colorMap; diff --git a/WinDirStat/windirstat/globalhelpers.cpp b/WinDirStat/windirstat/globalhelpers.cpp index 4e0b812..782b6f9 100644 --- a/WinDirStat/windirstat/globalhelpers.cpp +++ b/WinDirStat/windirstat/globalhelpers.cpp @@ -459,11 +459,20 @@ namespace { } +void Children_String_Heap_Manager::reset( const rsize_t number_of_characters_needed ) { + m_buffer_filled = 0u; + m_string_buffer.reset( new wchar_t[ number_of_characters_needed ] ); + m_buffer_size = number_of_characters_needed; + } + +Children_String_Heap_Manager::Children_String_Heap_Manager( ) : m_buffer_size { 0u }, m_buffer_filled { 0u }, m_string_buffer { nullptr } { } + Children_String_Heap_Manager::Children_String_Heap_Manager( const rsize_t number_of_characters_needed ) : m_buffer_size( number_of_characters_needed ), m_buffer_filled( 0 ), m_string_buffer( new wchar_t[ number_of_characters_needed ] ) { } _Success_( SUCCEEDED( return ) ) const HRESULT Children_String_Heap_Manager::copy_name_str_into_buffer( _Pre_invalid_ _Post_z_ _Post_readable_size_( new_name_length ) wchar_t*& new_name_ptr, _In_ _In_range_( 0, UINT16_MAX ) const rsize_t& new_name_length, const std::wstring& name ) { ASSERT( new_name_length < UINT16_MAX ); + ASSERT( new_name_length == ( name.length( ) + 1 ) ); new_name_ptr = ( m_string_buffer.get( ) + m_buffer_filled ); ASSERT( ( m_buffer_filled + new_name_length ) < m_buffer_size ); m_buffer_filled += new_name_length; @@ -478,13 +487,15 @@ const HRESULT Children_String_Heap_Manager::copy_name_str_into_buffer( _Pre_inva ASSERT( SUCCEEDED( res ) ); if ( SUCCEEDED( res ) ) { #ifdef DEBUG - ASSERT( wcslen( new_name_ptr ) == new_name_length ); + ASSERT( wcslen( new_name_ptr ) == ( new_name_length - 1u ) ); ASSERT( wcscmp( new_name_ptr, name.c_str( ) ) == 0 ); const auto da_ptrdiff = ( std::ptrdiff_t( pszend ) - std::ptrdiff_t( new_name_ptr ) ); - ASSERT( ( da_ptrdiff / sizeof( wchar_t ) ) == new_name_length ); + ASSERT( ( da_ptrdiff / sizeof( wchar_t ) ) == ( new_name_length - 1u ) ); #endif return res; } + m_buffer_filled -= new_name_length; + new_name_ptr = ( m_string_buffer.get( ) + m_buffer_filled ); displayWindowsMsgBoxWithMessage( L"Copy of name_str into Children_String_Heap_Manager failed!!!" ); std::terminate( ); return res; diff --git a/WinDirStat/windirstat/globalhelpers.h b/WinDirStat/windirstat/globalhelpers.h index 4cb72da..6677668 100644 --- a/WinDirStat/windirstat/globalhelpers.h +++ b/WinDirStat/windirstat/globalhelpers.h @@ -39,15 +39,18 @@ inline type_struct_to_init zero_init_struct( ) { struct Children_String_Heap_Manager { //TODO: I'm not using these yet, but if I define them inline, the compiler bitches that they're not used. + Children_String_Heap_Manager( ); Children_String_Heap_Manager( const rsize_t number_of_characters_needed ); Children_String_Heap_Manager& operator=( const Children_String_Heap_Manager& in ) = delete; Children_String_Heap_Manager( const Children_String_Heap_Manager& in ) = delete; + void reset( const rsize_t number_of_characters_needed ); + _Success_( SUCCEEDED( return ) ) const HRESULT copy_name_str_into_buffer( _Pre_invalid_ _Post_z_ _Post_readable_size_( new_name_length ) wchar_t*& new_name_ptr, _In_ _In_range_( 0, UINT16_MAX ) const rsize_t& new_name_length, const std::wstring& name ); _Field_size_part_( m_buffer_size, m_buffer_filled ) std::unique_ptr m_string_buffer; - const size_t m_buffer_size; + size_t m_buffer_size; size_t m_buffer_filled; }; diff --git a/WinDirStat/windirstat/item.cpp b/WinDirStat/windirstat/item.cpp index e04683e..7d2c988 100644 --- a/WinDirStat/windirstat/item.cpp +++ b/WinDirStat/windirstat/item.cpp @@ -250,7 +250,7 @@ INT CItemBranch::CompareSibling( _In_ const CTreeListItem* const tlib, _In_ _In_ auto const other = static_cast< const CItemBranch* >( tlib ); switch ( subitem ) { case column::COL_NAME: - return signum( wcscmp( m_name.get( ), other->m_name.get( ) ) ); + return signum( wcscmp( m_name, other->m_name ) ); case column::COL_PERCENTAGE: return signum( GetFraction( ) - other->GetFraction( ) ); case column::COL_SUBTREETOTAL: @@ -340,8 +340,8 @@ std::wstring CItemBranch::GetPath( ) const { std::wstring pathBuf; pathBuf.reserve( MAX_PATH ); UpwardGetPathWithoutBackslash( pathBuf ); - ASSERT( wcslen( m_name.get( ) ) == m_name_length ); - ASSERT( wcslen( m_name.get( ) ) < 33000 ); + ASSERT( wcslen( m_name ) == m_name_length ); + ASSERT( wcslen( m_name ) < 33000 ); ASSERT( pathBuf.length( ) < 33000 ); return pathBuf; } @@ -351,8 +351,8 @@ void CItemBranch::UpwardGetPathWithoutBackslash( std::wstring& pathBuf ) const { if ( myParent != NULL ) { myParent->UpwardGetPathWithoutBackslash( pathBuf ); } - ASSERT( wcslen( m_name.get( ) ) == m_name_length ); - ASSERT( wcslen( m_name.get( ) ) < 33000 ); + ASSERT( wcslen( m_name ) == m_name_length ); + ASSERT( wcslen( m_name ) < 33000 ); if ( m_children == nullptr ) { //ASSERT( m_parent != NULL ); if ( m_parent != NULL ) { @@ -360,18 +360,18 @@ void CItemBranch::UpwardGetPathWithoutBackslash( std::wstring& pathBuf ) const { //TODO: BUGBUG: what is dis? if ( m_parent->m_parent != NULL ) { pathBuf += L'\\'; - ASSERT( wcslen( m_name.get( ) ) == m_name_length ); - pathBuf += m_name.get( ); + ASSERT( wcslen( m_name ) == m_name_length ); + pathBuf += m_name; return; } pathBuf += L'\\'; - ASSERT( wcslen( m_name.get( ) ) == m_name_length ); - pathBuf += m_name.get( ); + ASSERT( wcslen( m_name ) == m_name_length ); + pathBuf += m_name; return; } ASSERT( pathBuf.empty( ) ); - ASSERT( wcslen( m_name.get( ) ) == m_name_length ); - pathBuf = m_name.get( ); + ASSERT( wcslen( m_name ) == m_name_length ); + pathBuf = m_name; return; //ASSERT( false ); //return; @@ -379,13 +379,13 @@ void CItemBranch::UpwardGetPathWithoutBackslash( std::wstring& pathBuf ) const { if ( !pathBuf.empty( ) ) { if ( pathBuf.back( ) != L'\\' ) {//if pathBuf is empty, it's because we don't have a parent ( we're the root ), so we already have a "\\" pathBuf += L'\\'; - pathBuf += m_name.get( ); + pathBuf += m_name; return; } - pathBuf += m_name.get( ); + pathBuf += m_name; return; } - pathBuf += m_name.get( ); + pathBuf += m_name; return; } @@ -549,7 +549,7 @@ _Pre_satisfies_( this->m_children._Myptr == nullptr ) PCWSTR const CItemBranch::CStyle_GetExtensionStrPtr( ) const { ASSERT( m_name_length < ( MAX_PATH + 1 ) ); - PCWSTR const resultPtrStr = PathFindExtensionW( m_name.get( ) ); + PCWSTR const resultPtrStr = PathFindExtensionW( m_name ); ASSERT( resultPtrStr != '\0' ); return resultPtrStr; } @@ -560,7 +560,7 @@ _Success_( SUCCEEDED( return ) ) HRESULT CItemBranch::CStyle_GetExtension( WDS_WRITES_TO_STACK( strSize, chars_written ) PWSTR psz_extension, const rsize_t strSize, _Out_ rsize_t& chars_written ) const { psz_extension[ 0 ] = 0; - PWSTR resultPtrStr = PathFindExtensionW( m_name.get( ) ); + PWSTR resultPtrStr = PathFindExtensionW( m_name ); ASSERT( resultPtrStr != '\0' ); if ( resultPtrStr != '\0' ) { size_t extLen = 0; @@ -599,12 +599,12 @@ _Pre_satisfies_( this->m_children._Myptr == nullptr ) const std::wstring CItemBranch::GetExtension( ) const { //if ( m_type == IT_FILE ) { if ( m_children == nullptr ) { - PWSTR const resultPtrStr = PathFindExtensionW( m_name.get( ) ); + PWSTR const resultPtrStr = PathFindExtensionW( m_name ); ASSERT( resultPtrStr != 0 ); if ( resultPtrStr != '\0' ) { return resultPtrStr; } - PCWSTR const i = wcsrchr( m_name.get( ), L'.' ); + PCWSTR const i = wcsrchr( m_name, L'.' ); if ( i == NULL ) { return _T( "." ); diff --git a/WinDirStat/windirstat/minimal_CWnd_equivalent.h b/WinDirStat/windirstat/minimal_CWnd_equivalent.h new file mode 100644 index 0000000..864afe1 --- /dev/null +++ b/WinDirStat/windirstat/minimal_CWnd_equivalent.h @@ -0,0 +1,11 @@ +//I'm fed up with all the bloat in MFC's CWnd, so maybe I'll just write my own goddamn version! +//use "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\include\atlwin.h":776 (ATL::CWindow) as an inspiration. +#include "stdafx.h" + +struct WDS_cmdtarget { + + }; + +struct WDS_wnd { + + }; \ No newline at end of file diff --git a/WinDirStat/windirstat/ownerdrawnlistcontrol.h b/WinDirStat/windirstat/ownerdrawnlistcontrol.h index 6761eed..2a29af3 100644 --- a/WinDirStat/windirstat/ownerdrawnlistcontrol.h +++ b/WinDirStat/windirstat/ownerdrawnlistcontrol.h @@ -63,7 +63,9 @@ class COwnerDrawnListItem { COwnerDrawnListItem( const COwnerDrawnListItem& in ) = delete; COwnerDrawnListItem& operator=( const COwnerDrawnListItem& in ) = delete; COwnerDrawnListItem( ) = default; - virtual ~COwnerDrawnListItem( ) = default; + virtual ~COwnerDrawnListItem( ) { + m_name = nullptr; + } INT compare_interface ( _In_ const COwnerDrawnListItem* const other, RANGE_ENUM_COL const column::ENUM_COL subitem ) const { return Compare( other, subitem ); @@ -71,7 +73,7 @@ class COwnerDrawnListItem { INT CompareS ( _In_ const COwnerDrawnListItem* const other, _In_ const SSorting& sorting ) const { if ( sorting.column1 == column::COL_NAME ) { - const auto sort_result = signum( wcscmp( m_name.get( ), other->m_name.get( ) ) ); + const auto sort_result = signum( wcscmp( m_name, other->m_name ) ); if ( sort_result != 0 ) { return sort_result; @@ -164,11 +166,8 @@ class COwnerDrawnListItem { return res; } - - - INT default_compare ( _In_ const COwnerDrawnListItem* const baseOther ) const { - return signum( wcscmp( m_name.get( ), baseOther->m_name.get( ) ) ); + return signum( wcscmp( m_name, baseOther->m_name ) ); } //defined at bottom of THIS file. @@ -189,9 +188,10 @@ class COwnerDrawnListItem { public: - _Field_z_ _Field_size_( m_name_length ) std::unique_ptr<_Null_terminated_ const wchar_t[]> m_name; + //_Field_z_ _Field_size_( m_name_length ) std::unique_ptr<_Null_terminated_ const wchar_t[]> m_name; + _Field_z_ _Field_size_( m_name_length ) PCWSTR m_name; //C4820: 'COwnerDrawnListItem' : '6' bytes padding added after data member 'COwnerDrawnListItem::m_name_length' - std::uint16_t m_name_length; + std::uint16_t m_name_length; }; namespace { @@ -704,7 +704,7 @@ class COwnerDrawnListCtrl : public CListCtrl { return; } const auto w = GetSubItemWidth( item, col ); - ASSERT( w == ( GetStringWidth( item->m_name.get( ) ) + 10 ) ); + ASSERT( w == ( GetStringWidth( item->m_name ) + 10 ) ); if ( w > width ) { width = w; } @@ -910,7 +910,7 @@ class COwnerDrawnListCtrl : public CListCtrl { if ( subitem == column::COL_NAME ) { //fastpath. No work to be done! - dcmem.DrawTextW( item->m_name.get( ), static_cast< int >( item->m_name_length ), &rcText, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_NOPREFIX | DT_NOCLIP | static_cast< UINT >( align ) ); + dcmem.DrawTextW( item->m_name, static_cast< int >( item->m_name_length ), &rcText, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_NOPREFIX | DT_NOCLIP | static_cast< UINT >( align ) ); return; } @@ -1062,16 +1062,16 @@ class COwnerDrawnListCtrl : public CListCtrl { INT GetWidthFastPath( _In_ const COwnerDrawnListItem* const item, _In_ _In_range_( 0, INT_MAX ) const column::ENUM_COL subitem, _In_ CHeaderCtrl* const thisHeaderCtrl, _In_ RECT& rc, _In_ CClientDC& dc ) const { //column::COL_NAME requires very little work! if ( item->m_name_length == 0 ) { - ASSERT( 0 == GetStringWidth( item->m_name.get( ) ) ); + ASSERT( 0 == GetStringWidth( item->m_name ) ); return 0; } CSelectObject sofont( dc, *( GetFont( ) ) ); const auto align = IsColumnRightAligned( subitem, thisHeaderCtrl ) ? DT_RIGHT : DT_LEFT; - dc.DrawTextW( item->m_name.get( ), static_cast( item->m_name_length ), &rc, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT | DT_NOPREFIX | DT_NOCLIP | static_cast( align ) ); + dc.DrawTextW( item->m_name, static_cast( item->m_name_length ), &rc, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT | DT_NOPREFIX | DT_NOCLIP | static_cast( align ) ); VERIFY( ::InflateRect( &rc, TEXT_X_MARGIN, 0 ) ); //rc.InflateRect( TEXT_X_MARGIN, 0 ); - ASSERT( ( rc.right - rc.left ) == GetStringWidth( item->m_name.get( ) ) ); + ASSERT( ( rc.right - rc.left ) == GetStringWidth( item->m_name ) ); return ( rc.right - rc.left ); } @@ -1503,11 +1503,11 @@ class COwnerDrawnListCtrl : public CListCtrl { if ( ( di->item.mask bitand LVIF_TEXT ) != 0 ) { if ( static_cast< column::ENUM_COL >( di->item.iSubItem ) == column::COL_NAME ) { //easy fastpath! - if ( item->m_name.get( ) == nullptr ) { + if ( item->m_name == nullptr ) { return; } size_t chars_remaining = 0; - const HRESULT res = StringCchCopyExW( di->item.pszText, static_cast< rsize_t >( di->item.cchTextMax ), item->m_name.get( ), NULL, &chars_remaining, 0 ); + const HRESULT res = StringCchCopyExW( di->item.pszText, static_cast< rsize_t >( di->item.cchTextMax ), item->m_name, NULL, &chars_remaining, 0 ); ASSERT( SUCCEEDED( res ) ); if ( !SUCCEEDED( res ) ) { displayWindowsMsgBoxWithMessage( global_strings::COwnerDrawnListCtrl_handle_LvnGetdispinfo_err ); @@ -1589,7 +1589,7 @@ inline void COwnerDrawnListItem::DrawLabel( _In_ const COwnerDrawnListCtrl* cons VERIFY( ::InflateRect( &rcRest, -( TEXT_X_MARGIN ), -( 0 ) ) ); RECT rcLabel = rcRest; - pdc.DrawTextW( m_name.get( ), static_cast( m_name_length ), &rcLabel, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX | DT_NOCLIP );//DT_CALCRECT modifies rcLabel!!! + pdc.DrawTextW( m_name, static_cast( m_name_length ), &rcLabel, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX | DT_NOCLIP );//DT_CALCRECT modifies rcLabel!!! AdjustLabelForMargin( rcRest, rcLabel ); @@ -1610,7 +1610,7 @@ inline void COwnerDrawnListItem::DrawLabel( _In_ const COwnerDrawnListCtrl* cons CSetTextColor stc( pdc, textColor ); if ( width == NULL ) { - pdc.DrawTextW( m_name.get( ), static_cast( m_name_length ), &rcRest, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_NOPREFIX | DT_NOCLIP ); + pdc.DrawTextW( m_name, static_cast( m_name_length ), &rcRest, DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_NOPREFIX | DT_NOCLIP ); } //subtract one from left, add one to right diff --git a/WinDirStat/windirstat/typeview.cpp b/WinDirStat/windirstat/typeview.cpp index 11d5b2e..8b5de54 100644 --- a/WinDirStat/windirstat/typeview.cpp +++ b/WinDirStat/windirstat/typeview.cpp @@ -314,8 +314,14 @@ void CExtensionListControl::SetExtensionData( _In_ const std::vectorsize( ); m_exts_count = ext_data_size; - m_exts.reset( new CListItem[ ext_data_size ] ); + + std::uint64_t total_name_length = 1; + for ( size_t i = 0; i < ext_data_size; ++i ) { + total_name_length += ( extData->at( i ).ext.length( ) + 1 ); + } + + m_name_pool.reset( total_name_length ); //Not vectorized: 1304, loop includes assignments of different sizes for ( size_t i = 0; i < ext_data_size; ++i ) { @@ -323,7 +329,9 @@ void CExtensionListControl::SetExtensionData( _In_ const std::vectorat( i ).ext ); + //const HRESULT copy_res = allocate_and_copy_name_str( new_name_ptr, new_name_length, extData->at( i ).ext ); + const HRESULT copy_res = m_name_pool.copy_name_str_into_buffer( new_name_ptr, ( new_name_length + 1u ), extData->at( i ).ext ); + if ( !SUCCEEDED( copy_res ) ) { displayWindowsMsgBoxWithMessage( L"Failed to allocate & copy name str! (CExtensionListControl::SetExtensionData)(aborting!)" ); displayWindowsMsgBoxWithMessage( extData->at( i ).ext.c_str( ) ); @@ -378,7 +386,7 @@ void CExtensionListControl::SelectExtension( _In_ const std::wstring ext ) { const auto countItems = this->GetItemCount( ); SetRedraw( FALSE ); for ( INT i = 0; i < countItems; i++ ) { - if ( ( wcscmp( GetListItem( i )->m_name.get( ), ext.c_str( ) ) == 0 ) && ( i >= 0 ) ) { + if ( ( wcscmp( GetListItem( i )->m_name, ext.c_str( ) ) == 0 ) && ( i >= 0 ) ) { TRACE( _T( "Selecting extension %s (item #%i)...\r\n" ), ext.c_str( ), i ); SetItemState( i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );//Unreachable code? EnsureVisible( i, false ); @@ -396,7 +404,7 @@ const std::wstring CExtensionListControl::GetSelectedExtension( ) const { } const auto i = GetNextSelectedItem( pos );//SIX CYCLES PER INSTRUCTION!!!! const auto item = GetListItem( i ); - return std::wstring( item->m_name.get( ) ); + return std::wstring( item->m_name ); } void CExtensionListControl::OnLvnDeleteitem( NMHDR *pNMHDR, LRESULT *pResult ) { diff --git a/WinDirStat/windirstat/typeview.h b/WinDirStat/windirstat/typeview.h index f1440e1..b4552e8 100644 --- a/WinDirStat/windirstat/typeview.h +++ b/WinDirStat/windirstat/typeview.h @@ -114,6 +114,7 @@ class CExtensionListControl final : public COwnerDrawnListCtrl { size_t m_exts_count; _Field_size_( m_exts_count ) std::unique_ptr m_exts; CTypeView* m_typeView; + Children_String_Heap_Manager m_name_pool; _Ret_notnull_ CListItem* GetListItem( _In_ const INT i ) const; diff --git a/WinDirStat/windirstat/windirstat.vcxproj b/WinDirStat/windirstat/windirstat.vcxproj index 68bb4f9..c0d223a 100644 --- a/WinDirStat/windirstat/windirstat.vcxproj +++ b/WinDirStat/windirstat/windirstat.vcxproj @@ -213,7 +213,7 @@ true false true - OnlyExplicitInline + Disabled Kernel32.lib;Psapi.lib;%(AdditionalDependencies) @@ -265,7 +265,7 @@ false Send false - OnlyExplicitInline + Disabled Kernel32.lib;Psapi.lib;%(AdditionalDependencies) @@ -756,6 +756,7 @@ + diff --git a/WinDirStat/windirstat/windirstat.vcxproj.filters b/WinDirStat/windirstat/windirstat.vcxproj.filters index dcc4b4b..fabc5ab 100644 --- a/WinDirStat/windirstat/windirstat.vcxproj.filters +++ b/WinDirStat/windirstat/windirstat.vcxproj.filters @@ -152,6 +152,9 @@ Header Files + + Header Files +