Click here to Skip to main content
15,892,059 members
Articles / Desktop Programming / MFC

Understanding CDockablePane

Rate me:
Please Sign up or sign in to vote.
4.95/5 (80 votes)
19 Aug 2015Apache12 min read 362.4K   11.8K   134  
A good reference for CDockablePane
/* 
 * 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

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Software Developer (Senior)
Syrian Arab Republic Syrian Arab Republic
C++ , MFC , Win32 professional Developer.

Comments and Discussions