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"
57 #include "wx/msw/treectrl.h"
59 // Bug in headers, sometimes
61 #define TVIS_FOCUSED 0x0001
64 // ----------------------------------------------------------------------------
66 // ----------------------------------------------------------------------------
68 // a convenient wrapper around TV_ITEM struct which adds a ctor
69 struct wxTreeViewItem
: public TV_ITEM
71 wxTreeViewItem(const wxTreeItemId
& item
,
72 UINT mask_
, UINT stateMask_
= 0)
75 stateMask
= stateMask_
;
76 hItem
= (HTREEITEM
) (WXHTREEITEM
) item
;
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 #if !USE_SHARED_LIBRARY
85 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
, wxControl
)
88 // hide the ugly cast (of course, the macro is _quite_ ugly too...)
89 #define wxhWnd ((HWND)m_hWnd)
91 // ----------------------------------------------------------------------------
93 // ----------------------------------------------------------------------------
95 // handy table for sending events
96 static const wxEventType g_events
[2][2] =
98 { wxEVT_COMMAND_TREE_ITEM_COLLAPSED
, wxEVT_COMMAND_TREE_ITEM_COLLAPSING
},
99 { wxEVT_COMMAND_TREE_ITEM_EXPANDED
, wxEVT_COMMAND_TREE_ITEM_EXPANDING
}
102 // ============================================================================
104 // ============================================================================
106 // ----------------------------------------------------------------------------
107 // construction and destruction
108 // ----------------------------------------------------------------------------
110 void wxTreeCtrl::Init()
112 m_imageListNormal
= NULL
;
113 m_imageListState
= NULL
;
117 bool wxTreeCtrl::Create(wxWindow
*parent
, wxWindowID id
,
118 const wxPoint
& pos
, const wxSize
& size
,
119 long style
, const wxValidator
& validator
,
120 const wxString
& name
)
124 wxSystemSettings settings
;
127 SetValidator(validator
);
129 m_windowStyle
= style
;
133 m_windowId
= (id
== -1) ? NewControlId() : id
;
135 DWORD wstyle
= WS_VISIBLE
| WS_CHILD
| WS_TABSTOP
| TVS_HASLINES
;
138 WXDWORD exStyle
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
) ;
140 // Even with extended styles, need to combine with WS_BORDER
141 // for them to look right.
142 if ( want3D
|| wxStyleHasBorder(m_windowStyle
) )
147 if ( m_windowStyle
& wxTR_HAS_BUTTONS
)
148 wstyle
|= TVS_HASBUTTONS
;
150 if ( m_windowStyle
& wxTR_EDIT_LABELS
)
151 wstyle
|= TVS_EDITLABELS
;
153 if ( m_windowStyle
& wxTR_LINES_AT_ROOT
)
154 wstyle
|= TVS_LINESATROOT
;
156 // Create the tree control.
157 m_hWnd
= (WXHWND
)::CreateWindowEx
163 pos
.x
, pos
.y
, size
.x
, size
.y
,
164 (HWND
)parent
->GetHWND(),
170 wxCHECK_MSG( m_hWnd
, FALSE
, "Failed to create tree ctrl" );
173 parent
->AddChild(this);
180 wxTreeCtrl::~wxTreeCtrl()
184 // delete user data to prevent memory leaks
188 // ----------------------------------------------------------------------------
190 // ----------------------------------------------------------------------------
192 // simple wrappers which add error checking in debug mode
194 bool wxTreeCtrl::DoGetItem(wxTreeViewItem
* tvItem
) const
196 if ( !TreeView_GetItem(wxhWnd
, tvItem
) )
198 wxLogLastError("TreeView_GetItem");
206 void wxTreeCtrl::DoSetItem(wxTreeViewItem
* tvItem
)
208 if ( TreeView_SetItem(wxhWnd
, tvItem
) == -1 )
210 wxLogLastError("TreeView_SetItem");
214 size_t wxTreeCtrl::GetCount() const
216 return (size_t)TreeView_GetCount(wxhWnd
);
219 unsigned int wxTreeCtrl::GetIndent() const
221 return TreeView_GetIndent(wxhWnd
);
224 void wxTreeCtrl::SetIndent(unsigned int indent
)
226 TreeView_SetIndent(wxhWnd
, indent
);
229 wxImageList
*wxTreeCtrl::GetImageList() const
231 return m_imageListNormal
;
234 wxImageList
*wxTreeCtrl::GetStateImageList() const
236 return m_imageListNormal
;
239 void wxTreeCtrl::SetAnyImageList(wxImageList
*imageList
, int which
)
242 TreeView_SetImageList(wxhWnd
,
243 imageList
? imageList
->GetHIMAGELIST() : 0,
247 void wxTreeCtrl::SetImageList(wxImageList
*imageList
)
249 SetAnyImageList(m_imageListNormal
= imageList
, TVSIL_NORMAL
);
252 void wxTreeCtrl::SetStateImageList(wxImageList
*imageList
)
254 SetAnyImageList(m_imageListState
= imageList
, TVSIL_STATE
);
257 // ----------------------------------------------------------------------------
259 // ----------------------------------------------------------------------------
261 wxString
wxTreeCtrl::GetItemText(const wxTreeItemId
& item
) const
263 char buf
[512]; // the size is arbitrary...
265 wxTreeViewItem
tvItem(item
, TVIF_TEXT
);
266 tvItem
.pszText
= buf
;
267 tvItem
.cchTextMax
= WXSIZEOF(buf
);
268 if ( !DoGetItem(&tvItem
) )
270 // don't return some garbage which was on stack, but an empty string
274 return wxString(buf
);
277 void wxTreeCtrl::SetItemText(const wxTreeItemId
& item
, const wxString
& text
)
279 wxTreeViewItem
tvItem(item
, TVIF_TEXT
);
280 tvItem
.pszText
= (char *)text
.c_str(); // conversion is ok
284 int wxTreeCtrl::GetItemImage(const wxTreeItemId
& item
) const
286 wxTreeViewItem
tvItem(item
, TVIF_IMAGE
);
289 return tvItem
.iImage
;
292 void wxTreeCtrl::SetItemImage(const wxTreeItemId
& item
, int image
)
294 wxTreeViewItem
tvItem(item
, TVIF_IMAGE
);
295 tvItem
.iImage
= image
;
299 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId
& item
) const
301 wxTreeViewItem
tvItem(item
, TVIF_SELECTEDIMAGE
);
304 return tvItem
.iSelectedImage
;
307 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId
& item
, int image
)
309 wxTreeViewItem
tvItem(item
, TVIF_SELECTEDIMAGE
);
310 tvItem
.iSelectedImage
= image
;
314 wxTreeItemData
*wxTreeCtrl::GetItemData(const wxTreeItemId
& item
) const
316 wxTreeViewItem
tvItem(item
, TVIF_PARAM
);
317 if ( !DoGetItem(&tvItem
) )
322 return (wxTreeItemData
*)tvItem
.lParam
;
325 void wxTreeCtrl::SetItemData(const wxTreeItemId
& item
, wxTreeItemData
*data
)
327 wxTreeViewItem
tvItem(item
, TVIF_PARAM
);
328 tvItem
.lParam
= (LPARAM
)data
;
332 void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId
& item
, bool has
)
334 wxTreeViewItem
tvItem(item
, TVIF_CHILDREN
);
335 tvItem
.cChildren
= (int)has
;
339 void wxTreeCtrl::SetItemBold(const wxTreeItemId
& item
, bool bold
)
341 wxTreeViewItem
tvItem(item
, TVIF_STATE
, TVIS_BOLD
);
342 tvItem
.state
= bold
? TVIS_BOLD
: 0;
346 // ----------------------------------------------------------------------------
348 // ----------------------------------------------------------------------------
350 bool wxTreeCtrl::IsVisible(const wxTreeItemId
& item
) const
352 // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
354 return SendMessage(wxhWnd
, TVM_GETITEMRECT
, FALSE
, (LPARAM
)&rect
) != 0;
358 bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId
& item
) const
360 wxTreeViewItem
tvItem(item
, TVIF_CHILDREN
);
363 return tvItem
.cChildren
!= 0;
366 bool wxTreeCtrl::IsExpanded(const wxTreeItemId
& item
) const
368 // probably not a good idea to put it here
369 //wxASSERT( ItemHasChildren(item) );
371 wxTreeViewItem
tvItem(item
, TVIF_STATE
, TVIS_EXPANDED
);
374 return (tvItem
.state
& TVIS_EXPANDED
) != 0;
377 bool wxTreeCtrl::IsSelected(const wxTreeItemId
& item
) const
379 wxTreeViewItem
tvItem(item
, TVIF_STATE
, TVIS_SELECTED
);
382 return (tvItem
.state
& TVIS_SELECTED
) != 0;
385 bool wxTreeCtrl::IsBold(const wxTreeItemId
& item
) const
387 wxTreeViewItem
tvItem(item
, TVIF_STATE
, TVIS_BOLD
);
390 return (tvItem
.state
& TVIS_BOLD
) != 0;
393 // ----------------------------------------------------------------------------
395 // ----------------------------------------------------------------------------
397 wxTreeItemId
wxTreeCtrl::GetRootItem() const
399 return wxTreeItemId((WXHTREEITEM
) TreeView_GetRoot(wxhWnd
));
402 wxTreeItemId
wxTreeCtrl::GetSelection() const
404 return wxTreeItemId((WXHTREEITEM
) TreeView_GetSelection(wxhWnd
));
407 wxTreeItemId
wxTreeCtrl::GetParent(const wxTreeItemId
& item
) const
409 return wxTreeItemId((WXHTREEITEM
) TreeView_GetParent(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
));
412 wxTreeItemId
wxTreeCtrl::GetFirstChild(const wxTreeItemId
& item
,
415 // remember the last child returned in 'cookie'
416 _cookie
= (long)TreeView_GetChild(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
)item
);
418 return wxTreeItemId((WXHTREEITEM
)_cookie
);
421 wxTreeItemId
wxTreeCtrl::GetNextChild(const wxTreeItemId
& WXUNUSED(item
),
424 wxTreeItemId l
=wxTreeItemId((WXHTREEITEM
) TreeView_GetNextSibling(wxhWnd
,
425 (HTREEITEM
) (WXHTREEITEM
)_cookie
));
430 wxTreeItemId
wxTreeCtrl::GetNextSibling(const wxTreeItemId
& item
) const
432 return wxTreeItemId((WXHTREEITEM
) TreeView_GetNextSibling(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
));
435 wxTreeItemId
wxTreeCtrl::GetPrevSibling(const wxTreeItemId
& item
) const
437 return wxTreeItemId((WXHTREEITEM
) TreeView_GetPrevSibling(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
));
440 wxTreeItemId
wxTreeCtrl::GetFirstVisibleItem() const
442 return wxTreeItemId((WXHTREEITEM
) TreeView_GetFirstVisible(wxhWnd
));
445 wxTreeItemId
wxTreeCtrl::GetNextVisible(const wxTreeItemId
& item
) const
447 wxASSERT_MSG( IsVisible(item
), "The item you call GetNextVisible() "
448 "for must be visible itself!");
450 return wxTreeItemId((WXHTREEITEM
) TreeView_GetNextVisible(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
));
453 wxTreeItemId
wxTreeCtrl::GetPrevVisible(const wxTreeItemId
& item
) const
455 wxASSERT_MSG( IsVisible(item
), "The item you call GetPrevVisible() "
456 "for must be visible itself!");
458 return wxTreeItemId((WXHTREEITEM
) TreeView_GetPrevVisible(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
));
461 // ----------------------------------------------------------------------------
463 // ----------------------------------------------------------------------------
465 wxTreeItemId
wxTreeCtrl::DoInsertItem(const wxTreeItemId
& parent
,
466 wxTreeItemId hInsertAfter
,
467 const wxString
& text
,
468 int image
, int selectedImage
,
469 wxTreeItemData
*data
)
471 TV_INSERTSTRUCT tvIns
;
472 tvIns
.hParent
= (HTREEITEM
) (WXHTREEITEM
)parent
;
473 tvIns
.hInsertAfter
= (HTREEITEM
) (WXHTREEITEM
) hInsertAfter
;
475 if ( !text
.IsEmpty() )
478 tvIns
.item
.pszText
= (char *)text
.c_str(); // cast is ok
484 tvIns
.item
.iImage
= image
;
486 if ( selectedImage
== -1 )
488 // take the same image for selected icon if not specified
489 selectedImage
= image
;
493 if ( selectedImage
!= -1 )
495 mask
|= TVIF_SELECTEDIMAGE
;
496 tvIns
.item
.iSelectedImage
= selectedImage
;
502 tvIns
.item
.lParam
= (LPARAM
)data
;
505 tvIns
.item
.mask
= mask
;
507 HTREEITEM id
= (HTREEITEM
) TreeView_InsertItem(wxhWnd
, &tvIns
);
510 wxLogLastError("TreeView_InsertItem");
515 // associate the application tree item with Win32 tree item handle
516 data
->SetId((WXHTREEITEM
)id
);
519 return wxTreeItemId((WXHTREEITEM
)id
);
522 // for compatibility only
523 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
524 const wxString
& text
,
525 int image
, int selImage
,
528 return DoInsertItem(parent
, (WXHTREEITEM
)insertAfter
, text
,
529 image
, selImage
, NULL
);
532 wxTreeItemId
wxTreeCtrl::AddRoot(const wxString
& text
,
533 int image
, int selectedImage
,
534 wxTreeItemData
*data
)
536 return DoInsertItem(wxTreeItemId((WXHTREEITEM
) 0), (WXHTREEITEM
) 0,
537 text
, image
, selectedImage
, data
);
540 wxTreeItemId
wxTreeCtrl::PrependItem(const wxTreeItemId
& parent
,
541 const wxString
& text
,
542 int image
, int selectedImage
,
543 wxTreeItemData
*data
)
545 return DoInsertItem(parent
, (WXHTREEITEM
) TVI_FIRST
,
546 text
, image
, selectedImage
, data
);
549 wxTreeItemId
wxTreeCtrl::InsertItem(const wxTreeItemId
& parent
,
550 const wxTreeItemId
& idPrevious
,
551 const wxString
& text
,
552 int image
, int selectedImage
,
553 wxTreeItemData
*data
)
555 return DoInsertItem(parent
, idPrevious
, text
, image
, selectedImage
, data
);
558 wxTreeItemId
wxTreeCtrl::AppendItem(const wxTreeItemId
& parent
,
559 const wxString
& text
,
560 int image
, int selectedImage
,
561 wxTreeItemData
*data
)
563 return DoInsertItem(parent
, (WXHTREEITEM
) TVI_LAST
,
564 text
, image
, selectedImage
, data
);
567 void wxTreeCtrl::Delete(const wxTreeItemId
& item
)
569 if ( !TreeView_DeleteItem(wxhWnd
, (HTREEITEM
)(WXHTREEITEM
)item
) )
571 wxLogLastError("TreeView_DeleteItem");
575 void wxTreeCtrl::DeleteAllItems()
577 if ( !TreeView_DeleteAllItems(wxhWnd
) )
579 wxLogLastError("TreeView_DeleteAllItems");
583 void wxTreeCtrl::DoExpand(const wxTreeItemId
& item
, int flag
)
585 wxASSERT_MSG( flag
== TVE_COLLAPSE
|| flag
== TVE_COLLAPSERESET
||
586 flag
== TVE_EXPAND
|| flag
== TVE_TOGGLE
,
587 "Unknown flag in wxTreeCtrl::DoExpand" );
589 // TreeView_Expand doesn't send TVN_ITEMEXPAND(ING) messages, so we must
591 if ( TreeView_Expand(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
, flag
) != 0 )
593 wxTreeEvent
event(wxEVT_NULL
, m_windowId
);
596 bool isExpanded
= IsExpanded(item
);
598 event
.SetEventObject(this);
600 // @@@ return values of {EXPAND|COLLAPS}ING event handler is discarded
601 event
.SetEventType(g_events
[isExpanded
][TRUE
]);
602 GetEventHandler()->ProcessEvent(event
);
604 event
.SetEventType(g_events
[isExpanded
][FALSE
]);
605 GetEventHandler()->ProcessEvent(event
);
609 // I wonder if it really ever happens...
610 wxLogDebug("TreeView_Expand: change didn't took place.");
614 void wxTreeCtrl::Expand(const wxTreeItemId
& item
)
616 DoExpand(item
, TVE_EXPAND
);
619 void wxTreeCtrl::Collapse(const wxTreeItemId
& item
)
621 DoExpand(item
, TVE_COLLAPSE
);
624 void wxTreeCtrl::CollapseAndReset(const wxTreeItemId
& item
)
626 DoExpand(item
, TVE_COLLAPSERESET
);
629 void wxTreeCtrl::Toggle(const wxTreeItemId
& item
)
631 DoExpand(item
, TVE_TOGGLE
);
634 void wxTreeCtrl::ExpandItem(const wxTreeItemId
& item
, int action
)
636 DoExpand(item
, action
);
639 void wxTreeCtrl::Unselect()
641 SelectItem(wxTreeItemId((WXHTREEITEM
) 0));
644 void wxTreeCtrl::SelectItem(const wxTreeItemId
& item
)
646 if ( !TreeView_SelectItem(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
) )
648 wxLogLastError("TreeView_SelectItem");
652 void wxTreeCtrl::EnsureVisible(const wxTreeItemId
& item
)
655 TreeView_EnsureVisible(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
);
658 void wxTreeCtrl::ScrollTo(const wxTreeItemId
& item
)
660 if ( !TreeView_SelectSetFirstVisible(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
) )
662 wxLogLastError("TreeView_SelectSetFirstVisible");
666 wxTextCtrl
* wxTreeCtrl::GetEditControl() const
671 void wxTreeCtrl::DeleteTextCtrl()
675 m_textCtrl
->UnsubclassWin();
676 m_textCtrl
->SetHWND(0);
682 wxTextCtrl
* wxTreeCtrl::EditLabel(const wxTreeItemId
& item
,
683 wxClassInfo
* textControlClass
)
685 wxASSERT( textControlClass
->IsKindOf(CLASSINFO(wxTextCtrl
)) );
687 HWND hWnd
= (HWND
) TreeView_EditLabel(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
);
689 wxCHECK_MSG( hWnd
, NULL
, "Can't edit tree ctrl label" );
693 m_textCtrl
= (wxTextCtrl
*)textControlClass
->CreateObject();
694 m_textCtrl
->SetHWND((WXHWND
)hWnd
);
695 m_textCtrl
->SubclassWin((WXHWND
)hWnd
);
700 // End label editing, optionally cancelling the edit
701 void wxTreeCtrl::EndEditLabel(const wxTreeItemId
& item
, bool discardChanges
)
703 TreeView_EndEditLabelNow(wxhWnd
, discardChanges
);
708 wxTreeItemId
wxTreeCtrl::HitTest(const wxPoint
& point
, int& flags
)
710 TV_HITTESTINFO hitTestInfo
;
711 hitTestInfo
.pt
.x
= (int)point
.x
;
712 hitTestInfo
.pt
.y
= (int)point
.y
;
714 TreeView_HitTest(wxhWnd
, &hitTestInfo
);
719 #define TRANSLATE_FLAG(flag) if ( hitTestInfo.flags & TVHT_##flag ) \
720 flags |= wxTREE_HITTEST_##flag
722 TRANSLATE_FLAG(ABOVE
);
723 TRANSLATE_FLAG(BELOW
);
724 TRANSLATE_FLAG(NOWHERE
);
725 TRANSLATE_FLAG(ONITEMBUTTON
);
726 TRANSLATE_FLAG(ONITEMICON
);
727 TRANSLATE_FLAG(ONITEMINDENT
);
728 TRANSLATE_FLAG(ONITEMLABEL
);
729 TRANSLATE_FLAG(ONITEMRIGHT
);
730 TRANSLATE_FLAG(ONITEMSTATEICON
);
731 TRANSLATE_FLAG(TOLEFT
);
732 TRANSLATE_FLAG(TORIGHT
);
734 #undef TRANSLATE_FLAG
736 return wxTreeItemId((WXHTREEITEM
) hitTestInfo
.hItem
);
739 void wxTreeCtrl::SortChildren(const wxTreeItemId
& item
,
740 wxTreeItemCmpFunc
*cmpFunction
)
742 if ( cmpFunction
== NULL
)
744 TreeView_SortChildren(wxhWnd
, (HTREEITEM
) (WXHTREEITEM
) item
, 0);
748 // TODO: use TreeView_SortChildrenCB
749 wxFAIL_MSG("wxTreeCtrl::SortChildren not implemented");
754 size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId
& item
, bool recursively
)
759 // ----------------------------------------------------------------------------
761 // ----------------------------------------------------------------------------
763 bool wxTreeCtrl::MSWCommand(WXUINT cmd
, WXWORD id
)
765 if ( cmd
== EN_UPDATE
)
767 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, id
);
768 event
.SetEventObject( this );
769 ProcessCommand(event
);
771 else if ( cmd
== EN_KILLFOCUS
)
773 wxCommandEvent
event(wxEVT_KILL_FOCUS
, id
);
774 event
.SetEventObject( this );
775 ProcessCommand(event
);
787 // process WM_NOTIFY Windows message
788 bool wxTreeCtrl::MSWNotify(WXWPARAM wParam
, WXLPARAM lParam
, WXLPARAM
*result
)
790 wxTreeEvent
event(wxEVT_NULL
, m_windowId
);
791 wxEventType eventType
= wxEVT_NULL
;
792 NMHDR
*hdr
= (NMHDR
*)lParam
;
797 eventType
= wxEVT_COMMAND_TREE_BEGIN_DRAG
;
802 if ( eventType
== wxEVT_NULL
)
803 eventType
= wxEVT_COMMAND_TREE_BEGIN_RDRAG
;
804 //else: left drag, already set above
806 NM_TREEVIEW
*tv
= (NM_TREEVIEW
*)lParam
;
808 event
.m_item
= (WXHTREEITEM
) tv
->itemNew
.hItem
;
809 event
.m_pointDrag
= wxPoint(tv
->ptDrag
.x
, tv
->ptDrag
.y
);
813 case TVN_BEGINLABELEDIT
:
815 eventType
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
;
816 TV_DISPINFO
*info
= (TV_DISPINFO
*)lParam
;
818 event
.m_item
= (WXHTREEITEM
) info
->item
.hItem
;
824 eventType
= wxEVT_COMMAND_TREE_DELETE_ITEM
;
825 NM_TREEVIEW
*tv
= (NM_TREEVIEW
*)lParam
;
827 event
.m_item
= (WXHTREEITEM
) tv
->itemOld
.hItem
;
831 case TVN_ENDLABELEDIT
:
833 eventType
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
;
834 TV_DISPINFO
*info
= (TV_DISPINFO
*)lParam
;
836 event
.m_item
= (WXHTREEITEM
) info
->item
.hItem
;
840 case TVN_GETDISPINFO
:
841 eventType
= wxEVT_COMMAND_TREE_GET_INFO
;
844 case TVN_SETDISPINFO
:
846 if ( eventType
== wxEVT_NULL
)
847 eventType
= wxEVT_COMMAND_TREE_SET_INFO
;
848 //else: get, already set above
850 TV_DISPINFO
*info
= (TV_DISPINFO
*)lParam
;
852 event
.m_item
= (WXHTREEITEM
) info
->item
.hItem
;
856 case TVN_ITEMEXPANDING
:
857 event
.m_code
= FALSE
;
860 case TVN_ITEMEXPANDED
:
862 NM_TREEVIEW
* tv
= (NM_TREEVIEW
*)lParam
;
865 switch ( tv
->action
)
876 wxLogDebug("unexpected code %d in TVN_ITEMEXPAND "
877 "message", tv
->action
);
880 bool ing
= (hdr
->code
== TVN_ITEMEXPANDING
);
881 eventType
= g_events
[expand
][ing
];
883 event
.m_item
= (WXHTREEITEM
) tv
->itemNew
.hItem
;
889 eventType
= wxEVT_COMMAND_TREE_KEY_DOWN
;
890 TV_KEYDOWN
*info
= (TV_KEYDOWN
*)lParam
;
892 event
.m_code
= wxCharCodeMSWToWX(info
->wVKey
);
897 eventType
= wxEVT_COMMAND_TREE_SEL_CHANGED
;
900 case TVN_SELCHANGING
:
902 if ( eventType
== wxEVT_NULL
)
903 eventType
= wxEVT_COMMAND_TREE_SEL_CHANGING
;
904 //else: already set above
906 NM_TREEVIEW
* tv
= (NM_TREEVIEW
*)lParam
;
908 event
.m_item
= (WXHTREEITEM
) tv
->itemNew
.hItem
;
909 event
.m_itemOld
= (WXHTREEITEM
) tv
->itemOld
.hItem
;
914 return wxControl::MSWNotify(wParam
, lParam
, result
);
917 event
.SetEventObject(this);
918 event
.SetEventType(eventType
);
920 bool processed
= GetEventHandler()->ProcessEvent(event
);
923 if ( hdr
->code
== TVN_DELETEITEM
)
925 // NB: we might process this message using wxWindows event tables, but
926 // due to overhead of wxWin event system we prefer to do it here
927 // (otherwise deleting a tree with many items is just too slow)
928 NM_TREEVIEW
* tv
= (NM_TREEVIEW
*)lParam
;
929 wxTreeItemData
*data
= (wxTreeItemData
*)tv
->itemOld
.lParam
;
930 delete data
; // may be NULL, ok
933 *result
= !event
.IsAllowed();
938 // ----------------------------------------------------------------------------
940 // ----------------------------------------------------------------------------
942 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent
, wxCommandEvent
)
944 wxTreeEvent::wxTreeEvent(wxEventType commandType
, int id
)
945 : wxNotifyEvent(commandType
, id
)