📄 statisticstree.cpp
字号:
/* CStatisticsTree Class Implementation File by Khaos
Copyright (C) 2003
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
This file is a part of the KX mod, and more
specifically, it is a part of my statistics
add-on.
The purpose of deriving a custom class from CTreeCtrl
was to provide another level of customization and control.
This allows us to easily code complicated parsing features
and a context menu.
*/
#include "stdafx.h"
#include "emule.h"
#include "StatisticsTree.h"
#include "StatisticsDlg.h"
#include "emuledlg.h"
#include "Preferences.h"
#include "OtherFunctions.h"
#include "Log.h"
#include "StringConversion.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(CStatisticsTree, CTreeCtrl)
BEGIN_MESSAGE_MAP(CStatisticsTree, CTreeCtrl)
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_CONTEXTMENU()
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemExpanded)
END_MESSAGE_MAP()
CStatisticsTree::CStatisticsTree()
{
}
CStatisticsTree::~CStatisticsTree()
{
if (mnuHTML) VERIFY( mnuHTML.DestroyMenu() );
if (mnuContext) VERIFY( mnuContext.DestroyMenu() );
}
// This function is called from CStatisticsDlg::OnInitDialog in StatisticsDlg.cpp
void CStatisticsTree::Init()
{
m_bExpandingAll = false;
}
// It is necessary to disrupt whatever behavior was preventing
// us from getting OnContextMenu to work. This seems to be the
// magic fix...
void CStatisticsTree::OnRButtonDown( UINT nFlags, CPoint point )
{
UINT uHitFlags;
HTREEITEM hItem = HitTest(point, &uHitFlags);
if (hItem != NULL && (uHitFlags & TVHT_ONITEM))
{
Select(hItem, TVGN_CARET);
SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
}
return;
}
void CStatisticsTree::OnContextMenu( CWnd* pWnd, CPoint point )
{
DoMenu(point, TPM_LEFTALIGN | TPM_RIGHTBUTTON);
}
void CStatisticsTree::OnLButtonUp( UINT nFlags, CPoint point )
{
theApp.emuledlg->statisticswnd->ShowStatistics();
CTreeCtrl::OnLButtonUp(nFlags, point);
}
// This function saves the expanded tree items intelligently. Instead
// of saving them every time we ShowStatistics, now they are only saved
// when a parent item is expanded or collapsed.
// m_bExpandingAll is TRUE when CollapseAll, ExpandAll or ApplyExpandedMask
// are executing. This is to prevent us from saving the string a bajillion
// times whenever these functions are called. CollapseAll and ExpandAll
// call GetExpandedMask() upon completion.
void CStatisticsTree::OnItemExpanded( NMHDR* pNMHDR, LRESULT* pResult )
{
if (!m_bExpandingAll)
thePrefs.SetExpandedTreeItems(GetExpandedMask());
}
// Displays the command menu. This function is overloaded
// because it is used both to display the context menu and also
// the menu that drops down from the button.
void CStatisticsTree::DoMenu()
{
CPoint cursorPos;
GetCursorPos(&cursorPos);
DoMenu(cursorPos);
}
void CStatisticsTree::DoMenu(CPoint doWhere)
{
DoMenu( doWhere, TPM_RIGHTALIGN | TPM_RIGHTBUTTON );
}
void CStatisticsTree::DoMenu(CPoint doWhere, UINT nFlags)
{
CFileFind findBackUp;
CString myBuffer;
int myFlags;
myBuffer.Format(_T("%sstatbkup.ini"),thePrefs.GetConfigDir());
if (!findBackUp.FindFile(myBuffer)) myFlags = MF_GRAYED;
else myFlags = MF_STRING;
mnuContext.CreatePopupMenu();
mnuContext.AddMenuTitle(GetResString(IDS_STATS_MNUTREETITLE), true);
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_RESET, GetResString(IDS_STATS_BNRESET), _T("DELETE"));
mnuContext.AppendMenu(myFlags, MP_STATTREE_RESTORE, GetResString(IDS_STATS_BNRESTORE), _T("RESTORE"));
mnuContext.AppendMenu(MF_SEPARATOR);
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_EXPANDMAIN, GetResString(IDS_STATS_MNUTREEEXPANDMAIN), _T("EXPANDMAIN"));
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_EXPANDALL, GetResString(IDS_STATS_MNUTREEEXPANDALL), _T("EXPANDALL"));
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_COLLAPSEALL, GetResString(IDS_STATS_MNUTREECOLLAPSEALL), _T("COLLAPSE"));
mnuContext.AppendMenu(MF_SEPARATOR);
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_COPYSEL, GetResString(IDS_STATS_MNUTREECPYSEL), _T("COPY"));
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_COPYVIS, GetResString(IDS_STATS_MNUTREECPYVIS), _T("COPYVISIBLE"));
mnuContext.AppendMenu(MF_STRING, MP_STATTREE_COPYALL, GetResString(IDS_STATS_MNUTREECPYALL), _T("COPYSELECTED"));
mnuContext.AppendMenu(MF_SEPARATOR);
mnuHTML.CreateMenu();
mnuHTML.AddMenuTitle(NULL, true);
mnuHTML.AppendMenu(MF_STRING, MP_STATTREE_HTMLCOPYSEL, GetResString(IDS_STATS_MNUTREECPYSEL), _T("COPY"));
mnuHTML.AppendMenu(MF_STRING, MP_STATTREE_HTMLCOPYVIS, GetResString(IDS_STATS_MNUTREECPYVIS), _T("COPYVISIBLE"));
mnuHTML.AppendMenu(MF_STRING, MP_STATTREE_HTMLCOPYALL, GetResString(IDS_STATS_MNUTREECPYALL), _T("COPYSELECTED"));
mnuHTML.AppendMenu(MF_SEPARATOR);
mnuHTML.AppendMenu(MF_STRING, MP_STATTREE_HTMLEXPVIS, GetResString(IDS_STATS_EXPORTVIS), _T("EXPORTSELECTED"));
mnuHTML.AppendMenu(MF_STRING, MP_STATTREE_HTMLEXPORT, GetResString(IDS_STATS_EXPORT2HTML), _T("EXPORTALL"));
mnuContext.AppendMenu(MF_STRING | MF_POPUP, (UINT_PTR)mnuHTML.m_hMenu, GetResString(IDS_STATS_MNUTREEHTML), _T("WEB"));
GetPopupMenuPos(*this, doWhere);
mnuContext.TrackPopupMenu(nFlags, doWhere.x, doWhere.y, this);
VERIFY( mnuHTML.DestroyMenu() );
VERIFY( mnuContext.DestroyMenu() );
}
// Process context menu items...
BOOL CStatisticsTree::OnCommand( WPARAM wParam, LPARAM lParam )
{
switch (wParam) {
case MP_STATTREE_RESET:
{
if(AfxMessageBox(GetResString(IDS_STATS_MBRESET_TXT), MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
break;
thePrefs.ResetCumulativeStatistics();
AddLogLine(false, GetResString(IDS_STATS_NFORESET));
theApp.emuledlg->statisticswnd->ShowStatistics();
CString myBuffer;
myBuffer.Format(GetResString(IDS_STATS_LASTRESETSTATIC), thePrefs.GetStatsLastResetStr(false));
GetParent()->GetDlgItem(IDC_STATIC_LASTRESET)->SetWindowText(myBuffer);
break;
}
case MP_STATTREE_RESTORE:
{
if (AfxMessageBox(GetResString(IDS_STATS_MBRESTORE_TXT), MB_YESNO | MB_ICONQUESTION) == IDNO)
break;
if(!thePrefs.LoadStats(1))
LogError(LOG_STATUSBAR, GetResString(IDS_ERR_NOSTATBKUP));
else {
AddLogLine(false, GetResString(IDS_STATS_NFOLOADEDBKUP));
CString myBuffer;
myBuffer.Format(GetResString(IDS_STATS_LASTRESETSTATIC), thePrefs.GetStatsLastResetStr(false));
GetParent()->GetDlgItem(IDC_STATIC_LASTRESET)->SetWindowText(myBuffer);
}
break;
}
case MP_STATTREE_EXPANDMAIN:
{
SetRedraw(false);
ExpandAll(true);
goto lblSaveExpanded;
}
case MP_STATTREE_EXPANDALL:
{
SetRedraw(false);
ExpandAll();
goto lblSaveExpanded;
}
case MP_STATTREE_COLLAPSEALL:
{
SetRedraw(false);
CollapseAll();
lblSaveExpanded:
thePrefs.SetExpandedTreeItems(GetExpandedMask());
SetRedraw(true);
break;
}
case MP_STATTREE_COPYSEL:
case MP_STATTREE_COPYVIS:
case MP_STATTREE_COPYALL:
{
CopyText(wParam);
break;
}
case MP_STATTREE_HTMLCOPYSEL:
case MP_STATTREE_HTMLCOPYVIS:
case MP_STATTREE_HTMLCOPYALL:
{
CopyHTML(wParam);
break;
}
case MP_STATTREE_HTMLEXPORT:
case MP_STATTREE_HTMLEXPVIS:
{
ExportHTML(wParam==MP_STATTREE_HTMLEXPVIS);
break;
}
}
return true;
}
// If the item is bold it returns true, otherwise
// false. Very straightforward.
// EX: if(IsBold(myTreeItem)) AfxMessageBox("It's bold.");
bool CStatisticsTree::IsBold(HTREEITEM theItem)
{
UINT stateBold = GetItemState(theItem, TVIS_BOLD);
return (stateBold & TVIS_BOLD);
}
// If the item is expanded it returns true, otherwise
// false. Very straightforward.
// EX: if(IsExpanded(myTreeItem)) AfxMessageBox("It's expanded.");
bool CStatisticsTree::IsExpanded(HTREEITEM theItem)
{
UINT stateExpanded = GetItemState(theItem, TVIS_EXPANDED);
return (stateExpanded & TVIS_EXPANDED);
}
// This is a generic function to check if a state is valid or not.
// It accepts a tree item handle and a state/statemask/whatever.
// It then retrieves the state UINT value and does a bitand
// with the original input. This should translate into a
// boolean result that tells us whether the checked state is
// true or not. This is currently unused, but may come in handy
// for states other than bold and expanded.
// EX: if(CheckState(myTreeItem, TVIS_BOLD)) AfxMessageBox("It's bold.");
bool CStatisticsTree::CheckState(HTREEITEM hItem, UINT state)
{
UINT stateGeneric = GetItemState(hItem, state);
return (stateGeneric & state);
}
// Returns the entire text label of an HTREEITEM. This
// is an overloaded function.
// EX: CString itemText = GetItemText(myTreeItem);
CString CStatisticsTree::GetItemText(HTREEITEM theItem)
{
if (theItem == NULL)
return _T("");
TVITEM item;
TCHAR szText[1024];
item.mask = TVIF_TEXT | TVIF_HANDLE;
item.hItem = theItem;
item.pszText = szText;
item.cchTextMax = 1024;
if (GetItem(&item))
return CString(item.pszText);
return _T("");
}
// This seperates the title from the value in a tree item that has
// a title to the left of a colon, and a value to the right, with
// a space seperating the value from the colon. ": "
// int getPart can be GET_TITLE (0) or GET_VALUE (1)
// EXAMPLE:
// HTREEITEM hMyItem = treeCtrl.InsertItem("Title: 5", hMyParent);
// CString strTitle = treeCtrl.GetItemText(hMyItem, GET_TITLE);
// CString strValue = treeCtrl.GetItemText(hMyItem, GET_VALUE);
// AfxMessageBox("The title is: " + strTitle + "\nThe value is: " + strValue);
CString CStatisticsTree::GetItemText(HTREEITEM theItem, int getPart)
{
if (theItem == NULL)
return _T("");
CString fullText, returnText;
fullText = GetItemText(theItem);
if (fullText.IsEmpty())
return _T("");
int posSeparator = fullText.Find(_T(": "));
if (posSeparator < 1) {
returnText = getPart == GET_TITLE ? fullText : _T("");
return returnText;
}
if (getPart == GET_TITLE)
returnText = fullText.Left(posSeparator);
else if (getPart == GET_VALUE)
returnText = fullText.Mid(posSeparator + 2);
else
returnText = _T("");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -