// NewTreeListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "TLView.h"
#include "NewTreeListCtrl.h"
#include "TLFrame.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ID_TREE_LIST_HEADER 370
/////////////////////////////////////////////////////////////////////////////
// CTLItem
CTLItem::CTLItem()
{
m_cEnding = '�';
m_itemString = "";
m_Bold = FALSE;
m_Color = ::GetSysColor(COLOR_WINDOWTEXT);
m_HasChildren = FALSE;
m_nPriority = 1000;
m_Group = FALSE;
}
CTLItem::CTLItem(CTLItem ©Item)
{
m_cEnding = copyItem.m_cEnding;
m_itemString = copyItem.GetItemString();
m_Bold = copyItem.m_Bold;
m_Color = copyItem.m_Color;
itemData = copyItem.itemData;
m_HasChildren = copyItem.m_HasChildren;
m_nPriority = copyItem.m_nPriority;
m_Group = copyItem.m_Group;
}
CString CTLItem::GetSubstring(int m_nSub)
{
CString m_tmpStr("");
int i=0, nHits=0;
int length = m_itemString.GetLength();
while((i<length) && (nHits<=m_nSub))
{
if(m_itemString[i]==m_cEnding)
{
nHits++;
}
else
if(nHits==m_nSub)
m_tmpStr+=m_itemString[i];
i++;
}
if((i>=length) && (nHits<m_nSub))
return "";
else
return m_tmpStr;
}
void CTLItem::SetSubstring(int m_nSub, CString m_sText)
{
CString m_tmpStr("");
int i=0, nHits=0, first=0;
int length = m_itemString.GetLength();
while((i<length) && (nHits<=m_nSub))
{
if(m_itemString[i]==m_cEnding)
{
if(nHits!=m_nSub)
first = i;
nHits++;
}
i++;
}
CString m_newStr("");
if((nHits>m_nSub) || ((nHits==m_nSub) && (i>=length)))
{
// insert in the middle
if(first!=0)
{
m_newStr = m_itemString.Left(first);
m_newStr += m_cEnding;
}
m_newStr += m_sText;
if(i<length)
{
m_newStr += m_cEnding;
m_newStr += m_itemString.Right(m_itemString.GetLength()-i);
}
m_itemString=m_newStr;
}
else
{
// insert at the end
for(i=nHits;i<m_nSub;i++)
m_itemString+=m_cEnding;
m_itemString+=m_sText;
}
}
/////////////////////////////////////////////////////////////////////////////
// CNewTreeListCtrl
CNewTreeListCtrl::CNewTreeListCtrl()
{
m_nColumns = m_nColumnsWidth = 0;
m_nOffset = 0;
m_ParentsOnTop = TRUE;
m_bLDragging = FALSE;
m_htiOldDrop = m_htiDrop = m_htiDrag = NULL;
m_scrollTimer = m_idTimer = 0;
m_timerticks = 0;
m_toDrag = FALSE;
m_RTL = FALSE;
}
CNewTreeListCtrl::~CNewTreeListCtrl()
{
}
BEGIN_MESSAGE_MAP(CNewTreeListCtrl, CTreeCtrl)
//{{AFX_MSG_MAP(CNewTreeListCtrl)
ON_WM_PAINT()
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_KEYDOWN()
ON_WM_TIMER()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNewTreeListCtrl message handlers
int CNewTreeListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
HTREEITEM CNewTreeListCtrl::GetTreeItem(int nItem)
{
HTREEITEM m_ParentItem = GetRootItem();
int m_nCount = 0;
while((m_ParentItem!=NULL) && (m_nCount<nItem))
{
m_nCount ++ ;
GetNextSiblingItem(m_ParentItem);
}
return m_ParentItem;
}
int CNewTreeListCtrl::GetListItem(HTREEITEM hItem)
{
HTREEITEM m_ParentItem = GetRootItem();
int m_nCount = 0;
while((m_ParentItem!=NULL) && (m_ParentItem!=hItem))
{
m_nCount ++ ;
GetNextSiblingItem(m_ParentItem);
}
return m_nCount;
}
void CNewTreeListCtrl::RecalcHeaderPosition()
{
if(m_RTL)
{
CRect m_clientRect;
GetClientRect(&m_clientRect);
if(GetColumnsWidth() > m_clientRect.Width())
{
int m_nOffset = m_clientRect.Width() - GetColumnsWidth();
CTLFrame *pFrame = (CTLFrame *)GetParent();
CRect m_wndRect;
pFrame->GetClientRect(&m_wndRect);
CRect m_headerRect;
m_wndHeader.GetClientRect(&m_headerRect);
m_wndHeader.SetWindowPos(&wndTop, m_nOffset, 0, max(pFrame->StretchWidth(GetColumnsWidth(),m_clientRect.Width()),m_wndRect.Width()), m_headerRect.Height(), SWP_SHOWWINDOW);
}
}
}
int CNewTreeListCtrl::InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat, int nWidth, int nSubItem)
{
HD_ITEM hdi;
hdi.mask = HDI_TEXT | HDI_FORMAT;
if(nWidth!=-1)
{
hdi.mask |= HDI_WIDTH;
hdi.cxy = nWidth;
}
hdi.pszText = (LPTSTR)lpszColumnHeading;
hdi.fmt = HDF_OWNERDRAW;
if(nFormat == LVCFMT_RIGHT)
hdi.fmt |= HDF_RIGHT;
else
if(nFormat == LVCFMT_CENTER)
hdi.fmt |= HDF_CENTER;
else
hdi.fmt |= HDF_LEFT;
m_nColumns ++ ;
int m_nReturn = m_wndHeader.InsertItem(nCol, &hdi);
if(m_nColumns==1)
{
m_wndHeader.SetItemImage(m_nReturn, 0);
}
RecalcColumnsWidth();
if(m_RTL)
RecalcHeaderPosition();
UpdateWindow();
return m_nReturn;
}
int CNewTreeListCtrl::GetColumnWidth(int nCol)
{
if(m_RTL)
{
nCol = GetColumnsNum() - nCol - 1;
}
HD_ITEM hItem;
hItem.mask = HDI_WIDTH;
if(!m_wndHeader.GetItem(nCol, &hItem))
return 0;
return hItem.cxy;
}
int CNewTreeListCtrl::GetColumnAlign(int nCol)
{
HD_ITEM hItem;
hItem.mask = HDI_FORMAT;
if(!m_wndHeader.GetItem(nCol, &hItem))
return LVCFMT_LEFT;
if(hItem.fmt & HDF_RIGHT)
return LVCFMT_RIGHT;
else
if(hItem.fmt & HDF_CENTER)
return LVCFMT_CENTER;
else
return LVCFMT_LEFT;
}
void CNewTreeListCtrl::RecalcColumnsWidth()
{
m_nColumnsWidth = 0;
for(int i=0;i<m_nColumns;i++)
m_nColumnsWidth += GetColumnWidth(i);
}
void CNewTreeListCtrl::DrawItemText (CDC* pDC, CString text, CRect rect, int nWidth, int nFormat)
{
//
// Make sure the text will fit in the prescribed rectangle, and truncate
// it if it won't.
//
BOOL bNeedDots = FALSE;
int nMaxWidth = nWidth - 4;
while ((text.GetLength()>0) && (pDC->GetTextExtent((LPCTSTR) text).cx > (nMaxWidth - 4))) {
text = text.Left (text.GetLength () - 1);
bNeedDots = TRUE;
}
if (bNeedDots) {
if (text.GetLength () >= 1)
text = text.Left (text.GetLength () - 1);
if(!m_RTL)
text += "...";
else
text = "..." + text;
}
//
// Draw the text into the rectangle using MFC's handy CDC::DrawText
// function.
//
rect.right = rect.left + nMaxWidth;
if(m_RTL)
{
rect.right += 4;
rect.left += 4;
}
UINT nStyle = DT_VCENTER | DT_SINGLELINE;
if (nFormat == LVCFMT_LEFT)
nStyle |= DT_LEFT;
else if (nFormat == LVCFMT_CENTER)
nStyle |= DT_CENTER;
else // nFormat == LVCFMT_RIGHT
nStyle |= DT_RIGHT;
if((text.GetLength()>0) && (rect.right>rect.left))
pDC->DrawText (text, rect, nStyle);
}
CRect CNewTreeListCtrl::CRectGet(int left, int top, int right, int bottom)
{
if(m_RTL)
{
CRect m_clientRect;
GetClientRect(&m_clientRect);
return CRect(m_clientRect.Width() - right, top, m_clientRect.Width() - left, bottom);
}
else
return CRect(left, top, right, bottom);
}
void CNewTreeListCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rcClient;
GetClientRect(&rcClient);
//CMemDC dc(&paintdc, rcClient);
CRect rcClip;
dc.GetClipBox( &rcClip );
// Set clip region to be same as that in paint DC
CRgn rgn;
rgn.CreateRectRgnIndirect( &rcClip );
dc.SelectClipRgn(&rgn);
rgn.DeleteObject();
COLORREF m_wndColor = GetSysColor( COLOR_WINDOW );
dc.SetViewportOrg(m_nOffset, 0);
dc.SetTextColor(m_wndColor);
// First let the control do its default drawing.
CRect m_clientRect;
GetClientRect(&m_clientRect);
if(m_RTL)
{
dc.SetViewportOrg(m_clientRect.Width(), 0);
CSize ext = dc.GetViewportExt();
ext.cx = ext.cx > 0 ? -ext.cx : ext.cx;
dc.SetMapMode(MM_ANISOTROPIC);
dc.SetViewportExt(ext);
}
CTree