1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin to be less MSW-specific on 10.10.98
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #pragma implementation "treectrl.h"
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
34 #if defined(__WIN95__)
37 #include "wx/imaglist.h"
39 #include "wx/msw/private.h"
45 #define wxHTREEITEM_DEFINED // flag used in wx/msw/treectrl.h
46 #include "wx/treectrl.h"
48 // Bug in headers, sometimes
50 #define TVIS_FOCUSED 0x0001
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 // a convenient wrapper around TV_ITEM struct which adds a ctor
58 struct wxTreeViewItem
: public TV_ITEM
60 wxTreeViewItem(const wxTreeItemId
& item
,
61 UINT mask_
, UINT stateMask_
= 0)
64 stateMask
= stateMask_
;
65 hItem
= (HTREEITEM
)item
;
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 #if !USE_SHARED_LIBRARY
74 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
, wxControl
)
77 // hide the ugly cast (of course, the macro is _quite_ ugly too...)
78 #define hwnd ((HWND)m_hWnd)
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 // handy table for sending events
85 static const wxEventType g_events
[2][2] =
87 { wxEVT_COMMAND_TREE_ITEM_COLLAPSED
, wxEVT_COMMAND_TREE_ITEM_COLLAPSING
},
88 { wxEVT_COMMAND_TREE_ITEM_EXPANDED
, wxEVT_COMMAND_TREE_ITEM_EXPANDING
}
91 // ============================================================================
93 // ============================================================================
95 // ----------------------------------------------------------------------------
96 // construction and destruction
97 // ----------------------------------------------------------------------------
99 void wxTreeCtrl::Init()
101 m_imageListNormal
= NULL
;
102 m_imageListState
= NULL
;
106 bool wxTreeCtrl::Create(wxWindow
*parent
, wxWindowID id
,
107 const wxPoint
& pos
, const wxSize
& size
,
108 long style
, const wxValidator
& validator
,
109 const wxString
& name
)
113 wxSystemSettings settings
;
116 SetValidator(validator
);
118 m_windowStyle
= style
;
122 m_windowId
= (id
== -1) ? NewControlId() : id
;
124 DWORD wstyle
= WS_VISIBLE
| WS_CHILD
| WS_TABSTOP
| TVS_HASLINES
;
127 WXDWORD exStyle
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
) ;
129 // Even with extended styles, need to combine with WS_BORDER
130 // for them to look right.
131 if ( want3D
|| wxStyleHasBorder(m_windowStyle
) )
136 if ( m_windowStyle
& wxTR_HAS_BUTTONS
)
137 wstyle
|= TVS_HASBUTTONS
;
139 if ( m_windowStyle
& wxTR_EDIT_LABELS
)
140 wstyle
|= TVS_EDITLABELS
;
142 if ( m_windowStyle
& wxTR_LINES_AT_ROOT
)
143 wstyle
|= TVS_LINESATROOT
;
145 // Create the tree control.
146 m_hWnd
= (WXHWND
)::CreateWindowEx
152 pos
.x
, pos
.y
, size
.x
, size
.y
,
153 (HWND
)parent
->GetHWND(),
159 wxCHECK_MSG( m_hWnd
, FALSE
, "Failed to create tree ctrl" );
162 parent
->AddChild(this);
169 wxTreeCtrl::~wxTreeCtrl()
173 // delete user data to prevent memory leaks
177 // ----------------------------------------------------------------------------
179 // ----------------------------------------------------------------------------
181 // simple wrappers which add error checking in debug mode
183 bool wxTreeCtrl::DoGetItem(wxTreeViewItem
* tvItem
) const
185 if ( !TreeView_GetItem(hwnd
, tvItem
) )
187 wxLogLastError("TreeView_GetItem");
195 void wxTreeCtrl::DoSetItem(wxTreeViewItem
* tvItem
)
197 if ( TreeView_SetItem(hwnd
, tvItem
) == -1 )
199 wxLogLastError("TreeView_SetItem");
203 size_t wxTreeCtrl::GetCount() const
205 return (size_t)TreeView_GetCount(hwnd
);
208 unsigned int wxTreeCtrl::GetIndent() const
210 return TreeView_GetIndent(hwnd
);
213 void wxTreeCtrl::SetIndent(unsigned int indent
)
215 TreeView_SetIndent(hwnd
, indent
);
218 wxImageList
*wxTreeCtrl::GetImageList() const
220 return m_imageListNormal
;
223 wxImageList
*wxTreeCtrl::GetStateImageList() const
225 return m_imageListNormal
;
228 void wxTreeCtrl::SetAnyImageList(wxImageList
*imageList
, int which
)
231 TreeView_SetImageList(hwnd
,
232 imageList
? imageList
->GetHIMAGELIST() : 0,
236 void wxTreeCtrl::SetImageList(wxImageList
*imageList
)
238 SetAnyImageList(m_imageListNormal
= imageList
, TVSIL_NORMAL
);
241 void wxTreeCtrl::SetStateImageList(wxImageList
*imageList
)
243 SetAnyImageList(m_imageListState
= imageList
, TVSIL_STATE
);
246 // ----------------------------------------------------------------------------
248 // ----------------------------------------------------------------------------
250 wxString
wxTreeCtrl::GetItemText(const wxTreeItemId
& item
) const
252 char buf
[512]; // the size is arbitrary...
254 wxTreeViewItem
tvItem(item
, TVIF_TEXT
);
255 tvItem
.pszText
= buf
;
256 tvItem
.cchTextMax
= WXSIZEOF(buf
);
257 if ( !DoGetItem(&tvItem
) )
259 // don't return some garbage which was on stack, but an empty string
263 return wxString(buf
);
266 void wxTreeCtrl::SetItemText(const wxTreeItemId
& item
, const wxString
& text
)
268 wxTreeViewItem
tvItem(item
, TVIF_TEXT
);
269 tvItem
.pszText
= (char *)text
.c_str(); // conversion is ok
273 int wxTreeCtrl::GetItemImage(const wxTreeItemId
& item
) const
275 wxTreeViewItem
tvItem(item
, TVIF_IMAGE
);
278 return tvItem
.iImage
;
281 void wxTreeCtrl::SetItemImage(const wxTreeItemId
& item
, int image
)
283 wxTreeViewItem
tvItem(item
, TVIF_IMAGE
);
284 tvItem
.iImage
= image
;
288 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId
& item
) const
290 wxTreeViewItem
tvItem(item
, TVIF_SELECTEDIMAGE
);
293 return tvItem
.iSelectedImage
;
296 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId
& item
, int image
)
298 wxTreeViewItem
tvItem(item
, TVIF_SELECTEDIMAGE
);
299 tvItem
.iSelectedImage
= image
;
303 wxTreeItemData
*wxTreeCtrl::GetItemData(const wxTreeItemId
& item
) const
305 wxTreeViewItem
tvItem(item
, TVIF_PARAM
);
306 if ( !DoGetItem(&tvItem
) )
311 wxTreeItemData
*data
= (wxTreeItemData
*)tvItem
.lParam
;
314 // the data object should know about its id
315 data
->m_itemId
= item
;
321 void wxTreeCtrl::SetItemData(const wxTreeItemId
& item
, wxTreeItemData
*data
)
323 wxTreeViewItem
tvItem(item
, TVIF_PARAM
);
324 tvItem
.lParam
= (LPARAM
)data
;
328 // ----------------------------------------------------------------------------
330 // ----------------------------------------------------------------------------
332 bool wxTreeCtrl::IsVisible(const wxTreeItemId
& item
) const
335 return TreeView_GetItemRect(hwnd
, (HTREEITEM
)item
, &rect
, FALSE
) != 0;
338 bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId
& item
) const
340 wxTreeViewItem
tvItem(item
, TVIF_CHILDREN
);
343 return tvItem
.cChildren
!= 0;
346 bool wxTreeCtrl::IsExpanded(const wxTreeItemId
& item
) const
348 // probably not a good idea to put it here
349 //wxASSERT( ItemHasChildren(item) );
351 wxTreeViewItem
tvItem(item
, TVIF_STATE
, TVIS_EXPANDED
);
354 return (tvItem
.state
& TVIS_EXPANDED
) != 0;
357 bool wxTreeCtrl::IsSelected(const wxTreeItemId
& item
) const
359 wxTreeViewItem
tvItem(item
, TVIF_STATE
, TVIS_SELECTED
);
362 return (tvItem
.state
& TVIS_SELECTED
) != 0;
365 // ----------------------------------------------------------------------------
367 // ----------------------------------------------------------------------------
369 wxTreeItemId
wxTreeCtrl::GetRootItem() const
371 return wxTreeItemId(TreeView_GetRoot(hwnd
));
374 wxTreeItemId
wxTreeCtrl::GetSelection() const
376 return wxTreeItemId(TreeView_GetSelection(hwnd
));
379 wxTreeItemId
wxTreeCtrl::GetParent(const wxTreeItemId
& item
) const
381 return wxTreeItemId(TreeView_GetParent(hwnd
, item
));
384 wxTreeItemId
wxTreeCtrl::GetFirstChild(const wxTreeItemId
& item
,
387 // remember the last child returned in 'cookie'
388 cookie
= (long)TreeView_GetChild(hwnd
, (HTREEITEM
)item
);
390 return wxTreeItemId((HTREEITEM
)cookie
);
393 wxTreeItemId
wxTreeCtrl::GetNextChild(const wxTreeItemId
& WXUNUSED(item
),
396 return wxTreeItemId(TreeView_GetNextSibling(hwnd
,
400 wxTreeItemId
wxTreeCtrl::GetNextSibling(const wxTreeItemId
& item
) const
402 return wxTreeItemId(TreeView_GetNextSibling(hwnd
, item
));
405 wxTreeItemId
wxTreeCtrl::GetPrevSibling(const wxTreeItemId
& item
) const
407 return wxTreeItemId(TreeView_GetPrevSibling(hwnd
, item
));
410 wxTreeItemId
wxTreeCtrl::GetFirstVisibleItem() const
412 return wxTreeItemId(TreeView_GetFirstVisible(hwnd
));
415 wxTreeItemId
wxTreeCtrl::GetNextVisible(const wxTreeItemId
& item
) const
417 wxASSERT_MSG( IsVisible(item
), "The item you call GetNextVisible() "
418 "for must be visible itself!");
420 return wxTreeItemId(TreeView_GetNextVisible(hwnd
, item
));
423 wxTreeItemId
wxTreeCtrl::GetPrevVisible(const wxTreeItemId
& item
) const
425 wxASSERT_MSG( IsVisible(item
), "The item you call GetPrevVisible() "
426 "for must be visible itself!");
428 return wxTreeItemId(TreeView_GetPrevVisible(hwnd
, item
));
431 // ----------------------------------------------------------------------------
433 // ----------------------------------------------------------------------------
435 wxTreeItemId
wxTreeCtrl::DoInsertItem(const wxTreeItemId
& parent
,
436 wxTreeItemId hInsertAfter
,
437 const wxString
& text
,
438 int image
, int selectedImage
,
439 wxTreeItemData
*data
)
441 TV_INSERTSTRUCT tvIns
;
442 tvIns
.hParent
= (HTREEITEM
)parent
;
443 tvIns
.hInsertAfter
= hInsertAfter
;
445 if ( !text
.IsEmpty() )
448 tvIns
.item
.pszText
= (char *)text
.c_str(); // cast is ok
454 tvIns
.item
.iImage
= image
;
457 if ( selectedImage
!= -1 )
459 mask
|= TVIF_SELECTEDIMAGE
;
460 tvIns
.item
.iSelectedImage
= selectedImage
;
466 tvIns
.item
.lParam
= (LPARAM
)data
;
469 tvIns
.item
.mask
= mask
;
471 HTREEITEM id
= TreeView_InsertItem(hwnd
, &tvIns
);
474 wxLogLastError("TreeView_InsertItem");
477 return wxTreeItemId(id
);
480 // for compatibility only
481 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
482 const wxString
& text
,
483 int image
, int selImage
,
486 return DoInsertItem(parent
, (HTREEITEM
)insertAfter
, text
,
487 image
, selImage
, NULL
);
490 wxTreeItemId
wxTreeCtrl::AddRoot(const wxString
& text
,
491 int image
, int selectedImage
,
492 wxTreeItemData
*data
)
494 return DoInsertItem(wxTreeItemId(0), 0,
495 text
, image
, selectedImage
, data
);
498 wxTreeItemId
wxTreeCtrl::PrependItem(const wxTreeItemId
& parent
,
499 const wxString
& text
,
500 int image
, int selectedImage
,
501 wxTreeItemData
*data
)
503 return DoInsertItem(parent
, TVI_FIRST
,
504 text
, image
, selectedImage
, data
);
507 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
508 const wxTreeItemId
& idPrevious
,
509 const wxString
& text
,
510 int image
, int selectedImage
,
511 wxTreeItemData
*data
)
513 return DoInsertItem(parent
, idPrevious
, text
, image
, selectedImage
, data
);
516 wxTreeItemId
wxTreeCtrl::AppendItem(const wxTreeItemId
& parent
,
517 const wxString
& text
,
518 int image
, int selectedImage
,
519 wxTreeItemData
*data
)
521 return DoInsertItem(parent
, TVI_LAST
,
522 text
, image
, selectedImage
, data
);
525 void wxTreeCtrl::Delete(const wxTreeItemId
& item
)
527 wxTreeItemData
*data
= GetItemData(item
);
528 delete data
; // may be NULL, ok
530 if ( !TreeView_DeleteItem(hwnd
, (HTREEITEM
)item
) )
532 wxLogLastError("TreeView_DeleteItem");
536 void wxTreeCtrl::DeleteAllItems()
538 if ( !TreeView_DeleteAllItems(hwnd
) )
540 wxLogLastError("TreeView_DeleteAllItems");
544 void wxTreeCtrl::DoExpand(const wxTreeItemId
& item
, int flag
)
546 wxASSERT_MSG( flag
== TVE_COLLAPSE
|| flag
== TVE_COLLAPSERESET
||
547 flag
== TVE_EXPAND
|| flag
== TVE_TOGGLE
,
548 "Unknown flag in wxTreeCtrl::DoExpand" );
550 // TreeView_Expand doesn't send TVN_ITEMEXPAND(ING) messages, so we must
552 if ( TreeView_Expand(hwnd
, item
, flag
) != 0 )
554 wxTreeEvent
event(wxEVT_NULL
, m_windowId
);
557 bool isExpanded
= IsExpanded(item
);
559 event
.SetEventObject(this);
561 // @@@ return values of {EXPAND|COLLAPS}ING event handler is discarded
562 event
.SetEventType(g_events
[isExpanded
][TRUE
]);
563 GetEventHandler()->ProcessEvent(event
);
565 event
.SetEventType(g_events
[isExpanded
][FALSE
]);
566 GetEventHandler()->ProcessEvent(event
);
570 // I wonder if it really ever happens...
571 wxLogDebug("TreeView_Expand: change didn't took place.");
575 void wxTreeCtrl::Expand(const wxTreeItemId
& item
)
577 DoExpand(item
, TVE_EXPAND
);
580 void wxTreeCtrl::Collapse(const wxTreeItemId
& item
)
582 DoExpand(item
, TVE_COLLAPSE
);
585 void wxTreeCtrl::CollapseAndReset(const wxTreeItemId
& item
)
587 DoExpand(item
, TVE_COLLAPSERESET
);
590 void wxTreeCtrl::Toggle(const wxTreeItemId
& item
)
592 DoExpand(item
, TVE_TOGGLE
);
595 void wxTreeCtrl::Unselect()
597 SelectItem(wxTreeItemId(0));
600 void wxTreeCtrl::SelectItem(const wxTreeItemId
& item
)
602 if ( !TreeView_SelectItem(hwnd
, item
) )
604 wxLogLastError("TreeView_SelectItem");
608 void wxTreeCtrl::EnsureVisible(const wxTreeItemId
& item
)
611 TreeView_EnsureVisible(hwnd
, item
);
614 void wxTreeCtrl::ScrollTo(const wxTreeItemId
& item
)
616 if ( !TreeView_SelectSetFirstVisible(hwnd
, item
) )
618 wxLogLastError("TreeView_SelectSetFirstVisible");
622 wxTextCtrl
* wxTreeCtrl::GetEditControl() const
627 void wxTreeCtrl::DeleteTextCtrl()
631 m_textCtrl
->UnsubclassWin();
632 m_textCtrl
->SetHWND(0);
638 wxTextCtrl
* wxTreeCtrl::EditLabel(const wxTreeItemId
& item
,
639 wxClassInfo
* textControlClass
)
641 wxASSERT( textControlClass
->IsKindOf(CLASSINFO(wxTextCtrl
)) );
643 HWND hWnd
= TreeView_EditLabel(hwnd
, item
);
645 wxCHECK_MSG( hWnd
, NULL
, "Can't edit tree ctrl label" );
649 m_textCtrl
= (wxTextCtrl
*)textControlClass
->CreateObject();
650 m_textCtrl
->SetHWND((WXHWND
)hWnd
);
651 m_textCtrl
->SubclassWin((WXHWND
)hWnd
);
656 // End label editing, optionally cancelling the edit
657 void wxTreeCtrl::EndEditLabel(const wxTreeItemId
& item
, bool discardChanges
)
659 TreeView_EndEditLabelNow(hwnd
, discardChanges
);
664 wxTreeItemId
wxTreeCtrl::HitTest(const wxPoint
& point
, int& flags
)
666 TV_HITTESTINFO hitTestInfo
;
667 hitTestInfo
.pt
.x
= (int)point
.x
;
668 hitTestInfo
.pt
.y
= (int)point
.y
;
670 TreeView_HitTest(hwnd
, &hitTestInfo
);
675 #define TRANSLATE_FLAG(flag) if ( hitTestInfo.flags & TVHT_##flag ) \
676 flags |= wxTREE_HITTEST_##flag
678 TRANSLATE_FLAG(ABOVE
);
679 TRANSLATE_FLAG(BELOW
);
680 TRANSLATE_FLAG(NOWHERE
);
681 TRANSLATE_FLAG(ONITEMBUTTON
);
682 TRANSLATE_FLAG(ONITEMICON
);
683 TRANSLATE_FLAG(ONITEMINDENT
);
684 TRANSLATE_FLAG(ONITEMLABEL
);
685 TRANSLATE_FLAG(ONITEMRIGHT
);
686 TRANSLATE_FLAG(ONITEMSTATEICON
);
687 TRANSLATE_FLAG(TOLEFT
);
688 TRANSLATE_FLAG(TORIGHT
);
690 #undef TRANSLATE_FLAG
692 return wxTreeItemId(hitTestInfo
.hItem
);
695 void wxTreeCtrl::SortChildren(const wxTreeItemId
& item
,
696 wxTreeItemCmpFunc
*cmpFunction
)
698 if ( cmpFunction
== NULL
)
700 TreeView_SortChildren(hwnd
, item
, 0);
704 // TODO: use TreeView_SortChildrenCB
705 wxFAIL_MSG("wxTreeCtrl::SortChildren not implemented");
709 // ----------------------------------------------------------------------------
711 // ----------------------------------------------------------------------------
713 bool wxTreeCtrl::MSWCommand(WXUINT cmd
, WXWORD id
)
715 if ( cmd
== EN_UPDATE
)
717 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, id
);
718 event
.SetEventObject( this );
719 ProcessCommand(event
);
721 else if ( cmd
== EN_KILLFOCUS
)
723 wxCommandEvent
event(wxEVT_KILL_FOCUS
, id
);
724 event
.SetEventObject( this );
725 ProcessCommand(event
);
737 // process WM_NOTIFY Windows message
738 bool wxTreeCtrl::MSWNotify(WXWPARAM wParam
, WXLPARAM lParam
)
740 wxTreeEvent
event(wxEVT_NULL
, m_windowId
);
741 wxEventType eventType
= wxEVT_NULL
;
742 NMHDR
*hdr
= (NMHDR
*)lParam
;
747 eventType
= wxEVT_COMMAND_TREE_BEGIN_DRAG
;
752 if ( eventType
== wxEVT_NULL
)
753 eventType
= wxEVT_COMMAND_TREE_BEGIN_RDRAG
;
754 //else: left drag, already set above
756 NM_TREEVIEW
*tv
= (NM_TREEVIEW
*)lParam
;
758 event
.m_item
= tv
->itemNew
.hItem
;
759 event
.m_pointDrag
= wxPoint(tv
->ptDrag
.x
, tv
->ptDrag
.y
);
763 case TVN_BEGINLABELEDIT
:
765 eventType
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
;
766 TV_DISPINFO
*info
= (TV_DISPINFO
*)lParam
;
768 event
.m_item
= info
->item
.hItem
;
774 eventType
= wxEVT_COMMAND_TREE_DELETE_ITEM
;
775 NM_TREEVIEW
*tv
= (NM_TREEVIEW
*)lParam
;
777 event
.m_item
= tv
->itemOld
.hItem
;
781 case TVN_ENDLABELEDIT
:
783 eventType
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
;
784 TV_DISPINFO
*info
= (TV_DISPINFO
*)lParam
;
786 event
.m_item
= info
->item
.hItem
;
790 case TVN_GETDISPINFO
:
791 eventType
= wxEVT_COMMAND_TREE_GET_INFO
;
794 case TVN_SETDISPINFO
:
796 if ( eventType
== wxEVT_NULL
)
797 eventType
= wxEVT_COMMAND_TREE_SET_INFO
;
798 //else: get, already set above
800 TV_DISPINFO
*info
= (TV_DISPINFO
*)lParam
;
802 event
.m_item
= info
->item
.hItem
;
806 case TVN_ITEMEXPANDING
:
807 event
.m_code
= FALSE
;
810 case TVN_ITEMEXPANDED
:
812 NM_TREEVIEW
* tv
= (NM_TREEVIEW
*)lParam
;
815 switch ( tv
->action
)
826 wxLogDebug("unexpected code %d in TVN_ITEMEXPAND "
827 "message", tv
->action
);
830 bool ing
= hdr
->code
== TVN_ITEMEXPANDING
;
831 eventType
= g_events
[expand
][ing
];
833 event
.m_item
= tv
->itemNew
.hItem
;
839 eventType
= wxEVT_COMMAND_TREE_KEY_DOWN
;
840 TV_KEYDOWN
*info
= (TV_KEYDOWN
*)lParam
;
842 event
.m_code
= wxCharCodeMSWToWX(info
->wVKey
);
847 eventType
= wxEVT_COMMAND_TREE_SEL_CHANGED
;
850 case TVN_SELCHANGING
:
852 if ( eventType
== wxEVT_NULL
)
853 eventType
= wxEVT_COMMAND_TREE_SEL_CHANGING
;
854 //else: already set above
856 NM_TREEVIEW
* tv
= (NM_TREEVIEW
*)lParam
;
858 event
.m_item
= tv
->itemNew
.hItem
;
859 event
.m_itemOld
= tv
->itemOld
.hItem
;
864 return wxControl::MSWNotify(wParam
, lParam
);
867 event
.SetEventObject(this);
868 event
.SetEventType(eventType
);
870 bool rc
= GetEventHandler()->ProcessEvent(event
);
875 // NB: we might process this message using wxWindows event tables, but
876 // due to overhead of wxWin event system we prefer to do it here
877 // (otherwise deleting a tree with many items is just too slow)
880 NM_TREEVIEW
* tv
= (NM_TREEVIEW
*)lParam
;
881 wxTreeItemData
*data
= (wxTreeItemData
*)tv
->itemOld
.lParam
;
882 delete data
; // may be NULL, ok
886 case TVN_ITEMEXPANDING
:
887 // if user called Veto(), don't allow expansion/collapse by
888 // returning TRUE from here
889 rc
= event
.m_code
!= 0;
896 // ----------------------------------------------------------------------------
898 // ----------------------------------------------------------------------------
900 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent
, wxCommandEvent
)
902 wxTreeEvent::wxTreeEvent(wxEventType commandType
, int id
)
903 : wxCommandEvent(commandType
, id
)