simplify the client data/non standard images handling code by unconditionally using wxTreeItemParam struct instead of using indirect data only sometimes; also extend it to contain the id which allows to always sort the items correctly (closes bug 1447419) (patch 1449096 from Ryan)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39078 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2006-05-06 19:17:22 +00:00
parent 4c15a37592
commit 4523ebb3f1
2 changed files with 171 additions and 345 deletions

View File

@ -247,11 +247,6 @@ protected:
// end edit label
void DoEndEditLabel(bool discardChanges = false);
// data used only while editing the item label:
wxTextCtrl *m_textCtrl; // text control in which it is edited
wxTreeItemId m_idEdited; // the item being edited
virtual wxTreeItemId DoInsertItem(const wxTreeItemId& parent,
size_t pos,
const wxString& text,
@ -264,6 +259,14 @@ protected:
wxTreeItemData *data = NULL);
virtual wxTreeItemId DoTreeHitTest(const wxPoint& point, int& flags);
// obtain the user data for the lParam member of TV_ITEM
class wxTreeItemParam *GetItemParam(const wxTreeItemId& item) const;
// data used only while editing the item label:
wxTextCtrl *m_textCtrl; // text control in which it is edited
wxTreeItemId m_idEdited; // the item being edited
private:
// the common part of all ctors
void Init();
@ -274,23 +277,8 @@ private:
inline void DoExpand(const wxTreeItemId& item, int flag);
int DoGetItemImageFromData(const wxTreeItemId& item,
wxTreeItemIcon which) const;
void DoSetItemImageFromData(const wxTreeItemId& item,
int image,
wxTreeItemIcon which) const;
void DoSetItemImages(const wxTreeItemId& item, int image, int imageSel);
void DeleteTextCtrl();
// support for additional item images which we implement using
// wxTreeItemIndirectData technique - see the comments in msw/treectrl.cpp
void SetIndirectItemData(const wxTreeItemId& item,
class wxTreeItemIndirectData *data);
bool HasIndirectData(const wxTreeItemId& item) const;
bool IsDataIndirect(wxTreeItemData *data) const
{ return data && data->GetId().m_pItem == 0; }
// the hash storing the items attributes (indexed by item ids)
wxMapTreeAttr m_attrs;

View File

@ -270,27 +270,93 @@ struct wxTreeViewItem : public TV_ITEM
}
};
// ----------------------------------------------------------------------------
// This class is our userdata/lParam for the TV_ITEMs stored in the treeview.
//
// We need this for a couple of reasons:
//
// 1) This class is needed for support of different images: the Win32 common
// control natively supports only 2 images (the normal one and another for the
// selected state). We wish to provide support for 2 more of them for folder
// items (i.e. those which have children): for expanded state and for expanded
// selected state. For this we use this structure to store the additional items
// images.
//
// 2) This class is also needed to hold the HITEM so that we can sort
// it correctly in the MSW sort callback.
//
// In addition it makes other workarounds such as this easier and helps
// simplify the code.
// ----------------------------------------------------------------------------
class wxTreeItemParam
{
public:
wxTreeItemParam()
: m_item(NULL),
m_data(NULL)
{
for ( size_t n = 0; n < WXSIZEOF(m_images); n++ )
{
m_images[n] = -1;
}
}
// dtor deletes the associated data as well
virtual ~wxTreeItemParam() { delete m_data; }
// accessors
// get the real data associated with the item
wxTreeItemData *GetData() const { return m_data; }
// change it
void SetData(wxTreeItemData *data) { m_data = data; }
// do we have such image?
bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; }
// get image
int GetImage(wxTreeItemIcon which) const { return m_images[which]; }
// change it
void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
// get item
const wxTreeItemId& GetItem() const { return m_item; }
// set item
void SetItem(const wxTreeItemId& item) { m_item = item; }
protected:
// all the images associated with the item
int m_images[wxTreeItemIcon_Max];
// item for sort callbacks
wxTreeItemId m_item;
// the real client data
wxTreeItemData *m_data;
DECLARE_NO_COPY_CLASS(wxTreeItemParam)
};
// wxVirutalNode is used in place of a single root when 'hidden' root is
// specified.
class wxVirtualNode : public wxTreeViewItem
{
public:
wxVirtualNode(wxTreeItemData *data)
wxVirtualNode(wxTreeItemParam *param)
: wxTreeViewItem(TVI_ROOT, 0)
{
m_data = data;
m_param = param;
}
~wxVirtualNode()
{
delete m_data;
delete m_param;
}
wxTreeItemData *GetData() const { return m_data; }
void SetData(wxTreeItemData *data) { delete m_data; m_data = data; }
wxTreeItemParam *GetParam() const { return m_param; }
void SetParam(wxTreeItemParam *param) { delete m_param; m_param = param; }
private:
wxTreeItemData *m_data;
wxTreeItemParam *m_param;
DECLARE_NO_COPY_CLASS(wxVirtualNode)
};
@ -411,69 +477,6 @@ private:
DECLARE_NO_COPY_CLASS(TraverseCounter)
};
// ----------------------------------------------------------------------------
// This class is needed for support of different images: the Win32 common
// control natively supports only 2 images (the normal one and another for the
// selected state). We wish to provide support for 2 more of them for folder
// items (i.e. those which have children): for expanded state and for expanded
// selected state. For this we use this structure to store the additional items
// images.
//
// There is only one problem with this: when we retrieve the item's data, we
// don't know whether we get a pointer to wxTreeItemData or
// wxTreeItemIndirectData. So we always set the item id to an invalid value
// in this class and the code using the client data checks for it and retrieves
// the real client data in this case.
// ----------------------------------------------------------------------------
class wxTreeItemIndirectData : public wxTreeItemData
{
public:
// ctor associates this data with the item and the real item data becomes
// available through our GetData() method
wxTreeItemIndirectData(wxTreeCtrl *tree, const wxTreeItemId& item)
{
for ( size_t n = 0; n < WXSIZEOF(m_images); n++ )
{
m_images[n] = -1;
}
// save the old data
m_data = tree->GetItemData(item);
// and set ourselves as the new one
tree->SetIndirectItemData(item, this);
// we must have the invalid value for the item
m_pItem = 0l;
}
// dtor deletes the associated data as well
virtual ~wxTreeItemIndirectData() { delete m_data; }
// accessors
// get the real data associated with the item
wxTreeItemData *GetData() const { return m_data; }
// change it
void SetData(wxTreeItemData *data) { m_data = data; }
// do we have such image?
bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; }
// get image
int GetImage(wxTreeItemIcon which) const { return m_images[which]; }
// change it
void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
private:
// all the images associated with the item
int m_images[wxTreeItemIcon_Max];
// the real client data
wxTreeItemData *m_data;
DECLARE_NO_COPY_CLASS(wxTreeItemIndirectData)
};
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
@ -798,7 +801,7 @@ wxTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
// simple wrappers which add error checking in debug mode
bool wxTreeCtrl::DoGetItem(wxTreeViewItem* tvItem) const
bool wxTreeCtrl::DoGetItem(wxTreeViewItem *tvItem) const
{
wxCHECK_MSG( tvItem->hItem != TVI_ROOT, false,
_T("can't retrieve virtual root item") );
@ -813,7 +816,7 @@ bool wxTreeCtrl::DoGetItem(wxTreeViewItem* tvItem) const
return true;
}
void wxTreeCtrl::DoSetItem(wxTreeViewItem* tvItem)
void wxTreeCtrl::DoSetItem(wxTreeViewItem *tvItem)
{
if ( TreeView_SetItem(GetHwnd(), tvItem) == -1 )
{
@ -945,29 +948,40 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
}
}
int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item,
wxTreeItemIcon which) const
int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
wxTreeItemIcon which) const
{
wxTreeViewItem tvItem(item, TVIF_PARAM);
if ( !DoGetItem(&tvItem) )
wxCHECK_MSG( item.IsOk(), -1, wxT("invalid tree item") );
if ( (HITEM(item) == TVI_ROOT) && (m_windowStyle & wxTR_HIDE_ROOT) )
{
// no images for hidden root item
return -1;
}
return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which);
wxTreeItemParam *param = GetItemParam(item);
return param ? param->GetImage(which) : -1;
}
void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
int image,
wxTreeItemIcon which) const
void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
wxTreeItemIcon which)
{
wxTreeViewItem tvItem(item, TVIF_PARAM);
if ( !DoGetItem(&tvItem) )
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
wxCHECK_RET( which >= 0 &&
which < wxTreeItemIcon_Max,
wxT("invalid image index"));
if ( (HITEM(item) == TVI_ROOT) && (m_windowStyle & wxTR_HIDE_ROOT) )
{
// no images for hidden root item
return;
}
wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam);
wxTreeItemParam *data = GetItemParam(item);
if ( !data )
return;
data->SetImage(image, which);
@ -985,218 +999,47 @@ void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
}
}
void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
int image,
int imageSel)
{
wxTreeViewItem tvItem(item, TVIF_IMAGE | TVIF_SELECTEDIMAGE);
tvItem.iSelectedImage = imageSel;
tvItem.iImage = image;
DoSetItem(&tvItem);
}
int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
wxTreeItemIcon which) const
{
wxCHECK_MSG( item.IsOk(), -1, wxT("invalid tree item") );
if ( (HITEM(item) == TVI_ROOT) && (m_windowStyle & wxTR_HIDE_ROOT) )
{
// TODO: Maybe a hidden root can still provide images?
return -1;
}
if ( HasIndirectData(item) )
{
return DoGetItemImageFromData(item, which);
}
UINT mask;
switch ( which )
{
default:
wxFAIL_MSG( wxT("unknown tree item image type") );
case wxTreeItemIcon_Normal:
mask = TVIF_IMAGE;
break;
case wxTreeItemIcon_Selected:
mask = TVIF_SELECTEDIMAGE;
break;
case wxTreeItemIcon_Expanded:
case wxTreeItemIcon_SelectedExpanded:
return -1;
}
wxTreeViewItem tvItem(item, mask);
DoGetItem(&tvItem);
return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
}
void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
wxTreeItemIcon which)
{
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
if ( IS_VIRTUAL_ROOT(item) )
{
// TODO: Maybe a hidden root can still store images?
return;
}
int imageNormal,
imageSel;
switch ( which )
{
default:
wxFAIL_MSG( wxT("unknown tree item image type") );
// fall through
case wxTreeItemIcon_Normal:
{
const int imageNormalOld = GetItemImage(item);
const int imageSelOld =
GetItemImage(item, wxTreeItemIcon_Selected);
// always set the normal image
imageNormal = image;
// if the selected and normal images were the same, they should
// be the same after the update, otherwise leave the selected
// image as it was
imageSel = imageNormalOld == imageSelOld ? image : imageSelOld;
}
break;
case wxTreeItemIcon_Selected:
imageNormal = GetItemImage(item);
imageSel = image;
break;
case wxTreeItemIcon_Expanded:
case wxTreeItemIcon_SelectedExpanded:
if ( !HasIndirectData(item) )
{
// we need to get the old images first, because after we create
// the wxTreeItemIndirectData GetItemXXXImage() will use it to
// get the images
imageNormal = GetItemImage(item);
imageSel = GetItemImage(item, wxTreeItemIcon_Selected);
// if it doesn't have it yet, add it
wxTreeItemIndirectData *data = new
wxTreeItemIndirectData(this, item);
// copy the data to the new location
data->SetImage(imageNormal, wxTreeItemIcon_Normal);
data->SetImage(imageSel, wxTreeItemIcon_Selected);
}
DoSetItemImageFromData(item, image, which);
// reset the normal/selected images because we won't use them any
// more - now they're stored inside the indirect data
imageNormal =
imageSel = I_IMAGECALLBACK;
break;
}
// NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
// change both normal and selected image - otherwise the change simply
// doesn't take place!
DoSetItemImages(item, imageNormal, imageSel);
}
wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
wxTreeItemParam *wxTreeCtrl::GetItemParam(const wxTreeItemId& item) const
{
wxCHECK_MSG( item.IsOk(), NULL, wxT("invalid tree item") );
wxTreeViewItem tvItem(item, TVIF_PARAM);
// Hidden root may have data.
// hidden root may still have data.
if ( IS_VIRTUAL_ROOT(item) )
{
return GET_VIRTUAL_ROOT()->GetData();
return GET_VIRTUAL_ROOT()->GetParam();
}
// Visible node.
// visible node.
if ( !DoGetItem(&tvItem) )
{
return NULL;
}
wxTreeItemData *data = (wxTreeItemData *)tvItem.lParam;
if ( IsDataIndirect(data) )
{
data = ((wxTreeItemIndirectData *)data)->GetData();
}
return (wxTreeItemParam *)tvItem.lParam;
}
return data;
wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
{
wxTreeItemParam *data = GetItemParam(item);
return data ? data->GetData() : NULL;
}
void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
{
wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
if ( IS_VIRTUAL_ROOT(item) )
{
GET_VIRTUAL_ROOT()->SetData(data);
}
// first, associate this piece of data with this item
if ( data )
{
data->SetId(item);
}
wxTreeViewItem tvItem(item, TVIF_PARAM);
wxTreeItemParam *param = GetItemParam(item);
if ( HasIndirectData(item) )
{
if ( DoGetItem(&tvItem) )
{
((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data);
}
else
{
wxFAIL_MSG( wxT("failed to change tree items data") );
}
}
else
{
tvItem.lParam = (LPARAM)data;
DoSetItem(&tvItem);
}
}
wxCHECK_RET( param, wxT("failed to change tree items data") );
void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
wxTreeItemIndirectData *data)
{
// this should never happen because it's unnecessary and will probably lead
// to crash too because the code elsewhere supposes that the pointer the
// wxTreeItemIndirectData has is a real wxItemData and not
// wxTreeItemIndirectData as well
wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
SetItemData(item, data);
}
bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
{
// query the item itself
wxTreeViewItem tvItem(item, TVIF_PARAM);
if ( !DoGetItem(&tvItem) )
{
return false;
}
wxTreeItemData *data = (wxTreeItemData *)tvItem.lParam;
return data && IsDataIndirect(data);
param->SetData(data);
}
void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
@ -1643,30 +1486,24 @@ wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent,
tvIns.item.cchTextMax = 0;
}
if ( image != -1 )
{
mask |= TVIF_IMAGE;
tvIns.item.iImage = image;
// we use the wxTreeItemParam of the LPARAM to return the image
mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvIns.item.iImage = I_IMAGECALLBACK;
tvIns.item.iSelectedImage = I_IMAGECALLBACK;
if ( selectedImage == -1 )
{
// take the same image for selected icon if not specified
selectedImage = image;
}
}
// create the param and setup the initial image numbers
wxTreeItemParam *param = new wxTreeItemParam;
if ( selectedImage != -1 )
{
mask |= TVIF_SELECTEDIMAGE;
tvIns.item.iSelectedImage = selectedImage;
}
param->SetImage(image, wxTreeItemIcon_Normal);
if ( data != NULL )
{
mask |= TVIF_PARAM;
tvIns.item.lParam = (LPARAM)data;
}
// take the same image for selected icon if not specified
if ( selectedImage == -1 )
param->SetImage(image, wxTreeItemIcon_Selected);
else
param->SetImage(selectedImage, wxTreeItemIcon_Selected);
mask |= TVIF_PARAM;
tvIns.item.lParam = (LPARAM)param;
tvIns.item.mask = mask;
HTREEITEM id = (HTREEITEM) TreeView_InsertItem(GetHwnd(), &tvIns);
@ -1675,9 +1512,13 @@ wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent,
wxLogLastError(wxT("TreeView_InsertItem"));
}
// associate the application tree item with Win32 tree item handle
param->SetItem(id);
// setup wxTreeItemData
if ( data != NULL )
{
// associate the application tree item with Win32 tree item handle
param->SetData(data);
data->SetId(id);
}
@ -1712,7 +1553,10 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text,
if ( m_windowStyle & wxTR_HIDE_ROOT )
{
// create a virtual root item, the parent for all the others
m_pVirtualRoot = new wxVirtualNode(data);
wxTreeItemParam *param = new wxTreeItemParam;
param->SetData(data);
m_pVirtualRoot = new wxVirtualNode(param);
return TVI_ROOT;
}
@ -1986,8 +1830,8 @@ void wxTreeCtrl::DeleteTextCtrl()
}
}
wxTextCtrl* wxTreeCtrl::EditLabel(const wxTreeItemId& item,
wxClassInfo* textControlClass)
wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item,
wxClassInfo *textControlClass)
{
wxASSERT( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)) );
@ -2087,16 +1931,10 @@ public:
static int CALLBACK Compare(LPARAM data1, LPARAM data2, LPARAM tree);
private:
static wxTreeItemId GetIdFromData(wxTreeCtrl *tree, LPARAM item)
static wxTreeItemId GetIdFromData(LPARAM lParam)
{
wxTreeItemData *data = (wxTreeItemData *)item;
if ( tree->IsDataIndirect(data) )
{
data = ((wxTreeItemIndirectData *)data)->GetData();
return ((wxTreeItemParam*)lParam)->GetItem();
}
return data->GetId();
}
};
int CALLBACK wxTreeSortHelper::Compare(LPARAM pItem1,
@ -2108,8 +1946,8 @@ int CALLBACK wxTreeSortHelper::Compare(LPARAM pItem1,
wxTreeCtrl *tree = (wxTreeCtrl *)htree;
return tree->OnCompareItems(GetIdFromData(tree, pItem1),
GetIdFromData(tree, pItem2));
return tree->OnCompareItems(GetIdFromData(pItem1),
GetIdFromData(pItem2));
}
void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
@ -2119,6 +1957,10 @@ void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
// rely on the fact that TreeView_SortChildren does the same thing as our
// default behaviour, i.e. sorts items alphabetically and so call it
// directly if we're not in derived class (much more efficient!)
// RN: Note that if you find you're code doesn't sort as expected this
// may be why as if you don't use the DECLARE_CLASS/IMPLEMENT_CLASS
// combo for your derived wxTreeCtrl if will sort without
// OnCompareItems
if ( GetClassInfo() == CLASSINFO(wxTreeCtrl) )
{
TreeView_SortChildren(GetHwnd(), HITEM(item), 0);
@ -2707,7 +2549,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
case TVN_ITEMEXPANDING:
case TVN_ITEMEXPANDED:
{
NM_TREEVIEW* tv = (NM_TREEVIEW*)lParam;
NM_TREEVIEW *tv = (NM_TREEVIEW*)lParam;
int what;
switch ( tv->action )
@ -2796,13 +2638,13 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
if (hdr->code == TVN_SELCHANGINGW ||
hdr->code == TVN_SELCHANGEDW)
{
NM_TREEVIEWW* tv = (NM_TREEVIEWW *)lParam;
NM_TREEVIEWW *tv = (NM_TREEVIEWW *)lParam;
event.m_item = tv->itemNew.hItem;
event.m_itemOld = tv->itemOld.hItem;
}
else
{
NM_TREEVIEWA* tv = (NM_TREEVIEWA *)lParam;
NM_TREEVIEWA *tv = (NM_TREEVIEWA *)lParam;
event.m_item = tv->itemNew.hItem;
event.m_itemOld = tv->itemOld.hItem;
}
@ -2971,20 +2813,13 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
// tables, but due to overhead of wxWin event system we
// prefer to do it here ourself (otherwise deleting a tree
// with many items is just too slow)
NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
wxTreeItemId item = event.m_item;
if ( HasIndirectData(item) )
{
wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
tv->itemOld.lParam;
delete data; // can't be NULL here
}
else
{
wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam;
delete data; // may be NULL, ok
}
wxTreeItemParam *param =
(wxTreeItemParam *)tv->itemOld.lParam;
delete param;
processed = true; // Make sure we don't get called twice
}
@ -2998,15 +2833,15 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
if ( event.IsAllowed() )
{
HWND hText = TreeView_GetEditControl(GetHwnd());
if(hText != NULL)
if ( hText )
{
// MBN: if m_textCtrl already has an HWND, it is a stale
// pointer from a previous edit (because the user
// didn't modify the label before dismissing the control,
// and TVN_ENDLABELEDIT was not sent), so delete it
if(m_textCtrl && m_textCtrl->GetHWND() != 0)
if ( m_textCtrl && m_textCtrl->GetHWND() )
DeleteTextCtrl();
if(!m_textCtrl)
if ( !m_textCtrl )
m_textCtrl = new wxTextCtrl();
m_textCtrl->SetParent(this);
m_textCtrl->SetHWND((WXHWND)hText);
@ -3064,7 +2899,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
// an image depending on the expanded/collapsed state - bug in
// comctl32.dll or our code?
{
NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
wxTreeItemId id(tv->itemNew.hItem);
int image = GetItemImage(id, wxTreeItemIcon_Expanded);
@ -3078,16 +2913,20 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
case TVN_GETDISPINFO:
// NB: so far the user can't set the image himself anyhow, so do it
// anyway - but this may change later
//if ( /* !processed && */ 1 )
//if ( /* !processed && */ )
{
wxTreeItemId item = event.m_item;
TV_DISPINFO *info = (TV_DISPINFO *)lParam;
wxTreeItemParam *param = GetItemParam(item);
if ( !param )
break;
if ( info->item.mask & TVIF_IMAGE )
{
info->item.iImage =
DoGetItemImageFromData
param->GetImage
(
item,
IsExpanded(item) ? wxTreeItemIcon_Expanded
: wxTreeItemIcon_Normal
);
@ -3095,9 +2934,8 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
if ( info->item.mask & TVIF_SELECTEDIMAGE )
{
info->item.iSelectedImage =
DoGetItemImageFromData
param->GetImage
(
item,
IsExpanded(item) ? wxTreeItemIcon_SelectedExpanded
: wxTreeItemIcon_Selected
);