📄 disktreectrl.cpp
字号:
if (i < nChildren) // To be thread safe, when sorting and scanning at sametime
{
pParent->m_listChild.SetAt(pos, ppSortArray[i]);
pParent->m_listChild.GetNext(pos);
}
}
delete [] ppSortArray;
}
POSITION pos = pParent->m_listChild.GetHeadPosition();
while (pos)
{
CTreeItem *pChild = (CTreeItem*)pParent->m_listChild.GetNext(pos);
Sort(pChild);
}
}
int CDiskTreeCtrl::CompareChildren(const void *p1, const void *p2)
{
CTreeItem * pChild1 = *(CTreeItem**)p1;
CTreeItem * pChild2 = *((CTreeItem**)p2);
CItemInfo *pItem1=(*pChild1).m_lpNodeInfo;
CItemInfo *pItem2=(*pChild2).m_lpNodeInfo;
int nResult=0;
switch (m_nSortCol)
{
case 0: // Title
nResult = (pItem1->GetItemText()).CompareNoCase(pItem2->GetItemText());
break;
case 1: // Size
nResult = int(pItem1->m_pFolder->GetFolderSize(TRUE) - pItem2->m_pFolder->GetFolderSize(TRUE));
break;
case 2: // Folders
nResult = int(pItem1->m_pFolder->GetFolderCount(TRUE) - pItem2->m_pFolder->GetFolderCount(TRUE));
break;
case 3: // Files
nResult = int(pItem1->m_pFolder->GetFileCount(TRUE) - pItem2->m_pFolder->GetFileCount(TRUE));
break;
}
if (m_bSortAscending == FALSE)
nResult = 0 - nResult;
return nResult;//StrComp(&(pItem1->GetItemText()), &(pItem2->GetItemText()));
}
void CDiskTreeCtrl::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
CWaitCursor wait;
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
if( pNMListView->iSubItem == CDiskTreeCtrl::m_nSortCol )
CDiskTreeCtrl::m_bSortAscending = !CDiskTreeCtrl::m_bSortAscending;
else
CDiskTreeCtrl::m_bSortAscending = TRUE;
m_wndFlatHeader.SetSortColumn(pNMListView->iSubItem, CDiskTreeCtrl::m_bSortAscending);
CDiskTreeCtrl::m_nSortCol = pNMListView->iSubItem;
CTreeItem *pRootItem = GetRootItem();
CTreeItem* pSelItem = NULL;
int nItem = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if (nItem != -1)
pSelItem = reinterpret_cast<CTreeItem*>(GetItemData(nItem));
if (pRootItem)
{
Sort(pRootItem);
SetRedraw(0);
RedrawOpenedItems(pRootItem);
SetRedraw(1);
if (pSelItem)
SelectNode(pSelItem);
}
*pResult = 0;
}
CMyFolder* CDiskTreeCtrl::GetSelectedFolder()
{
int nItem = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if (nItem == -1)
return NULL;
CTreeItem* pSelItem = reinterpret_cast<CTreeItem*>(GetItemData(nItem));
return pSelItem->m_lpNodeInfo->m_pFolder;
}
CString CDiskTreeCtrl::GetItemPath(CTreeItem* pItem)
{
CString strThis = pItem->m_lpNodeInfo->m_pFolder->m_strFolderName;
if (pItem == GetRootItem())
return strThis;
CTreeItem* pParentItem = GetParentItem(pItem);
CString str = GetItemPath(pParentItem);
if (str.Right(1) != "\\")
str += "\\";
if (!(pItem->m_lpNodeInfo->m_pFolder->IsFile()))
str += strThis;
return str;
}
CString CDiskTreeCtrl::GetSelectedPath()
{
int nItem = GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
if (nItem == -1)
return CString("");
CTreeItem* pSelItem = reinterpret_cast<CTreeItem*>(GetItemData(nItem));
return GetItemPath(pSelItem);
}
// Just to create a estimated progress ctrl for folders
int CDiskTreeCtrl::GetNrSubFolders(LPCTSTR strRoot, bool bSub)
{
int i=0;
HANDLE hFind;
WIN32_FIND_DATA fd;
TCHAR charCmp[MAX_PATH];
strcpy(charCmp, strRoot);
strcat(charCmp, "\\*.*");
if ((hFind = ::FindFirstFile ((LPCTSTR) charCmp, &fd)) !=
INVALID_HANDLE_VALUE)
{
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if ((strcmp(fd.cFileName, ".")!=0) && (strcmp(fd.cFileName, "..")!=0))
{
strcpy(charCmp, strRoot);
strcat(charCmp, "\\");
strcat(charCmp, fd.cFileName);
if (bSub)
i += GetNrSubFolders(charCmp, bSub);
i++;
}
}
} while (::FindNextFile (hFind, &fd));
::FindClose (hFind);
}
return i;
}
void CDiskTreeCtrl::PrintTree(CDC *pDC, const CPoint& ptStart, const CSize& szSize, int nStart, int nEnd)
{
if (GetItemCount()<=0)
return;
CRect rc(ptStart,szSize);
for (int i=nStart; i < nEnd; i++)
{
CTreeItem *pItem = reinterpret_cast<CTreeItem*>(GetItemData(0));
/*DRAWITEMSTRUCT dr;
dr.CtlID = 0;
dr.CtlType = ODT_LISTVIEW;
dr.hDC = pDC->GetSafeHdc();
dr.hwndItem = NULL;
dr.itemAction = ODA_DRAWENTIRE;
dr.itemData = (unsigned long)pItem;
dr.itemID = NULL;
dr.rcItem = rc;
DrawItem(&dr);*/
//DrawRow(pDC, rc, i);
DrawTreeItem(pDC, pItem, i, rc);
rc.OffsetRect(CSize(0, szSize.cy));
}
/*
//Set origin to print header and Header control. Keep Y position at 0 to
//print header information
//Change Y position of origin to print List control header
//Adjust the List control origin to start printing after page margins
//pDC->SetWindowOrg(-rc.left, -rc.top);
//double d = (double)pDC->GetDeviceCaps(LOGPIXELSY)/(double)pCtlDC->GetDeviceCaps(LOGPIX ELSY);
//GetDlgItem(0)->SendMessage(WM_PAINT, (WPARAM)pDC->m_hDC);
/*//*/Chage window position to take care of ListControl Horizontal scrolling.
//if List control is scrolled to left horizontally the above window origin
//will not start painting from first column, instead it starts painting from
//first visible column, because rcBounds etc are will have -ve left value
//Same thing with vertical scrolling also
CRect rcBounds;
GetItemRect(nStartRow, &rcBounds, LVIR_BOUNDS);
//offset top margin of rcBounds by ListControl header
CRect rc;
m_wndFlatHeader.GetClientRect(&rc);
rcBounds.OffsetRect(0, -rc.Height());
pDC->OffsetWindowOrg(rcBounds.left, rcBounds.top);
//start printing rows
for(int i = nStartRow; i < nEndRow; i++)
DrawRow(pDC, i);
//SetWindowOrg back for next page
pDC->SetWindowOrg(0,0);
pDC->SetWindowOrg(0,0);*/
/*
CTreeItem *pItem = pParent;
CItemInfo* lp = GetData(pParent);
CString strData = lp->GetItemText();
strData+='\t';
nLineY+=cy;
for(int nCol=0; nCol < lp->GetItemCount(); nCol++)
{
CString str = lp->GetSubItem(nCol);
strData+=str;
strData+='\t';
}
pDC->TabbedTextOut(rcClient.left,nLineY,strData,strData.GetLength(), 0, NULL, 0);
nLineY+=cy;
//GetNext ....loop through all children
for(;;)
{
CTreeItem *pCur= GetNextSiblingItem(pItem, TRUE, TRUE);
if(!IsChildOf(pParent, pCur))
break;
else
if(pCur==pItem)
break;
CItemInfo* lp = GetData(pCur);
CString strData = lp->GetItemText();
strData+='\t';
for(int nCol=0; nCol < lp->GetItemCount(); nCol++)
{
CString str = lp->GetSubItem(nCol);
strData+=str;
strData+='\t';
}
pDC->TabbedTextOut(rcClient.left,nLineY,strData,strData.GetLength(), 0, NULL, 0);
nLineY+=cy;
pItem=pCur;
}*/
}
//this is drawing code copied RowList sample and from www.codeguru.com site
int CDiskTreeCtrl::DrawRow(CDC *pDC, const CRect& rc, int nItem)
{
return 0;
}
void CDiskTreeCtrl::OnSize(UINT nType, int cx, int cy)
{
CSuperGridCtrl::OnSize(nType, cx, cy);
//if (GetSafeHwnd())
// ;//ResizeColumns(TRUE);
}
void CDiskTreeCtrl::BuildTreeToHTML()
{
CTreeItem* pRoot = GetRootItem();
int nIndex = GetNextItem(-1, LVNI_ALL);
if(nIndex!=-1)
{
//GetHeadPosition
CTreeItem *pParent = reinterpret_cast<CTreeItem*>(GetItemData(nIndex));
CTreeItem *pItem = pParent;
for(;;)
{
CTreeItem *pCur= GetNextSiblingItem(pItem, TRUE, TRUE);
if(!IsChildOf(pParent, pCur))
break;
else
if(pCur==pItem)
break;
BuildItemRow(pItem, pRoot);
pItem=pCur;
}
BuildItemRow(pItem, pRoot);
}
}
void CDiskTreeCtrl::BuildItemRow(CTreeItem *pItem, CTreeItem* pRoot)
{
CreateHTMLRow();
CItemInfo* lp = GetData(pItem);
CString strData = lp->GetItemText();
CString strImage("");
int iIndent = GetIndent(pItem);
int nListItem = GetCurIndex(pItem);
CTreeItem *pSelItem = pItem;
while(pRoot != pSelItem)
{
CTreeItem* pParent = GetParentItem(pSelItem);
POSITION pos = pParent->m_listChild.GetTailPosition();
while(pos!=NULL)
{
CTreeItem *pLastChild = (CTreeItem*)pParent->m_listChild.GetPrev(pos);
int nIndex = GetCurIndex(pLastChild);
//no drawing outside the 1st columns right
if (nIndex == nListItem && (GetIndent(pLastChild)==iIndent))
{
//draw '-
strImage = CreateHTMLImageString(_T("linelast.gif")) + strImage;
break;
}
else if(nIndex > nListItem && (GetIndent(pLastChild)==iIndent))
{
//draw |-
strImage = CreateHTMLImageString(_T("line.gif")) + strImage;
break;
}
else if(nIndex > nListItem && (GetIndent(pLastChild) < iIndent))
{
//draw |
strImage = CreateHTMLImageString(_T("linever.gif")) + strImage;
break;
}else
{
strImage = CreateHTMLImageString(_T("empty.gif")) + strImage;
break;
}
}
pSelItem = pParent;//next
}
/*for (int i=1; i<pItem->m_nIndent-1; i++)
strImage += CreateHTMLImageString(_T("empty.gif"));
if (pItem->m_nIndent > 1)
strImage += CreateHTMLImageString(_T("line.gif"));*/
CMyFolder* pFolder = lp->m_pFolder;
if (pFolder->IsFile())
strImage += CreateHTMLImageString(_T("file.gif"));
else if (ItemHasChildren(pItem) && !IsCollapsed(pItem))
strImage += CreateHTMLImageString(_T("folder_o.gif"));
else
strImage += CreateHTMLImageString(_T("folder_c.gif"));
InsertHTMLCell("", strImage + _T(" ") + strData);
for(int nCol=0; nCol < lp->GetItemCount(); nCol++)
{
strData = lp->GetSubItem(nCol);
InsertHTMLCell("", strData);
}
FinishHTMLRow();
}
#include "stdafx.h"
#define LEFT_MARGIN 2
#define RIGHT_MARGIN 4
#define HEADER_HEIGHT 4
#define FOOTER_HEIGHT 3
//Set it all to 0
//********************************CONSTRUCTOR************************************
CTreeListPrinting::CTreeListPrinting()
{
lc = 0;
pOldFont = 0;
TitleStr = "";
DateStr = "";
page_rc.SetRect(0,0,0,0);
m_nRowHeight = 0;
m_nRowsPerPage = 0;
m_nMaxRowCount = 0;
m_ratiox = 0;
m_ratioy = 0;
hc_items = 0;
return;
}
//Using default for printer guess at # of pages.
//If no printer exists return FALSE;
//************************ONPREPAREPRINTING*******************************
BOOL CTreeListPrinting::OnPreparePrinting(CPrintInfo* pInfo, CView * cview, CDiskTreeCtrl * t_lc)
{
if(t_lc==NULL || cview==NULL || pInfo == NULL) return FALSE;
lc = t_lc;//Set Pointer to list Control
//Lets make a guess as to how many pages there are based on the default printer.
CPrintDialog pdlg(FALSE);
if (!pdlg.GetDefaults()) return FALSE;//If no defaults then no printer!!
CDC t_pDC;
t_pDC.Attach(pdlg.GetPrinterDC());
compute_metrics(&t_pDC);
m_nMaxRowCount = lc->GetItemCount(); if(!m_nMaxRowCount) return FALSE;//Get the number of rows
int nMaxPage = m_nMaxRowCount/m_nRowsPerPage + 1;
pInfo->SetMaxPage(nMaxPage);
pInfo->m_nCurPage = 1; // start printing at page# 1
//If you want to be able to do this remove it.
pInfo->m_pPD->m_pd.Flags |=PD_HIDEPRINTTOFILE;
return cview->DoPreparePrinting(pInfo);
}
//Call this from your view class OnBeingPrinting function
//*************************ONBEGINGPRINTING*************************
void CTreeListPrinting::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo, CString & t_title, CString & t_date)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -