/*
* Developed by Huzifa Terkawi
* http://www.codeproject.com/Members/huzifa30
* All permission granted to use this code as long as you retain this notice
* and refere to orginal Material when part of this code is re-puplished
* part of this tree algorithm and item traversing is taken from Hans Dietrich
* XHtmlTree http://www.codeproject.com/Members/Hans-Dietrich
*/
#ifndef TREE_H_4C9F67F8F7784f0e8FDE01EF02F6A21D
#define TREE_H_4C9F67F8F7784f0e8FDE01EF02F6A21D
#if _MSC_VER > 1000
#pragma once
#endif
#include <vector>
#include <map>
#include <list>
#ifndef SHIFT_DOWN
#define SHIFT_DOWN (GetKeyState(VK_SHIFT) < 0)
#endif
#ifndef CTRL_DOWN
#define CTRL_DOWN (GetKeyState(VK_CONTROL) < 0)
#endif
#ifndef STATEIMAGEMASKTOINDEX
#define STATEIMAGEMASKTOINDEX(i) ((i) >> 12)
#endif
#ifndef TreeCtrlExBase
#define TreeCtrlExBase CTreeCtrl
#endif
const UINT HOT_INDEX = 8; // hot index logical OR mask for checkbox imagelist (TVIL_STATE)
const UINT DISABLED_INDEX = 4; // disable index logical or mask for checkbox imagelist (TVIL_STATE)
enum CheckedState
{
//normal Check box
UNUSED1 = 0, //0000
UNCHECKED, //0001
CHECKED, //0010
TRISTATE, //0011
//0100 is Disable mask See DISABLED_INDEX Above
// disable check box
UNCHECKED_DISABLED = 5 , //0101
CHECKED_DISABLED, //0110
TRISTATE_DISABLED , //0111
//1000 is Hot mask Set HOT_INDEX Above
};
enum SortType { ASCENDING , DESCENDING };
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamCtrl);
typedef struct ItemDrawData
{
BOOL m_bEnabled ;
BOOL m_bReadOnly ;
BOOL m_bRadioGroup ;
COLORREF m_clrText ;
COLORREF m_clrBack ;
ItemDrawData()
{
m_bEnabled = TRUE ;
m_bReadOnly = FALSE ;
m_bRadioGroup = FALSE;
m_clrText = CLR_NONE ;
m_clrBack = CLR_NONE ;
}
ItemDrawData(BOOL bEnabled ,BOOL ReadOnly, COLORREF clrText , COLORREF clrBack)
{
m_bReadOnly = ReadOnly ;
m_bEnabled = bEnabled ;
m_clrText = clrText ;
m_clrBack = clrBack ;
}
void Copy(ItemDrawData* old)
{
m_bReadOnly = old->m_bReadOnly ;
m_bEnabled = old->m_bEnabled ;
m_clrText = old->m_clrText ;
m_clrBack = old->m_clrBack ;
}
}* PItemDrawData;
class CTreeCtrlEx : public TreeCtrlExBase
{
private :
DECLARE_DYNAMIC(CTreeCtrlEx);
DECLARE_MESSAGE_MAP();
public:
CTreeCtrlEx();
virtual ~CTreeCtrlEx();
public :
void EnableDrawHot(BOOL bEnable = TRUE){ m_bDrawHot = bEnable ;}
DWORD GetStyle()const{return m_bCheckBox ? TreeCtrlExBase::GetStyle()|TVS_CHECKBOXES:TreeCtrlExBase::GetStyle();}
public : // sort functionality
void Sort(HTREEITEM = TVI_ROOT);
void SetSortType(SortType = ASCENDING );
void ToggleSort(HTREEITEM hItem = TVI_ROOT)
{
m_sortType = m_sortType == ASCENDING? DESCENDING :ASCENDING;
Sort(hItem);
}
SortType GetSortType();
HTREEITEM FindItemByLParam(LPARAM l);
public:
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
afx_msg void OnMouseMove(UINT ,CPoint);
afx_msg void OnLButtonDown(UINT , CPoint);
afx_msg void OnLButtonDblClk(UINT flag, CPoint pt );
afx_msg void OnLButtonUp(UINT , CPoint);
afx_msg int OnCreate(LPCREATESTRUCT cs);
void OnKey(NMHDR* hdr, LRESULT* result);
void OnDelete(NMHDR* hdr, LRESULT* result);
void OnBeginDrag(NMHDR* hdr, LRESULT* result);
void OnBeginLabelEdit(NMHDR* hdr,LRESULT* result);
void OnEndLabelEdit(NMHDR* hdr,LRESULT* result);
BOOL OnSelChanging(NMHDR* hdr,LRESULT* result);
BOOL OnSelChanged(NMHDR* hdr,LRESULT* result);
afx_msg LRESULT OnMouseLeave(WPARAM,LPARAM);
afx_msg void OnCustomDraw(NMHDR*,LRESULT*);
afx_msg void OnClick(NMHDR*,LRESULT*);
afx_msg void OnChar(NMHDR*, LRESULT*);
afx_msg BOOL OnEraseBkgnd(CDC*);
afx_msg void OnPaint();
afx_msg void OnCancelMode();
public :
CRect GetItemRect(HTREEITEM h);
void RedrawItem(HTREEITEM hItem);
virtual void DrawBackground(CDC* dc,CRect rect,HTREEITEM h,UINT state);
virtual void DrawItemText(CDC* dc,CRect rect,HTREEITEM h, UINT state);
BOOL CreateCheckboxImageList(CDC *pDC,CImageList& imagelist,
int nSize,COLORREF crBackground);
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
virtual BOOL PreTranslateMessage(MSG* pMsg) ;
virtual void PreSubclassWindow();
void AdjustEditRect();
void AutoScroll(HTREEITEM hItem);
virtual void Initalize(BOOL Check);
void SetDragCursor();
public :
// insert operation
HTREEITEM InsertItem(_In_ LPTVINSERTSTRUCT lpInsertStruct);
HTREEITEM InsertItem(_In_ UINT nMask, _In_z_ LPCTSTR lpszItem, _In_ int nImage,
_In_ int nSelectedImage, _In_ UINT nState, _In_ UINT nStateMask, _In_ LPARAM lParam,
_In_ HTREEITEM hParent, _In_ HTREEITEM hInsertAfter);
HTREEITEM InsertItem(_In_z_ LPCTSTR lpszItem, _In_ HTREEITEM hParent = TVI_ROOT,
_In_ HTREEITEM hInsertAfter = TVI_LAST);
HTREEITEM InsertItem(_In_z_ LPCTSTR lpszItem, _In_ int nImage, _In_ int nSelectedImage,
_In_ HTREEITEM hParent = TVI_ROOT, _In_ HTREEITEM hInsertAfter = TVI_LAST);
public :
// get called in response to delete action to delete user data
virtual void PreDeleteItem(HTREEITEM hItem){ return ;}
virtual BOOL DoBeginEditLabel(HTREEITEM &tv){ return TRUE;}
virtual BOOL DoEndEditLabel(TVITEM &tv){return TRUE;}
virtual BOOL DoKeyDown(LPNMTVKEYDOWN key,HTREEITEM hItem){return FALSE;}
virtual BOOL DoLButtonDown(UINT flag,CPoint pt){return FALSE;}
virtual BOOL DoMouseMove(UINT flag ,CPoint){return FALSE;}
virtual BOOL DoLButtonUp(UINT flag ,CPoint){return FALSE;}
virtual BOOL DoBeginDrag(LPNMTREEVIEW pNM){return FALSE;}
virtual void PostMoveItem(HTREEITEM hOldItem,HTREEITEM hNewItem,HTREEITEM hNewParent);
public : // tree traverse
HTREEITEM NextItem(HTREEITEM hItem);
HTREEITEM PrevItem(HTREEITEM hItem);
HTREEITEM LastItem(HTREEITEM hItem);
HTREEITEM MoveBranch(HTREEITEM hBranch,HTREEITEM hNewParent);
HTREEITEM MoveItem(HTREEITEM hItem,HTREEITEM hNewParent);
void ToggleCheck(HTREEITEM hItem);
BOOL SetCheckState(HTREEITEM hItem, CheckedState cs = CHECKED);
CheckedState GetCheckState(HTREEITEM hItem) const;
BOOL GetCheck( HTREEITEM hItem ) const;
BOOL SetCheck( HTREEITEM hItem, BOOL bCheck = TRUE );
void RecursiveCheckChildren(HTREEITEM hItem, CheckedState nState);
void RecursiveCheckParent(HTREEITEM hItem, CheckedState nState);
void EnableSmartCheck(BOOL bEnable = TRUE );
void SetTreeReadOnly(BOOL bReadonly);
void SetReadOnly(HTREEITEM hItem,BOOL bReadOnly = TRUE,BOOL bRecursive = FALSE);
void SetItemColor(HTREEITEM hItem,COLORREF clrText = CLR_NONE ,COLORREF clrBack = CLR_NONE);
HTREEITEM CursorItem(LPPOINT = NULL);
void CheckChildren(HTREEITEM hItem, BOOL fCheck);
void ChangeItemState(HTREEITEM hItem, BOOL fCheck);
BOOL IsChildNodeOf(HTREEITEM hitem, HTREEITEM hitemSuspectedParent);
BOOL IsExpanded(HTREEITEM hItem);
BOOL IsReadOnly(HTREEITEM hItem);
BOOL IsEnabled(HTREEITEM hItem);
void EnableItem(HTREEITEM hItem, BOOL bEnable = TRUE,BOOL bRecursive = FALSE);
BOOL IsChecked(HTREEITEM hItem) { return GetCheck(hItem); }
int GetItemDepth(HTREEITEM hItem);
CString GetItemPath(HTREEITEM hItem);
public : // multiSelection Function
BOOL IsSelected(HTREEITEM hItem)const;
inline BOOL IsMultiSelect() const { return m_bMultiSel; }
void SetMultiSelect(BOOL bMultiSel = TRUE);
int GetSelectedCount();
void SelectAll( BOOL bSelect);
void FillSelectList();
void SelectRange(HTREEITEM hBegin,HTREEITEM hEnd,BOOL bSelect = TRUE);
BOOL TestDragDropRelation(HTREEITEM hItem);
HTREEITEM FirstSelectedItem() ;
HTREEITEM NextSelectedItem(HTREEITEM hItem) ;
HTREEITEM PrevSelectedItem(HTREEITEM hItem) ;
public :
void AddItemStruct(HTREEITEM hItem);
ItemDrawData* GetItemStruct(HTREEITEM hItem);
void RemoveItemDrawData(HTREEITEM hItem = NULL);
protected : //container
std::map<HTREEITEM,ItemDrawData*> m_map; // items data
std::vector<HTREEITEM> m_sellist; // list of selected items
protected :
SortType m_sortType ;
BOOL m_bSmartCheckBox;
BOOL m_bCaptured; // mouse capture
BOOL m_bCheckBox; // check box style
BOOL m_bDrag; // Drag in Progress
BOOL m_bReadOnly; // tree is read only
BOOL m_bMultiSel; // enable multiselect
BOOL m_bDrawHot;
UINT m_nHorzPos ;// horizental scroll bar position
UINT m_nHitTest; // hittest falg in LButtonDown
HTREEITEM m_hDragItem;
HTREEITEM m_hDropItem;
HTREEITEM m_hHotItem;
HTREEITEM m_hSelectLast;
COLORREF clrText , clrGrayText , clrWindow ,clrGrayWindow;
COLORREF clrBorderHot,clrBorderSel;
COLORREF clrFillSelected1,clrFillSelected2,clrFillSelected3,clrFillSelected4 ;
COLORREF clrFillHot1 , clrFillHot2 ,clrFillHot3,clrFillHot4 ;
HCURSOR m_hDropMoveCursor ;
HCURSOR m_hDropCopyCursor ;
HCURSOR m_hNoDropCursor ;
HCURSOR m_hOldCursor;
CImageList m_StateImage;
CImageList m_NormalImage ;
};
#endif