//
// mxToolKit (c) 1999 by Mete Ciragan
//
// file: mxTreeView.cpp
// implementation: Win32 API
// last modified: May 03 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
#include <mx/mxTreeView.h>
#include <windows.h>
#include <commctrl.h>
class mxTreeView_i
{
public:
HWND d_hwnd;
};
mxTreeView::mxTreeView (mxWindow *parent, int x, int y, int w, int h, int id)
: mxWidget (parent, x, y, w, h)
{
if (!parent)
return;
d_this = new mxTreeView_i;
DWORD dwStyle = TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_VISIBLE | WS_CHILD;
HWND hwndParent = (HWND) ((mxWidget *) parent)->getHandle ();
d_this->d_hwnd = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREEVIEW, "", dwStyle,
x, y, w, h, hwndParent,
(HMENU) id, (HINSTANCE) GetModuleHandle (NULL), NULL);
SendMessage (d_this->d_hwnd, WM_SETFONT, (WPARAM) (HFONT) GetStockObject (ANSI_VAR_FONT), MAKELPARAM (TRUE, 0));
SetWindowLong (d_this->d_hwnd, GWL_USERDATA, (LONG) this);
setHandle ((void *) d_this->d_hwnd);
setType (MX_TREEVIEW);
setParent (parent);
setId (id);
}
mxTreeView::~mxTreeView ()
{
remove (0);
delete d_this;
}
mxTreeViewItem*
mxTreeView::add (mxTreeViewItem *parent, const char *item)
{
if (!d_this)
return 0;
TV_ITEM tvItem;
tvItem.mask = TVIF_TEXT;
tvItem.pszText = (LPSTR) item;
tvItem.cchTextMax = 256;
HTREEITEM hParent;
if (!parent)
hParent = TVI_ROOT;
else
hParent = (HTREEITEM) parent;
TV_INSERTSTRUCT tvInsert;
tvInsert.hParent = hParent;
tvInsert.hInsertAfter = TVI_LAST;
tvInsert.item = tvItem;
return (mxTreeViewItem *) TreeView_InsertItem (d_this->d_hwnd, &tvInsert);
}
void
mxTreeView::remove (mxTreeViewItem *item)
{
if (!d_this)
return;
if (!item)
TreeView_DeleteAllItems (d_this->d_hwnd);
else
TreeView_DeleteItem (d_this->d_hwnd, (HTREEITEM) item);
}
void
mxTreeView::removeAll ()
{
remove( 0 );
}
void
mxTreeView::setLabel (mxTreeViewItem *item, const char *label)
{
if (!d_this)
return;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_TEXT;
tvItem.hItem = (HTREEITEM) item;
tvItem.pszText = (LPSTR) label;
tvItem.cchTextMax = 256;
TreeView_SetItem (d_this->d_hwnd, &tvItem);
}
}
void
mxTreeView::setUserData (mxTreeViewItem *item, void *userData)
{
if (!d_this)
return;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_PARAM;
tvItem.hItem = (HTREEITEM) item;
tvItem.lParam = (LPARAM) userData;
TreeView_SetItem (d_this->d_hwnd, &tvItem);
}
}
void
mxTreeView::setOpen (mxTreeViewItem *item, bool b)
{
if (!d_this)
return;
if (item)
TreeView_Expand (d_this->d_hwnd, (HTREEITEM) item, b ? TVE_EXPAND:TVE_COLLAPSE);
}
void
mxTreeView::setSelected (mxTreeViewItem *item, bool b)
{
if (!d_this)
return;
if (item)
TreeView_SelectItem (d_this->d_hwnd, (HTREEITEM) item);
}
mxTreeViewItem*
mxTreeView::getFirstChild (mxTreeViewItem *item) const
{
if (!d_this)
return 0;
return (mxTreeViewItem *) TreeView_GetChild (d_this->d_hwnd, item ? (HTREEITEM) item:TVI_ROOT);
}
mxTreeViewItem*
mxTreeView::getNextChild (mxTreeViewItem *item) const
{
if (!d_this)
return 0;
if (item)
return (mxTreeViewItem *) TreeView_GetNextSibling (d_this->d_hwnd, (HTREEITEM) item);
else
return 0;
}
mxTreeViewItem*
mxTreeView::getSelectedItem () const
{
if (!d_this)
return 0;
return (mxTreeViewItem *) TreeView_GetSelection (d_this->d_hwnd);
}
const char*
mxTreeView::getLabel (mxTreeViewItem *item) const
{
static char label[256];
strcpy (label, "");
if (!d_this)
return label;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_TEXT;
tvItem.hItem = (HTREEITEM) item;
tvItem.pszText = (LPSTR) label;
tvItem.cchTextMax = 256;
TreeView_GetItem (d_this->d_hwnd, &tvItem);
return tvItem.pszText;
}
return label;
}
void*
mxTreeView::getUserData (mxTreeViewItem *item) const
{
if (!d_this)
return 0;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_PARAM;
tvItem.hItem = (HTREEITEM) item;
TreeView_GetItem (d_this->d_hwnd, &tvItem);
return (void *) tvItem.lParam;
}
return 0;
}
bool
mxTreeView::isOpen (mxTreeViewItem *item) const
{
if (!d_this)
return false;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = (HTREEITEM) item;
tvItem.stateMask = TVIS_STATEIMAGEMASK;
TreeView_GetItem (d_this->d_hwnd, &tvItem);
return ((tvItem.state & TVIS_EXPANDED) == TVIS_EXPANDED);
}
return false;
}
bool
mxTreeView::isSelected (mxTreeViewItem *item) const
{
if (!d_this)
return false;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = (HTREEITEM) item;
tvItem.stateMask = TVIS_STATEIMAGEMASK;
TreeView_GetItem (d_this->d_hwnd, &tvItem);
return ((tvItem.state & TVIS_SELECTED) == TVIS_SELECTED);
}
return false;
}
mxTreeViewItem *
mxTreeView::getParent (mxTreeViewItem *item) const
{
if (!d_this)
return 0;
if (item)
return (mxTreeViewItem *) TreeView_GetParent (d_this->d_hwnd, (HTREEITEM) item);
return 0;
}
void mxTreeView::setImageList( void *himagelist )
{
TreeView_SetImageList(d_this->d_hwnd, (HIMAGELIST)himagelist, TVSIL_NORMAL);
}
void mxTreeView::setImages(mxTreeViewItem *item, int imagenormal, int imageselected )
{
if (!d_this)
return;
if (item)
{
TV_ITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_SELECTEDIMAGE | TVIF_IMAGE ;
tvItem.hItem = (HTREEITEM) item;
tvItem.iImage = imagenormal;
tvItem.iSelectedImage = imageselected;
tvItem.stateMask = TVIS_STATEIMAGEMASK;
TreeView_SetItem (d_this->d_hwnd, &tvItem);
}
}
void mxTreeView::sortTree( mxTreeViewItem *parent, bool recurse,
void *func, int parameter )
{
if (!d_this)
return;
TVSORTCB cb;
memset( &cb, 0, sizeof( cb ) );
cb.hParent = (HTREEITEM)parent;
cb.lParam = parameter;
cb.lpfnCompare = (int (__stdcall *)(long,long,long)) func;
TreeView_SortChildrenCB( d_this->d_hwnd, &cb, recurse );
}
void mxTreeView::scrollTo( mxTreeViewItem *item )
{
if (!d_this)
return;
TreeView_EnsureVisible( d_this->d_hwnd, item );
}