You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
6.3 KiB
356 lines
6.3 KiB
// |
|
// 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 "mxtk/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 ); |
|
}
|
|
|