#if !defined(AFX_CCUSTOMTREECTRL_H__234C8D10_F2CD_42B3_9972_384F6609F5D8__INCLUDED_)
#define AFX_CCUSTOMTREECTRL_H__234C8D10_F2CD_42B3_9972_384F6609F5D8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CVersatileTreeCtrl.h : header file
//
#include <vector>
#include <set>
#include <map>
using namespace std;
/************************************************************************************************
--------------------------------------------------------------------------------------------
CVersatileTreeCtrl
--------------------------------------------------------------------------------------------
AUTHOR: BABU
------
DATE: 30/01/2013
-----
FEATURES:
--------
1) THIS HAS THE FACILITY OF THE TREE ITEM TO HAVE CHECKBOX.SOME OF THE ITEMS
CAN HAVE CHECKBOXES AND SOME MAY NOT.
2) ALONG WITH THE CHECKBOX THE ITEM CAN HAVE ITS REGULAR IMAGE
3) SUPPORTS DRAG AND DROP. CONTAINS ENHANCED WAY OF DISPLAYING THE DRAG IMAGE.
4) IT PROVIDES THE MULTISELECTION USING THE CONTROL KEYS AS WELL AS SELECTION
BY USING RUBBER BAND
5) WHEN THE ITEM IS SELECTED/DESELECTED IT SENDS THE NOTIFICATION TO ITS PARENT
DIALOG VIA TVN_SELECTION_CHANGED.ARRAY OF SELECTED ITEMS ARE PASSED AS WPARAM.
6) WHEN THE ITEM IS CHECKED/UNCHECKED IT SENDS NOTIFICATION TO ITS PARENT DIALOG
VIA TVN_STATEICON_CLICKED.ARRAY OF CHECKED ITEMS ARE PASSED AS WPARAM
7) THE TREE COMES WITH ITS 5 CHECKBOXES.CHECK,MASKFORCHECK,UNCHECK,UNCHECKMASK AND
EMPTY.THESE ARE ALL OF SIZE 16X16.BUT IT IS NOT MANDATORY THAT YOU SHOULD HAVE
YOUR IMAGE FOR THE TREE ITEM OF SIZE16X16.THE ABOVE 5 BITMAPS WILL BE AUTOMATICALLY
SCALED BASED ON THE IMAGE SIZE OF THE ITEM.
8) YOU DONT HAVE TO DISPLAY THE CONTEXT MENU FOR EACH ITEM.JUST PROVIDE THE MENU ID
FOR EACH ITEM VIA THE CUSTOMDATA WHEN THE ITEM IS INSERTED.THEN THE TREE WILL TAKE
CARE OF DISPLAYING THE MENU.BUT IT'S YOU RESPONSIBILITY TO ADD THE HANDLER FOR
THE MENU COMMANDS AND HANDLE IT
9) FACILITY TO DISABLE THE LABEL EDITING FOR THE ITEMS.
10) FACILTIY TO SET THE COLOR FOR EACH ITEM
11) FACITLITY TO SET THE ITEM AS BOLD
12) FACILITY TO SET THE CALLBACK FUNCTION WHICH IS CALLED WHILE SCANNING THE TREE
13) PROVIDE ONLY THE IMAGE FOR THE ITEM.NO NEED FOR THE MASK IMAGE.BUT THE IMAGE
BACKGROUND SHOULD BE THE DEFAULT BACKGROUND COLOR CREATED FOR THE ICON.i.e,
GREEN COLOR (0,128128 ).
14) FACILITY TO DISABLE THE ITEM.NO NEED TO PROVIDE DISABLED IMAGE.
IT IS GENERATED AUTOMATICALLY.DISABLED ITEM CAN'T BE EXPANDED,RENAMED.
15) ROOT ITEM CAN'T BE DRAG AND DROPPED
16) ABILITY TO SET AN ITEM AS A TARGET FOR DROP OPERATION.IF ITEM IS NOT A
TARGET FOR THE DROP OPERATION,MOVING THE DRAGGED ITEMS OVER IT CHANGES TO
NO CURSOR.
*/
//************************************************************************************************
class CVersatileTreeCtrl;
//*************************************************************************
//THIS STRUCTURE IS SENT WHEN THE ITEMS OF THE TREE ARE SCANNED.
//SCAN IS NOTHING BUT THE TRAVERSING ALL THE ITEMS OF THE TREE
typedef struct __LOOPINFO
{
CVersatileTreeCtrl* pTree; //Pointer to the tree control
HTREEITEM hItem; //Current traversed item
CWnd* pParent; //Parent to the tree control usually the dialog
void* m_param1; //User specific information
void* m_param2; //User specific information
void* m_pResult; //Return value if any
}LOOPINFO,*PLOOPINFO;
//*************************************************************************
//TYPEDEF OF CALLBACK FUNCTION
typedef int (*ScanCallBackFunc) (LOOPINFO* pLoopInfo );
//GLOBAL FUNCTIONS USED AS THE CALLBACK FUNCTIONS TO BE CALLED WHILE SCANNING THE ITEMS
int FindItemsInRect( LOOPINFO* pLoopInfo );
int SelectItems( LOOPINFO* pLoopInfo );
int SetItemTextColor( LOOPINFO* pLoopInfo );
int ExpandItem( LOOPINFO* pLoopInfo );
int SearchItemData( LOOPINFO* pLoopInfo );
//*************************************************************************
//CUSTOM DATA WHICH IS ASSOCIATED WITH EACH TREE ITEM.THIS CONTAIN LOT OF INFORMATION
//OF THE ITEMS SUCH AS ITS NORMAL IMAGE,EXPANDED IMAGE,MASK FOR THEM,CHECKBOX IS REQUIRED ETC
typedef struct __CUSTOMITEMDATA
{
__CUSTOMITEMDATA()
{
m_uNormalImage = -1;
m_uExpandedImage = -1;
m_cMaskColor = RGB(0,128,128);
m_bEditable = true;
m_bDropTarget = true;
m_bChecked = false;
m_bCheckState = false;
m_iNormalIndex = -1;
m_iExpandedIndex = -1;
m_iCheckedNormalIndex = -1;
m_iUnCheckedNormalIndex = -1;
m_iCheckedExpandedIndex = -1;
m_iUnCheckedExpandedIndex = -1;
m_cItemColor = RGB(255,255,255);
m_bIsBold = false;
m_uMenuID = -1;
m_bEnable = true;
m_iDisableIndex = -1;
m_bExpStateBefDisable = false;
}
__CUSTOMITEMDATA(__CUSTOMITEMDATA& src )
{
m_uNormalImage = src.m_uNormalImage;
m_uExpandedImage = src.m_uExpandedImage;
m_bEditable = src.m_bEditable;
m_bDropTarget = src.m_bDropTarget;
m_bChecked = src.m_bChecked;
m_bCheckState = src.m_bCheckState;
m_iNormalIndex = src.m_iNormalIndex;
m_iExpandedIndex = src.m_iExpandedIndex;
m_iCheckedNormalIndex = src.m_iCheckedNormalIndex;
m_iUnCheckedNormalIndex = src.m_iUnCheckedNormalIndex;
m_iCheckedExpandedIndex = src.m_iCheckedExpandedIndex;
m_iUnCheckedExpandedIndex = src.m_iUnCheckedExpandedIndex;
m_cItemColor = src.m_cItemColor;
m_bIsBold = src.m_bIsBold;
m_uMenuID = src.m_uMenuID;
m_bEnable = src.m_bEnable;
m_iDisableIndex = src.m_iDisableIndex;
m_bExpStateBefDisable = src.m_bExpStateBefDisable;
}
void operator = ( __CUSTOMITEMDATA& rhs )
{
m_uNormalImage = rhs.m_uNormalImage;
m_uExpandedImage = rhs.m_uExpandedImage;
m_bEditable = rhs.m_bEditable;
m_bDropTarget = rhs.m_bDropTarget;
m_bChecked = rhs.m_bChecked;
m_bCheckState = rhs.m_bCheckState;
m_iNormalIndex = rhs.m_iNormalIndex;
m_iExpandedIndex = rhs.m_iExpandedIndex;
m_iCheckedNormalIndex = rhs.m_iCheckedNormalIndex;
m_iUnCheckedNormalIndex = rhs.m_iUnCheckedNormalIndex;
m_iCheckedExpandedIndex = rhs.m_iCheckedExpandedIndex;
m_iUnCheckedExpandedIndex = rhs.m_iUnCheckedExpandedIndex;
m_cItemColor = rhs.m_cItemColor;
m_bIsBold = rhs.m_bIsBold;
m_uMenuID = rhs.m_uMenuID;
m_bEnable = rhs.m_bEnable;
m_iDisableIndex = rhs.m_iDisableIndex;
m_bExpStateBefDisable = rhs.m_bExpStateBefDisable;
}
//EXPOSED DATA: TO BE SET BY THE USER.
//####################################
//Resource of the images for normal and expanded states.Remember these are the bitmap
//ID's and not the indice.
UINT m_uNormalImage; //Image given when the item is in normal state
UINT m_uExpandedImage; //Image Given when the item is expanded
COLORREF m_cMaskColor; //If the mask image is not given this can be considered as the mask color
bool m_bEditable; //Flag to indicate whether the item is editable or not
bool m_bDropTarget; //Is the item is valid target for dropping operation
bool m_bChecked; //Whether the item has to have CHECKBOX or NOT
bool m_bCheckState; //If checkbox is needed, state of it [CHECKED/UNCHECKED]
COLORREF m_cItemColor; //Color of the text of the item
bool m_bIsBold; //Item to be displayed in bold font
UINT m_uMenuID; //Context menu id given to the item
bool m_bEnable; //Enable or disable tree item
bool m_bExpStateBefDisable; //True if the item is in expanded state before disabling, false otherwise
//INTERNAL DATA: DATA NOT EXPOSED TO USER.INERNALLY USED BY THE TREE
//####################################################################
//Indice of the images representing various state from the image list
//-------------------------------------------------------------------
//Normal State with NO CHECKBOX
int m_iNormalIndex;
//Expanded State with NO CHECKBOX
int m_iExpandedIndex;
//Normal State with CHECKBOX
int m_iCheckedNormalIndex; //Index of the checked/collapsed(normal) image
int m_iUnCheckedNormalIndex; //Index of the unchecked/collapsed(normal) image
//Expanded State: In Some case item wont have expanded image.So the following
//are equal to the above 2. i.e, m_iCheckedExpandedIndex = m_iCheckedNormalIndex
//and m_iUnCheckedExpandedIndex = m_iUnCheckedNormalIndex.
//Expaned State with CHECKBOX
int m_iCheckedExpandedIndex; //Index of the checked/expanded image
int m_iUnCheckedExpandedIndex; //Index of the checked/expanded image
//Disabled image index
int m_iDisableIndex; //Index of the image for the disable state
}CUSTOMITEMDATA,*PCUSTOMITEMDATA;
//*************************************************************************
//INSERT STRUCTURE USED TO INSERT THE ITEM IN THE TREE.SIMILAR TO TVINSERTSTRUCT
//USED IN THE CTreeCtrl WITH ADDITIONAL INFORMATION OF CUSTOM DATA
typedef struct __CUSTOMINSERTSTRUCT
{
__CUSTOMINSERTSTRUCT()
{
m_pCustomData = NULL;
}
~__CUSTOMINSERTSTRUCT()
{
//delete m_pCustomData;
}
TVINSERTSTRUCT m_tvIS; //Insert structure of the CTreeCtrl
PCUSTOMITEMDATA m_pCustomData; //Custom data to be used with the item
}CUSTOMINSERTSTRUCT,*PCUSTOMINSERTSTRUCT;
//*************************************************************************
//CUSTOM STRUCTURE WHICH GIVES INFORMATION ABOUT THE NOTIFICATIION MESSAGE.
//SAME AS OF NMHDR OF CTreeCtrl WITH ADDITIONAL INFORMATION
typedef struct _CUSTNMHDR
{
NMHDR m_hdr; //Info about the notification
HTREEITEM m_hItem; //Tree item which caused the notification
void* m_data; //User specific data,if any
}CUSTNMHDR,*LPCUSTNMHDR;
//*************************************************************************
/////////////////////////////////////////////////////////////////////////////
// CVersatileTreeCtrl window
class CVersatileTreeCtrl : public CTreeCtrl
{
// Construction
public:
CVersatileTreeCtrl();
// Attributes
public:
//Dragging Related Info
//---------------------
bool m_bIsDragging; //Whether the dragging in ON/OFF
HTREEITEM m_hDragSourceItem; //Item which is getting dragged
HTREEITEM m_hDragTargetItem; //Target item on which the dragged to be dropped
bool m_bMoveItem; //When dropped on the target the source item will be moved
HTREEITEM m_hOrigTgt;
//Rubber banding selection Related Info
//-------------------------------------
bool m_bIsBandingON; //Is Banding selection is ON/OFF
CPoint m_startPt,m_endPt; //Start point and end point of the banding rectangle
CArray<HTREEITEM,HTREEITEM> m_aItemsInRect; //Items falls inside the banding rectangle
HCURSOR m_defaultCursor,m_noCursor; //Cursors to indicate the banding status
vector<HTREEITEM> m_vecSelectedItems; //vector of selected items
vector<HTREEITEM> m_vecDraggedItems; //vector of items being dragged for drop operation
set<HTREEITEM> m_vecCheckedItems; //vector of items with check box is ON
//Flag to indicate the selected items matches with the previous selected items
bool m_bOldItemSelected;
CImageList* m_pImgList; //Image list associated with the tree
CImageList* m_pDragImageList; //Image list to be used for dragging
bool m_bStartFound; //Flag used for scan operation
//To store the resource id's of the bitmaps used in the imagelist
map<UINT, vector<int> > m_mapBitmapID;
//Make this flag as false when the user double clicks on the check box so that it
//wont allow expand/collpase.Where as clicking on the image of the item should allow expand/collpase.
bool m_bAllowExpand;
//Item on which right click is done.All the menu command acts on
//the right clicked item and not on the selected items
HTREEITEM m_hRClickItem;
//To stop the scanning [ Iterating ] the items
bool m_bContinueScan;
COLORREF m_cMaskColor;
// Operations
public:
//To set the background color for the tree control
void SetBackgroundColor( COLORREF bkColor ); //[in] - New background color to be set
//Helper function used to Show the item information
void ShowItemInfo(HTREEITEM hItem );
//To set the bold font for the label
void SetBoldFont( HTREEITEM hItem ); //[in] - Item to which the font to be set as bold
//To set the color for the item text
void SetItemColor( HTREEITEM hItem, //[in] - Item to which the color to be set
COLORREF col //[in] - New color of the item
);
//To set checkbox for a given item
void SetCheckBox( HTREEITEM hItem, //[in] - Item to be set
bool bCheck ); //[in] - TRUE to set the checkbox,false to remove
//To check/uncheck an item
void SetCheck( HTREEITEM hItem, //[in] - Item to which checkbox to be set
bool bCheck //[in] - TRUE to set the checkbox,false to remove
);
//To enable/disable the item
void EnableItem( HTREEITEM hItem, //[in] - Item to be enabled/disabled
bool bEnable //[in] - True for enable,false for disable
);
//To expand the entire tree
void ExpandTree(HTREEITEM hItem,bool Expand = true); //[in] - Item to be expanded
//To insert a item
HTREEITEM InsertItem(PCUSTOMINSERTSTRUCT lpInsertStruct ); //[in] - Insert structure
//Copy item to another parent
void CopyItem( HTREEITEM hSourceItem, //[in] - Item to be copied
HTREEITEM hTargetItem, //[in] - Target item into which the item is copied
bool bMoveSibling = false //[in] - Whether the sibling has to be moved
);
//To a delete an item recurisvely
void DeleteItem( HTREEITEM hTreeItem ); //[in] - Item to be deleted
//To iterate all the items and call the callback function for each item
void IterateItems( ScanCallBackFunc func, //[in] - Call back function to be called on each item
HTREEITEM hIterStart = NULL, //[in] - Start node for the iteration
HTREEITEM hIterEnd = NULL, //[in] - End node to stop the iteration
void* pInfo = NULL //[in] - User parameter
);
//To iterate all the items and call the callback function for each item
void ScanItems( ScanCallBackFunc func, //[in] - Call back function to be called on each item
HTREEITEM hStart, //[in] - Start node of the tree
HTREEITEM hIterStart = NULL, //[in] - Start node for the iteration
HTREEITEM hIterEnd = NULL, //[in] - End node to stop the iteration
void* pInfo = NULL //[in] - User parameter
);
//To invert the rectangle being drawn
void InvertRectangle( CDC* pDC, //[in] - Device context used for drawing
CPoint startPt, //[in] - Start point of the rectangle
CPoint endPt ); //[in] - End point of the rectangle
//To find the items inside the given rectangle
bool ItemsInRect(CRect rect); //[in] - Bounding rectangle
//To get the list of selected items
void CollectSelectedItems();
//To get the first selected item
HTREEITEM GetFirstSelectedItem() const ;
//To get the next selected item
HTREEITEM GetNextSelectedItem(HTREEITEM hItem) const ;
//To generate the imagelist for the dragging
//CImageList* GetImageListForDrag(CArray<HTREEITEM,HTREEITEM> &cArrDragItems);
CImageList* GetImageListForDrag(vector<HTREEITEM> &cArrDragItems);
//To prepare the bitmap along with the check box
int PrepareImageWithPrefixBmp( UINT iBmpID, //[in] - ID of the bitmap
CBitmap& bmp, //[out] - Prepared bitmap object
int& newBmpW, //[out] - Width of the newbitmap
int& newBmpH, //[out] - Height of the newbitmap
UINT iPrefixBmpID = -1 //[in] - ID of the bitmap prefixed to the image
);
int AddImageToList( PCUSTOMINSERTSTRUCT lpInsertStruct );
//To add the images for normal and expanded state [ WITHOUT CHECKBOX ]
int AddNoramlStateImages( UINT uBmpID, //[in] - ID for the normal image
UINT uExpBmpID, //[in] - ID for the expanded image
PCUSTOMINSERTSTRUCT lpInsertStruct //[in] - Custom Insert strcutre
);
//To add the images for the check,uncheck images for normal state [WITH CHECKBOX]
int AddCheckStateImages(UINT uBmpID, //[in] - ID for the normal image
UINT uCheckBmpID, //[in] l- ID of the check image
UINT uUnCheckBmpID, //[in] - ID of the uncheck image
PCUSTOMITEMDATA pCustData //[in] - Custom data where the image index is stored
);
//To add the images for the check,uncheck images for expanded state
int AddExpStateImages(UINT uBmpID, //[in] - ID for the normal image
UINT uExpBmpID, //[in] - ID for the expanded image
UINT uCheckBmpID, //[in] - ID of the check image
UINT uUnCheckBmpID, //[in] - ID of the uncheck image
PCUSTOMITEMDATA pCustData //[in[ - Custom data where the image index is stored
);
//To find the index of the bitmap image
int GetImageIndex( UINT nBmpID ); //[in] - ID of the bitmap
//To scale a giveb bitmap
void ScaleBitmap( CBitmap& bmp, //[in] - Bitmap to be scaled
int Width, //[in] - width of the bitmap
int Height, //[in] - Height of the bitmap
int newWidth, //[in] - New width of the bitmap
int newHeight, //[in] - New Height of the bitmap
CBitmap& resBmp//[in] - Resulting scaled bitmap
);
//To combine to given bitmaps
bool AddBitamps( CBitmap* pBmp1, //[in] - First bitmap Ref
CBitmap* pBmp2, //[in] - Second bitmap Ref
CBitmap* resBmp, //[out] - Resulting bitmap
int W = -1, //[in] - New width of the bitmap
int H = -1); //[in] - New height of the bitmap
//To get the index of the bitmap from the image list
int GetBitmapIndexFromImgList( UINT uBitmapID ); //[in] - ID of the bitmap
//To add a given image and its mask to the list
int AddImage( UINT uBmpID, //[in] - Resource id of the bitmap
UINT uPrefixBmpID //[in] - Resource id of the prefix bitmap
);
//To set the Move Item flag of drag
void SetMoveDraggedItem( bool flag ); //[in] - True to move the item,false to copy the item
//To set the color in the bitmap
void SetBitMapColor( CBitmap& bmp, //[out] - Resuting disabled image
COLORREF color, //[in] - Color to be set for each pixel of the bitmap
COLORREF excludeColor //[in] - Color to be excluded
);
//To generate the disabled image for the item
void GenerateDisableImage( CBitmap& bmp ); //[out] - Resuting disabled image
//To get the bitmap of the image from the image list
bool GetBitampFromImageList( int iIndex, //[in] - Index of the image
CBitmap& bmp //[out] - Resulting bitmap
);
//To convert the icon into bitmap
bool GetBitmapFromIcon( HICON hIcon, //[in] - Handle to the icon to be converted
int w, //[in] - Width of the icon
int h ,CBitmap& bmp); //[in] - Height of the icon
//To set the image index based on the state of the item
void SetImage( HTREEITEM hItem ); //[in] - Item to which the image to be set
//To set the image when the item is expanded
void SetExpandImage( HTREEITEM hItem, //[in] - Item to which the image to be set
bool bItemExpanded //[in] - Item is expanded or collpased
);
//To check whether normal checked index is avialbale or not
int IsNormalCheckedExists( UINT uBmpID );
//Is any of the parent is in disabled state
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CVersatileTreeCtrl)
protected:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CVersatileTreeCtrl();
// Generated message map functions
protected:
//{{AFX_MSG(CVersatileTreeCtrl)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnClickLButton(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg LRESULT OnChkBoxClicked( WPARAM wp, LPARAM lp);
//afx_msg void OnChkBoxClicked( NMHDR* pNMHDR,LRESULT* pResult );
afx_msg void OnPaint();
afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
friend void FindItemsInRect( HTREEITEM hItem,CWnd* pParent );
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CCUSTOMTREECTRL_H__234C8D10_F2CD_42B3_9972_384F6609F5D8__INCLUDED_)