diff --git a/WinDirStat/README.md b/WinDirStat/README.md index 32a2884..b98533a 100644 --- a/WinDirStat/README.md +++ b/WinDirStat/README.md @@ -52,6 +52,21 @@ Major features: This is a Microsoft Visual Studio 2013 Project. +============================================================================= +# A few notes on style + +I have some (admittedly weird) style preferences, so I'll try to document them. + +1. I use [Ratliff-style indentation](http://en.wikipedia.org/wiki/Indent_style#Ratliff_style). + - I find it much easier to spot weird scope issues. + - I find it much easier to quickly skim code, all the while comprehending control-flow. +2. I never throw exceptions. +3. I never catch exceptions. +4. I compile with exceptions **disabled**. + - Don't get me wrong, exceptions are a great feature of C++, but (sadly) they currently add too much bloat to code. + - Exceptions theoretically can *improve* performance, but that's not the case just quite yet. + - When Visual Studio supports `noexcept`, I'll reconsider. +5. I *ALWAYS* use braces in an `if`/`else` statement. ============================================================================= How to create a resource dll. * **Don't**, this isn't a solved problem yet. diff --git a/WinDirStat/altWinDirStat.smproj b/WinDirStat/altWinDirStat.smproj index 4cf6e4a..a935a2c 100644 Binary files a/WinDirStat/altWinDirStat.smproj and b/WinDirStat/altWinDirStat.smproj differ diff --git a/WinDirStat/windirstat/PageGeneral.cpp b/WinDirStat/windirstat/PageGeneral.cpp index 4a1e340..2d34201 100644 --- a/WinDirStat/windirstat/PageGeneral.cpp +++ b/WinDirStat/windirstat/PageGeneral.cpp @@ -60,12 +60,13 @@ BOOL CPageGeneral::OnInitDialog( ) { void CPageGeneral::OnOK( ) { VERIFY( UpdateData( ) ); + ASSERT( m_appptr != NULL ); const auto Options = GetOptions( ); //Compare with TRUE to prevent int->bool coercion Options->m_followMountPoints = ( ( m_followMountPoints == TRUE ) ? true : false ); Options->m_followJunctionPoints = ( ( m_followJunctionPoints == TRUE ) ? true : false ); Options->m_showTimeSpent = ( ( m_showTimeSpent == TRUE ) ? true : false ); - Options->SetHumanFormat ( ( ( m_humanFormat == TRUE ) ? true : false ) ); + Options->SetHumanFormat ( ( ( m_humanFormat == TRUE ) ? true : false ), m_appptr ); Options->SetListGrid ( ( ( m_listGrid == TRUE ) ? true : false ) ); Options->SetListStripes ( ( ( m_listStripes == TRUE ) ? true : false ) ); Options->SetListFullRowSelection( ( ( m_listFullRowSelection == TRUE ) ? true : false ) ); diff --git a/WinDirStat/windirstat/PageGeneral.h b/WinDirStat/windirstat/PageGeneral.h index 111cdc1..1ab7150 100644 --- a/WinDirStat/windirstat/PageGeneral.h +++ b/WinDirStat/windirstat/PageGeneral.h @@ -5,14 +5,12 @@ #pragma once #include "stdafx.h" +#include "windirstat.h" #ifndef WDS_PAGEGENERAL_H #define WDS_PAGEGENERAL_H - - - class COptionsPropertySheet; class CPageGeneral; @@ -28,7 +26,7 @@ class CPageGeneral final : public CPropertyPage { CPageGeneral& operator=( const CPageGeneral& in ) = delete; CPageGeneral( const CPageGeneral& in ) = delete; - CPageGeneral( ) : CPropertyPage( CPageGeneral::IDD ), m_followMountPoints( FALSE ), m_followJunctionPoints( FALSE ), m_humanFormat( FALSE ), m_listGrid( FALSE ), m_listStripes( FALSE ), m_listFullRowSelection( FALSE ), m_showTimeSpent( FALSE ) { } + CPageGeneral( CDirstatApp* app ) : CPropertyPage( CPageGeneral::IDD ), m_followMountPoints( FALSE ), m_followJunctionPoints( FALSE ), m_humanFormat( FALSE ), m_listGrid( FALSE ), m_listStripes( FALSE ), m_listFullRowSelection( FALSE ), m_showTimeSpent( FALSE ), m_appptr( app ) { } protected: @@ -59,7 +57,7 @@ class CPageGeneral final : public CPropertyPage { CButton m_ctlFollowMountPoints; CButton m_ctlFollowJunctionPoints; - + CDirstatApp* m_appptr; DECLARE_MESSAGE_MAP() afx_msg void OnBnClickedAnyOption( ) { SetModified( ); diff --git a/WinDirStat/windirstat/PageTreemap.h b/WinDirStat/windirstat/PageTreemap.h index 48b8497..8c1441b 100644 --- a/WinDirStat/windirstat/PageTreemap.h +++ b/WinDirStat/windirstat/PageTreemap.h @@ -19,6 +19,8 @@ // //CTreemap::Options; +class CDirstatApp; + class CPageTreemap final : public CPropertyPage { DECLARE_DYNAMIC(CPageTreemap) enum { diff --git a/WinDirStat/windirstat/TreeListControl.cpp b/WinDirStat/windirstat/TreeListControl.cpp index 2323845..c13bddd 100644 --- a/WinDirStat/windirstat/TreeListControl.cpp +++ b/WinDirStat/windirstat/TreeListControl.cpp @@ -118,6 +118,24 @@ struct compare_CTreeListItems { const CTreeListControl* const ctrl; }; + + +const bool CTreeListItem::set_plusminus_and_title_rects( _In_ const RECT rcLabel, _In_ const RECT rc_const ) const { + const POINT rc_top_left = { rc_const.left, rc_const.top }; + const RECT _rcPlusMinus = { 0, 0, 0, 0 }; + //const CRect rcLabel_( rcLabel ); + RECT temp_rect = _rcPlusMinus; + VERIFY( ::OffsetRect( &temp_rect, -( rc_top_left.x ), -( rc_top_left.y ) ) ); + const RECT& new_plus_minus_rect = temp_rect; + + SetPlusMinusRect( new_plus_minus_rect ); + + RECT new_title_rect = rcLabel; + VERIFY( ::OffsetRect( &new_title_rect, -( rc_top_left.x ), -( rc_top_left.y ) ) ); + SetTitleRect( new_title_rect ); + return true; + } + //CRect rc is NOT const here so that other virtual functions may modify it? //DOES NOT draw self for NON-NAME columns! //DRAWS self for NAME column!//This is because we need to draw indentation & the little boxes @@ -153,10 +171,8 @@ bool CTreeListItem::DrawSubitem( RANGE_ENUM_COL const column::ENUM_COL subitem, } RECT rcNode = rc_const; - //tree_list_control->DrawNode( this, pdc, rcNode, rcPlusMinus );//pass subitem to drawNode? static_cast( list )->DrawNode( this, pdc, rcNode );//pass subitem to drawNode? - RECT rcLabel = rc_const; rcLabel.left = rcNode.right; DrawLabel( list, pdc, rcLabel, state, width, focusLeft, false ); @@ -164,20 +180,7 @@ bool CTreeListItem::DrawSubitem( RANGE_ENUM_COL const column::ENUM_COL subitem, *width = ( rcLabel.right - rcLabel.left ); return true; } - const POINT rc_top_left = { rc_const.left, rc_const.top }; - const RECT _rcPlusMinus = { 0, 0, 0, 0 }; - - //const CRect rcLabel_( rcLabel ); - RECT temp_rect = _rcPlusMinus; - VERIFY( ::OffsetRect( &temp_rect, -( rc_top_left.x ), -( rc_top_left.y ) ) ); - const RECT& new_plus_minus_rect = temp_rect; - - SetPlusMinusRect( new_plus_minus_rect ); - - RECT new_title_rect = rcLabel; - VERIFY( ::OffsetRect( &new_title_rect, -( rc_top_left.x ), -( rc_top_left.y ) ) ); - SetTitleRect( new_title_rect ); - return true; + return set_plusminus_and_title_rects( rcLabel, rc_const ); } void CTreeListItem::childNotNull( _In_ CItemBranch* const aTreeListChild, const size_t i ) { @@ -236,21 +239,17 @@ CItemBranch* CTreeListItem::children_ptr( ) const { _Success_( return != NULL ) _Must_inspect_result_ _Ret_maybenull_ CTreeListItem* CTreeListItem::GetSortedChild( _In_ const size_t i ) const { ASSERT( m_vi != nullptr ); + ASSERT( !( m_vi->cache_sortedChildren.empty( ) ) ); if ( m_vi != nullptr ) { if ( !( m_vi->cache_sortedChildren.empty( ) ) ) { return m_vi->cache_sortedChildren.at( i ); } + return NULL; } return NULL; } INT CTreeListItem::concrete_compare( _In_ const CTreeListItem* const other, RANGE_ENUM_COL const column::ENUM_COL subitem ) const { - if ( other == NULL ) { - ASSERT( false ); - displayWindowsMsgBoxWithMessage( L"CTreeListItem::concrete_compare passed a NULL `other`! This should never happen!" ); - std::terminate( ); - return 666; - } if ( other == this ) { return 0; } @@ -304,26 +303,18 @@ bool CTreeListItem::HasSiblings( ) const { } ASSERT( count >= 2u ); ASSERT( count > 0 ); - //const auto child_count = GetChildrenCount_( ); - if ( count > 0 ) { - //do we even need to find it? -#ifdef DEBUG - //this is OBSCENELY slow in debug builds. - //const auto i = m_parent->FindSortedChild( this, count ); - //ASSERT( i < count ); -#endif - return true;//return true if `i` is in valid range ( it was found ) - } - ASSERT( count == 0 ); - return false; + return true; + ////const auto child_count = GetChildrenCount_( ); + //if ( count > 0 ) { + // //do we even need to find it? + // return true;//return true if `i` is in valid range ( it was found ) + // } + //ASSERT( count == 0 ); + //return false; } void CTreeListItem::SetVisible( _In_ const bool next_state_visible ) const { if ( next_state_visible ) { - if ( m_vi != nullptr ) { - m_vi.reset( ); - } - ASSERT( m_vi == nullptr ); m_vi.reset( new VISIBLEINFO ); m_vi->isExpanded = false; if ( m_parent == NULL ) { @@ -334,15 +325,10 @@ void CTreeListItem::SetVisible( _In_ const bool next_state_visible ) const { m_vi->indent = m_parent->GetIndent( ) + 1; } m_vi->isExpanded = false; - - //m_vi->sizeCache = UINT64_ERROR; - //Eww. - //m_vi->sizeCache = static_cast< const CItemBranch* >( this )->size_recurse( ); - } - else { - ASSERT( m_vi != nullptr ); - m_vi.reset( ); + return; } + ASSERT( m_vi != nullptr ); + m_vi.reset( ); } @@ -389,18 +375,20 @@ void CTreeListControl::adjustColumnSize( _In_ const CTreeListItem* const item_at void CTreeListControl::expand_item_no_scroll_then_doWhateverJDoes( _In_ const CTreeListItem* const pathZero, _In_range_( 0, INT_MAX ) const int parent ) { //auto j = FindTreeItem( pathZero ); TRACE( _T( "doing whatever j does....\r\n" ) ); - auto j = FindListItem( pathZero ); - if ( j == -1 ) { + const auto item_index = FindListItem( pathZero ); + if ( item_index == -1 ) { ASSERT( parent >= 0 ); //ExpandItem( parent, false ); ExpandItemNoScroll( parent ); - j = FindListItem( pathZero );//TODO: j? + + //FindListItem is const, doesn't affect anything. + //j = FindListItem( pathZero );//TODO: j? } } void CTreeListControl::expand_item_then_scroll_to_it( _In_ const CTreeListItem* const pathZero, _In_range_( 0, INT_MAX ) const int index, _In_ const bool showWholePath ) { expand_item_no_scroll_then_doWhateverJDoes( pathZero, index ); - ASSERT( index >= -1 ); + ASSERT( index >= 0 ); const auto item_at_index = GetItem( index ); ASSERT( item_at_index != NULL ); if ( item_at_index != NULL ) { @@ -739,7 +727,6 @@ void CTreeListControl::PrepareDefaultMenu( _In_ const CItemBranch* const item, _ void CTreeListControl::OnSetFocus( _In_ CWnd* pOldWnd ) { CWnd::OnSetFocus( pOldWnd ); - ASSERT( GetMainFrame( ) == m_frameptr ); m_frameptr->SetLogicalFocus( LOGICAL_FOCUS::LF_DIRECTORYLIST ); } @@ -769,13 +756,14 @@ CTreeListItem* CTreeListControl::GetItem( _In_ _In_range_( 0, INT_MAX ) const in void CTreeListControl::SetRootItem( _In_opt_ const CTreeListItem* const root ) { VERIFY( DeleteAllItems( ) ); - if ( root != NULL ) { - SetRedraw( FALSE ); - InsertItem( root, 0 ); - //ExpandItem( static_cast( 0 ), true );//otherwise ambiguous call - is it a NULL pointer? - ExpandItemAndScroll( 0 );//otherwise ambiguous call - is it a NULL pointer? - SetRedraw( TRUE ); + if ( root == NULL ) { + return; } + SetRedraw( FALSE ); + InsertItem( root, 0 ); + //ExpandItem( static_cast( 0 ), true );//otherwise ambiguous call - is it a NULL pointer? + ExpandItemAndScroll( 0 );//otherwise ambiguous call - is it a NULL pointer? + SetRedraw( TRUE ); } void CTreeListControl::InsertItem( _In_ const CTreeListItem* const item, _In_ _In_range_( 0, INT32_MAX ) const INT_PTR i ) { @@ -802,39 +790,45 @@ int CTreeListControl::EnumNode( _In_ const CTreeListItem* const item ) const { return static_cast( ENUM_NODE::NODE_END ); } +RECT CTreeListControl::DrawNode_Indented( _In_ const CTreeListItem* const item, _In_ CDC& pdc, _Inout_ RECT& rc, _Inout_ RECT& rcRest ) const { + bool didBitBlt = false; + RECT rcPlusMinus; + rcRest.left += 3; + CDC dcmem; + VERIFY( dcmem.CreateCompatibleDC( &pdc ) ); + CSelectObject sonodes( dcmem, ( IsItemStripeColor( item ) ? m_bmNodes1 : m_bmNodes0 ) ); + auto ysrc = ( NODE_HEIGHT / 2 ) - ( m_rowHeight / 2 ); + DrawNodeNullWidth( item, pdc, rcRest, didBitBlt, dcmem, ysrc ); + rcRest.left += ( item->GetIndent( ) - 1 ) * INDENT_WIDTH; + const auto node = EnumNode( item ); + ASSERT_VALID( &dcmem ); + if ( !didBitBlt ) {//Else we'd double BitBlt? + VERIFY( pdc.BitBlt( static_cast( rcRest.left ), static_cast( rcRest.top ), static_cast( NODE_WIDTH ), static_cast( NODE_HEIGHT ), &dcmem, ( NODE_WIDTH * node ), static_cast( ysrc ), SRCCOPY ) ); + } + rcPlusMinus.left = rcRest.left + HOTNODE_X; + rcPlusMinus.right = rcPlusMinus.left + HOTNODE_CX; + rcPlusMinus.top = rcRest.top + ( rcRest.bottom - rcRest.top )/ 2 - HOTNODE_CY / 2 - 1; + rcPlusMinus.bottom = rcPlusMinus.top + HOTNODE_CY; + + rcRest.left += NODE_WIDTH; + //VERIFY( dcmem.DeleteDC( ) ); + rc.right = rcRest.left; + return rcPlusMinus; + } + RECT CTreeListControl::DrawNode( _In_ const CTreeListItem* const item, _In_ CDC& pdc, _Inout_ RECT& rc ) const { //ASSERT_VALID( pdc ); RECT rcRest = rc; - RECT rcPlusMinus; - bool didBitBlt = false; + rcRest.left += GENERAL_INDENT; if ( item->GetIndent( ) > 0 ) { - rcRest.left += 3; - CDC dcmem; - VERIFY( dcmem.CreateCompatibleDC( &pdc ) ); - CSelectObject sonodes( dcmem, ( IsItemStripeColor( item ) ? m_bmNodes1 : m_bmNodes0 ) ); - auto ysrc = ( NODE_HEIGHT / 2 ) - ( m_rowHeight / 2 ); - DrawNodeNullWidth( item, pdc, rcRest, didBitBlt, dcmem, ysrc ); - rcRest.left += ( item->GetIndent( ) - 1 ) * INDENT_WIDTH; - const auto node = EnumNode( item ); - ASSERT_VALID( &dcmem ); - if ( !didBitBlt ) {//Else we'd double BitBlt? - VERIFY( pdc.BitBlt( static_cast( rcRest.left ), static_cast( rcRest.top ), static_cast( NODE_WIDTH ), static_cast( NODE_HEIGHT ), &dcmem, ( NODE_WIDTH * node ), static_cast( ysrc ), SRCCOPY ) ); - } - rcPlusMinus.left = rcRest.left + HOTNODE_X; - rcPlusMinus.right = rcPlusMinus.left + HOTNODE_CX; - rcPlusMinus.top = rcRest.top + ( rcRest.bottom - rcRest.top )/ 2 - HOTNODE_CY / 2 - 1; - rcPlusMinus.bottom = rcPlusMinus.top + HOTNODE_CY; - - rcRest.left += NODE_WIDTH; - //VERIFY( dcmem.DeleteDC( ) ); - } - else { - rcPlusMinus.bottom = 0; - rcPlusMinus.left = 0; - rcPlusMinus.right = 0; - rcPlusMinus.top = 0; + return DrawNode_Indented( item, pdc, rc, rcRest ); } + RECT rcPlusMinus; + rcPlusMinus.bottom = 0; + rcPlusMinus.left = 0; + rcPlusMinus.right = 0; + rcPlusMinus.top = 0; rc.right = rcRest.left; return rcPlusMinus; } @@ -865,19 +859,21 @@ void CTreeListControl::OnLButtonDown( UINT nFlags, CPoint point ) { const auto item = GetItem( i ); m_lButtonDownItem = i; - if ( item != NULL ) { - const RECT plus_minus_rect = item->GetPlusMinusRect( ); - //if ( CRect( item->GetPlusMinusRect( ) ).PtInRect( pt ) ) { - if ( ::PtInRect( &plus_minus_rect, pt ) ) { - m_lButtonDownOnPlusMinusRect = true; - ToggleExpansion( i ); - } - else { - m_lButtonDownOnPlusMinusRect = false; - COwnerDrawnListCtrl::OnLButtonDown( nFlags, point ); - } - } + ASSERT( item != NULL ); + if ( item == NULL ) { + return; + } + + const RECT plus_minus_rect = item->GetPlusMinusRect( ); + //if ( CRect( item->GetPlusMinusRect( ) ).PtInRect( pt ) ) { + if ( ::PtInRect( &plus_minus_rect, pt ) ) { + m_lButtonDownOnPlusMinusRect = true; + ToggleExpansion( i ); + return; + } + m_lButtonDownOnPlusMinusRect = false; + COwnerDrawnListCtrl::OnLButtonDown( nFlags, point ); } void CTreeListControl::OnLButtonDblClk( UINT nFlags, CPoint point ) { @@ -898,34 +894,38 @@ void CTreeListControl::OnLButtonDblClk( UINT nFlags, CPoint point ) { void CTreeListControl::ToggleExpansion( _In_ _In_range_( 0, INT_MAX ) const INT i ) { const auto item_at_i = GetItem( i ); ASSERT( item_at_i != NULL ); - if ( item_at_i != NULL ) { - SetRedraw( FALSE ); - if ( item_at_i->IsExpanded( ) ) { - VERIFY( CollapseItem( i ) ); - return; - } - //ExpandItem( i, true ); - ExpandItemAndScroll( i ); + if ( item_at_i == NULL ) { + return; + } + SetRedraw( FALSE ); + if ( item_at_i->IsExpanded( ) ) { + VERIFY( CollapseItem( i ) ); SetRedraw( TRUE ); + return; } + //ExpandItem( i, true ); + ExpandItemAndScroll( i ); + SetRedraw( TRUE ); } int CTreeListControl::countItemsToDelete( _In_ const CTreeListItem* const item, bool& selectNode, _In_ _In_range_( 0, INT_MAX ) const int& i ) { int todelete = 0; const auto itemCount = GetItemCount( ); - for ( int k = i + 1; k < itemCount; k++ ) { + const auto count_to_start_at = ( i + 1 ); + for ( int k = count_to_start_at; k < itemCount; k++ ) { const auto child = GetItem( k ); + ASSERT( child != NULL ); if ( child != NULL ) { if ( child->GetIndent( ) <= item->GetIndent( ) ) { break; } } - ASSERT( child != NULL ); if ( GetItemState( k, LVIS_SELECTED ) == LVIS_SELECTED ) { selectNode = true; } todelete++; } + TRACE( _T( "Need to delete %i items from %s\r\n" ), todelete, item->m_name.get( ) ); return todelete; } @@ -940,32 +940,42 @@ _Success_( return == true ) bool CTreeListControl::CollapseItem( _In_ _In_range_ return false; } TRACE( _T( "Collapsing item %i: %s\r\n" ), i, item->m_name.get( ) ); - WTL::CWaitCursor wc; + //WTL::CWaitCursor wc; SetRedraw( FALSE ); bool selectNode = false; - auto todelete = countItemsToDelete( item, selectNode, i ); + const auto item_number_to_delete = ( i + 1 ); + const auto todelete = countItemsToDelete( item, selectNode, i ); for ( INT m = 0; m < todelete; m++ ) { + #ifdef DEBUG - const auto local_var = GetItem( i + 1 ); + const auto local_var = GetItem( item_number_to_delete ); + ASSERT( local_var != NULL ); if ( local_var != NULL ) { - TRACE( _T( "deleting item %i (%i/%i), %s\r\n" ), ( i + 1 ), m, todelete, local_var->m_name.get( ) ); + 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( ) ); } else { - TRACE( _T( "deleting item %i (%i/%i), %s\r\n" ), ( i + 1 ), m, todelete, L"ERROR: NULL POINTER!" ); + TRACE( _T( "deleting item %i (%i/%i), %s\r\n" ), ( item_number_to_delete ), m, todelete, L"ERROR: NULL POINTER!" ); } #endif - DeleteItem( i + 1 ); + ASSERT( local_var->GetIndent( ) > item->GetIndent( ) ); + DeleteItem( item_number_to_delete ); + + } item->SetExpanded( false ); if ( selectNode ) { - SelectItem( i ); } SetRedraw( TRUE ); - VERIFY( RedrawItems( i, i ) ); + const auto item_count = GetItemCount( ); + TRACE( _T( "Redrawing items %i to %i....\r\n" ), i, item_count ); + VERIFY( RedrawItems( i, item_count ) ); + //VERIFY( RedrawItems( i, item_count + 1 ) ); TRACE( _T( "Collapsing item succeeded!\r\n" ) ); + GetDocument( )->UpdateAllViews( NULL, UpdateAllViews_ENUM::HINT_NULL ); return true; } @@ -1006,8 +1016,6 @@ void CTreeListControl::insertItemsAdjustWidths( _In_ const CTreeListItem* const InsertItem( child, i + static_cast( 1 ) + static_cast( c ) ); if ( scroll ) { const auto w = GetSubItemWidth( child, column::COL_NAME ); - //const auto predicted_str_width = ( GetStringWidth( child->m_name.get( ) ) + 10 ); - //ASSERT( w == predicted_str_width ); if ( w > maxwidth ) { ASSERT( w >= 0 ); if ( w >= 0 ) { @@ -1102,6 +1110,17 @@ void CTreeListControl::ExpandItem( _In_ _In_range_( 0, INT_MAX ) const int i, _I void CTreeListControl::handle_VK_LEFT( _In_ const CTreeListItem* const item, _In_ _In_range_( 0, INT32_MAX ) const int i ) { if ( item->IsExpanded( ) ) { +#ifdef DEBUG + //const auto item_position = FindListItem( item ); + const auto child = GetItem( i + 1 ); + ASSERT( child != NULL ); + if ( child == NULL ) { + _CrtDbgBreak( ); + return; + } + ASSERT( child->m_parent == item ); + +#endif VERIFY( CollapseItem( i ) ); } else if ( item->m_parent != NULL ) { @@ -1125,41 +1144,58 @@ void CTreeListControl::handle_VK_RIGHT( _In_ const CTreeListItem* const item, _I } } +void CTreeListControl::handle_VK_TAB( const UINT nChar, const UINT nRepCnt, const UINT nFlags ) { + if ( m_frameptr->GetTypeView( ) != NULL ) { + TRACE( _T( "TAB pressed! Focusing on extension list!\r\n" ) ); + m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_EXTENSIONLIST ); + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + } + TRACE( _T( "TAB pressed! No extension list! Setting Null focus!\r\n" ) ); + m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_NONE ); + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + } + +void CTreeListControl::handle_VK_ESCAPE( const UINT nChar, const UINT nRepCnt, const UINT nFlags ) { + TRACE( _T( "ESCAPE pressed! Null focus!\r\n" ) ); + m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_NONE ); + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + } + +void CTreeListControl::handle_remaining_keys( const UINT nChar, const UINT nRepCnt, const UINT nFlags ) { + //docs for GetNextItem, nItem: "Index of the item to begin the searching with, or -1 to find the first item that matches the specified flags. The specified item itself is excluded from the search." + //docs for GetNextItem, return: "The index of the next item if successful, or -1 otherwise." + const auto i = GetNextItem( -1, LVNI_FOCUSED ); + if ( i == ( -1 ) ) { + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + } + const auto item = GetItem( i ); + ASSERT( item != NULL ); + if ( item == NULL ) { + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + } + if ( nChar == VK_LEFT ) { + return handle_VK_LEFT( item, i ); + } + if ( nChar == VK_RIGHT ) { + return handle_VK_RIGHT( item, i ); + } + + WDS_ASSERT_NEVER_REACHED( ); + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + } void CTreeListControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if ( nChar == VK_TAB ) { - ASSERT( GetMainFrame( ) == m_frameptr ); - if ( m_frameptr->GetTypeView( ) != NULL ) { - TRACE( _T( "TAB pressed! Focusing on extension list!\r\n" ) ); - m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_EXTENSIONLIST ); - } - else { - TRACE( _T( "TAB pressed! No extension list! Setting Null focus!\r\n" ) ); - m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_NONE ); - } + return handle_VK_TAB( nChar, nRepCnt, nFlags ); } - else if ( nChar == VK_ESCAPE ) { - ASSERT( GetMainFrame( ) == m_frameptr ); - TRACE( _T( "ESCAPE pressed! Null focus!\r\n" ) ); - m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_NONE ); + if ( nChar == VK_ESCAPE ) { + return handle_VK_ESCAPE( nChar, nRepCnt, nFlags ); } - const auto i = GetNextItem( -1, LVNI_FOCUSED ); - if ( i != -1 ) { - const auto item = GetItem( i ); - if ( item != NULL ) { - switch ( nChar ) { - case VK_LEFT: - handle_VK_LEFT( item, i ); - return; - - case VK_RIGHT: - handle_VK_RIGHT( item, i ); - return; - } - } - ASSERT( item != NULL ); + if ( ( nChar != VK_LEFT ) && ( nChar != VK_RIGHT ) ) { + return COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); } - COwnerDrawnListCtrl::OnKeyDown( nChar, nRepCnt, nFlags ); + + return handle_remaining_keys( nChar, nRepCnt, nFlags ); } _Pre_satisfies_( !isDone ) void CTreeListControl::OnChildAdded( _In_opt_ const CTreeListItem* const parent, _In_ CTreeListItem* const child, _In_ const bool isDone ) { @@ -1197,12 +1233,13 @@ void CTreeListControl::Sort( ) { //Not vectorized: 1200, loop contains data dependencies for ( int i = 0; i < countItems; i++ ) {//convert to ranged for? const auto Item = GetItem( i ); - if ( Item != NULL ) { - if ( Item->IsExpanded( ) ) { - Item->SortChildren( this ); - } - } ASSERT( Item != NULL ); + if ( Item == NULL ) { + continue; + } + if ( Item->IsExpanded( ) ) { + Item->SortChildren( this ); + } } COwnerDrawnListCtrl::SortItems( ); } diff --git a/WinDirStat/windirstat/TreeListControl.h b/WinDirStat/windirstat/TreeListControl.h index 547cb7d..80cbc54 100644 --- a/WinDirStat/windirstat/TreeListControl.h +++ b/WinDirStat/windirstat/TreeListControl.h @@ -56,7 +56,7 @@ class CTreeListItem : public COwnerDrawnListItem { virtual INT Compare ( _In_ const COwnerDrawnListItem* const other, RANGE_ENUM_COL const column::ENUM_COL subitem ) const override final; INT concrete_compare ( _In_ const CTreeListItem* const other, RANGE_ENUM_COL const column::ENUM_COL subitem ) const; - + const bool set_plusminus_and_title_rects( _In_ const RECT rcLabel, _In_ const RECT rc_const ) const; public: //default constructor DOES NOT initialize jack shit. @@ -208,15 +208,21 @@ class CTreeListControl final : public COwnerDrawnListCtrl { //void ExpandItem ( _In_ const CTreeListItem* const item ); void handle_VK_LEFT ( _In_ const CTreeListItem* const item, _In_ _In_range_( 0, INT32_MAX ) const int i ); + //void SetItemScrollPosition ( _In_ const CTreeListItem* const item, _In_ const INT top ); void DrawNodeNullWidth ( _In_ const CTreeListItem* const item, _In_ CDC& pdc, _In_ const RECT& rcRest, _Inout_ bool& didBitBlt, _In_ CDC& dcmem, _In_ const UINT ysrc ) const; + RECT DrawNode_Indented ( _In_ const CTreeListItem* const item, _In_ CDC& pdc, _Inout_ RECT& rc, _Inout_ RECT& rcRest ) const; + RECT DrawNode ( _In_ const CTreeListItem* const item, _In_ CDC& pdc, _Inout_ RECT& rc ) const; _Pre_satisfies_( ( parent + 1 ) < index ) _Ret_range_( -1, INT_MAX ) - int collapse_parent_plus_one_through_index ( _In_ const CTreeListItem* thisPath, const int index, _In_range_( 0, INT_MAX ) const int parent ); - + int collapse_parent_plus_one_through_index ( _In_ const CTreeListItem* thisPath, const int index, _In_range_( 0, INT_MAX ) const int parent ); + + void handle_VK_ESCAPE ( const UINT nChar, const UINT nRepCnt, const UINT nFlags ); + void handle_VK_TAB ( const UINT nChar, const UINT nRepCnt, const UINT nFlags ); + void handle_remaining_keys ( const UINT nChar, const UINT nRepCnt, const UINT nFlags ); private: void ExpandItemAndScroll( _In_ _In_range_( 0, INT_MAX ) const int i ) { ExpandItem( i, true ); diff --git a/WinDirStat/windirstat/datastructures.h b/WinDirStat/windirstat/datastructures.h index 545f6bc..1cf8505 100644 --- a/WinDirStat/windirstat/datastructures.h +++ b/WinDirStat/windirstat/datastructures.h @@ -8,11 +8,6 @@ #ifndef WDS_DATASTRUCTURES_H #define WDS_DATASTRUCTURES_H - - - - - class CSelectObject { public: CSelectObject( _In_ CDC& pdc, _In_ CGdiObject& pObject ) : m_pdc{ &pdc } { @@ -266,7 +261,15 @@ static const Treemap_Options _defaultOptions = { Treemap_STYLE::KDirStatStyle, f struct FILEINFO { FILEINFO( ) { } - + FILEINFO( const FILEINFO& in ) = delete; + FILEINFO& operator=( const FILEINFO& in ) = delete; + FILEINFO& operator=( FILEINFO&& in ) { + length = std::move( in.length ); + lastWriteTime = std::move( in.lastWriteTime ); + attributes = std::move( in.attributes ); + name = std::move( in.name ); + return ( *this ); + } FILEINFO( FILEINFO&& in ) { length = std::move( in.length ); lastWriteTime = std::move( in.lastWriteTime ); @@ -326,12 +329,6 @@ enum RADIO : INT { RADIO_AFOLDER }; -namespace copied_from_VCPP_stdlib { - enum { // length of internal buffer, [1, 16] - SSO_THRESHOLD_BUF_SIZE = ( 16 / sizeof( wchar_t ) ) - }; - - } //Boilerplate D2D code: http://msdn.microsoft.com/en-us/library/windows/desktop/dd370994(v=vs.85).aspx template @@ -382,7 +379,7 @@ namespace UpdateAllViews_ENUM { HINT_EXTENSIONSELECTIONCHANGED, // Type list selected a new extension //HINT_ZOOMCHANGED, // Only zoom item has changed. HINT_REDRAWWINDOW, // Only graphically redraw views. - //HINT_SOMEWORKDONE, // Directory list shall process mouse messages first, then re-sort. + //HINT_SOMEWORKDONE, // Directory list shall process mouse messages first, then re-sort. HINT_LISTSTYLECHANGED, // Options: List style (grid/stripes) or treelist colors changed HINT_TREEMAPSTYLECHANGED, // Options: Treemap style (grid, colors etc.) changed }; diff --git a/WinDirStat/windirstat/directory_enumeration.cpp b/WinDirStat/windirstat/directory_enumeration.cpp index 9b9a3cc..705f5ed 100644 --- a/WinDirStat/windirstat/directory_enumeration.cpp +++ b/WinDirStat/windirstat/directory_enumeration.cpp @@ -15,10 +15,6 @@ namespace { ULARGE_INTEGER ret; ret.QuadPart = 0;//zero initializing this is critical! ret.LowPart = GetCompressedFileSizeW( path.c_str( ), &ret.HighPart ); - #ifdef PERF_DEBUG_SLEEP - Sleep( 0 ); - Sleep( 10 ); - #endif const auto last_err = GetLastError( ); #ifdef DEBUG const rsize_t error_message_buffer_size = 128; @@ -92,10 +88,6 @@ namespace { ASSERT( dirs_to_work_on[ i ].second.back( ) != L'\\' ); ASSERT( dirs_to_work_on[ i ].second.back( ) != L'*' ); //TODO: investigate task_group -#ifdef PERF_DEBUG_SLEEP - Sleep( 0 ); - Sleep( 10 ); -#endif //using std::launch::async ( instead of the default, std::launch::any ) causes WDS to hang! workers.emplace_back( std::async( DoSomeWork, std::move( dirs_to_work_on[ i ].first ), std::move( dirs_to_work_on[ i ].second ), app, sizes_to_work_on_in, std::move( false ) ) ); } @@ -193,11 +185,6 @@ std::vector> addFiles_returnSizesToWorkOn( //sizesToWorkOn_.emplace_back( std::move( newChild ), std::move( std::async( GetCompressedFileSize_filename, std::move( path + _T( '\\' ) + aFile.name ) ) ) ); sizesToWorkOn_.emplace_back( std::move( newChild ), std::move( path + _T( '\\' ) + aFile.name ) ); } - -#ifdef PERF_DEBUG_SLEEP - Sleep( 0 ); - Sleep( 10 ); -#endif } else { const auto new_name_length = aFile.name.length( ); @@ -347,10 +334,12 @@ DOUBLE DoSomeWorkShim( _In_ CItemBranch* const ThisCItem, std::wstring path, _In const auto debug_buf_res_1 = _snwprintf_s( debug_buf, debug_buf_size, _TRUNCATE, L"WDS: enum timing: %f\r\n", timing ); ASSERT( debug_buf_res_1 != -1 ); if ( debug_buf_res_1 == -1 ) { + //NOTE TO SELF, TODO: BUGBUG: OutputDebugString calls RtlUnicodeStringToAnsiString OutputDebugStringW( global_strings::output_dbg_string_error ); //std::terminate( ); } + //NOTE TO SELF, TODO: BUGBUG: OutputDebugString calls RtlUnicodeStringToAnsiString OutputDebugStringW( debug_buf ); @@ -367,10 +356,11 @@ DOUBLE DoSomeWorkShim( _In_ CItemBranch* const ThisCItem, std::wstring path, _In const auto debug_buf_res_2 = _snwprintf_s( debug_buf_2, debug_buf_size, _TRUNCATE, L"WDS: compressed file timing: %f\r\n", timing_2 ); ASSERT( debug_buf_res_2 != -1 ); if ( debug_buf_res_2 == -1 ) { + //NOTE TO SELF, TODO: BUGBUG: OutputDebugString calls RtlUnicodeStringToAnsiString OutputDebugStringW( global_strings::output_dbg_string_error ); //std::terminate( ); } - + //NOTE TO SELF, TODO: BUGBUG: OutputDebugString calls RtlUnicodeStringToAnsiString OutputDebugStringW( debug_buf_2 ); return timing_2; @@ -420,10 +410,6 @@ void DoSomeWork( _In_ CItemBranch* const ThisCItem, std::wstring path, _In_ cons } for ( auto& worker : workers ) { -#ifdef PERF_DEBUG_SLEEP - Sleep( 0 ); - Sleep( 10 ); -#endif worker.get( ); } diff --git a/WinDirStat/windirstat/dirstatdoc.cpp b/WinDirStat/windirstat/dirstatdoc.cpp index 17846e3..1cd8514 100644 --- a/WinDirStat/windirstat/dirstatdoc.cpp +++ b/WinDirStat/windirstat/dirstatdoc.cpp @@ -269,7 +269,7 @@ CDirstatDoc* GetDocument() { IMPLEMENT_DYNCREATE(CDirstatDoc, CDocument) _Pre_satisfies_( _theDocument == NULL ) _Post_satisfies_( _theDocument == this ) -CDirstatDoc::CDirstatDoc( ) : m_workingItem( NULL ), m_selectedItem( NULL ), m_extensionDataValid( false ), m_timeTextWritten( false ), m_showMyComputer( true ), m_searchTime( DBL_MAX ), m_iterations( 0 ), m_compressed_file_timing( -1 ), m_frameptr( GetMainFrame( ) ) { +CDirstatDoc::CDirstatDoc( ) : m_workingItem( NULL ), m_selectedItem( NULL ), m_extensionDataValid( false ), m_timeTextWritten( false ), m_showMyComputer( true ), m_searchTime( DBL_MAX ), m_iterations( 0 ), m_compressed_file_timing( -1 ), m_frameptr( GetMainFrame( ) ), m_appptr( GetApp( ) ) { ASSERT( _theDocument == NULL ); _theDocument = this; TRACE( _T( "_theDocument has been set to %p\r\n" ), _theDocument ); @@ -357,7 +357,7 @@ std::vector CDirstatDoc::buildRootFolders( _In_ const std::vector< BOOL CDirstatDoc::OnOpenDocument( _In_z_ PCWSTR const pszPathName ) { m_frameptr = GetMainFrame( ); ++m_iterations; - GetApp( )->m_mountPoints.Initialize( ); + m_appptr->m_mountPoints.Initialize( ); TRACE( _T( "Opening new document, path: %s\r\n" ), pszPathName ); VERIFY( CDocument::OnNewDocument( ) ); // --> DeleteContents() const std::wstring spec( pszPathName ); @@ -374,10 +374,6 @@ BOOL CDirstatDoc::OnOpenDocument( _In_z_ PCWSTR const pszPathName ) { const auto drives( DecodeSelection( pszPathName, folder ) ); check8Dot3NameCreationAndNotifyUser( ); -#ifdef PERF_DEBUG_SLEEP - displayWindowsMsgBoxWithMessage( _T( "PERF_DEBUG_SLEEP ENABLED! this is meant for debugging!" ) ); -#endif - const auto rootFolders_( buildRootFolders( drives, folder ) ); buildDriveItems( rootFolders_ ); @@ -385,7 +381,6 @@ BOOL CDirstatDoc::OnOpenDocument( _In_z_ PCWSTR const pszPathName ) { m_searchStartTime = help_QueryPerformanceCounter( ); m_workingItem = m_rootItem.get( ); - ASSERT( GetMainFrame( ) == m_frameptr ); m_frameptr->m_wndSplitter.SetSplitterPos( 1.0 ); m_frameptr->m_wndSubSplitter.SetSplitterPos( 1.0 ); @@ -433,7 +428,6 @@ void CDirstatDoc::ForgetItemTree( ) { void CDirstatDoc::SortTreeList( ) { ASSERT( m_rootItem != NULL ); - ASSERT( m_frameptr == GetMainFrame( ) ); const auto DirStatView = ( m_frameptr->GetDirstatView( ) ); if ( DirStatView != NULL ) { m_rootItem->SortChildren( &( DirStatView->m_treeListControl ) ); @@ -443,11 +437,8 @@ void CDirstatDoc::SortTreeList( ) { bool CDirstatDoc::OnWorkFinished( ) { TRACE( _T( "Finished walking tree...\r\n" ) ); -#ifdef PERF_DEBUG_SLEEP - Sleep( 1000 ); -#endif m_extensionDataValid = false; - ASSERT( m_frameptr == GetMainFrame( ) ); + m_frameptr->RestoreTypeView( ); const auto doneTime = help_QueryPerformanceCounter( ); @@ -461,7 +452,7 @@ bool CDirstatDoc::OnWorkFinished( ) { ASSERT( doneTime.QuadPart != 0 ); m_searchTime = -2;//Negative (that's not -1) informs WriteTimeToStatusBar that there was a problem. } - ASSERT( m_frameptr == GetMainFrame( ) ); + m_frameptr->RestoreGraphView( ); //Complete? SortTreeList(); @@ -488,7 +479,7 @@ bool CDirstatDoc::Work( ) { path = L"\\\\?\\" + path; TRACE( _T( "path fixed as: %s\r\n" ), path.c_str( ) ); } - const auto thisApp = GetApp( ); + const auto thisApp = m_appptr; m_compressed_file_timing = DoSomeWorkShim( m_rootItem.get( ), std::move( path ), thisApp, true ); ASSERT( m_rootItem->m_attr.m_done ); @@ -520,14 +511,12 @@ bool CDirstatDoc::IsRootDone( ) const { void CDirstatDoc::SetSelection( _In_ const CItemBranch& item ) { m_selectedItem = const_cast< CItemBranch* >( &item ); - ASSERT( m_frameptr == GetMainFrame( ) ); m_frameptr->SetSelectionMessageText( ); } void CDirstatDoc::SetHighlightExtension( _In_ const std::wstring ext ) { TRACE( _T( "Highlighting extension %s; previously highlighted: %s\r\n" ), ext.c_str( ), m_highlightExtension.c_str( ) ); m_highlightExtension = std::move( ext ); - ASSERT( m_frameptr == GetMainFrame( ) ); m_frameptr->SetSelectionMessageText( ); } @@ -656,7 +645,6 @@ void CDirstatDoc::OnEditCopy( ) { } itemPath.resize( itemPath.length( ) + MAX_PATH ); - ASSERT( m_frameptr == GetMainFrame( ) ); m_frameptr->CopyToClipboard( std::move( itemPath ) ); //itemPath.ReleaseBuffer( ); } diff --git a/WinDirStat/windirstat/dirstatdoc.h b/WinDirStat/windirstat/dirstatdoc.h index bbad3f2..a1e484e 100644 --- a/WinDirStat/windirstat/dirstatdoc.h +++ b/WinDirStat/windirstat/dirstatdoc.h @@ -12,7 +12,7 @@ class CItemBranch; class CMainFrame; - +class CDirstatApp; // The treemap colors as calculated in CDirstatDoc::SetExtensionColors() all have the "brightness" BASE_BRIGHTNESS. I define brightness as a number from 0 to 3.0: (r+g+b)/255. RGB(127, 255, 0), for example, has a brightness of 2.5. #define BASE_BRIGHTNESS 1.8 @@ -98,6 +98,7 @@ class CDirstatDoc final : public CDocument { DOUBLE m_compressed_file_timing; LARGE_INTEGER m_searchStartTime; CMainFrame* m_frameptr; + CDirstatApp* m_appptr; protected: DECLARE_MESSAGE_MAP() afx_msg void OnUpdateEditCopy( _In_ CCmdUI* pCmdUI ); diff --git a/WinDirStat/windirstat/dirstatview.cpp b/WinDirStat/windirstat/dirstatview.cpp index 833d74b..c97e321 100644 --- a/WinDirStat/windirstat/dirstatview.cpp +++ b/WinDirStat/windirstat/dirstatview.cpp @@ -10,24 +10,21 @@ #define WDS_DIRSTATVIEW_CPP //encourage inter-procedural optimization (and class-hierarchy analysis!) -#include "ownerdrawnlistcontrol.h" -#include "TreeListControl.h" -#include "item.h" -#include "typeview.h" - - -#include "options.h" +//#include "ownerdrawnlistcontrol.h" +//#include "TreeListControl.h" +//#include "item.h" +//#include "typeview.h" +// +// +//#include "options.h" #include "dirstatview.h" -#include "dirstatdoc.h" -#include "windirstat.h" -#include "mainframe.h" -#include "globalhelpers.h" +//#include "dirstatdoc.h" +//#include "windirstat.h" +//#include "mainframe.h" +//#include "globalhelpers.h" -namespace { - const UINT _nIdTreeListControl = 4711; - } //BEGIN_MESSAGE_MAP(CMyTreeListControl, CTreeListControl) //END_MESSAGE_MAP() @@ -49,172 +46,173 @@ BEGIN_MESSAGE_MAP(CDirstatView, CView) ON_COMMAND(ID_POPUP_TOGGLE, &( CDirstatView::OnPopupToggle ) ) END_MESSAGE_MAP() -void CDirstatView::OnSize( UINT nType, INT cx, INT cy ) { - CView::OnSize( nType, cx, cy ); - if ( IsWindow( m_treeListControl.m_hWnd ) ) { - CRect rc( 0, 0, cx, cy ); - m_treeListControl.MoveWindow( rc ); - } - } - -void CDirstatView::SetTreeListControlOptions( ) { - auto Options = GetOptions( ); - m_treeListControl.ShowGrid ( Options->m_listGrid ); - m_treeListControl.ShowStripes ( Options->m_listStripes ); - return m_treeListControl.ShowFullRowSelection( Options->m_listFullRowSelection ); - } - -INT CDirstatView::OnCreate( LPCREATESTRUCT lpCreateStruct ) { - if ( CView::OnCreate( lpCreateStruct ) == -1 ){ - return -1; - } - RECT rect = { 0, 0, 0, 0 }; - VERIFY( m_treeListControl.CreateEx( 0, WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, rect, this, _nIdTreeListControl ) ); - m_treeListControl.AddExtendedStyle( LVS_EX_HEADERDRAGDROP ); - SetTreeListControlOptions( ); - m_treeListControl.InsertColumn( column::COL_NAME, _T( "Name" ), LVCFMT_LEFT, 200, column::COL_NAME ); - m_treeListControl.InsertColumn( column::COL_PERCENTAGE, _T( "Percentage" ), LVCFMT_RIGHT, 55, column::COL_PERCENTAGE ); - m_treeListControl.InsertColumn( column::COL_SUBTREETOTAL, _T( "Size" ), LVCFMT_RIGHT, 90, column::COL_SUBTREETOTAL ); - m_treeListControl.InsertColumn( column::COL_ITEMS, _T( "Items" ), LVCFMT_RIGHT, 55, column::COL_ITEMS ); - m_treeListControl.InsertColumn( column::COL_FILES, _T( "Files" ), LVCFMT_RIGHT, 55, column::COL_FILES ); - //m_treeListControl.InsertColumn( column::COL_SUBDIRS, _T( "Subdirs" ), LVCFMT_RIGHT, 55, column::COL_SUBDIRS ); - m_treeListControl.InsertColumn( column::COL_LASTCHANGE, _T( "Last Change" ), LVCFMT_LEFT, 120, column::COL_LASTCHANGE ); - m_treeListControl.InsertColumn( column::COL_ATTRIBUTES, _T( "Attributes" ), LVCFMT_LEFT, 50, column::COL_ATTRIBUTES ); - - TRACE( _T( "Loading persistent attributes....\r\n" ) ); - m_treeListControl.OnColumnsInserted( ); - return 0; - } - -void CDirstatView::OnUpdatePopupToggle( _In_ CCmdUI* pCmdUI ) { - pCmdUI->Enable( m_treeListControl.SelectedItemCanToggle( ) ); - } - -void CDirstatView::OnPopupToggle( ) { - m_treeListControl.ToggleSelectedItem( ); - } - -void CDirstatView::OnSetFocus( CWnd* pOldWnd ) { - UNREFERENCED_PARAMETER( pOldWnd ); - m_treeListControl.SetFocus( ); - } - -void CDirstatView::OnDestroy( ) { - CView::OnDestroy(); - } - -CDirstatView::CDirstatView( ) : m_treeListControl( ITEM_ROW_HEIGHT, GetDocument( ) ) {// Created by MFC only - m_treeListControl.SetSorting( column::COL_SUBTREETOTAL, false ); - } - -void CDirstatView::SysColorChanged( ) { - m_treeListControl.SysColorChanged( ); - } - - -BOOL CDirstatView::OnEraseBkgnd( CDC* pDC ) { - TRACE( _T( "CDirstatView::OnEraseBkgnd!\r\n" ) ); - UNREFERENCED_PARAMETER( pDC ); - return TRUE; - } - - - -void CDirstatView::OnLvnItemchanged( NMHDR *pNMHDR, LRESULT *pResult ) { - const auto pNMLV = reinterpret_cast< LPNMLISTVIEW >( pNMHDR ); - //( pResult != NULL ) ? ( *pResult = 0 ) : ASSERT( false );//WTF - ASSERT( pResult != NULL ); - if ( pResult != NULL ) { - *pResult = 0; - } - if ( ( pNMLV->uChanged & LVIF_STATE ) == 0 ) { - return; - } - if ( pNMLV->iItem == -1 ) { - ASSERT( false ); // mal gucken //'watch times'? - return; - } - // This is not true (don't know why): ASSERT(m_treeListControl.GetItemState(pNMLV->iItem, LVIS_SELECTED) == pNMLV->uNewState); - const bool selected = ( ( m_treeListControl.GetItemState( pNMLV->iItem, LVIS_SELECTED ) & LVIS_SELECTED ) != 0 ); - const auto item = static_cast< CItemBranch * >( m_treeListControl.GetItem( pNMLV->iItem ) ); - ASSERT( item != NULL );//We got a NULL item??!? WTF - if ( item == NULL ) { - return; - } - if ( selected ) { - const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); - ASSERT( Document != NULL ); - if ( Document == NULL ) { - TRACE( _T( "I'm told that the selection has changed in a NULL document?!?? This can't be right.\r\n" ) ); - return; - } - Document->SetSelection( *item ); - ASSERT( Document == m_pDocument ); - return m_pDocument->UpdateAllViews( this, UpdateAllViews_ENUM::HINT_SELECTIONCHANGED ); - } - - } - -_Must_inspect_result_ CDirstatDoc* CDirstatView::GetDocument( ) { - return STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); - } - - -void CDirstatView::OnUpdateHINT_NEWROOT( ) { - const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); - ASSERT( Document != NULL );//The document is NULL??!? WTF - if ( Document == NULL ) { - return; - } - const auto newRootItem = Document->m_rootItem.get( ); - if ( newRootItem != NULL ) { - m_treeListControl.SetRootItem( newRootItem ); - VERIFY( m_treeListControl.RedrawItems( 0, m_treeListControl.GetItemCount( ) - 1 ) ); - return; - } - //m_treeListControl.SetRootItem( newRootItem ); - //VERIFY( m_treeListControl.RedrawItems( 0, m_treeListControl.GetItemCount( ) - 1 ) ); - } - -void CDirstatView::OnUpdateHINT_SELECTIONCHANGED( ) { - const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); - ASSERT( Document != NULL );//The document is NULL??!? WTF - if ( Document == NULL ) { - return; - } - TRACE( _T( "CDirstatView::OnUpdateHINT_SELECTIONCHANGED\r\n" ) ); - const auto Selection = Document->m_selectedItem; - ASSERT( Selection != NULL ); - if ( Selection == NULL ) { - TRACE( _T( "I was told that the selection changed, but found a NULL selection. I can neither select nor show NULL - What would that even mean??\r\n" ) ); - return; - } - m_treeListControl.SelectAndShowItem( Selection, false ); - } - -void CDirstatView::OnUpdateHINT_SHOWNEWSELECTION( ) { - const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); - ASSERT( Document != NULL );//The document is NULL??!? WTF - if ( Document == NULL ) { - return; - } - const auto Selection = Document->m_selectedItem; - ASSERT( Selection != NULL ); - if ( Selection == NULL ) { - TRACE( _T( "I was told that the selection changed, but found a NULL selection. I can neither select nor show NULL - What would that even mean??\r\n" ) ); - return; - } - TRACE( _T( "New item selected! item: %s\r\n" ), Selection->GetPath( ).c_str( ) ); - m_treeListControl.SelectAndShowItem( Selection, true ); - } - -void CDirstatView::OnUpdateHINT_LISTSTYLECHANGED( ) { - TRACE( _T( "List style has changed, redrawing!\r\n" ) ); - const auto Options = GetOptions( ); - m_treeListControl.ShowGrid( Options->m_listGrid ); - m_treeListControl.ShowStripes( Options->m_listStripes ); - m_treeListControl.ShowFullRowSelection( Options->m_listFullRowSelection ); - } +//void CDirstatView::OnSize( UINT nType, INT cx, INT cy ) { +// CView::OnSize( nType, cx, cy ); +// if ( IsWindow( m_treeListControl.m_hWnd ) ) { +// CRect rc( 0, 0, cx, cy ); +// m_treeListControl.MoveWindow( rc ); +// } +// } + +//void CDirstatView::SetTreeListControlOptions( ) { +// const auto Options = GetOptions( ); +// m_treeListControl.ShowGrid ( Options->m_listGrid ); +// m_treeListControl.ShowStripes ( Options->m_listStripes ); +// m_treeListControl.ShowFullRowSelection( Options->m_listFullRowSelection ); +// return; +// } + +//INT CDirstatView::OnCreate( LPCREATESTRUCT lpCreateStruct ) { +// if ( CView::OnCreate( lpCreateStruct ) == -1 ){ +// return -1; +// } +// RECT rect = { 0, 0, 0, 0 }; +// VERIFY( m_treeListControl.CreateEx( 0, WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, rect, this, _nIdTreeListControl ) ); +// m_treeListControl.AddExtendedStyle( LVS_EX_HEADERDRAGDROP ); +// SetTreeListControlOptions( ); +// m_treeListControl.InsertColumn( column::COL_NAME, _T( "Name" ), LVCFMT_LEFT, 200, column::COL_NAME ); +// m_treeListControl.InsertColumn( column::COL_PERCENTAGE, _T( "Percentage" ), LVCFMT_RIGHT, 55, column::COL_PERCENTAGE ); +// m_treeListControl.InsertColumn( column::COL_SUBTREETOTAL, _T( "Size" ), LVCFMT_RIGHT, 90, column::COL_SUBTREETOTAL ); +// m_treeListControl.InsertColumn( column::COL_ITEMS, _T( "Items" ), LVCFMT_RIGHT, 55, column::COL_ITEMS ); +// m_treeListControl.InsertColumn( column::COL_FILES, _T( "Files" ), LVCFMT_RIGHT, 55, column::COL_FILES ); +// //m_treeListControl.InsertColumn( column::COL_SUBDIRS, _T( "Subdirs" ), LVCFMT_RIGHT, 55, column::COL_SUBDIRS ); +// m_treeListControl.InsertColumn( column::COL_LASTCHANGE, _T( "Last Change" ), LVCFMT_LEFT, 120, column::COL_LASTCHANGE ); +// m_treeListControl.InsertColumn( column::COL_ATTRIBUTES, _T( "Attributes" ), LVCFMT_LEFT, 50, column::COL_ATTRIBUTES ); +// +// TRACE( _T( "Loading persistent attributes....\r\n" ) ); +// m_treeListControl.OnColumnsInserted( ); +// return 0; +// } + +//void CDirstatView::OnUpdatePopupToggle( _In_ CCmdUI* pCmdUI ) { +// pCmdUI->Enable( m_treeListControl.SelectedItemCanToggle( ) ); +// } + +//void CDirstatView::OnPopupToggle( ) { +// m_treeListControl.ToggleSelectedItem( ); +// } + +//void CDirstatView::OnSetFocus( CWnd* pOldWnd ) { +// UNREFERENCED_PARAMETER( pOldWnd ); +// m_treeListControl.SetFocus( ); +// } + +//void CDirstatView::OnDestroy( ) { +// CView::OnDestroy(); +// } + +//CDirstatView::CDirstatView( ) : m_treeListControl( ITEM_ROW_HEIGHT, GetDocument( ) ) {// Created by MFC only +// m_treeListControl.SetSorting( column::COL_SUBTREETOTAL, false ); +// } + +//void CDirstatView::SysColorChanged( ) { +// m_treeListControl.SysColorChanged( ); +// } + + +//BOOL CDirstatView::OnEraseBkgnd( CDC* pDC ) { +// TRACE( _T( "CDirstatView::OnEraseBkgnd!\r\n" ) ); +// UNREFERENCED_PARAMETER( pDC ); +// return TRUE; +// } + + + +//void CDirstatView::OnLvnItemchanged( NMHDR *pNMHDR, LRESULT *pResult ) { +// const auto pNMLV = reinterpret_cast< LPNMLISTVIEW >( pNMHDR ); +// //( pResult != NULL ) ? ( *pResult = 0 ) : ASSERT( false );//WTF +// ASSERT( pResult != NULL ); +// if ( pResult != NULL ) { +// *pResult = 0; +// } +// if ( ( pNMLV->uChanged & LVIF_STATE ) == 0 ) { +// return; +// } +// if ( pNMLV->iItem == -1 ) { +// ASSERT( false ); // mal gucken //'watch times'? +// return; +// } +// // This is not true (don't know why): ASSERT(m_treeListControl.GetItemState(pNMLV->iItem, LVIS_SELECTED) == pNMLV->uNewState); +// const bool selected = ( ( m_treeListControl.GetItemState( pNMLV->iItem, LVIS_SELECTED ) & LVIS_SELECTED ) != 0 ); +// const auto item = static_cast< CItemBranch * >( m_treeListControl.GetItem( pNMLV->iItem ) ); +// ASSERT( item != NULL );//We got a NULL item??!? WTF +// if ( item == NULL ) { +// return; +// } +// if ( selected ) { +// const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); +// ASSERT( Document != NULL ); +// if ( Document == NULL ) { +// TRACE( _T( "I'm told that the selection has changed in a NULL document?!?? This can't be right.\r\n" ) ); +// return; +// } +// Document->SetSelection( *item ); +// ASSERT( Document == m_pDocument ); +// return m_pDocument->UpdateAllViews( this, UpdateAllViews_ENUM::HINT_SELECTIONCHANGED ); +// } +// +// } + +//_Must_inspect_result_ CDirstatDoc* CDirstatView::GetDocument( ) { +// return STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); +// } + + +//void CDirstatView::OnUpdateHINT_NEWROOT( ) { +// const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); +// ASSERT( Document != NULL );//The document is NULL??!? WTF +// if ( Document == NULL ) { +// return; +// } +// const auto newRootItem = Document->m_rootItem.get( ); +// if ( newRootItem != NULL ) { +// m_treeListControl.SetRootItem( newRootItem ); +// VERIFY( m_treeListControl.RedrawItems( 0, m_treeListControl.GetItemCount( ) - 1 ) ); +// return; +// } +// //m_treeListControl.SetRootItem( newRootItem ); +// //VERIFY( m_treeListControl.RedrawItems( 0, m_treeListControl.GetItemCount( ) - 1 ) ); +// } + +//void CDirstatView::OnUpdateHINT_SELECTIONCHANGED( ) { +// const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); +// ASSERT( Document != NULL );//The document is NULL??!? WTF +// if ( Document == NULL ) { +// return; +// } +// TRACE( _T( "CDirstatView::OnUpdateHINT_SELECTIONCHANGED\r\n" ) ); +// const auto Selection = Document->m_selectedItem; +// ASSERT( Selection != NULL ); +// if ( Selection == NULL ) { +// TRACE( _T( "I was told that the selection changed, but found a NULL selection. I can neither select nor show NULL - What would that even mean??\r\n" ) ); +// return; +// } +// m_treeListControl.SelectAndShowItem( Selection, false ); +// } + +//void CDirstatView::OnUpdateHINT_SHOWNEWSELECTION( ) { +// const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); +// ASSERT( Document != NULL );//The document is NULL??!? WTF +// if ( Document == NULL ) { +// return; +// } +// const auto Selection = Document->m_selectedItem; +// ASSERT( Selection != NULL ); +// if ( Selection == NULL ) { +// TRACE( _T( "I was told that the selection changed, but found a NULL selection. I can neither select nor show NULL - What would that even mean??\r\n" ) ); +// return; +// } +// TRACE( _T( "New item selected! item: %s\r\n" ), Selection->GetPath( ).c_str( ) ); +// m_treeListControl.SelectAndShowItem( Selection, true ); +// } + +//void CDirstatView::OnUpdateHINT_LISTSTYLECHANGED( ) { +// TRACE( _T( "List style has changed, redrawing!\r\n" ) ); +// const auto Options = GetOptions( ); +// m_treeListControl.ShowGrid( Options->m_listGrid ); +// m_treeListControl.ShowStripes( Options->m_listStripes ); +// m_treeListControl.ShowFullRowSelection( Options->m_listFullRowSelection ); +// } //void CDirstatView::OnUpdateHINT_SOMEWORKDONE( ) { // MSG msg; @@ -228,37 +226,31 @@ void CDirstatView::OnUpdateHINT_LISTSTYLECHANGED( ) { // } // } -void CDirstatView::OnUpdate( CView *pSender, LPARAM lHint, CObject *pHint ) { - switch ( lHint ) - { - case UpdateAllViews_ENUM::HINT_NEWROOT: - return OnUpdateHINT_NEWROOT( ); - - case UpdateAllViews_ENUM::HINT_SELECTIONCHANGED: - return OnUpdateHINT_SELECTIONCHANGED( ); - - case UpdateAllViews_ENUM::HINT_SHOWNEWSELECTION: - return OnUpdateHINT_SHOWNEWSELECTION( ); - - case UpdateAllViews_ENUM::HINT_REDRAWWINDOW: - VERIFY( m_treeListControl.RedrawWindow( ) ); - break; - - case UpdateAllViews_ENUM::HINT_LISTSTYLECHANGED: - return OnUpdateHINT_LISTSTYLECHANGED( ); - - //case UpdateAllViews_ENUM::HINT_SOMEWORKDONE: - // OnUpdateHINT_SOMEWORKDONE( ); - - // fall thru - //case UpdateAllViews_ENUM::HINT_ZOOMCHANGED: - case 0: - return CView::OnUpdate( pSender, lHint, pHint ); - - default: - return; - } - } +//void CDirstatView::OnUpdate( CView *pSender, LPARAM lHint, CObject *pHint ) { +// switch ( lHint ) +// { +// case UpdateAllViews_ENUM::HINT_NEWROOT: +// return OnUpdateHINT_NEWROOT( ); +// +// case UpdateAllViews_ENUM::HINT_SELECTIONCHANGED: +// return OnUpdateHINT_SELECTIONCHANGED( ); +// +// case UpdateAllViews_ENUM::HINT_SHOWNEWSELECTION: +// return OnUpdateHINT_SHOWNEWSELECTION( ); +// +// case UpdateAllViews_ENUM::HINT_REDRAWWINDOW: +// VERIFY( m_treeListControl.RedrawWindow( ) ); +// break; +// +// case UpdateAllViews_ENUM::HINT_LISTSTYLECHANGED: +// return OnUpdateHINT_LISTSTYLECHANGED( ); +// case 0: +// return CView::OnUpdate( pSender, lHint, pHint ); +// +// default: +// return; +// } +// } #else diff --git a/WinDirStat/windirstat/dirstatview.h b/WinDirStat/windirstat/dirstatview.h index bebe26b..9ba0f15 100644 --- a/WinDirStat/windirstat/dirstatview.h +++ b/WinDirStat/windirstat/dirstatview.h @@ -12,17 +12,30 @@ - +//encourage inter-procedural optimization (and class-hierarchy analysis!) +#include "ownerdrawnlistcontrol.h" #include "TreeListControl.h" +#include "item.h" +#include "typeview.h" + +#include "dirstatdoc.h" class CDirstatView; class CDirstatDoc; class CItemBranch; +namespace { + const UINT _nIdTreeListControl = 4711; + } + + + // CDirstatView. The upper left view, which consists of the TreeList. class CDirstatView final : public CView { protected: - CDirstatView( ); + CDirstatView( ) : m_treeListControl( ITEM_ROW_HEIGHT, GetDocument( ) ) {// Created by MFC only + m_treeListControl.SetSorting( column::COL_SUBTREETOTAL, false ); + } CDirstatView( const CDirstatView& in ) = delete; DECLARE_DYNCREATE( CDirstatView ) @@ -32,7 +45,9 @@ class CDirstatView final : public CView { CDirstatView& operator=( const CDirstatView& in ) = delete; - void SysColorChanged( ); + void SysColorChanged( ) { + m_treeListControl.SysColorChanged( ); + } CTreeListControl m_treeListControl; // The tree list protected: @@ -58,28 +73,180 @@ class CDirstatView final : public CView { //(CDirstatDoc*)AfxDynamicDownCast(((CRuntimeClass*)(&CDirstatDoc::classCDirstatDoc)), m_pDocument) */ - _Must_inspect_result_ CDirstatDoc* GetDocument( ); + _Must_inspect_result_ CDirstatDoc* GetDocument( ) { + return STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); + } + + virtual void OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint ) override final { + switch ( lHint ) + { + case UpdateAllViews_ENUM::HINT_NEWROOT: + return OnUpdateHINT_NEWROOT( ); + + case UpdateAllViews_ENUM::HINT_SELECTIONCHANGED: + return OnUpdateHINT_SELECTIONCHANGED( ); + + case UpdateAllViews_ENUM::HINT_SHOWNEWSELECTION: + return OnUpdateHINT_SHOWNEWSELECTION( ); - virtual void OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint ) override final; + case UpdateAllViews_ENUM::HINT_REDRAWWINDOW: + VERIFY( m_treeListControl.RedrawWindow( ) ); + break; + + case UpdateAllViews_ENUM::HINT_LISTSTYLECHANGED: + return OnUpdateHINT_LISTSTYLECHANGED( ); + case 0: + return CView::OnUpdate( pSender, lHint, pHint ); + + default: + return; + } + } - void OnUpdateHINT_NEWROOT( ); - void OnUpdateHINT_SELECTIONCHANGED( ); - void OnUpdateHINT_SHOWNEWSELECTION( ); - void OnUpdateHINT_LISTSTYLECHANGED( ); + void OnUpdateHINT_NEWROOT( ) { + const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); + ASSERT( Document != NULL );//The document is NULL??!? WTF + if ( Document == NULL ) { + return; + } + const auto newRootItem = Document->m_rootItem.get( ); + if ( newRootItem != NULL ) { + m_treeListControl.SetRootItem( newRootItem ); + VERIFY( m_treeListControl.RedrawItems( 0, m_treeListControl.GetItemCount( ) - 1 ) ); + return; + } + //m_treeListControl.SetRootItem( newRootItem ); + //VERIFY( m_treeListControl.RedrawItems( 0, m_treeListControl.GetItemCount( ) - 1 ) ); + } + void OnUpdateHINT_SELECTIONCHANGED( ) { + const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); + ASSERT( Document != NULL );//The document is NULL??!? WTF + if ( Document == NULL ) { + return; + } + TRACE( _T( "CDirstatView::OnUpdateHINT_SELECTIONCHANGED\r\n" ) ); + const auto Selection = Document->m_selectedItem; + ASSERT( Selection != NULL ); + if ( Selection == NULL ) { + TRACE( _T( "I was told that the selection changed, but found a NULL selection. I can neither select nor show NULL - What would that even mean??\r\n" ) ); + return; + } + m_treeListControl.SelectAndShowItem( Selection, false ); + } + void OnUpdateHINT_SHOWNEWSELECTION( ) { + const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); + ASSERT( Document != NULL );//The document is NULL??!? WTF + if ( Document == NULL ) { + return; + } + const auto Selection = Document->m_selectedItem; + ASSERT( Selection != NULL ); + if ( Selection == NULL ) { + TRACE( _T( "I was told that the selection changed, but found a NULL selection. I can neither select nor show NULL - What would that even mean??\r\n" ) ); + return; + } + TRACE( _T( "New item selected! item: %s\r\n" ), Selection->GetPath( ).c_str( ) ); + m_treeListControl.SelectAndShowItem( Selection, true ); + } + void OnUpdateHINT_LISTSTYLECHANGED( ) { + TRACE( _T( "List style has changed, redrawing!\r\n" ) ); + const auto Options = GetOptions( ); + m_treeListControl.ShowGrid( Options->m_listGrid ); + m_treeListControl.ShowStripes( Options->m_listStripes ); + m_treeListControl.ShowFullRowSelection( Options->m_listFullRowSelection ); + } //void OnUpdateHINT_SOMEWORKDONE( ); - void SetTreeListControlOptions( ); + void SetTreeListControlOptions( ) { + const auto Options = GetOptions( ); + m_treeListControl.ShowGrid ( Options->m_listGrid ); + m_treeListControl.ShowStripes ( Options->m_listStripes ); + m_treeListControl.ShowFullRowSelection( Options->m_listFullRowSelection ); + return; + } protected: DECLARE_MESSAGE_MAP() - afx_msg void OnSize( UINT nType, INT cx, INT cy ); - afx_msg INT OnCreate( LPCREATESTRUCT lpCreateStruct ); - afx_msg BOOL OnEraseBkgnd( CDC* pDC ); - afx_msg void OnDestroy( ); - afx_msg void OnSetFocus( CWnd* pOldWnd ); - afx_msg void OnLvnItemchanged( NMHDR* pNMHDR, LRESULT* pResult ); - afx_msg void OnUpdatePopupToggle( _In_ CCmdUI* pCmdUI ); - afx_msg void OnPopupToggle( ); + afx_msg void OnSize( UINT nType, INT cx, INT cy ) { + CView::OnSize( nType, cx, cy ); + if ( IsWindow( m_treeListControl.m_hWnd ) ) { + const RECT rc = { 0, 0, cx, cy }; + //If [MoveWindow] succeeds, the return value is nonzero. + VERIFY( ::MoveWindow( m_treeListControl.m_hWnd, rc.left, rc.top, ( rc.right - rc.left ), ( rc.bottom - rc.top ), TRUE ) ); + } + } + afx_msg INT OnCreate( LPCREATESTRUCT lpCreateStruct ) { + if ( CView::OnCreate( lpCreateStruct ) == -1 ){ + return -1; + } + const RECT rect = { 0, 0, 0, 0 }; + VERIFY( m_treeListControl.CreateEx( 0, WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS, rect, this, _nIdTreeListControl ) ); + m_treeListControl.AddExtendedStyle( LVS_EX_HEADERDRAGDROP ); + SetTreeListControlOptions( ); + m_treeListControl.InsertColumn( column::COL_NAME, _T( "Name" ), LVCFMT_LEFT, 200, column::COL_NAME ); + m_treeListControl.InsertColumn( column::COL_PERCENTAGE, _T( "Percentage" ), LVCFMT_RIGHT, 55, column::COL_PERCENTAGE ); + m_treeListControl.InsertColumn( column::COL_SUBTREETOTAL, _T( "Size" ), LVCFMT_RIGHT, 90, column::COL_SUBTREETOTAL ); + m_treeListControl.InsertColumn( column::COL_ITEMS, _T( "Items" ), LVCFMT_RIGHT, 55, column::COL_ITEMS ); + m_treeListControl.InsertColumn( column::COL_FILES, _T( "Files" ), LVCFMT_RIGHT, 55, column::COL_FILES ); + //m_treeListControl.InsertColumn( column::COL_SUBDIRS, _T( "Subdirs" ), LVCFMT_RIGHT, 55, column::COL_SUBDIRS ); + m_treeListControl.InsertColumn( column::COL_LASTCHANGE, _T( "Last Change" ), LVCFMT_LEFT, 120, column::COL_LASTCHANGE ); + m_treeListControl.InsertColumn( column::COL_ATTRIBUTES, _T( "Attributes" ), LVCFMT_LEFT, 50, column::COL_ATTRIBUTES ); + + TRACE( _T( "Loading persistent attributes....\r\n" ) ); + m_treeListControl.OnColumnsInserted( ); + return 0; + } + afx_msg BOOL OnEraseBkgnd( CDC* pDC ) { + TRACE( _T( "CDirstatView::OnEraseBkgnd!\r\n" ) ); + UNREFERENCED_PARAMETER( pDC ); + return TRUE; + } + afx_msg void OnDestroy( ) { + CView::OnDestroy( ); + } + afx_msg void OnSetFocus( CWnd* pOldWnd ) { + UNREFERENCED_PARAMETER( pOldWnd ); + m_treeListControl.SetFocus( ); + } + afx_msg void OnLvnItemchanged( NMHDR* pNMHDR, LRESULT* pResult ) { + const auto pNMLV = reinterpret_cast< LPNMLISTVIEW >( pNMHDR ); + //( pResult != NULL ) ? ( *pResult = 0 ) : ASSERT( false );//WTF + ASSERT( pResult != NULL ); + if ( pResult != NULL ) { + *pResult = 0; + } + if ( ( pNMLV->uChanged & LVIF_STATE ) == 0 ) { + return; + } + if ( pNMLV->iItem == -1 ) { + ASSERT( false ); // mal gucken //'watch times'? + return; + } + // This is not true (don't know why): ASSERT(m_treeListControl.GetItemState(pNMLV->iItem, LVIS_SELECTED) == pNMLV->uNewState); + const bool selected = ( ( m_treeListControl.GetItemState( pNMLV->iItem, LVIS_SELECTED ) & LVIS_SELECTED ) != 0 ); + const auto item = static_cast< CItemBranch * >( m_treeListControl.GetItem( pNMLV->iItem ) ); + ASSERT( item != NULL );//We got a NULL item??!? WTF + if ( item == NULL ) { + return; + } + if ( selected ) { + const auto Document = STATIC_DOWNCAST( CDirstatDoc, m_pDocument ); + ASSERT( Document != NULL ); + if ( Document == NULL ) { + TRACE( _T( "I'm told that the selection has changed in a NULL document?!?? This can't be right.\r\n" ) ); + return; + } + Document->SetSelection( *item ); + ASSERT( Document == m_pDocument ); + return m_pDocument->UpdateAllViews( this, UpdateAllViews_ENUM::HINT_SELECTIONCHANGED ); + } + } + afx_msg void OnUpdatePopupToggle( _In_ CCmdUI* pCmdUI ) { + pCmdUI->Enable( m_treeListControl.SelectedItemCanToggle( ) ); + } + afx_msg void OnPopupToggle( ) { + m_treeListControl.ToggleSelectedItem( ); + } public: #ifdef _DEBUG diff --git a/WinDirStat/windirstat/globalhelpers.cpp b/WinDirStat/windirstat/globalhelpers.cpp index 7e4a19e..14dcbee 100644 --- a/WinDirStat/windirstat/globalhelpers.cpp +++ b/WinDirStat/windirstat/globalhelpers.cpp @@ -492,7 +492,9 @@ const HRESULT Children_String_Heap_Manager::copy_name_str_into_buffer( _Pre_inva -QPC_timer::QPC_timer( ) : m_frequency( help_QueryPerformanceFrequency( ).QuadPart ), m_start( 0 ), m_end( 0 ) { } +QPC_timer::QPC_timer( ) : m_frequency( help_QueryPerformanceFrequency( ).QuadPart ), m_start( 0 ), m_end( 0 ) { + ASSERT( m_frequency > 0 ); + } void QPC_timer::begin( ) { m_start = help_QueryPerformanceCounter( ).QuadPart; @@ -502,6 +504,16 @@ void QPC_timer::end( ) { m_end = help_QueryPerformanceCounter( ).QuadPart; } +const double QPC_timer::total_time_elapsed( ) const { + ASSERT( m_end > m_start ); + static_assert( std::is_same::value, "difference is wrong!" ); + const auto difference = ( m_end - m_start ); + const DOUBLE adjustedTimingFrequency = ( static_cast< DOUBLE >( 1.00 ) ) / static_cast< DOUBLE >( m_frequency ); + const auto total_time = ( difference * adjustedTimingFrequency ); + return total_time; + } + + void InitializeCriticalSection_wrapper( _Pre_invalid_ _Post_valid_ _Out_ CRITICAL_SECTION& cs ) { InitializeCriticalSection( &cs ); } diff --git a/WinDirStat/windirstat/globalhelpers.h b/WinDirStat/windirstat/globalhelpers.h index 93cd616..421c3b5 100644 --- a/WinDirStat/windirstat/globalhelpers.h +++ b/WinDirStat/windirstat/globalhelpers.h @@ -57,6 +57,7 @@ struct QPC_timer { QPC_timer( ); void begin( ); void end( ); + const double total_time_elapsed( ) const; QPC_timer& operator=( const QPC_timer& in ) = delete; const std::int64_t m_frequency; diff --git a/WinDirStat/windirstat/graphview.cpp b/WinDirStat/windirstat/graphview.cpp index bbae78c..02a2f03 100644 --- a/WinDirStat/windirstat/graphview.cpp +++ b/WinDirStat/windirstat/graphview.cpp @@ -40,6 +40,7 @@ BEGIN_MESSAGE_MAP( CGraphView, CView ) END_MESSAGE_MAP( ) void CGraphView::DrawEmptyView( _In_ CDC& pScreen_Device_Context ) { + TRACE( _T( "Drawing Empty view...\r\n" ) ); const COLORREF gray = RGB( 160, 160, 160 ); Inactivate( ); @@ -153,7 +154,6 @@ void CGraphView::OnDraw( CDC* pScreen_Device_Context ) { void CGraphView::DrawHighlights( _In_ CDC& pdc ) const { - ASSERT( m_frameptr == GetMainFrame( ) ); const auto logicalFocus = m_frameptr->m_logicalFocus; if ( logicalFocus == LOGICAL_FOCUS::LF_DIRECTORYLIST ) { DrawSelection( pdc ); @@ -161,8 +161,7 @@ void CGraphView::DrawHighlights( _In_ CDC& pdc ) const { if ( logicalFocus == LOGICAL_FOCUS::LF_EXTENSIONLIST ) { DrawHighlightExtension( pdc ); } - - GetApp( )->PeriodicalUpdateRamUsage( ); + m_appptr->PeriodicalUpdateRamUsage( ); } void CGraphView::DrawHighlightExtension( _In_ CDC& pdc ) const { @@ -349,7 +348,6 @@ void CGraphView::Inactivate( ) { } void CGraphView::OnSetFocus( CWnd* /*pOldWnd*/ ) { - ASSERT( m_frameptr == GetMainFrame( ) ); ASSERT( m_frameptr != NULL ); if ( m_frameptr == NULL ) { return; @@ -462,7 +460,6 @@ void CGraphView::OnMouseMove( UINT /*nFlags*/, CPoint point ) { return reset_timer_if_zero( ); } ASSERT( m_frameptr != NULL ); - ASSERT( GetMainFrame( ) == m_frameptr ); if ( m_frameptr == NULL ) { return reset_timer_if_zero( ); } @@ -490,7 +487,6 @@ void CGraphView::OnTimer( UINT_PTR /*nIDEvent*/ ) { if ( !PtInRect( &rc, point ) ) { TRACE( _T( "Mouse has left the tree map area!\r\n" ) ); - ASSERT( GetMainFrame( ) == m_frameptr ); m_frameptr->SetSelectionMessageText( ); VERIFY( KillTimer( m_timer ) ); m_timer = 0; diff --git a/WinDirStat/windirstat/graphview.h b/WinDirStat/windirstat/graphview.h index 1706cc4..f7ac387 100644 --- a/WinDirStat/windirstat/graphview.h +++ b/WinDirStat/windirstat/graphview.h @@ -11,7 +11,7 @@ #include "treemap.h" #include "windirstat.h" - +#include "options.h" class CDirstatDoc; class CItemBranch; class CGraphView; @@ -20,11 +20,12 @@ class CGraphView; // CGraphView. The treemap window. class CGraphView final : public CView { protected: - CGraphView( ) : m_recalculationSuspended( false ), m_showTreemap( true ), m_timer( 0 ), m_frameptr( GetMainFrame( ) ) { + CGraphView( ) : m_recalculationSuspended( false ), m_showTreemap( true ), m_timer( 0 ), m_frameptr( GetMainFrame( ) ), m_appptr( GetApp( ) ) { m_size.cx = 0; m_size.cy = 0; m_dimmedSize.cx = 0; m_dimmedSize.cy = 0; + m_showTreemap = CPersistence::GetShowTreemap( ); } DECLARE_DYNCREATE(CGraphView) @@ -111,6 +112,7 @@ class CGraphView final : public CView { CBitmap m_dimmed; // Dimmed view. Used during refresh to avoid the ooops-effect. UINT_PTR m_timer; // We need a timer to realize when the mouse left our window. CMainFrame* const m_frameptr; + CDirstatApp* m_appptr; DECLARE_MESSAGE_MAP() afx_msg void OnSize(UINT nType, INT cx, INT cy); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); diff --git a/WinDirStat/windirstat/item.cpp b/WinDirStat/windirstat/item.cpp index ed04637..b1aa8a9 100644 --- a/WinDirStat/windirstat/item.cpp +++ b/WinDirStat/windirstat/item.cpp @@ -244,6 +244,7 @@ std::vector CItemBranch::size_sorted_vector_of_children( ) const ASSERT( m_childCount == 0 ); } #endif + //TODO: qsort is bleh qsort( children.data( ), static_cast< const size_t >( children.size( ) ), sizeof( CTreeListItem* ), &CItem_compareBySize ); //std::sort( children.begin( ), children.end( ), [] ( const CTreeListItem* const lhs, const CTreeListItem* const rhs ) { return static_cast< const CItemBranch* >( lhs )->size_recurse( ) < static_cast< const CItemBranch* >( rhs )->size_recurse( ); } ); return children; diff --git a/WinDirStat/windirstat/layout.cpp b/WinDirStat/windirstat/layout.cpp index fe60230..83f2b2d 100644 --- a/WinDirStat/windirstat/layout.cpp +++ b/WinDirStat/windirstat/layout.cpp @@ -17,13 +17,13 @@ //#endif -CLayout::CLayout( _In_ CWnd* dialog, _In_z_ PCWSTR const name ) : m_dialog( dialog ), m_name( name ) { - ASSERT( m_dialog != NULL ); - - // This is necessary because OnGetMinMaxInfo() will be called before OnInitDialog! - m_originalDialogSize.cx = 0; - m_originalDialogSize.cy = 0; - } +//CLayout::CLayout( _In_ CWnd* dialog, _In_z_ PCWSTR const name ) : m_dialog( dialog ), m_name( name ) { +// ASSERT( m_dialog != NULL ); +// +// // This is necessary because OnGetMinMaxInfo() will be called before OnInitDialog! +// m_originalDialogSize.cx = 0; +// m_originalDialogSize.cy = 0; +// } //size_t CLayout::AddControl( _In_ CWnd* control, _In_ const DOUBLE movex, _In_ const DOUBLE movey, _In_ const DOUBLE stretchx, _In_ const DOUBLE stretchy ) { // m_control.emplace_back( SControlInfo { control, movex, movey, stretchx, stretchy, CRect( ) } ); @@ -59,13 +59,17 @@ void CLayout::OnInitDialog( _In_ const bool centerWindow ) { m_control.emplace_back( SControlInfo { &m_sizeGripper, 1, 1, 0, 0, sg } ); CPersistence::GetDialogRectangle( m_name, rcDialog ); - m_dialog->MoveWindow( &rcDialog ); + + ASSERT( ::IsWindow( m_dialog->m_hWnd ) ); + + //If [MoveWindow] succeeds, the return value is nonzero. + VERIFY( ::MoveWindow( m_dialog->m_hWnd, rcDialog.left, rcDialog.top, ( rcDialog.right - rcDialog.left ), ( rcDialog.bottom - rcDialog.top ), TRUE ) ); if ( centerWindow ) { m_dialog->CenterWindow( ); } } -CLayout::SControlInfo::SControlInfo( CWnd* control_in, DOUBLE movex_in, DOUBLE movey_in, DOUBLE stretchx_in, DOUBLE stretchy_in, RECT originalRectangle_in ) : control( control_in ), movex( std::move( movex_in ) ), movey( std::move( movey_in ) ), stretchx ( std::move( stretchx_in ) ), stretchy( std::move( stretchy_in ) ), originalRectangle( std::move( originalRectangle_in ) ) { } +//CLayout::SControlInfo::SControlInfo( CWnd* control_in, DOUBLE movex_in, DOUBLE movey_in, DOUBLE stretchx_in, DOUBLE stretchy_in, RECT originalRectangle_in ) : control( control_in ), movex( std::move( movex_in ) ), movey( std::move( movey_in ) ), stretchx ( std::move( stretchx_in ) ), stretchy( std::move( stretchy_in ) ), originalRectangle( std::move( originalRectangle_in ) ) { } void CLayout::OnDestroy( ) { RECT rc; @@ -96,10 +100,10 @@ void CLayout::OnSize( ) { VERIFY( EndDeferWindowPos( hdwp ) ); } -void CLayout::OnGetMinMaxInfo( _Out_ MINMAXINFO* mmi ) const { - mmi->ptMinTrackSize.x = m_originalDialogSize.cx; - mmi->ptMinTrackSize.y = m_originalDialogSize.cy; - } +//void CLayout::OnGetMinMaxInfo( _Out_ MINMAXINFO* mmi ) const { +// mmi->ptMinTrackSize.x = m_originalDialogSize.cx; +// mmi->ptMinTrackSize.y = m_originalDialogSize.cy; +// } ///////////////////////////////////////////////////////////////////////////// @@ -108,9 +112,9 @@ const INT CLayout::CSizeGripper::_width = 14; //CLayout::CSizeGripper::CSizeGripper( ) { } -void CLayout::CSizeGripper::Create( _Inout_ CWnd* parent, _In_ const RECT rc ) { - VERIFY( CWnd::Create( AfxRegisterWndClass( 0, AfxGetApp( )->LoadStandardCursor( IDC_ARROW ), ( HBRUSH ) ( COLOR_BTNFACE + 1 ), 0 ), _T( "" ), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, rc, parent, IDC_SIZEGRIPPER ) ); - } +//void CLayout::CSizeGripper::Create( _Inout_ CWnd* parent, _In_ const RECT rc ) { +// VERIFY( CWnd::Create( AfxRegisterWndClass( 0, AfxGetApp( )->LoadStandardCursor( IDC_ARROW ), ( HBRUSH ) ( COLOR_BTNFACE + 1 ), 0 ), _T( "" ), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, rc, parent, IDC_SIZEGRIPPER ) ); +// } BEGIN_MESSAGE_MAP(CLayout::CSizeGripper, CWnd) ON_WM_PAINT() @@ -143,7 +147,7 @@ void CLayout::CSizeGripper::OnPaint( ) { end.y += 4; DrawShadowLine( dc, start, end ); - + start.x += 4; end.y += 4; diff --git a/WinDirStat/windirstat/layout.h b/WinDirStat/windirstat/layout.h index de29979..686bb6e 100644 --- a/WinDirStat/windirstat/layout.h +++ b/WinDirStat/windirstat/layout.h @@ -13,12 +13,14 @@ // Simple, flat, and sufficient for our purposes. class CLayout { struct SControlInfo { - SControlInfo( CWnd* control_in, DOUBLE movex_in, DOUBLE movey_in, DOUBLE stretchx_in, DOUBLE stretchy_in, RECT originalRectangle_in ); + SControlInfo( CWnd* control_in, DOUBLE movex_in, DOUBLE movey_in, DOUBLE stretchx_in, DOUBLE stretchy_in, RECT originalRectangle_in ) : control( control_in ), movex( std::move( movex_in ) ), movey( std::move( movey_in ) ), stretchx ( std::move( stretchx_in ) ), stretchy( std::move( stretchy_in ) ), originalRectangle( std::move( originalRectangle_in ) ) { } + + SControlInfo& operator=( const SControlInfo& in ) = delete; CWnd* control; - DOUBLE movex; - DOUBLE movey; - DOUBLE stretchx; - DOUBLE stretchy; + const DOUBLE movex; + const DOUBLE movey; + const DOUBLE stretchx; + const DOUBLE stretchy; RECT originalRectangle; }; @@ -27,8 +29,14 @@ class CLayout { CLayout& operator=( const CLayout& in ) = delete; CLayout( const CLayout& in ) = delete; - CLayout( _In_ CWnd* dialog, _In_z_ PCWSTR const name ); - CLayout( CLayout&& other ); + CLayout( _In_ CWnd* dialog, _In_z_ PCWSTR const name ) : m_dialog( dialog ), m_name( name ) { + ASSERT( m_dialog != NULL ); + + // This is necessary because OnGetMinMaxInfo() will be called before OnInitDialog! + m_originalDialogSize.cx = 0; + m_originalDialogSize.cy = 0; + } + class CSizeGripper final : public CWnd { @@ -41,7 +49,9 @@ class CLayout { //CSizeGripper( ); #pragma warning( suppress: 4263 ) - void Create( _Inout_ CWnd* parent, _In_ const RECT rc ); + void Create( _Inout_ CWnd* parent, _In_ const RECT rc ) { + VERIFY( CWnd::Create( AfxRegisterWndClass( 0, AfxGetApp( )->LoadStandardCursor( IDC_ARROW ), ( HBRUSH ) ( COLOR_BTNFACE + 1 ), 0 ), _T( "" ), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, rc, parent, IDC_SIZEGRIPPER ) ); + } private: void DrawShadowLine( _In_ CDC& pdc, _In_ WTL::CPoint start, _In_ WTL::CPoint end ); @@ -56,7 +66,11 @@ class CLayout { //size_t AddControl ( _In_ CWnd* control, _In_ const DOUBLE movex, _In_ const DOUBLE movey, _In_ const DOUBLE stretchx, _In_ const DOUBLE stretchy ); void AddControl ( _In_ const UINT id, _In_ const DOUBLE movex, _In_ const DOUBLE movey, _In_ const DOUBLE stretchx, _In_ const DOUBLE stretchy ); void OnInitDialog ( _In_ const bool centerWindow ); - void OnGetMinMaxInfo( _Out_ MINMAXINFO* mmi ) const; + + void OnGetMinMaxInfo( _Out_ MINMAXINFO* mmi ) const { + mmi->ptMinTrackSize.x = m_originalDialogSize.cx; + mmi->ptMinTrackSize.y = m_originalDialogSize.cy; + } void OnDestroy ( ); void OnSize ( ); diff --git a/WinDirStat/windirstat/mainframe.cpp b/WinDirStat/windirstat/mainframe.cpp index 44a5047..6211764 100644 --- a/WinDirStat/windirstat/mainframe.cpp +++ b/WinDirStat/windirstat/mainframe.cpp @@ -75,10 +75,57 @@ namespace { const BOOL m_open; }; + const UINT indicators[ ] = { ID_SEPARATOR, ID_INDICATOR_MEMORYUSAGE }; + + template + void SetIndicators( CStatusBar& status_bar, const UINT( &indicators_array )[ count ] ) { + static_assert( sizeof( indicators_array ) == ( count * sizeof( UINT ) ), "Bad SetIndicators argument!" ); + VERIFY( status_bar.SetIndicators( indicators_array, count ) ); + } + + const rsize_t debug_str_size = 100u; + + void debug_output_searching_time( _In_ const double searchingTime ) { + _Null_terminated_ wchar_t searching_done_str[ debug_str_size ] = { 0 }; + const auto printf_res_1 = _snwprintf_s( searching_done_str, debug_str_size, _TRUNCATE, L"WDS: searching time: %f\r\n", searchingTime ); + ASSERT( printf_res_1 != -1 ); + OutputDebugStringW( searching_done_str ); + +#ifndef DEBUG + UNREFERENCED_PARAMETER( printf_res_1 ); +#endif + } + + void debug_output_frequency( _In_ const std::int64_t m_frequency ) { + _Null_terminated_ wchar_t freq_str[ debug_str_size ] = { 0 }; + const auto printf_res_3 = _snwprintf_s( freq_str, debug_str_size, _TRUNCATE, L"WDS: timing frequency: %lld\r\n", m_frequency ); + ASSERT( printf_res_3 != -1 ); + OutputDebugStringW( freq_str ); +#ifndef DEBUG + UNREFERENCED_PARAMETER( printf_res_3 ); +#endif + } + + void debug_output_time_to_draw_empty_window( _In_ const double timeToDrawEmptyWindow ) { + _Null_terminated_ wchar_t drawing_done_str[ debug_str_size ] = { 0 }; + const auto printf_res_4 = _snwprintf_s( drawing_done_str, debug_str_size, _TRUNCATE, L"WDS: time to draw window: %f\r\n", timeToDrawEmptyWindow ); + ASSERT( printf_res_4 != -1 ); + OutputDebugStringW( drawing_done_str ); +#ifndef DEBUG + UNREFERENCED_PARAMETER( printf_res_4 ); +#endif + } + + void output_debugging_info( _In_ const double searchingTime, _In_ const std::int64_t frequency, _In_ const double timeToDrawEmptyWindow ) { + debug_output_searching_time( searchingTime ); + debug_output_frequency( frequency ); + debug_output_time_to_draw_empty_window( timeToDrawEmptyWindow ); + } } + ///////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC( COptionsPropertySheet, CPropertySheet ) @@ -86,12 +133,29 @@ IMPLEMENT_DYNAMIC( COptionsPropertySheet, CPropertySheet ) BOOL COptionsPropertySheet::OnInitDialog( ) { const BOOL bResult = CPropertySheet::OnInitDialog( ); - CRect rc; - GetWindowRect( rc ); - WTL::CPoint pt = rc.TopLeft( ); + RECT rc; + + /* +_AFXWIN_INLINE void CWnd::GetWindowRect(LPRECT lpRect) const + { ASSERT(::IsWindow(m_hWnd)); ::GetWindowRect(m_hWnd, lpRect); } + */ + + ASSERT( ::IsWindow( m_hWnd ) ); + + //If [GetWindowRect] succeeds, the return value is nonzero. + VERIFY( ::GetWindowRect( m_hWnd, &rc ) ); + + WTL::CPoint pt = CRect( rc ).TopLeft( ); + CPersistence::GetConfigPosition( pt ); - CRect rc2( pt, rc.Size( ) ); - MoveWindow( rc2 ); + CRect rc2( pt, CRect( rc ).Size( ) ); + + ASSERT( m_pCtrlSite == NULL ); + + ASSERT( ::IsWindow( m_hWnd ) ); + + //If [MoveWindow] succeeds, the return value is nonzero. + VERIFY( ::MoveWindow( m_hWnd, rc2.left, rc2.top, ( rc2.right - rc2.left ), ( rc2.bottom - rc2.top ), TRUE ) ); VERIFY( SetActivePage( CPersistence::GetConfigPage( GetPageCount( ) - 1 ) ) ); return bResult; @@ -103,7 +167,7 @@ BOOL COptionsPropertySheet::OnCommand( _In_ WPARAM wParam, _In_ LPARAM lParam ) CRect rc; GetWindowRect( rc ); CPersistence::SetConfigPosition( rc.TopLeft( ) ); - + ASSERT( m_pCtrlSite == NULL ); //INT cmd = LOWORD( wParam ); return CPropertySheet::OnCommand( wParam, lParam ); } @@ -225,7 +289,7 @@ END_MESSAGE_MAP( ) void CDeadFocusWnd::OnKeyDown( const UINT nChar, const UINT /* nRepCnt */, const UINT /* nFlags */ ) { if ( nChar == VK_TAB ) { - GetMainFrame( )->MoveFocus( LOGICAL_FOCUS::LF_DIRECTORYLIST ); + m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_DIRECTORYLIST ); } } @@ -265,32 +329,28 @@ INT CMainFrame::OnCreate( const LPCREATESTRUCT lpCreateStruct ) { Initializes a few related things, such as the memory display. */ + _theFrame = this; + m_appptr = GetApp( ); if ( CFrameWnd::OnCreate( lpCreateStruct ) == -1 ) { return -1; } - //VERIFY( m_wndToolBar.CreateEx( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC ) ); - - UINT indicators[ INDICATORS_NUMBER ] = { ID_SEPARATOR, ID_INDICATOR_MEMORYUSAGE }; - - VERIFY( m_wndStatusBar.Create( this ) ); - VERIFY( m_wndStatusBar.SetIndicators( indicators, INDICATORS_NUMBER ) ); + SetIndicators( m_wndStatusBar, indicators ); m_wndDeadFocus.Create( this ); - - //m_wndToolBar.EnableDocking( CBRS_ALIGN_ANY ); EnableDocking( CBRS_ALIGN_ANY ); - //DockControlBar( &m_wndToolBar ); LoadBarState( CPersistence::GetBarStateSection( ) ); ShowControlBar( &m_wndStatusBar, CPersistence::GetShowStatusbar( ), false ); TRACE( _T( "sizeof CItemBranch: %I64u\r\n" ), static_cast< std::uint64_t >( sizeof( CItemBranch ) ) ); #ifdef DISPLAY_FINAL_CITEMBRANCH_SIZE - const auto size_citembranch = std::to_wstring( sizeof( CItemBranch ) ); - const std::wstring size_text( L"sizeof CItemBranch: " + size_citembranch ); - displayWindowsMsgBoxWithMessage( size_text.c_str( ) ); + if ( IsDebuggerPresent( ) ) { + const auto size_citembranch = std::to_wstring( sizeof( CItemBranch ) ); + const std::wstring size_text( L"sizeof CItemBranch: " + size_citembranch ); + displayWindowsMsgBoxWithMessage( size_text.c_str( ) ); + } #endif return 0; } @@ -402,92 +462,39 @@ void CMainFrame::RestoreGraphView( ) { if ( thisGraphView == NULL ) { return; } - if ( thisGraphView->m_showTreemap ) { - m_wndSplitter.RestoreSplitterPos( 0.4 ); -#ifdef PERF_DEBUG_SLEEP - Sleep( 1000 ); -#endif - TRACE( _T( "Drawing Empty view...\r\n" ) ); - -#ifdef DEBUG - const auto emptyViewTiming_1 = help_QueryPerformanceCounter( ); - thisGraphView->DrawEmptyView( ); - const auto emptyViewTiming_2 = help_QueryPerformanceCounter( ); -#endif - const LARGE_INTEGER timingFrequency = help_QueryPerformanceFrequency( ); - const DOUBLE adjustedTimingFrequency = ( static_cast< DOUBLE >( 1.00 ) ) / static_cast< DOUBLE >( timingFrequency.QuadPart ); - -#ifdef DEBUG - const DOUBLE timeToDrawEmptyWindow = ( emptyViewTiming_2.QuadPart - emptyViewTiming_1.QuadPart ) * adjustedTimingFrequency; - TRACE( _T( "Done drawing empty view. Timing: %f\r\n" ), timeToDrawEmptyWindow ); -#endif - TRACE( _T( "Drawing treemap...\r\n" ) ); - const auto startDrawTime = help_QueryPerformanceCounter( ); - - VERIFY( thisGraphView->RedrawWindow( ) ); - const auto endDrawTime = help_QueryPerformanceCounter( ); - - const DOUBLE timeToDrawWindow = static_cast< DOUBLE >( endDrawTime.QuadPart - startDrawTime.QuadPart ) * adjustedTimingFrequency; - TRACE( _T( "Finished drawing treemap! Timing:: %f\r\n" ), timeToDrawWindow ); -#ifdef PERF_DEBUG_SLEEP - Sleep( 1000 ); -#endif - const auto comp_file_timing = GetDocument( )->m_compressed_file_timing; - const auto searchingTime = GetDocument( )->m_searchTime; - ASSERT( searchingTime != 0 ); - - const rsize_t debug_str_size = 100; - _Null_terminated_ wchar_t searching_done_str[ debug_str_size ] = { 0 }; - const auto printf_res_1 = _snwprintf_s( searching_done_str, debug_str_size, _TRUNCATE, L"WDS: searching time: %f\r\n", searchingTime ); - ASSERT( printf_res_1 != -1 ); - -#ifndef DEBUG - UNREFERENCED_PARAMETER( printf_res_1 ); -#endif - - _Null_terminated_ wchar_t drawing_start_str[ debug_str_size ] = { 0 }; - const auto printf_res_2 = _snwprintf_s( drawing_start_str, debug_str_size, _TRUNCATE, L"WDS: startDrawTime: %lld\r\n", startDrawTime.QuadPart ); - ASSERT( printf_res_2 != -1 ); - -#ifndef DEBUG - UNREFERENCED_PARAMETER( printf_res_2 ); -#endif - _Null_terminated_ wchar_t freq_str[ debug_str_size ] = { 0 }; - const auto printf_res_3 = _snwprintf_s( freq_str, debug_str_size, _TRUNCATE, L"WDS: timingFrequency: %lld\r\n", timingFrequency.QuadPart ); - ASSERT( printf_res_3 != -1 ); - -#ifndef DEBUG - UNREFERENCED_PARAMETER( printf_res_3 ); -#endif - - _Null_terminated_ wchar_t drawing_done_str[ debug_str_size ] = { 0 }; - const auto printf_res_4 = _snwprintf_s( drawing_done_str, debug_str_size, _TRUNCATE, L"WDS: endDrawTime: %lld\r\n", endDrawTime.QuadPart ); - ASSERT( printf_res_4 != -1 ); - -#ifndef DEBUG - UNREFERENCED_PARAMETER( printf_res_4 ); -#endif - - OutputDebugStringW( searching_done_str ); - OutputDebugStringW( drawing_start_str ); - OutputDebugStringW( drawing_done_str ); - OutputDebugStringW( freq_str ); - - - - const auto avg_name_leng = GetDocument( )->m_rootItem->averageNameLength( ); - ASSERT( timeToDrawWindow != 0 ); + if ( !( thisGraphView->m_showTreemap ) ) { + return; + } + m_wndSplitter.RestoreSplitterPos( 0.4 ); + + QPC_timer timer_draw_empty_view; + timer_draw_empty_view.begin( ); + thisGraphView->DrawEmptyView( ); + timer_draw_empty_view.end( ); + const DOUBLE timeToDrawEmptyWindow = timer_draw_empty_view.total_time_elapsed( ); + TRACE( _T( "Done drawing empty view. Timing: %f\r\nDrawing treemap...\r\n" ), timeToDrawEmptyWindow ); + QPC_timer timer_draw_treemap; + timer_draw_treemap.begin( ); + VERIFY( thisGraphView->RedrawWindow( ) ); + timer_draw_treemap.end( ); + + const DOUBLE timeToDrawWindow = timer_draw_treemap.total_time_elapsed( ); + TRACE( _T( "Finished drawing treemap! Timing: %f\r\n" ), timeToDrawWindow ); + const auto comp_file_timing = GetDocument( )->m_compressed_file_timing; + const auto searchingTime = GetDocument( )->m_searchTime; + ASSERT( searchingTime > 0 ); + output_debugging_info( searchingTime, timer_draw_treemap.m_frequency, timeToDrawEmptyWindow ); + const auto avg_name_leng = GetDocument( )->m_rootItem->averageNameLength( ); + ASSERT( timeToDrawWindow != 0 ); + m_lastSearchTime = searchingTime; + if ( m_lastSearchTime == -1 ) { m_lastSearchTime = searchingTime; - if ( m_lastSearchTime == -1 ) { - m_lastSearchTime = searchingTime; - ASSERT( m_lastSearchTime >= comp_file_timing ); - WriteTimeToStatusBar( timeToDrawWindow, m_lastSearchTime, avg_name_leng, comp_file_timing );//else the search time compounds whenever the time is written to the status bar - } - else { - WriteTimeToStatusBar( timeToDrawWindow, m_lastSearchTime, avg_name_leng, comp_file_timing ); - } + ASSERT( m_lastSearchTime >= comp_file_timing ); + WriteTimeToStatusBar( timeToDrawWindow, m_lastSearchTime, avg_name_leng, comp_file_timing );//else the search time compounds whenever the time is written to the status bar + } + else { + WriteTimeToStatusBar( timeToDrawWindow, m_lastSearchTime, avg_name_leng, comp_file_timing ); } - } _Must_inspect_result_ _Ret_maybenull_ CDirstatView* CMainFrame::GetDirstatView( ) const { @@ -495,6 +502,7 @@ _Must_inspect_result_ _Ret_maybenull_ CDirstatView* CMainFrame::GetDirstatView( return STATIC_DOWNCAST( CDirstatView, pWnd ); } +//cannot be defined in header. _Must_inspect_result_ _Ret_maybenull_ CGraphView* CMainFrame::GetGraphView( ) const { const auto pWnd = m_wndSplitter.GetPane( 1, 0 ); return STATIC_DOWNCAST( CGraphView, pWnd ); @@ -525,14 +533,14 @@ void CMainFrame::CopyToClipboard( _In_ const std::wstring psz ) const { COpenClipboard clipboard( const_cast< CMainFrame* >( this ), true ); const rsize_t strSizeInBytes = ( ( psz.length( ) + 1 ) * sizeof( WCHAR ) ); - const HGLOBAL h = GlobalAlloc( GMEM_MOVEABLE bitand GMEM_ZEROINIT, strSizeInBytes ); - if ( h == NULL ) { + const HGLOBAL handle_globally_allocated_memory = GlobalAlloc( GMEM_MOVEABLE bitand GMEM_ZEROINIT, strSizeInBytes ); + if ( handle_globally_allocated_memory == NULL ) { displayWindowsMsgBoxWithMessage( global_strings::global_alloc_failed ); TRACE( L"%s\r\n", global_strings::global_alloc_failed ); return; } - const auto lp = GlobalLock( h ); + const auto lp = GlobalLock( handle_globally_allocated_memory ); if ( lp == NULL ) { displayWindowsMsgBoxWithMessage( L"GlobalLock failed!" ); return; @@ -551,7 +559,7 @@ void CMainFrame::CopyToClipboard( _In_ const std::wstring psz ) const { else { displayWindowsMsgBoxWithMessage( global_strings::string_cch_copy_failed ); } - const BOOL unlock_res = GlobalUnlock( h ); + const BOOL unlock_res = GlobalUnlock( handle_globally_allocated_memory ); strP = NULL; const auto last_err = GetLastError( ); if ( unlock_res == 0 ) { @@ -564,7 +572,7 @@ void CMainFrame::CopyToClipboard( _In_ const std::wstring psz ) const { return; } - if ( GlobalUnlock( h ) == 0 ) { + if ( GlobalUnlock( handle_globally_allocated_memory ) == 0 ) { const auto err = GetLastError( ); if ( err != NO_ERROR ) { displayWindowsMsgBoxWithMessage( L"GlobalUnlock failed!" ); @@ -575,7 +583,7 @@ void CMainFrame::CopyToClipboard( _In_ const std::wstring psz ) const { UINT uFormat = CF_TEXT; uFormat = CF_UNICODETEXT; - if ( NULL == SetClipboardData( uFormat, h ) ) { + if ( NULL == SetClipboardData( uFormat, handle_globally_allocated_memory ) ) { displayWindowsMsgBoxWithMessage( global_strings::cannot_set_clipboard_data ); TRACE( L"%s\r\n", global_strings::cannot_set_clipboard_data ); return; @@ -626,7 +634,7 @@ size_t CMainFrame::getExtDataSize( ) const { } void CMainFrame::valid_timing_to_write( _In_ const double populate_timing, _In_ const double draw_timing, _In_ const double average_extension_length, _In_ const double enum_timing, _In_ const double compressed_file_timing, _In_ const double total_time, _In_ const rsize_t ext_data_size, _In_ const double file_name_length, _Out_ _Post_z_ _Pre_writable_size_( buffer_size_init ) PWSTR buffer_ptr, const rsize_t buffer_size_init ) { - const HRESULT fmt_res = StringCchPrintfW( buffer_ptr, buffer_size_init, _T( "File enumeration took %.3f sec. NTFS compressed file size processing took: %.3f sec. Drawing took %.3f sec. Populating 'file types' took %.3f sec. Total: %.4f sec. # file types: %u. Avg name len: %.2f. Avg extension len: %.2f. SSO threshold: %u" ), enum_timing, compressed_file_timing, draw_timing, populate_timing, total_time, unsigned( ext_data_size ), file_name_length, average_extension_length, unsigned( copied_from_VCPP_stdlib::SSO_THRESHOLD_BUF_SIZE ) ); + const HRESULT fmt_res = StringCchPrintfW( buffer_ptr, buffer_size_init, _T( "File enumeration took %.3f sec. NTFS compressed file size processing took: %.3f sec. Drawing took %.3f sec. Populating 'file types' took %.3f sec. Total: %.4f sec. # file types: %u. Avg name len: %.2f. Avg extension len: %.2f." ), enum_timing, compressed_file_timing, draw_timing, populate_timing, total_time, unsigned( ext_data_size ), file_name_length, average_extension_length ); ASSERT( SUCCEEDED( fmt_res ) ); if ( SUCCEEDED( fmt_res ) ) { SetMessageText( buffer_ptr ); @@ -650,7 +658,7 @@ void CMainFrame::valid_timing_to_write( _In_ const double populate_timing, _In_ } void CMainFrame::invalid_timing_to_write( _In_ const double average_extension_length, _In_ const double enum_timing, _In_ const rsize_t ext_data_size, _Out_ _Post_z_ _Pre_writable_size_( buffer_size_init ) PWSTR buffer_ptr, const rsize_t buffer_size_init ) { - const HRESULT fmt_res = StringCchPrintfW( buffer_ptr, buffer_size_init, _T( "I had trouble with QueryPerformanceCounter, and can't provide timing. # file types: %u. Avg name len: %.2f. Avg extension len: %.2f. SSO threshold: %u" ), unsigned( ext_data_size ), enum_timing, average_extension_length, unsigned( copied_from_VCPP_stdlib::SSO_THRESHOLD_BUF_SIZE ) ); + const HRESULT fmt_res = StringCchPrintfW( buffer_ptr, buffer_size_init, _T( "I had trouble with QueryPerformanceCounter, and can't provide timing. # file types: %u. Avg name len: %.2f. Avg extension len: %.2f." ), unsigned( ext_data_size ), enum_timing, average_extension_length ); ASSERT( SUCCEEDED( fmt_res ) ); if ( SUCCEEDED( fmt_res ) ) { SetMessageText( buffer_ptr ); @@ -680,6 +688,8 @@ void CMainFrame::WriteTimeToStatusBar( _In_ const double drawTiming, _In_ const */ ASSERT( searchTiming >= compressed_file_timing ); const rsize_t buffer_size_init = 512u; + + //TODO: why are we using heap here? std::unique_ptr<_Null_terminated_ wchar_t[ ]> buffer_uniq_ptr = std::make_unique<_Null_terminated_ wchar_t[ ]>( buffer_size_init ); PWSTR buffer_ptr = buffer_uniq_ptr.get( ); @@ -748,8 +758,7 @@ void CMainFrame::OnUpdateMemoryUsage( CCmdUI *pCmdUI ) { pCmdUI->Enable( true ); const rsize_t ramUsageStrBufferSize = 50; _Null_terminated_ wchar_t ramUsageStr[ ramUsageStrBufferSize ] = { 0 }; - - const HRESULT res = GetApp( )->GetCurrentProcessMemoryInfo( ramUsageStr, ramUsageStrBufferSize ); + const HRESULT res = m_appptr->GetCurrentProcessMemoryInfo( ramUsageStr, ramUsageStrBufferSize ); if ( !SUCCEEDED( res ) ) { rsize_t chars_written = 0; wds_fmt::write_BAD_FMT( ramUsageStr, chars_written ); @@ -818,7 +827,7 @@ void CMainFrame::OnViewShowfiletypes( ) { void CMainFrame::OnConfigure( ) { COptionsPropertySheet sheet; - CPageGeneral general; + CPageGeneral general( m_appptr ); CPageTreemap treemap; sheet.AddPage( &general ); diff --git a/WinDirStat/windirstat/mainframe.h b/WinDirStat/windirstat/mainframe.h index 4dafe13..5233537 100644 --- a/WinDirStat/windirstat/mainframe.h +++ b/WinDirStat/windirstat/mainframe.h @@ -4,19 +4,17 @@ #pragma once #include "stdafx.h" +#include "windirstat.h" #ifndef WDS_MAINFRAME_H #define WDS_MAINFRAME_H - - - - class CMySplitterWnd; class CMainFrame; class CDirstatView; class CGraphView; class CTypeView; +class CDirstatApp; // COptionsPropertySheet. The options dialog. class COptionsPropertySheet final : public CPropertySheet { @@ -61,12 +59,12 @@ class CMySplitterWnd final : public CSplitterWnd { // an invisible (zero-size) child of CMainFrame. class CDeadFocusWnd final : public CWnd { public: - CDeadFocusWnd( ) { } + CDeadFocusWnd( CMainFrame* ptr ) : m_frameptr( ptr ) { } CDeadFocusWnd& operator=( const CDeadFocusWnd& in ) = delete; CDeadFocusWnd( const CDeadFocusWnd& in ) = delete; //#pragma warning( once : 4263 ) - + CMainFrame* m_frameptr; #pragma warning( suppress: 4263 ) void Create( _In_ CWnd* parent ); ~CDeadFocusWnd( ) { @@ -84,9 +82,12 @@ class CDeadFocusWnd final : public CWnd { class CMainFrame final : public CFrameWnd { public: static CMainFrame* _theFrame; - CMainFrame( ) : m_wndSplitter( global_strings::main_split ), m_wndSubSplitter( global_strings::sub_split ), m_lastSearchTime( -1 ), m_logicalFocus( LOGICAL_FOCUS::LF_NONE ) {// Created by MFC only +#pragma warning( push ) +#pragma warning( disable: 4355 ) + CMainFrame( ) : m_wndSplitter( global_strings::main_split ), m_wndSubSplitter( global_strings::sub_split ), m_lastSearchTime( -1 ), m_logicalFocus( LOGICAL_FOCUS::LF_NONE ), m_appptr( nullptr ), m_wndDeadFocus( this ) {// Created by MFC only _theFrame = this; } +#pragma warning( pop ) DECLARE_DYNCREATE(CMainFrame) @@ -117,10 +118,14 @@ class CMainFrame final : public CFrameWnd { void WriteTimeToStatusBar ( _In_ const DOUBLE drawTiming, _In_ const DOUBLE searchTiming, _In_ const DOUBLE fileNameLength, _In_ const DOUBLE compressed_file_timing ); void CopyToClipboard ( _In_ const std::wstring psz ) const; size_t getExtDataSize ( ) const; + _Must_inspect_result_ _Ret_maybenull_ CDirstatView* GetDirstatView ( ) const; + private: _Must_inspect_result_ _Ret_maybenull_ CGraphView* GetGraphView ( ) const; + public: _Must_inspect_result_ _Ret_maybenull_ CTypeView* GetTypeView ( ) const; + public: virtual BOOL OnCreateClient ( LPCREATESTRUCT lpcs, CCreateContext* pContext ) override final; virtual BOOL PreCreateWindow ( CREATESTRUCT& cs ) override final { return CFrameWnd::PreCreateWindow( cs ); @@ -135,6 +140,7 @@ class CMainFrame final : public CFrameWnd { std::wstring m_drawTiming; DOUBLE m_lastSearchTime; CDeadFocusWnd m_wndDeadFocus; // Zero-size window which holds the focus if logical focus is "NONE" + CDirstatApp* m_appptr; DECLARE_MESSAGE_MAP() afx_msg INT OnCreate(LPCREATESTRUCT lpCreateStruct); diff --git a/WinDirStat/windirstat/options.cpp b/WinDirStat/windirstat/options.cpp index 7d466c4..880c527 100644 --- a/WinDirStat/windirstat/options.cpp +++ b/WinDirStat/windirstat/options.cpp @@ -16,61 +16,158 @@ #include "options.h" + +namespace registry_strings { + + + + _Null_terminated_ const wchar_t entrySplitterPosS[ ] = { _T( "%s-splitterPos" ) }; + _Null_terminated_ const wchar_t entryColumnOrderS[ ] = { _T( "%s-columnOrder" ) }; + + _Null_terminated_ const wchar_t entryDialogRectangleS[ ] = { _T( "%s-rectangle" ) }; + + + + _Null_terminated_ const wchar_t entrySelectDrivesDrives[ ] = { _T( "selectDrivesDrives" ) }; + + + _Null_terminated_ const wchar_t sectionOptions[ ] = { _T( "options" ) }; + _Null_terminated_ const wchar_t entryListGrid[ ] = { _T( "treelistGrid" ) }; // for compatibility with 1.0.1, this entry is named treelistGrid. + _Null_terminated_ const wchar_t entryListStripes[ ] = { _T( "listStripes" ) }; + _Null_terminated_ const wchar_t entryListFullRowSelection[ ] = { _T( "listFullRowSelection" ) }; + _Null_terminated_ const wchar_t entryTreelistColorCount[ ] = { _T( "treelistColorCount" ) }; + _Null_terminated_ const wchar_t entryTreelistColorN[ ] = { _T( "treelistColor%d" ) }; + _Null_terminated_ const wchar_t entryHumanFormat[ ] = { _T( "humanFormat" ) }; + _Null_terminated_ const wchar_t entryShowTimeSpent[ ] = { _T( "showTimeSpent" ) }; + _Null_terminated_ const wchar_t entryTreemapHighlightColor[ ] = { _T( "treemapHighlightColor" ) }; + _Null_terminated_ const wchar_t entryTreemapStyle[ ] = { _T( "treemapStyle" ) }; + _Null_terminated_ const wchar_t entryTreemapGrid[ ] = { _T( "treemapGrid" ) }; + _Null_terminated_ const wchar_t entryTreemapGridColor[ ] = { _T( "treemapGridColor" ) }; + _Null_terminated_ const wchar_t entryBrightness[ ] = { _T( "brightness" ) }; + _Null_terminated_ const wchar_t entryHeightFactor[ ] = { _T( "heightFactor" ) }; + _Null_terminated_ const wchar_t entryScaleFactor[ ] = { _T( "scaleFactor" ) }; + _Null_terminated_ const wchar_t entryAmbientLight[ ] = { _T( "ambientLight" ) }; + _Null_terminated_ const wchar_t entryLightSourceX[ ] = { _T( "lightSourceX" ) }; + _Null_terminated_ const wchar_t entryLightSourceY[ ] = { _T( "lightSourceY" ) }; + _Null_terminated_ const wchar_t entryFollowMountPoints[ ] = { _T( "followMountPoints" ) }; + _Null_terminated_ const wchar_t entryFollowJunctionPoints[ ] = { _T( "followJunctionPoints" ) }; + _Null_terminated_ const wchar_t entryEnabled[ ] = { _T( "enabled" ) }; + _Null_terminated_ const wchar_t entryTitle[ ] = { _T( "title" ) }; + _Null_terminated_ const wchar_t entryWorksForDrives[ ] = { _T( "worksForDrives" ) }; + _Null_terminated_ const wchar_t entryWorksForDirectories[ ] = { _T( "worksForDirectories" ) }; + _Null_terminated_ const wchar_t entryWorksForFilesFolder[ ] = { _T( "worksForFilesFolder" ) }; + _Null_terminated_ const wchar_t entryWorksForFiles[ ] = { _T( "worksForFiles" ) }; + _Null_terminated_ const wchar_t entryWorksForUncPaths[ ] = { _T( "worksForUncPaths" ) }; + _Null_terminated_ const wchar_t entryCommandLine[ ] = { _T( "commandLine" ) }; + _Null_terminated_ const wchar_t entryRecurseIntoSubdirectories[ ] = { _T( "recurseIntoSubdirectories" ) }; + _Null_terminated_ const wchar_t entryAskForConfirmation[ ] = { _T( "askForConfirmation" ) }; + _Null_terminated_ const wchar_t entryShowConsoleWindow[ ] = { _T( "showConsoleWindow" ) }; + _Null_terminated_ const wchar_t entryWaitForCompletion[ ] = { _T( "waitForCompletion" ) }; + _Null_terminated_ const wchar_t entryRefreshPolicy[ ] = { _T( "refreshPolicy" ) }; + _Null_terminated_ const wchar_t entryMainWindowPlacement[ ] = { _T( "mainWindowPlacement" ) }; + + } + +namespace helpers { + std::wstring generalized_make_entry( _In_z_ const PCTSTR name, _In_z_ const PCTSTR entry_fmt_str ) { + //TODO: uses heap! + const auto chars_needed = ( _scwprintf( entry_fmt_str, name ) + 1 ); + std::unique_ptr<_Null_terminated_ wchar_t[]> char_buffer_ptr = std::make_unique( static_cast( chars_needed ) ); + + //This is so that the `Locals`/`Autos` window shows an actual string! + PWSTR buffer_ptr = char_buffer_ptr.get( ); + const HRESULT fmt_res_1 = StringCchPrintfW( buffer_ptr, static_cast( chars_needed ), entry_fmt_str, name ); + ASSERT( SUCCEEDED( fmt_res_1 ) ); + if ( SUCCEEDED( fmt_res_1 ) ) { + return std::wstring( buffer_ptr ); + } + if ( fmt_res_1 == STRSAFE_E_INSUFFICIENT_BUFFER ) { + const auto double_chars_needed = static_cast< size_t >( chars_needed ) * 2u; + char_buffer_ptr.reset( new wchar_t[ double_chars_needed ] ); + PWSTR double_buffer_ptr = char_buffer_ptr.get( ); + const HRESULT fmt_res_2 = StringCchPrintfW( double_buffer_ptr, double_chars_needed, entry_fmt_str, name ); + if ( SUCCEEDED( fmt_res_2 ) ) { + return std::wstring( double_buffer_ptr ); + } + } + displayWindowsMsgBoxWithMessage( L"generalized_make_entry failed to format the string! OutputDebugString has the name string. Will return empty string." ); + OutputDebugStringW( L"generalized_make_entry failed to format the string! OutputDebugString has the name string. Will return empty string.\r\n" ); + + return L""; + } + std::wstring MakeColumnOrderEntry( _In_z_ const PCTSTR name ) { + const auto ws_entry = generalized_make_entry( name, registry_strings::entryColumnOrderS ); + if ( ws_entry.empty( ) ) { + displayWindowsMsgBoxWithMessage( L"MakeColumnOrderEntry failed to format the string! OutputDebugString has the name string. Will return empty string." ); + OutputDebugStringW( L"MakeColumnOrderEntry failed to format the string! OutputDebugString has the name string. Will return empty string.\r\n" ); + } + return ws_entry; + } + std::wstring MakeColumnWidthsEntry( _In_z_ const PCTSTR name ) { + const auto ws_entry = generalized_make_entry( name, registry_strings::entryColumnWidthsS ); + if ( ws_entry.empty( ) ) { + displayWindowsMsgBoxWithMessage( L"entryColumnWidthsS failed to format the string! OutputDebugString has the name string. Will return empty string." ); + OutputDebugStringW( L"entryColumnWidthsS failed to format the string! OutputDebugString has the name string. Will return empty string.\r\n" ); + } + return ws_entry; + } + } + namespace { COptions _theOptions; - const PCTSTR sectionPersistence = _T( "persistence" ); - const PCTSTR entryShowFileTypes = _T( "showFileTypes" ); - const PCTSTR entryShowTreemap = _T( "showTreemap" ); - const PCTSTR entryShowStatusbar = _T( "showStatusbar" ); - const PCTSTR entryMainWindowPlacement = _T( "mainWindowPlacement" ); - const PCTSTR entrySplitterPosS = _T( "%s-splitterPos" ); - const PCTSTR entryColumnOrderS = _T( "%s-columnOrder" ); - const PCTSTR entryColumnWidthsS = _T( "%s-columnWidths" ); - const PCTSTR entryDialogRectangleS = _T( "%s-rectangle" ); - const PCTSTR entryConfigPage = _T( "configPage" ); - const PCTSTR entryConfigPositionX = _T( "configPositionX" ); - const PCTSTR entryConfigPositionY = _T( "configPositionY" ); - const PCTSTR entrySelectDrivesRadio = _T( "selectDrivesRadio" ); - const PCTSTR entrySelectDrivesFolder = _T( "selectDrivesFolder" ); - const PCTSTR entrySelectDrivesDrives = _T( "selectDrivesDrives" ); - const PCTSTR entryShowDeleteWarning = _T( "showDeleteWarning" ); - const PCTSTR sectionBarState = _T( "persistence\\barstate" ); - const PCTSTR sectionOptions = _T( "options" ); - const PCTSTR entryListGrid = _T( "treelistGrid" ); // for compatibility with 1.0.1, this entry is named treelistGrid. - const PCTSTR entryListStripes = _T( "listStripes" ); - const PCTSTR entryListFullRowSelection = _T( "listFullRowSelection" ); - const PCTSTR entryTreelistColorCount = _T( "treelistColorCount" ); - const PCTSTR entryTreelistColorN = _T( "treelistColor%d" ); - const PCTSTR entryHumanFormat = _T( "humanFormat" ); - const PCTSTR entryShowTimeSpent = _T( "showTimeSpent" ); - const PCTSTR entryTreemapHighlightColor = _T( "treemapHighlightColor" ); - const PCTSTR entryTreemapStyle = _T( "treemapStyle" ); - const PCTSTR entryTreemapGrid = _T( "treemapGrid" ); - const PCTSTR entryTreemapGridColor = _T( "treemapGridColor" ); - const PCTSTR entryBrightness = _T( "brightness" ); - const PCTSTR entryHeightFactor = _T( "heightFactor" ); - const PCTSTR entryScaleFactor = _T( "scaleFactor" ); - const PCTSTR entryAmbientLight = _T( "ambientLight" ); - const PCTSTR entryLightSourceX = _T( "lightSourceX" ); - const PCTSTR entryLightSourceY = _T( "lightSourceY" ); - const PCTSTR entryFollowMountPoints = _T( "followMountPoints" ); - const PCTSTR entryFollowJunctionPoints = _T( "followJunctionPoints" ); - const PCTSTR entryEnabled = _T( "enabled" ); - const PCTSTR entryTitle = _T( "title" ); - const PCTSTR entryWorksForDrives = _T( "worksForDrives" ); - const PCTSTR entryWorksForDirectories = _T( "worksForDirectories" ); - const PCTSTR entryWorksForFilesFolder = _T( "worksForFilesFolder" ); - const PCTSTR entryWorksForFiles = _T( "worksForFiles" ); - const PCTSTR entryWorksForUncPaths = _T( "worksForUncPaths" ); - const PCTSTR entryCommandLine = _T( "commandLine" ); - const PCTSTR entryRecurseIntoSubdirectories = _T( "recurseIntoSubdirectories" ); - const PCTSTR entryAskForConfirmation = _T( "askForConfirmation" ); - const PCTSTR entryShowConsoleWindow = _T( "showConsoleWindow" ); - const PCTSTR entryWaitForCompletion = _T( "waitForCompletion" ); - const PCTSTR entryRefreshPolicy = _T( "refreshPolicy" ); - - COLORREF treelistColorDefault[TREELISTCOLORCOUNT] = { + + + + + //const PCTSTR entryMainWindowPlacement = _T( "mainWindowPlacement" ); + //const PCTSTR entrySplitterPosS = _T( "%s-splitterPos" ); + //const PCTSTR entryColumnOrderS = _T( "%s-columnOrder" ); + //const PCTSTR entryColumnWidthsS = _T( "%s-columnWidths" ); + //const PCTSTR entryDialogRectangleS = _T( "%s-rectangle" ); + //const PCTSTR entryConfigPage = _T( "configPage" ); + //const PCTSTR entryConfigPositionX = _T( "configPositionX" ); + //const PCTSTR entryConfigPositionY = _T( "configPositionY" ); + //const PCTSTR entrySelectDrivesRadio = _T( "selectDrivesRadio" ); + //const PCTSTR entrySelectDrivesFolder = _T( "selectDrivesFolder" ); + //const PCTSTR entrySelectDrivesDrives = _T( "selectDrivesDrives" ); + //const PCTSTR entryShowDeleteWarning = _T( "showDeleteWarning" ); + //const PCTSTR sectionBarState = _T( "persistence\\barstate" ); + //const PCTSTR sectionOptions = _T( "options" ); + //const PCTSTR entryListGrid = _T( "treelistGrid" ); // for compatibility with 1.0.1, this entry is named treelistGrid. + //const PCTSTR entryListStripes = _T( "listStripes" ); + //const PCTSTR entryListFullRowSelection = _T( "listFullRowSelection" ); + //const PCTSTR entryTreelistColorCount = _T( "treelistColorCount" ); + //const PCTSTR entryTreelistColorN = _T( "treelistColor%d" ); + //const PCTSTR entryHumanFormat = _T( "humanFormat" ); + //const PCTSTR entryShowTimeSpent = _T( "showTimeSpent" ); + //const PCTSTR entryTreemapHighlightColor = _T( "treemapHighlightColor" ); + //const PCTSTR entryTreemapStyle = _T( "treemapStyle" ); + //const PCTSTR entryTreemapGrid = _T( "treemapGrid" ); + //const PCTSTR entryTreemapGridColor = _T( "treemapGridColor" ); + //const PCTSTR entryBrightness = _T( "brightness" ); + //const PCTSTR entryHeightFactor = _T( "heightFactor" ); + //const PCTSTR entryScaleFactor = _T( "scaleFactor" ); + //const PCTSTR entryAmbientLight = _T( "ambientLight" ); + //const PCTSTR entryLightSourceX = _T( "lightSourceX" ); + //const PCTSTR entryLightSourceY = _T( "lightSourceY" ); + //const PCTSTR entryFollowMountPoints = _T( "followMountPoints" ); + //const PCTSTR entryFollowJunctionPoints = _T( "followJunctionPoints" ); + //const PCTSTR entryEnabled = _T( "enabled" ); + //const PCTSTR entryTitle = _T( "title" ); + //const PCTSTR entryWorksForDrives = _T( "worksForDrives" ); + //const PCTSTR entryWorksForDirectories = _T( "worksForDirectories" ); + //const PCTSTR entryWorksForFilesFolder = _T( "worksForFilesFolder" ); + //const PCTSTR entryWorksForFiles = _T( "worksForFiles" ); + //const PCTSTR entryWorksForUncPaths = _T( "worksForUncPaths" ); + //const PCTSTR entryCommandLine = _T( "commandLine" ); + //const PCTSTR entryRecurseIntoSubdirectories = _T( "recurseIntoSubdirectories" ); + //const PCTSTR entryAskForConfirmation = _T( "askForConfirmation" ); + //const PCTSTR entryShowConsoleWindow = _T( "showConsoleWindow" ); + //const PCTSTR entryWaitForCompletion = _T( "waitForCompletion" ); + //const PCTSTR entryRefreshPolicy = _T( "refreshPolicy" ); + + const COLORREF treelistColorDefault[TREELISTCOLORCOUNT] = { RGB( 64, 64, 140 ), RGB( 140, 64, 64 ), RGB( 64, 140, 64 ), @@ -81,31 +178,52 @@ namespace { RGB( 255, 255, 0 ) }; - void SanifyRect( _Inout_ CRect& rc ) { + void SanifyRect( _Inout_ RECT& rc ) { const INT visible = 30; - rc.NormalizeRect( ); + //rc.NormalizeRect( ); + normalize_RECT( rc ); + + RECT rcDesktop_temp = { 0, 0, 0, 0 }; - CRect rcDesktop; - CWnd::GetDesktopWindow( )->GetWindowRect( rcDesktop ); + /* +_AFXWIN_INLINE CWnd* PASCAL CWnd::GetDesktopWindow() + { return CWnd::FromHandle(::GetDesktopWindow()); } - if ( rc.Width( ) > rcDesktop.Width( ) ) { - rc.right = rc.left + rcDesktop.Width( ); +_AFXWIN_INLINE void CWnd::GetWindowRect(LPRECT lpRect) const + { ASSERT(::IsWindow(m_hWnd)); ::GetWindowRect(m_hWnd, lpRect); } + + */ + const auto desktop_window = CWnd::FromHandle( ::GetDesktopWindow( ) ); + ASSERT( ::IsWindow( desktop_window->m_hWnd ) ); + + //If the function succeeds, the return value is nonzero. + VERIFY( ::GetWindowRect( desktop_window->m_hWnd, &rcDesktop_temp ) ); + + //CWnd::GetDesktopWindow( )->GetWindowRect( &rcDesktop_temp ); + + const RECT& rcDesktop = rcDesktop_temp; + + if ( ( rc.right - rc.left ) > ( rcDesktop.right - rcDesktop.left ) ) { + rc.right = rc.left + ( rcDesktop.right - rcDesktop.left ); } - if ( rc.Height( ) > rcDesktop.Height( ) ) { - rc.bottom = rc.top + rcDesktop.Height( ); + if ( ( rc.bottom - rc.top ) > ( rcDesktop.bottom - rcDesktop.top ) ) { + rc.bottom = rc.top + ( rcDesktop.bottom - rcDesktop.top ); } if ( rc.left < 0 ) { - rc.OffsetRect( -rc.left, 0 ); + VERIFY( ::OffsetRect( &rc, -( rc.left ), 0 ) ); } if ( rc.left > rcDesktop.right - visible ) { - rc.OffsetRect( -visible, 0 ); + VERIFY( ::OffsetRect( &rc, -( visible ), 0 ) ); + //rc.OffsetRect( -visible, 0 ); } if ( rc.top < 0 ) { - rc.OffsetRect( -rc.top, 0 ); + //rc.OffsetRect( -rc.top, 0 ); + VERIFY( ::OffsetRect( &rc, -( rc.top ), 0 ) ); } if ( rc.top > rcDesktop.bottom - visible ) { - rc.OffsetRect( 0, -visible ); + //rc.OffsetRect( 0, -visible ); + VERIFY( ::OffsetRect( &rc, 0, -( visible ) ) ); } } @@ -163,99 +281,62 @@ namespace { } } - std::wstring generalized_make_entry( _In_z_ const PCTSTR name, _In_z_ const PCTSTR entry_fmt_str ) { - const auto chars_needed = ( _scwprintf( entry_fmt_str, name ) + 1 ); - std::unique_ptr<_Null_terminated_ wchar_t[]> char_buffer_ptr = std::make_unique( static_cast( chars_needed ) ); - - //This is so that the `Locals`/`Autos` window shows an actual string! - PWSTR buffer_ptr = char_buffer_ptr.get( ); - const HRESULT fmt_res_1 = StringCchPrintfW( buffer_ptr, static_cast( chars_needed ), entry_fmt_str, name ); - ASSERT( SUCCEEDED( fmt_res_1 ) ); - if ( SUCCEEDED( fmt_res_1 ) ) { - return std::wstring( buffer_ptr ); - } - if ( fmt_res_1 == STRSAFE_E_INSUFFICIENT_BUFFER ) { - const auto double_chars_needed = static_cast< size_t >( chars_needed ) * 2u; - char_buffer_ptr.reset( new wchar_t[ double_chars_needed ] ); - PWSTR double_buffer_ptr = char_buffer_ptr.get( ); - const HRESULT fmt_res_2 = StringCchPrintfW( double_buffer_ptr, double_chars_needed, entry_fmt_str, name ); - if ( SUCCEEDED( fmt_res_2 ) ) { - return std::wstring( double_buffer_ptr ); - } - } - displayWindowsMsgBoxWithMessage( L"generalized_make_entry failed to format the string! OutputDebugString has the name string. Will return empty string." ); - OutputDebugStringW( name ); - - return L""; - } std::wstring MakeSplitterPosEntry( _In_z_ const PCTSTR name ) { - const auto ws_entry = generalized_make_entry( name, entrySplitterPosS ); + const auto ws_entry = helpers::generalized_make_entry( name, registry_strings::entrySplitterPosS ); if ( ws_entry.empty( ) ) { displayWindowsMsgBoxWithMessage( L"MakeSplitterPosEntry failed to format the string! OutputDebugString has the name string. Will return empty string." ); - OutputDebugStringW( name ); + OutputDebugStringW( L"MakeSplitterPosEntry failed to format the string! OutputDebugString has the name string. Will return empty string.\r\n" ); } return ws_entry; } - std::wstring MakeColumnOrderEntry( _In_z_ const PCTSTR name ) { - const auto ws_entry = generalized_make_entry( name, entryColumnOrderS ); - if ( ws_entry.empty( ) ) { - displayWindowsMsgBoxWithMessage( L"MakeColumnOrderEntry failed to format the string! OutputDebugString has the name string. Will return empty string." ); - OutputDebugStringW( name ); - } - return ws_entry; - } std::wstring MakeDialogRectangleEntry( _In_z_ const PCTSTR name ) { - const auto ws_entry = generalized_make_entry( name, entryDialogRectangleS ); + const auto ws_entry = helpers::generalized_make_entry( name, registry_strings::entryDialogRectangleS ); if ( ws_entry.empty( ) ) { displayWindowsMsgBoxWithMessage( L"MakeDialogRectangleEntry failed to format the string! OutputDebugString has the name string. Will return empty string." ); - OutputDebugStringW( name ); + OutputDebugStringW( L"MakeDialogRectangleEntry failed to format the string! OutputDebugString has the name string. Will return empty string.\r\n" ); } return ws_entry; } - std::wstring MakeColumnWidthsEntry( _In_z_ const PCTSTR name ) { - const auto ws_entry = generalized_make_entry( name, entryColumnWidthsS ); - if ( ws_entry.empty( ) ) { - displayWindowsMsgBoxWithMessage( L"entryColumnWidthsS failed to format the string! OutputDebugString has the name string. Will return empty string." ); - OutputDebugStringW( name ); - } - return ws_entry; - } + //std::wstring MakeColumnWidthsEntry( _In_z_ const PCTSTR name ) { + // const auto ws_entry = generalized_make_entry( name, registry_strings::entryColumnWidthsS ); + // if ( ws_entry.empty( ) ) { + // displayWindowsMsgBoxWithMessage( L"entryColumnWidthsS failed to format the string! OutputDebugString has the name string. Will return empty string." ); + // OutputDebugStringW( L"entryColumnWidthsS failed to format the string! OutputDebugString has the name string. Will return empty string.\r\n" ); + // } + // return ws_entry; + // } - void SetProfileString( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_z_ const PCTSTR value ) { - TRACE( _T( "Setting profile string\r\n\tsection: `%s`,\r\n\tentry: `%s`,\r\n\tvalue: `%s`\r\n" ), section, entry, value ); - VERIFY( AfxGetApp( )->WriteProfileStringW( section, entry, value ) ); - } } class CTreemap; -bool CPersistence::GetShowFileTypes( ) { - return CRegistryUser::GetProfileBool( sectionPersistence, entryShowFileTypes, true ); - } +//bool CPersistence::GetShowFileTypes( ) { +// return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowFileTypes, true ); +// } -bool CPersistence::GetShowTreemap( ) { - return CRegistryUser::GetProfileBool( sectionPersistence, entryShowTreemap, true ); - } +//bool CPersistence::GetShowTreemap( ) { +// return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowTreemap, true ); +// } -bool CPersistence::GetShowStatusbar( ) { - return CRegistryUser::GetProfileBool( sectionPersistence, entryShowStatusbar, true ); - } +//bool CPersistence::GetShowStatusbar( ) { +// return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowStatusbar, true ); +// } -void CPersistence::SetShowFileTypes( _In_ const bool show ) { - CRegistryUser::SetProfileBool( sectionPersistence, entryShowFileTypes, show ); - } +//void CPersistence::SetShowFileTypes( _In_ const bool show ) { +// CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowFileTypes, show ); +// } -void CPersistence::SetShowTreemap( _In_ const bool show ) { - CRegistryUser::SetProfileBool( sectionPersistence, entryShowTreemap, show ); - } +//void CPersistence::SetShowTreemap( _In_ const bool show ) { +// CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowTreemap, show ); +// } -void CPersistence::SetShowStatusbar( _In_ const bool show ) { - CRegistryUser::SetProfileBool( sectionPersistence, entryShowStatusbar, show ); - } +//void CPersistence::SetShowStatusbar( _In_ const bool show ) { +// CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowStatusbar, show ); +// } void CPersistence::GetMainWindowPlacement( _Out_ WINDOWPLACEMENT& wp ) { //ASSERT( wp.length == sizeof( wp ) ); @@ -263,10 +344,11 @@ void CPersistence::GetMainWindowPlacement( _Out_ WINDOWPLACEMENT& wp ) { //const DWORD prof_string_size = MAX_PATH; //wchar_t prof_string[ prof_string_size ] = { 0 }; - //const auto s_2 = CRegistryUser::CStyle_GetProfileString( prof_string, prof_string_size, sectionPersistence, entryMainWindowPlacement, _T( "" ) ); - const auto s = CRegistryUser::GetProfileString_( sectionPersistence, entryMainWindowPlacement, _T( "" ) ); + //const auto s_2 = CRegistryUser::CStyle_GetProfileString( prof_string, prof_string_size, registry_strings::sectionPersistence, entryMainWindowPlacement, _T( "" ) ); + const auto s = CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, registry_strings::entryMainWindowPlacement, _T( "" ) ); DecodeWindowPlacement( s.c_str( ), wp ); - CRect rect_to_sanify = wp.rcNormalPosition; + + RECT rect_to_sanify = wp.rcNormalPosition; SanifyRect( rect_to_sanify ); wp.rcNormalPosition = rect_to_sanify; //SanifyRect( ( CRect & ) wp.rcNormalPosition ); @@ -274,7 +356,7 @@ void CPersistence::GetMainWindowPlacement( _Out_ WINDOWPLACEMENT& wp ) { void CPersistence::SetMainWindowPlacement( _In_ const WINDOWPLACEMENT& wp ) { const auto s = EncodeWindowPlacement( wp ); - SetProfileString( sectionPersistence, entryMainWindowPlacement, s.c_str( ) ); + SetProfileString( registry_strings::sectionPersistence, registry_strings::entryMainWindowPlacement, s.c_str( ) ); } void CPersistence::SetSplitterPos( _In_z_ const PCTSTR name, _In_ const bool valid, _In_ const DOUBLE userpos ) { @@ -285,11 +367,11 @@ void CPersistence::SetSplitterPos( _In_z_ const PCTSTR name, _In_ const bool val else { pos = -1; } - CRegistryUser::SetProfileInt( sectionPersistence, MakeSplitterPosEntry( name ).c_str( ), pos ); + CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, MakeSplitterPosEntry( name ).c_str( ), pos ); } void CPersistence::GetSplitterPos( _In_z_ const PCTSTR name, _Inout_ bool& valid, _Inout_ DOUBLE& userpos ) { - const auto pos = CRegistryUser::GetProfileInt_( sectionPersistence, MakeSplitterPosEntry( name ).c_str( ), -1 ); + const auto pos = CRegistryUser::GetProfileInt_( registry_strings::sectionPersistence, MakeSplitterPosEntry( name ).c_str( ), -1 ); if ( pos > 100 ) { valid = false; userpos = 0.5; @@ -304,8 +386,8 @@ void CPersistence::GetSplitterPos( _In_z_ const PCTSTR name, _Inout_ bool& vali // } void CPersistence::GetDialogRectangle( _In_z_ const PCTSTR name, _Out_ RECT& rc ) { - GetRect( MakeDialogRectangleEntry( name ).c_str( ), rc ); - CRect temp( rc ); + GetRect( MakeDialogRectangleEntry( name ), rc ); + RECT temp = rc; SanifyRect( temp ); rc = temp; } @@ -318,93 +400,94 @@ void CPersistence::GetDialogRectangle( _In_z_ const PCTSTR name, _Out_ RECT& rc // SetArray( MakeColumnWidthsEntry( name ), arr ); // } -void CPersistence::SetColumnWidths( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { - SetArray( MakeColumnWidthsEntry( name ), arr, arrSize ); - } +//void CPersistence::SetColumnWidths( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { +// SetArray( MakeColumnWidthsEntry( name ), arr, arrSize ); +// } //void CPersistence::SetColumnOrder( _In_z_ const PCTSTR name, _In_ const CArray& arr ) { // SetArray( MakeColumnOrderEntry( name ), arr ); // } -void CPersistence::SetColumnOrder( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { - SetArray( MakeColumnOrderEntry( name ), arr, arrSize ); - } +//void CPersistence::SetColumnOrder( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { +// SetArray( MakeColumnOrderEntry( name ), arr, arrSize ); +// } void CPersistence::SetDialogRectangle( _In_z_ const PCTSTR name, _In_ const RECT rc ) { SetRect( MakeDialogRectangleEntry( name ).c_str( ), rc ); } -void CPersistence::GetColumnOrder( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { - GetArray( MakeColumnOrderEntry( name ), arr, arrSize ); - } +//void CPersistence::GetColumnOrder( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { +// GetArray( MakeColumnOrderEntry( name ), arr, arrSize ); +// } -void CPersistence::GetColumnWidths( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { - GetArray( MakeColumnWidthsEntry( name ), arr, arrSize ); - } + +//void CPersistence::GetColumnWidths( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { +// GetArray( MakeColumnWidthsEntry( name ), arr, arrSize ); +// } INT CPersistence::GetConfigPage( _In_ const INT max_val ) { /* changed max to max_val to avoid conflict in ASSERT macro*/ - auto n = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionPersistence, entryConfigPage, 0 ) ); + auto n = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionPersistence, registry_strings::entryConfigPage, 0 ) ); CheckMinMax( n, 0, max_val ); ASSERT( ( n >= 0 ) && ( n <= max_val ) ); return n; } -void CPersistence::SetConfigPage( _In_ const INT page ) { - CRegistryUser::SetProfileInt( sectionPersistence, entryConfigPage, page ); - } +//void CPersistence::SetConfigPage( _In_ const INT page ) { +// CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entryConfigPage, page ); +// } void CPersistence::GetConfigPosition( _Inout_ WTL::CPoint& pt ) { - pt.x = static_cast( CRegistryUser::GetProfileInt_( sectionPersistence, entryConfigPositionX, pt.x ) ); - pt.y = static_cast( CRegistryUser::GetProfileInt_( sectionPersistence, entryConfigPositionY, pt.y ) ); + pt.x = static_cast( CRegistryUser::GetProfileInt_( registry_strings::sectionPersistence, registry_strings::entryConfigPositionX, pt.x ) ); + pt.y = static_cast( CRegistryUser::GetProfileInt_( registry_strings::sectionPersistence, registry_strings::entryConfigPositionY, pt.y ) ); CRect rc { pt, WTL::CSize( 100, 100 ) }; SanifyRect( rc ); pt = rc.TopLeft( ); } -void CPersistence::SetConfigPosition( _In_ const WTL::CPoint pt ) { - CRegistryUser::SetProfileInt( sectionPersistence, entryConfigPositionX, pt.x ); - CRegistryUser::SetProfileInt( sectionPersistence, entryConfigPositionY, pt.y ); - } +//void CPersistence::SetConfigPosition( _In_ const WTL::CPoint pt ) { +// CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entryConfigPositionX, pt.x ); +// CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entryConfigPositionY, pt.y ); +// } -PCTSTR CPersistence::GetBarStateSection( ) { - return sectionBarState; - } +//PCTSTR CPersistence::GetBarStateSection( ) { +// return registry_strings::sectionBarState; +// } RADIO CPersistence::GetSelectDrivesRadio( ) { - auto radio = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionPersistence, entrySelectDrivesRadio, 0 ) ); + auto radio = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesRadio, 0 ) ); CheckMinMax( radio, 0, 2 ); ASSERT( ( radio >= 0 ) && ( radio <= 2 ) ); return static_cast( radio ); } -void CPersistence::SetSelectDrivesRadio( _In_ const INT radio ) { - CRegistryUser::SetProfileInt( sectionPersistence, entrySelectDrivesRadio, radio ); - } +//void CPersistence::SetSelectDrivesRadio( _In_ const INT radio ) { +// CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesRadio, radio ); +// } -std::wstring CPersistence::GetSelectDrivesFolder( ) { - return CRegistryUser::GetProfileString_( sectionPersistence, entrySelectDrivesFolder, _T( "" ) ); - } +//std::wstring CPersistence::GetSelectDrivesFolder( ) { +// return CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesFolder, _T( "" ) ); +// } //DWORD CPersistence::CStyle_GetSelectDrivesFolder( _Out_writes_z_( strSize ) _Pre_writable_size_( strSize ) _Post_readable_size_( return ) PWSTR psz_text, _In_ const DWORD strSize ) { -// return CRegistryUser::CStyle_GetProfileString( psz_text, strSize, sectionPersistence, entrySelectDrivesFolder, _T( "" ) ); +// return CRegistryUser::CStyle_GetProfileString( psz_text, strSize, registry_strings::sectionPersistence, entrySelectDrivesFolder, _T( "" ) ); // } -void CPersistence::SetSelectDrivesFolder( _In_z_ const PCTSTR folder ) { - SetProfileString( sectionPersistence, entrySelectDrivesFolder, folder ); - } +//void CPersistence::SetSelectDrivesFolder( _In_z_ const PCTSTR folder ) { +// SetProfileString( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesFolder, folder ); +// } void CPersistence::GetSelectDrivesDrives( _Inout_ std::vector& drives ) { drives.clear( ); - const auto s = CRegistryUser::GetProfileString_( sectionPersistence, entrySelectDrivesDrives, _T( "" ) ); + const auto s = CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesDrives, _T( "" ) ); //const DWORD select_buf_size = MAX_PATH; //wchar_t select_buf[ select_buf_size ] = { 0 }; - //const auto chars_written = CRegistryUser::CStyle_GetProfileString( select_buf, select_buf_size, sectionPersistence, entrySelectDrivesDrives, _T( "" ) ); + //const auto chars_written = CRegistryUser::CStyle_GetProfileString( select_buf, select_buf_size, registry_strings::sectionPersistence, entrySelectDrivesDrives, _T( "" ) ); rsize_t i = 0; while ( i < s.length( ) ) { std::wstring drive; @@ -431,16 +514,16 @@ void CPersistence::SetSelectDrivesDrives( _In_ const std::vector& } s += drives.at( i ); } - SetProfileString( sectionPersistence, entrySelectDrivesDrives, s.c_str( ) ); + SetProfileString( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesDrives, s.c_str( ) ); } -bool CPersistence::GetShowDeleteWarning( ) { - return CRegistryUser::GetProfileBool( sectionPersistence, entryShowDeleteWarning, true ); - } +//bool CPersistence::GetShowDeleteWarning( ) { +// return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowDeleteWarning, true ); +// } -void CPersistence::SetShowDeleteWarning( _In_ const bool show ) { - CRegistryUser::SetProfileBool( sectionPersistence, entryShowDeleteWarning, show ); - } +//void CPersistence::SetShowDeleteWarning( _In_ const bool show ) { +// CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowDeleteWarning, show ); +// } void CPersistence::SetArray( _In_ const std::wstring entry, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { @@ -469,11 +552,11 @@ void CPersistence::SetArray( _In_ const std::wstring entry, _Inout_ _Pre_writabl } value += int_buf; } - SetProfileString( sectionPersistence, entry.c_str( ), value.c_str( ) ); + SetProfileString( registry_strings::sectionPersistence, entry.c_str( ), value.c_str( ) ); } //void CPersistence::GetArray( _In_z_ const PCTSTR entry, _Inout_ CArray& rarr ) { -// const auto s = CRegistryUser::GetProfileString_( sectionPersistence, entry, _T( "" ) ); +// const auto s = CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, entry, _T( "" ) ); // CArray arr; // INT i = 0; // while ( i < s.GetLength( ) ) { @@ -507,7 +590,7 @@ void CPersistence::GetArray( _In_ const std::wstring entry, _Out_ _Pre_writable_ if ( entry.length( ) == 0 ) { return; } - const auto s_temp = CRegistryUser::GetProfileString_( sectionPersistence, entry.c_str( ), _T( "" ) ); + const auto s_temp = CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, entry.c_str( ), _T( "" ) ); //const DWORD arr_buf_size = MAX_PATH; rsize_t current_arr_index = 0; @@ -566,7 +649,7 @@ void CPersistence::SetRect( _In_z_ const PCTSTR entry, _In_ const RECT rc ) { const HRESULT fmt_res = StringCchPrintfW( buffer_rect, buffer_size, L"%d,%d,%d,%d", rc.left, rc.top, rc.right, rc.bottom ); if ( SUCCEEDED( fmt_res ) ) { //ASSERT( s.Compare( buffer_rect ) == 0 ); - SetProfileString( sectionPersistence, entry, buffer_rect ); + SetProfileString( registry_strings::sectionPersistence, entry, buffer_rect ); return; } std::wstring dynamic_format; @@ -577,18 +660,27 @@ void CPersistence::SetRect( _In_z_ const PCTSTR entry, _In_ const RECT rc ) { dynamic_format += std::to_wstring( rc.right ); dynamic_format += L','; dynamic_format += std::to_wstring( rc.bottom ); - SetProfileString( sectionPersistence, entry, dynamic_format.c_str( ) ); + SetProfileString( registry_strings::sectionPersistence, entry, dynamic_format.c_str( ) ); } //TODO: return by value? -void CPersistence::GetRect( _In_z_ const PCTSTR entry, _Inout_ RECT& rc ) { - CString s = CRegistryUser::GetProfileString_( sectionPersistence, entry, _T( "" ) ).c_str( ); +_Success_( SUCCEEDED( return ) ) +const HRESULT CPersistence::GetRect( _In_ const std::wstring entry, _Out_ RECT& rc ) { + //TODO: BUGBUG: `const auto s` here resolves type of s as `wchar_t*` + const std::wstring s = CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, entry.c_str( ), _T( "" ) ).c_str( ); RECT tmp; - const auto r = swscanf_s( s, _T( "%d,%d,%d,%d" ), &tmp.left, &tmp.top, &tmp.right, &tmp.bottom ); + const auto r = swscanf_s( s.c_str( ), _T( "%d,%d,%d,%d" ), &tmp.left, &tmp.top, &tmp.right, &tmp.bottom ); + static_assert( SUCCEEDED( S_OK ), "Bad success return value!" ); if ( r == 4 ) { + TRACE( _T( "swscanf_s succeeded! read in rectangle: %d,%d,%d,%d\r\n" ), tmp.left, tmp.top, tmp.right, tmp.bottom ); rc = tmp; + return S_OK; } + + static_assert( !SUCCEEDED( E_FAIL ), "Bad failure return value!" ); + TRACE( _T( "swscanf_s failed! entry: `%s`, source string: `%s`\r\n" ), entry.c_str( ), s.c_str( ) ); + return E_FAIL; } ///////////////////////////////////////////////////////////////////////////// @@ -634,11 +726,11 @@ void COptions::SetListFullRowSelection( _In_ const bool show ) { // return m_treelistColor[ i ]; // } -void COptions::SetHumanFormat( _In_ const bool human ) { +void COptions::SetHumanFormat( _In_ const bool human, CDirstatApp* app_ptr ) { if ( m_humanFormat != human ) { m_humanFormat = human; GetDocument( )->UpdateAllViews( NULL, UpdateAllViews_ENUM::HINT_NULL ); - GetApp( )->UpdateRamUsage( ); + app_ptr->UpdateRamUsage( ); } } @@ -669,27 +761,27 @@ void COptions::SetTreemapOptions( _In_ const Treemap_Options& options ) { } void COptions::SaveToRegistry( ) { - CRegistryUser::SetProfileBool( sectionOptions, entryListGrid, m_listGrid ); - CRegistryUser::SetProfileBool( sectionOptions, entryListStripes, m_listStripes ); - CRegistryUser::SetProfileBool( sectionOptions, entryListFullRowSelection, m_listFullRowSelection ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryListGrid, m_listGrid ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryListStripes, m_listStripes ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryListFullRowSelection, m_listFullRowSelection ); - CRegistryUser::SetProfileInt( sectionOptions, entryTreelistColorCount, static_cast( m_treelistColorCount ) ); + CRegistryUser::SetProfileInt( registry_strings::sectionOptions, registry_strings::entryTreelistColorCount, static_cast( m_treelistColorCount ) ); for ( INT i = 0; i < static_cast( TREELISTCOLORCOUNT ); i++ ) { //CString entry; //entry.Format( entryTreelistColorN, i ); std::wstring dyn_fmt_str( std::wstring( L"treelistColor" + std::to_wstring( i ) ) ); //ASSERT( dyn_fmt_str.compare( entry ) == 0 ); - CRegistryUser::SetProfileInt( sectionOptions, dyn_fmt_str.c_str( ), static_cast( m_treelistColor[ i ] ) ); + CRegistryUser::SetProfileInt( registry_strings::sectionOptions, dyn_fmt_str.c_str( ), static_cast( m_treelistColor[ i ] ) ); } - CRegistryUser::SetProfileBool( sectionOptions, entryHumanFormat, m_humanFormat ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryHumanFormat, m_humanFormat ); - CRegistryUser::SetProfileBool( sectionOptions, entryShowTimeSpent, m_showTimeSpent ); - CRegistryUser::SetProfileInt( sectionOptions, entryTreemapHighlightColor, static_cast( m_treemapHighlightColor ) ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryShowTimeSpent, m_showTimeSpent ); + CRegistryUser::SetProfileInt( registry_strings::sectionOptions, registry_strings::entryTreemapHighlightColor, static_cast( m_treemapHighlightColor ) ); SaveTreemapOptions( ); - CRegistryUser::SetProfileBool( sectionOptions, entryFollowMountPoints, m_followMountPoints ); - CRegistryUser::SetProfileBool( sectionOptions, entryFollowJunctionPoints, m_followJunctionPoints ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryFollowMountPoints, m_followMountPoints ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryFollowJunctionPoints, m_followJunctionPoints ); // We must distinguish between 'empty' and 'default'. 'Default' will read "", 'Empty' will read "$", Others will read "$text.." //const PCTSTR stringPrefix = _T( "$" ); @@ -697,31 +789,33 @@ void COptions::SaveToRegistry( ) { } void COptions::LoadFromRegistry( ) { - m_listGrid = CRegistryUser::GetProfileBool( sectionOptions, entryListGrid, false ); - m_listStripes = CRegistryUser::GetProfileBool( sectionOptions, entryListStripes, false ); - m_listFullRowSelection = CRegistryUser::GetProfileBool( sectionOptions, entryListFullRowSelection, true ); + m_listGrid = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryListGrid, false ); + m_listStripes = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryListStripes, false ); + m_listFullRowSelection = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryListFullRowSelection, true ); - m_treelistColorCount = static_cast( CRegistryUser::GetProfileInt_( sectionOptions, entryTreelistColorCount, 4 ) ); + m_treelistColorCount = static_cast( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryTreelistColorCount, 4 ) ); auto temp = static_cast< INT >( m_treelistColorCount ); - CRegistryUser::CheckRange( temp, 1, TREELISTCOLORCOUNT ); + //CRegistryUser::CheckRange( temp, 1, TREELISTCOLORCOUNT ); + CheckMinMax( temp, 1, TREELISTCOLORCOUNT ); m_treelistColorCount = static_cast( temp ); ASSERT( ( m_treelistColorCount >= 1 ) && ( m_treelistColorCount <= TREELISTCOLORCOUNT ) ); for ( INT i = 0; i < TREELISTCOLORCOUNT; i++ ) { //CString entry; //entry.Format( entryTreelistColorN, i ); + //TODO, uses heap! std::wstring dyn_fmt_str( std::wstring( L"treelistColor" + std::to_wstring( i ) ) ); - m_treelistColor[ i ] = CRegistryUser::GetProfileInt_( sectionOptions, dyn_fmt_str.c_str( ), static_cast( treelistColorDefault[ i ] ) ); + m_treelistColor[ i ] = CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, dyn_fmt_str.c_str( ), static_cast( treelistColorDefault[ i ] ) ); } - m_humanFormat = CRegistryUser::GetProfileBool( sectionOptions, entryHumanFormat, true ); + m_humanFormat = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryHumanFormat, true ); - m_showTimeSpent = CRegistryUser::GetProfileBool( sectionOptions, entryShowTimeSpent, false ); - m_treemapHighlightColor = CRegistryUser::GetProfileInt_( sectionOptions, entryTreemapHighlightColor, RGB( 255, 255, 255 ) ); + m_showTimeSpent = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryShowTimeSpent, false ); + m_treemapHighlightColor = CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryTreemapHighlightColor, RGB( 255, 255, 255 ) ); ReadTreemapOptions( ); - m_followMountPoints = CRegistryUser::GetProfileBool( sectionOptions, entryFollowMountPoints, false ); + m_followMountPoints = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryFollowMountPoints, false ); // Ignore junctions by default - m_followJunctionPoints = CRegistryUser::GetProfileBool( sectionOptions, entryFollowJunctionPoints, false ); + m_followJunctionPoints = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryFollowJunctionPoints, false ); } @@ -729,55 +823,79 @@ void COptions::LoadFromRegistry( ) { void COptions::ReadTreemapOptions( ) { Treemap_Options standard = _defaultOptions; static_assert( std::is_convertible< INT, std::underlying_type< decltype( standard.style ) >::type>::value, "" ); - auto style = CRegistryUser::GetProfileInt_( sectionOptions, entryTreemapStyle, static_cast( standard.style ) ); + auto style = CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryTreemapStyle, static_cast( standard.style ) ); if ( style != static_cast( Treemap_STYLE::KDirStatStyle ) && style != static_cast( Treemap_STYLE::SequoiaViewStyle ) ) { style = static_cast( Treemap_STYLE::KDirStatStyle ); } static_assert( std::is_convertible< decltype( style ), std::underlying_type< decltype( m_treemapOptions.style ) >::type>::value, "" ); m_treemapOptions.style = static_cast( style ); - m_treemapOptions.grid = CRegistryUser::GetProfileBool( sectionOptions, entryTreemapGrid, standard.grid ); + m_treemapOptions.grid = CRegistryUser::GetProfileBool( registry_strings::sectionOptions, registry_strings::entryTreemapGrid, standard.grid ); - m_treemapOptions.gridColor = CRegistryUser::GetProfileInt_( sectionOptions, entryTreemapGridColor, static_cast( standard.gridColor ) ); + m_treemapOptions.gridColor = CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryTreemapGridColor, static_cast( standard.gridColor ) ); - auto brightness = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionOptions, entryBrightness, standard.GetBrightnessPercent( ) ) ); + auto brightness = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryBrightness, standard.GetBrightnessPercent( ) ) ); CheckMinMax( brightness, 0, 100 ); m_treemapOptions.SetBrightnessPercent( brightness ); - auto height = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionOptions, entryHeightFactor, standard.GetHeightPercent( ) ) ); + auto height = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryHeightFactor, standard.GetHeightPercent( ) ) ); CheckMinMax( height, 0, 100 ); m_treemapOptions.SetHeightPercent( height ); - auto scaleFactor = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionOptions, entryScaleFactor, standard.GetScaleFactorPercent( ) ) ); + auto scaleFactor = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryScaleFactor, standard.GetScaleFactorPercent( ) ) ); CheckMinMax( scaleFactor, 0, 100 ); m_treemapOptions.SetScaleFactorPercent( scaleFactor ); - auto ambientLight = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionOptions, entryAmbientLight, standard.GetAmbientLightPercent( ) ) ); + auto ambientLight = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryAmbientLight, standard.GetAmbientLightPercent( ) ) ); CheckMinMax( ambientLight, 0, 100 ); m_treemapOptions.SetAmbientLightPercent( ambientLight ); - auto lightSourceX = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionOptions, entryLightSourceX, standard.GetLightSourceXPercent( ) ) ); + auto lightSourceX = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryLightSourceX, standard.GetLightSourceXPercent( ) ) ); CheckMinMax( lightSourceX, -200, 200 ); m_treemapOptions.SetLightSourceXPercent( lightSourceX ); - auto lightSourceY = static_cast< INT >( CRegistryUser::GetProfileInt_( sectionOptions, entryLightSourceY, standard.GetLightSourceYPercent( ) ) ); + auto lightSourceY = static_cast< INT >( CRegistryUser::GetProfileInt_( registry_strings::sectionOptions, registry_strings::entryLightSourceY, standard.GetLightSourceYPercent( ) ) ); CheckMinMax( lightSourceY, -200, 200 ); m_treemapOptions.SetLightSourceYPercent( lightSourceY ); } void COptions::SaveTreemapOptions( ) { - CRegistryUser::SetProfileInt ( sectionOptions, entryTreemapStyle, static_cast( m_treemapOptions.style ) ); - CRegistryUser::SetProfileBool( sectionOptions, entryTreemapGrid, m_treemapOptions.grid ); - CRegistryUser::SetProfileInt ( sectionOptions, entryTreemapGridColor, static_cast( m_treemapOptions.gridColor ) ); - CRegistryUser::SetProfileInt ( sectionOptions, entryBrightness, m_treemapOptions.GetBrightnessPercent( ) ); - CRegistryUser::SetProfileInt ( sectionOptions, entryHeightFactor, m_treemapOptions.GetHeightPercent( ) ); - CRegistryUser::SetProfileInt ( sectionOptions, entryScaleFactor, m_treemapOptions.GetScaleFactorPercent( ) ); - CRegistryUser::SetProfileInt ( sectionOptions, entryAmbientLight, m_treemapOptions.GetAmbientLightPercent( ) ); - CRegistryUser::SetProfileInt ( sectionOptions, entryLightSourceX, m_treemapOptions.GetLightSourceXPercent( ) ); - CRegistryUser::SetProfileInt ( sectionOptions, entryLightSourceY, m_treemapOptions.GetLightSourceYPercent( ) ); - } - -std::wstring CRegistryUser::GetProfileString_( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_z_ const PCTSTR defaultValue ) { + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryTreemapStyle, static_cast( m_treemapOptions.style ) ); + CRegistryUser::SetProfileBool( registry_strings::sectionOptions, registry_strings::entryTreemapGrid, m_treemapOptions.grid ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryTreemapGridColor, static_cast( m_treemapOptions.gridColor ) ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryBrightness, m_treemapOptions.GetBrightnessPercent( ) ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryHeightFactor, m_treemapOptions.GetHeightPercent( ) ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryScaleFactor, m_treemapOptions.GetScaleFactorPercent( ) ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryAmbientLight, m_treemapOptions.GetAmbientLightPercent( ) ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryLightSourceX, m_treemapOptions.GetLightSourceXPercent( ) ); + CRegistryUser::SetProfileInt ( registry_strings::sectionOptions, registry_strings::entryLightSourceY, m_treemapOptions.GetLightSourceYPercent( ) ); + } + +std::wstring CRegistryUser::GetProfileString_( _In_z_ const PCWSTR section, _In_z_ const PCWSTR entry, _In_z_ const PCWSTR defaultValue ) { + + //const PCWSTR reg_key_str = GetApp( )->m_pszRegistryKey; + const HKEY reg_sec_key = GetApp( )->GetSectionKey( section ); + _Const_ DWORD dwType = REG_SZ; + const rsize_t buffer_size = 512u; + BYTE registry_data_buffer[ buffer_size ] = { 0 }; + static_assert( sizeof( registry_data_buffer ) == ( sizeof( BYTE ) * buffer_size ), "" ); + DWORD buffer_size_byte_count = sizeof( registry_data_buffer ); + const LONG query_res = ::RegQueryValueExW( reg_sec_key, entry, NULL, &dwType, registry_data_buffer, &buffer_size_byte_count ); + + if ( query_res == ERROR_SUCCESS ) { + ASSERT( ( wcslen( reinterpret_cast( registry_data_buffer ) ) + 1 ) == ( buffer_size_byte_count / sizeof( wchar_t ) ) ); + + //yeah, this is actually twice as big as the buffer size needed, but who cares? + _Null_terminated_ wchar_t reg_data_buffer[ buffer_size ] = { 0 }; + std::memcpy( reg_data_buffer, registry_data_buffer, buffer_size_byte_count ); + //_CrtDbgBreak( ); +#ifdef DEBUG + const std::wstring normal_res( AfxGetApp( )->GetProfileStringW( section, entry, defaultValue ).GetString( ) ); + ASSERT( normal_res.compare( reg_data_buffer ) == 0 ); +#endif + return std::wstring( reg_data_buffer ); + } + TRACE( _T( "C-Style GetProfileString failed!\r\n" ) ); return std::wstring( AfxGetApp( )->GetProfileStringW( section, entry, defaultValue ).GetString( ) ); } @@ -804,24 +922,25 @@ UINT CRegistryUser::GetProfileInt_( _In_z_ const PCTSTR section, _In_z_ const PC } void CRegistryUser::SetProfileBool( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_ const bool value ) { - SetProfileInt( section, entry, ( INT ) value ); + const BOOL value_to_set = ( ( value ) ? TRUE : FALSE ); + SetProfileInt( section, entry, value_to_set ); } bool CRegistryUser::GetProfileBool( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_ const bool defaultValue ) { return GetProfileInt_( section, entry, defaultValue ) != 0; } -void CRegistryUser::CheckRange( _Inout_ INT& value, _In_ const INT min_val, _In_ const INT max_val ) { - /*changed min and max to min_val and max_val to avoid name collision (with min() & max()) in ASSERT macro*/ - ASSERT( min_val < max_val ); - if ( value < min_val ) { - value = min_val; - } - if ( value > max_val ) { - value = max_val; - } - ASSERT( ( value >= min_val ) && ( value <= max_val ) ); - } +//void CRegistryUser::CheckRange( _Inout_ INT& value, _In_ const INT min_val, _In_ const INT max_val ) { +// /*changed min and max to min_val and max_val to avoid name collision (with min() & max()) in ASSERT macro*/ +// ASSERT( min_val < max_val ); +// if ( value < min_val ) { +// value = min_val; +// } +// if ( value > max_val ) { +// value = max_val; +// } +// ASSERT( ( value >= min_val ) && ( value <= max_val ) ); +// } #else diff --git a/WinDirStat/windirstat/options.h b/WinDirStat/windirstat/options.h index 0f6c895..a182d15 100644 --- a/WinDirStat/windirstat/options.h +++ b/WinDirStat/windirstat/options.h @@ -9,40 +9,66 @@ #ifndef WDS_OPTIONS_H #define WDS_OPTIONS_H +struct COptions; +class CDirstatApp; + + +namespace registry_strings { + _Null_terminated_ const wchar_t sectionPersistence[ ] = { _T( "persistence" ) }; + _Null_terminated_ const wchar_t entryShowFileTypes[ ] = { _T( "showFileTypes" ) }; + _Null_terminated_ const wchar_t entryShowStatusbar[ ] = { _T( "showStatusbar" ) }; + _Null_terminated_ const wchar_t entryShowTreemap[ ] = { _T( "showTreemap" ) }; + _Null_terminated_ const wchar_t sectionBarState[ ] = { _T( "persistence\\barstate" ) }; + _Null_terminated_ const wchar_t entryConfigPositionX[ ] = { _T( "configPositionX" ) }; + _Null_terminated_ const wchar_t entryConfigPositionY[ ] = { _T( "configPositionY" ) }; + _Null_terminated_ const wchar_t entryConfigPage[ ] = { _T( "configPage" ) }; + _Null_terminated_ const wchar_t entrySelectDrivesFolder[ ] = { _T( "selectDrivesFolder" ) }; + _Null_terminated_ const wchar_t entrySelectDrivesRadio[ ] = { _T( "selectDrivesRadio" ) }; + _Null_terminated_ const wchar_t entryShowDeleteWarning[ ] = { _T( "showDeleteWarning" ) }; + _Null_terminated_ const wchar_t entryColumnWidthsS[ ] = { _T( "%s-columnWidths" ) }; + } + +namespace helpers { + std::wstring generalized_make_entry( _In_z_ const PCTSTR name, _In_z_ const PCTSTR entry_fmt_str ); + std::wstring MakeColumnOrderEntry( _In_z_ const PCTSTR name ); + std::wstring MakeColumnWidthsEntry( _In_z_ const PCTSTR name ); + } + +namespace { + + + + void SetProfileString( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_z_ const PCTSTR value ) { + TRACE( _T( "Setting profile string\r\n\tsection: `%s`,\r\n\tentry: `%s`,\r\n\tvalue: `%s`\r\n" ), section, entry, value ); + VERIFY( AfxGetApp( )->WriteProfileStringW( section, entry, value ) ); + } + } -struct COptions; - // CRegistryUser. (Base class for COptions and CPersistence.) // Can read from and write to the registry. namespace CRegistryUser { - std::wstring GetProfileString_ ( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_z_ const PCTSTR defaultValue ); + std::wstring GetProfileString_ ( _In_z_ const PCWSTR section, _In_z_ const PCWSTR entry, _In_z_ const PCWSTR defaultValue ); UINT GetProfileInt_ ( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_ const INT defaultValue ); bool GetProfileBool ( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_ const bool defaultValue ); void SetProfileInt ( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_ const INT value ); void SetProfileBool ( _In_z_ const PCTSTR section, _In_z_ const PCTSTR entry, _In_ const bool value ); - void CheckRange ( _Inout_ INT& value, _In_ const INT min, _In_ const INT max ); - - //DWORD CStyle_GetProfileString( _Out_writes_z_( strSize ) _Pre_writable_size_( strSize ) _Post_readable_size_( return ) PWSTR psz_text, _In_ const DWORD strSize, _In_z_ const PCWSTR section, _In_z_ const PCWSTR entry, _In_z_ const PCWSTR defaultValue ); - + //void CheckRange ( _Inout_ INT& value, _In_ const INT min, _In_ const INT max ); }; // CPersistence. Reads from and writes to the registry all the persistent settings like window position, column order etc. class CPersistence { public: - static void SetConfigPage ( _In_ const INT page ); - static void SetConfigPosition ( _In_ const WTL::CPoint pt ); + + static void SetDialogRectangle ( _In_z_ const PCTSTR name, _In_ const RECT rc ); static void SetMainWindowPlacement ( _In_ const WINDOWPLACEMENT& wp ); static void SetSelectDrivesDrives ( _In_ const std::vector& drives ); - static void SetSelectDrivesFolder ( _In_z_ const PCTSTR folder ); - static void SetSelectDrivesRadio ( _In_ const INT radio ); - static void SetShowDeleteWarning ( _In_ const bool show ); - static void SetShowFileTypes ( _In_ const bool show ); - static void SetShowStatusbar ( _In_ const bool show ); - static void SetShowTreemap ( _In_ const bool show ); + + + static void SetSplitterPos ( _In_z_ const PCTSTR name, _In_ const bool valid, _In_ const DOUBLE userpos ); static void GetConfigPosition ( _Inout_ WTL::CPoint& pt ); @@ -51,29 +77,93 @@ class CPersistence { static void GetMainWindowPlacement ( _Out_ WINDOWPLACEMENT& wp ); static void GetSelectDrivesDrives ( _Inout_ std::vector& drives ); static INT GetConfigPage ( _In_ const INT max ); - static bool GetShowDeleteWarning ( ); - static bool GetShowFileTypes ( ); - static bool GetShowStatusbar ( ); - static bool GetShowTreemap ( ); + + + static void SetShowDeleteWarning( _In_ const bool show ) { + CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowDeleteWarning, show ); + } + + static bool GetShowDeleteWarning( ) { + return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowDeleteWarning, true ); + } + + static RADIO GetSelectDrivesRadio ( ); + + static void SetSelectDrivesRadio( _In_ const INT radio ) { + CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesRadio, radio ); + } + + + static void SetConfigPage( _In_ const INT page ) { + CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entryConfigPage, page ); + } + + + static void SetSelectDrivesFolder( _In_z_ const PCTSTR folder ) { + SetProfileString( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesFolder, folder ); + } + + static void SetConfigPosition( _In_ const WTL::CPoint pt ) { + CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entryConfigPositionX, pt.x ); + CRegistryUser::SetProfileInt( registry_strings::sectionPersistence, registry_strings::entryConfigPositionY, pt.y ); + } + + static void SetShowFileTypes( _In_ const bool show ) { + CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowFileTypes, show ); + } + static void SetShowStatusbar( _In_ const bool show ) { + CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowStatusbar, show ); + } + static void SetShowTreemap( _In_ const bool show ) { + CRegistryUser::SetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowTreemap, show ); + } + + static bool GetShowFileTypes( ) { + return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowFileTypes, true ); + } + static bool GetShowStatusbar( ) { + return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowStatusbar, true ); + } + static bool GetShowTreemap( ) { + return CRegistryUser::GetProfileBool( registry_strings::sectionPersistence, registry_strings::entryShowTreemap, true ); + } + + //static DWORD CStyle_GetSelectDrivesFolder( _Out_writes_z_( strSize ) _Pre_writable_size_( strSize ) _Post_readable_size_( return ) PWSTR psz_text, _In_ const DWORD strSize ); - static std::wstring GetSelectDrivesFolder ( ); + static std::wstring GetSelectDrivesFolder( ) { + return CRegistryUser::GetProfileString_( registry_strings::sectionPersistence, registry_strings::entrySelectDrivesFolder, _T( "" ) ); + } - static PCTSTR GetBarStateSection ( ); + static PCTSTR GetBarStateSection( ) { + return registry_strings::sectionBarState; + } - static void SetColumnWidths ( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ); - static void SetColumnOrder ( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ); + static void SetColumnWidths( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { + SetArray( helpers::MakeColumnWidthsEntry( name ), arr, arrSize ); + } - static void GetColumnOrder ( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ); - static void GetColumnWidths ( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ); + static void SetColumnOrder( _In_z_ const PCTSTR name, _Inout_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { + SetArray( helpers::MakeColumnOrderEntry( name ), arr, arrSize ); + } + + static void GetColumnOrder( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { + GetArray( helpers::MakeColumnOrderEntry( name ), arr, arrSize ); + } + + + static void GetColumnWidths( _In_z_ const PCTSTR name, _Out_ _Pre_writable_size_( arrSize ) INT* arr, const rsize_t arrSize ) { + GetArray( helpers::MakeColumnWidthsEntry( name ), arr, arrSize ); + } private: _Pre_satisfies_( arrSize > 1 ) static void GetArray ( _In_ const std::wstring entry, _Out_ _Pre_writable_size_( arrSize ) INT* arr_, const rsize_t arrSize ); - static void GetRect ( _In_z_ const PCTSTR entry, _Inout_ RECT& rc ); + _Success_( SUCCEEDED( return ) ) + static const HRESULT GetRect ( _In_ const std::wstring entry, _Out_ RECT& rc ); static void SetRect ( _In_z_ const PCTSTR entry, _In_ const RECT rc ); @@ -88,7 +178,7 @@ _Success_( return != NULL ) COptions *GetOptions(); struct COptions { COptions( ) = default; - void SetHumanFormat ( _In_ const bool human ); + void SetHumanFormat ( _In_ const bool human, CDirstatApp* app_ptr ); void SetListFullRowSelection ( _In_ const bool show ); void SetListGrid ( _In_ const bool show ); void SetListStripes ( _In_ const bool show ); diff --git a/WinDirStat/windirstat/ownerdrawnlistcontrol.h b/WinDirStat/windirstat/ownerdrawnlistcontrol.h index b9b6bf7..ef0fd57 100644 --- a/WinDirStat/windirstat/ownerdrawnlistcontrol.h +++ b/WinDirStat/windirstat/ownerdrawnlistcontrol.h @@ -114,9 +114,9 @@ class COwnerDrawnListItem { ASSERT( subitem != column::COL_NAME ); if ( subitem == column::COL_NAME ) { displayWindowsMsgBoxWithMessage( L"GetText_WriteToStackBuffer was called for column::COL_NAME!!! This should never happen!!!!" ); - if ( IsDebuggerPresent( ) ) { - _CrtDbgBreak( ); - } + //if ( IsDebuggerPresent( ) ) { + //_CrtDbgBreak( ); + //} std::terminate( ); } @@ -656,7 +656,7 @@ class COwnerDrawnListCtrl : public CListCtrl { } _Success_( return != -1 ) _Ret_range_( 0, INT_MAX ) - INT FindListItem( _In_ const COwnerDrawnListItem* const item ) const { + INT FindListItem( _In_ const COwnerDrawnListItem* const item ) const { auto fi = zero_init_struct( ); fi.flags = LVFI_PARAM; @@ -1143,11 +1143,6 @@ class COwnerDrawnListCtrl : public CListCtrl { //store item width in some sort of cache? //BUGBUG: this is an extremely slow way of doing this! if ( item->DrawSubitem_( subitem, dc, rc, 0, &width, &dummy, const_cast< COwnerDrawnListCtrl* >( this ) ) ) { - if ( subitem == column::COL_NAME ) { - //const auto predicted_str_width = ( GetStringWidth( item->m_name.get( ) ) + static_cast< int >( GENERAL_INDENT ) +static_cast< int >( LABEL_INFLATE_CX ) +2 ); - //ASSERT( width == predicted_str_width ); - } - return width; } diff --git a/WinDirStat/windirstat/stdafx.h b/WinDirStat/windirstat/stdafx.h index 26ee0ca..6b10202 100644 --- a/WinDirStat/windirstat/stdafx.h +++ b/WinDirStat/windirstat/stdafx.h @@ -75,7 +75,6 @@ static_assert( _WIN32_WINNT >= 0x0600, "" ); //#define DUMP_MEMUSAGE //#define GRAPH_LAYOUT_DEBUG //#define EXTENSION_LIST_DEBUG -//#define PERF_DEBUG_SLEEP #define COLOR_DEBUGGING //#define SIMD_ACCESS_DEBUGGING //#define WDS_STRING_ALLOC_DEBUGGING diff --git a/WinDirStat/windirstat/treemap.cpp b/WinDirStat/windirstat/treemap.cpp index 0f0d609..0daacd6 100644 --- a/WinDirStat/windirstat/treemap.cpp +++ b/WinDirStat/windirstat/treemap.cpp @@ -246,15 +246,12 @@ namespace { //passing by reference: `cmp r14, QWORD PTR [r12]` for `if ( ( i + 1 ) < rowEnd )`, inline const std::uint64_t if_i_plus_one_less_than_rowEnd( _In_ const size_t rowEnd, _In_ const size_t i, _Inout_ std::map& sizes, _In_ const std::vector& parent_vector_of_children ) { - std::uint64_t childAtIPlusOne_size = 0; if ( ( i + 1 ) >= rowEnd ) { - return childAtIPlusOne_size; + return 0; } - //if ( ( i + 1 ) < rowEnd ) { - // } const auto childAtIPlusOne = static_cast< CItemBranch* >( parent_vector_of_children[ i + 1 ] ); if ( childAtIPlusOne == NULL ) { - return childAtIPlusOne_size; + return 0; } if ( sizes.count( i + 1 ) == 0 ) { const auto recurse_size = childAtIPlusOne->size_recurse( ); @@ -263,9 +260,10 @@ namespace { //return childAtIPlusOne_size; return recurse_size; } - childAtIPlusOne_size = sizes[ i + 1 ]; - - return childAtIPlusOne_size; + //std::uint64_t childAtIPlusOne_size = 0; + //childAtIPlusOne_size = sizes[ i + 1 ]; + //ASSERT( childAtIPlusOne_size == childAtIPlusOne->size_recurse( ) ); + return childAtIPlusOne->size_recurse( ); } #ifdef DEBUG @@ -301,11 +299,15 @@ namespace { return widthOfRow; } - inline const std::uint64_t max_size_of_children_in_row( _In_ const std::map& sizes, _In_ const size_t rowBegin ) { + inline const std::uint64_t max_size_of_children_in_row( _In_ const std::map& sizes, _In_ const size_t rowBegin, _In_ const std::vector& vector_o_children ) { #ifdef GRAPH_LAYOUT_DEBUG TRACE( _T( "sizes[ rowBegin ]: %llu\r\n" ), sizes.at( rowBegin ) ); TRACE( _T( "maximumSizeOfChildrenInRow: %llu\r\n" ), maximumSizeOfChildrenInRow ); #endif +#ifndef DEBUG + UNREFERENCED_PARAMETER( vector_o_children ); +#endif + ASSERT( vector_o_children.at( rowBegin )->size_recurse_( ) == sizes.at( rowBegin ) ); return sizes.at( rowBegin ); } @@ -964,8 +966,6 @@ void CTreemap::KDS_DrawChildren( _In_ CDC& pdc, _In_ const CItemBranch* const pa ASSERT( parent->m_childCount > 0 ); - - //TODO: why is this a CRect& and not a CRect? const CRect rc = CRect( parent->TmiGetRectangle( ) ); std::vector rows; // Our rectangle is divided into rows, each of which gets this height (fraction of total height). @@ -1201,10 +1201,11 @@ void CTreemap::SQV_DrawChildren( _In_ CDC& pdc, _In_ const CItemBranch* const pa // Worst ratio so far double worst = DBL_MAX; + //TODO: BUGBUG: DO NOT USE std::map, it's slow as shit. auto sizes = std::map( ); sizes[ rowBegin ] = parent_vector_of_children.at( rowBegin )->size_recurse_( ); - const auto maximumSizeOfChildrenInRow = max_size_of_children_in_row( sizes, rowBegin ); + const auto maximumSizeOfChildrenInRow = max_size_of_children_in_row( sizes, rowBegin, parent_vector_of_children ); // Sum of sizes of children in row std::uint64_t sumOfSizesOfChildrenInRow = 0; diff --git a/WinDirStat/windirstat/typeview.cpp b/WinDirStat/windirstat/typeview.cpp index 51b97d9..11d5b2e 100644 --- a/WinDirStat/windirstat/typeview.cpp +++ b/WinDirStat/windirstat/typeview.cpp @@ -29,7 +29,9 @@ #pragma warning(suppress:4355) -CTypeView::CTypeView( ) : m_extensionListControl( this ), m_showTypes( true ) { } +CTypeView::CTypeView( ) : m_extensionListControl( this ), m_showTypes( true ) { + m_showTypes = CPersistence::GetShowFileTypes( ); + } //CTypeView::~CTypeView( ) { } @@ -40,6 +42,7 @@ bool CListItem::DrawSubitem( RANGE_ENUM_COL const column::ENUM_COL subitem, _In_ if ( subitem == column::COL_EXTENSION ) { ASSERT( list == m_list ); UNREFERENCED_PARAMETER( list ); + //ASSERT( width != NULL ); DrawLabel( m_list, pdc, rc, state, width, focusLeft, true ); return true; } @@ -338,11 +341,6 @@ void CExtensionListControl::SetExtensionData( _In_ const std::vector( ext_data_size + 1 ) ); TRACE( _T( "Built buffer of extension records, inserting....\r\n" ) ); - -#ifdef PERF_DEBUG_SLEEP - Sleep( 1000 ); -#endif - SetRedraw( FALSE ); const auto local_m_exts = m_exts.get( ); @@ -420,7 +418,6 @@ void CExtensionListControl::MeasureItem( PMEASUREITEMSTRUCT mis ) { void CExtensionListControl::OnSetFocus( CWnd* pOldWnd ) { COwnerDrawnListCtrl::OnSetFocus( pOldWnd ); - ASSERT( GetMainFrame( ) == m_frameptr ); m_frameptr->SetLogicalFocus( LOGICAL_FOCUS::LF_EXTENSIONLIST ); } @@ -434,7 +431,6 @@ void CExtensionListControl::OnLvnItemchanged( NMHDR *pNMHDR, LRESULT *pResult ) void CExtensionListControl::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ) { if ( nChar == VK_TAB ) { - ASSERT( GetMainFrame( ) == m_frameptr ); if ( m_frameptr->GetDirstatView( ) != NULL ) { TRACE( _T( "TAB pressed! Focusing on directory list!\r\n" ) ); m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_DIRECTORYLIST ); @@ -445,7 +441,6 @@ void CExtensionListControl::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ) { } } else if ( nChar == VK_ESCAPE ) { - ASSERT( GetMainFrame( ) == m_frameptr ); TRACE( _T( "ESCAPE pressed! Null focus!\r\n" ) ); m_frameptr->MoveFocus( LOGICAL_FOCUS::LF_NONE ); } @@ -502,15 +497,9 @@ void CTypeView::OnUpdate0( ) { if ( theDocument != NULL ) { if ( m_showTypes && theDocument->IsRootDone( ) ) { m_extensionListControl.m_rootSize = theDocument->m_rootItem->size_recurse( ); -#ifdef PERF_DEBUG_SLEEP - Sleep( 1000 ); -#endif TRACE( _T( "Populating extension list...\r\n" ) ); m_extensionListControl.SetExtensionData( theDocument->GetExtensionRecords( ) ); TRACE( _T( "Finished populating extension list...\r\n" ) ); -#ifdef PERF_DEBUG_SLEEP - Sleep( 1000 ); -#endif // If there is no vertical scroll bar, the header control doesn't repaint correctly. Don't know why. But this helps: m_extensionListControl.GetHeaderCtrl( )->InvalidateRect( NULL ); } @@ -622,8 +611,12 @@ void CTypeView::OnSetFocus( CWnd* pOldWnd ) { void CTypeView::OnSize( UINT nType, INT cx, INT cy ) { CView::OnSize(nType, cx, cy); if ( IsWindow( m_extensionListControl.m_hWnd ) ) { - CRect rc( 0, 0, cx, cy ); - m_extensionListControl.MoveWindow( rc ); + const RECT rc = { 0, 0, cx, cy }; + + ASSERT( ::IsWindow( m_hWnd ) ); + + //If [MoveWindow] succeeds, the return value is nonzero. + VERIFY( ::MoveWindow( m_extensionListControl.m_hWnd, rc.left, rc.top, ( rc.right - rc.left ), ( rc.bottom - rc.top ), TRUE ) ); } } diff --git a/WinDirStat/windirstat/windirstat.cpp b/WinDirStat/windirstat/windirstat.cpp index a69f942..df1455b 100644 --- a/WinDirStat/windirstat/windirstat.cpp +++ b/WinDirStat/windirstat/windirstat.cpp @@ -297,8 +297,10 @@ BOOL CDirstatApp::InitInstance( ) { //Program entry point TRACE( _T( "------>Program entry point!<------\r\n" ) ); - enable_heap_security_crash_on_corruption( ); - enable_aggressive_process_mitigations( ); + if ( IsWindows8OrGreater( ) ) { + enable_heap_security_crash_on_corruption( ); + enable_aggressive_process_mitigations( ); + } //uses ~29K memory if ( !SUCCEEDED( CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) ) ) { @@ -339,12 +341,17 @@ BOOL CDirstatApp::InitInstance( ) { ParseCommandLine( cmdInfo ); m_nCmdShow = SW_HIDE; - + + if ( !ProcessShellCommand( cmdInfo ) ) { return FALSE; } - GetMainFrame( )->InitialShowWindow( ); + m_frameptr = GetMainFrame( ); + m_frameptr->m_appptr = this; + + + m_frameptr->InitialShowWindow( ); m_pMainWnd->UpdateWindow( ); // When called by setup.exe, windirstat remained in the background, so we do a @@ -393,7 +400,7 @@ BOOL CDirstatApp::OnIdle( _In_ LONG lCount ) { if ( ramDiff > RAM_USAGE_UPDATE_INTERVAL ) { more = CWinApp::OnIdle( lCount ); if ( !more ) { - GetApp( )->PeriodicalUpdateRamUsage( ); + PeriodicalUpdateRamUsage( ); } else { more = CWinThread::OnIdle( 0 ); diff --git a/WinDirStat/windirstat/windirstat.h b/WinDirStat/windirstat/windirstat.h index 002d37a..99c0529 100644 --- a/WinDirStat/windirstat/windirstat.h +++ b/WinDirStat/windirstat/windirstat.h @@ -62,8 +62,8 @@ class CDirstatApp final : public CWinApp { public: //C4820: 'CDirstatApp' : '4' bytes padding added after data member 'CDirstatApp::m_altEncryptionColor' COLORREF m_altEncryptionColor; // Coloring of encrypted items - private: - +private: + CMainFrame* m_frameptr; protected: DECLARE_MESSAGE_MAP() afx_msg void OnFileOpen(); diff --git a/WinDirStat/windirstat/windirstat.vcxproj b/WinDirStat/windirstat/windirstat.vcxproj index 8847342..68bb4f9 100644 --- a/WinDirStat/windirstat/windirstat.vcxproj +++ b/WinDirStat/windirstat/windirstat.vcxproj @@ -213,6 +213,7 @@ true false true + OnlyExplicitInline Kernel32.lib;Psapi.lib;%(AdditionalDependencies) @@ -263,6 +264,8 @@ false false Send + false + OnlyExplicitInline Kernel32.lib;Psapi.lib;%(AdditionalDependencies) @@ -555,7 +558,7 @@ Fast Send Full - true + false AssemblyAndSourceCode false true diff --git a/WinDirStat/windirstat/xyslider.cpp b/WinDirStat/windirstat/xyslider.cpp index d0954b2..7b2c3f5 100644 --- a/WinDirStat/windirstat/xyslider.cpp +++ b/WinDirStat/windirstat/xyslider.cpp @@ -49,7 +49,11 @@ void CXySlider::Initialize( ) { if ( ( rc.bottom - rc.top ) % 2 == 0 ) { rc.bottom--; } - MoveWindow( rc ); + + ASSERT( ::IsWindow( m_hWnd ) ); + + //If [MoveWindow] succeeds, the return value is nonzero. + VERIFY( ::MoveWindow( m_hWnd, rc.left, rc.top, ( rc.right - rc.left ), ( rc.bottom - rc.top ), TRUE ) ); // Initialize constants CalcSizes( );