1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/treectrl.cpp
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 // ----------------------------------------------------------------------------
21 #pragma implementation "treectrl.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
33 #include "wx/os2/private.h"
37 #include "wx/dynarray.h"
38 #include "wx/imaglist.h"
39 #include "wx/settings.h"
40 #include "wx/os2/treectrl.h"
42 // a macro to hide the ugliness of nested casts
43 #define HITEM(item) (HTREEITEM)(WXHTREEITEM)(item)
45 // the native control doesn't support multiple selections under MSW and we
46 // have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
47 // checkboxes be the selection status (checked == selected) or by really
48 // emulating everything, i.e. intercepting mouse and key events &c. The first
49 // approach is much easier but doesn't work with comctl32.dll < 4.71 and also
51 #define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 // ----------------------------------------------------------------------------
61 typedef struct _MYRECORD
66 } MYRECORD
, *PMYRECORD
;
68 struct wxTreeViewItem
: public MYRECORD
70 wxTreeViewItem(const wxTreeItemId
& rItem
)
72 m_ulItemId
= (ULONG
)rItem
.m_pItem
;
74 }; // end of STRUCT wxTreeViewItem
76 class wxTreeItemInternalData
80 wxTreeItemInternalData() {}
81 ~wxTreeItemInternalData()
90 wxTreeItemAttr
* m_pAttr
;
91 WXLPARAM m_lParam
; // user data
92 #if defined(C_CM_COS232)
93 PMYRECORD m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted
95 }; // end of CLASS wxTreeItemInternalData
97 void BumpTreeRecordIds (
104 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
107 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
110 pRecord
->m_ulItemId
++;
112 } // end of BumpTreeRecordIds
114 PMYRECORD
FindOS2TreeRecordByID (
119 PMYRECORD pRecord
= NULL
;
123 if (!::WinSendMsg( hWnd
126 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
129 for (i
= 0; i
< vCnrInfo
.cRecords
; i
++)
132 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
135 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
138 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
141 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
145 if (pRecord
->m_ulItemId
== (ULONG
)lItemId
)
149 } // end of FindOS2ListRecordByID
153 class wxTreeTraversal
156 wxTreeTraversal(const wxTreeCtrl
* pTree
)
162 // Do traverse the tree: visit all items (recursively by default) under the
163 // given one; return true if all items were traversed or false if the
164 // traversal was aborted because OnVisit returned false
166 bool DoTraverse( const wxTreeItemId
& rRoot
167 ,bool bRecursively
= true
171 // Override this function to do whatever is needed for each item, return
172 // false to stop traversing
174 virtual bool OnVisit(const wxTreeItemId
& rItem
) = 0;
177 const wxTreeCtrl
* GetTree(void) const { return m_pTree
; }
180 bool Traverse( const wxTreeItemId
& rRoot
184 const wxTreeCtrl
* m_pTree
;
185 DECLARE_NO_COPY_CLASS(wxTreeTraversal
)
186 }; // end of CLASS wxTreeTraversal
189 // Internal class for getting the selected items
191 class TraverseSelections
: public wxTreeTraversal
194 TraverseSelections( const wxTreeCtrl
* pTree
195 ,wxArrayTreeItemIds
& raSelections
197 : wxTreeTraversal(pTree
)
198 , m_aSelections(raSelections
)
200 m_aSelections
.Empty();
201 DoTraverse(pTree
->GetRootItem());
204 virtual bool OnVisit(const wxTreeItemId
& rItem
)
207 // Can't visit a virtual node.
209 if ((GetTree()->GetRootItem() == rItem
) && (GetTree()->GetWindowStyle() & wxTR_HIDE_ROOT
))
213 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetTree()->GetHWND()
216 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SELECTED
)
218 m_aSelections
.Add(rItem
);
223 size_t GetCount(void) const { return m_aSelections
.GetCount(); }
226 wxArrayTreeItemIds
& m_aSelections
;
227 }; // end of CLASS TraverseSelections
230 // Internal class for counting tree items
232 class TraverseCounter
: public wxTreeTraversal
235 TraverseCounter( const wxTreeCtrl
* pTree
236 ,const wxTreeItemId
& rRoot
239 : wxTreeTraversal(pTree
)
242 DoTraverse(rRoot
, bRecursively
);
245 virtual bool OnVisit(const wxTreeItemId
& WXUNUSED(rItem
))
251 size_t GetCount(void) const { return m_nCount
; }
255 }; // end of CLASS TraverseCounter
257 // ----------------------------------------------------------------------------
259 // ----------------------------------------------------------------------------
261 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
, wxControl
)
263 // ----------------------------------------------------------------------------
265 // ----------------------------------------------------------------------------
267 // indices in gs_expandEvents table below
282 // handy table for sending events - it has to be initialized during run-time
283 // now so can't be const any more
284 static /* const */ wxEventType gs_expandEvents
[IDX_WHAT_MAX
][IDX_HOW_MAX
];
287 but logically it's a const table with the following entries:
290 { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
291 { wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxEVT_COMMAND_TREE_ITEM_EXPANDING }
295 // ============================================================================
297 // ============================================================================
299 // ----------------------------------------------------------------------------
301 // ----------------------------------------------------------------------------
303 bool wxTreeTraversal::DoTraverse (
304 const wxTreeItemId
& rRoot
311 return Traverse( rRoot
314 } // end of wxTreeTraversal::DoTraverse
316 bool wxTreeTraversal::Traverse (
317 const wxTreeItemId
& rRoot
322 wxTreeItemId vChild
= m_pTree
->GetFirstChild( rRoot
325 while (vChild
.IsOk())
328 // Depth first traversal
330 if (bRecursively
&& !Traverse(vChild
, true))
332 if (!OnVisit(vChild
))
334 vChild
= m_pTree
->GetNextChild( rRoot
339 } // end of wxTreeTraversal::Traverse
341 // ----------------------------------------------------------------------------
342 // construction and destruction
343 // ----------------------------------------------------------------------------
345 void wxTreeCtrl::Init ()
347 m_pImageListNormal
= NULL
;
348 m_pImageListState
= NULL
;
349 m_bOwnsImageListNormal
= false;
350 m_bOwnsImageListState
= false;
351 m_bHasAnyAttr
= false;
355 // Initialize the global array of events now as it can't be done statically
356 // with the wxEVT_XXX values being allocated during run-time only
358 gs_expandEvents
[IDX_COLLAPSE
][IDX_DONE
] = wxEVT_COMMAND_TREE_ITEM_COLLAPSED
;
359 gs_expandEvents
[IDX_COLLAPSE
][IDX_DOING
] = wxEVT_COMMAND_TREE_ITEM_COLLAPSING
;
360 gs_expandEvents
[IDX_EXPAND
][IDX_DONE
] = wxEVT_COMMAND_TREE_ITEM_EXPANDED
;
361 gs_expandEvents
[IDX_EXPAND
][IDX_DOING
] = wxEVT_COMMAND_TREE_ITEM_EXPANDING
;
362 } // end of wxTreeCtrl::Init
364 bool wxTreeCtrl::Create (
367 , const wxPoint
& rPos
368 , const wxSize
& rSize
370 , const wxValidator
& rValidator
371 , const wxString
& rsName
377 if (!CreateControl( pParent
387 DWORD dwStyle
= WS_VISIBLE
| WS_TABSTOP
;
389 if (m_windowStyle
& wxCLIP_SIBLINGS
)
390 dwStyle
|= WS_CLIPSIBLINGS
;
392 // Create the tree control.
393 if (!OS2CreateControl( "CONTAINER"
399 // Now set the display attributes to show a TREE/ICON view of the
402 if (!::WinSendMsg( GetHWND()
405 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
408 vCnrInfo
.flWindowAttr
= CV_TREE
|CV_ICON
;
409 vCnrInfo
.flWindowAttr
|= CA_DRAWBITMAP
;
410 if (m_windowStyle
& wxTR_NO_LINES
)
411 vCnrInfo
.flWindowAttr
|= CA_TREELINE
;
413 ::WinSendMsg( GetHWND()
416 ,(MPARAM
)CMA_FLWINDOWATTR
419 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
420 SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
421 SetFont(*wxSMALL_FONT
);
430 } // end of wxTreeCtrl::Create
432 wxTreeCtrl::~wxTreeCtrl ()
435 // Delete any attributes
439 for (wxNode
* pNode
= m_vAttrs
.Next(); pNode
; pNode
= m_vAttrs
.Next())
441 delete (wxTreeItemAttr
*)pNode
->Data();
443 m_bHasAnyAttr
= false;
448 // Delete user data to prevent memory leaks
449 // also deletes hidden root node storage.
452 if (m_bOwnsImageListNormal
)
453 delete m_pImageListNormal
;
454 if (m_bOwnsImageListState
)
455 delete m_pImageListState
;
456 } // end of wxTreeCtrl::~wxTreeCtrl
458 // ----------------------------------------------------------------------------
460 // ----------------------------------------------------------------------------
463 // simple wrappers which add error checking in debug mode. These methods
464 // assume the items are properly filled out already. If not, you get errors
466 bool wxTreeCtrl::DoGetItem (
467 wxTreeViewItem
* pTvItem
470 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
476 wxLogLastError(wxT("Item not obtained"));
480 } // end of wxTreeCtrl::DoGetItem
482 void wxTreeCtrl::DoSetItem (
483 wxTreeViewItem
* pTvItem
487 // Just invalidate the record to redisplay it
489 if (!::WinSendMsg( GetHWND()
492 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
495 wxLogLastError(wxT("CM_INVALIDATERECORD"));
497 } // end of wxTreeCtrl::DoSetItem
499 size_t wxTreeCtrl::GetCount () const
503 ::WinSendMsg( GetHWND()
506 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
508 return (size_t)vCnrInfo
.cRecords
;
509 } // end of wxTreeCtrl::GetCount
511 unsigned int wxTreeCtrl::GetIndent () const
515 ::WinSendMsg( GetHWND()
518 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
520 return (unsigned int)vCnrInfo
.cxTreeIndent
;
521 } // end of wxTreeCtrl::GetIndent
523 void wxTreeCtrl::SetIndent (
529 ::WinSendMsg( GetHWND()
532 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
534 vCnrInfo
.cxTreeIndent
= (LONG
)uIndent
;
535 ::WinSendMsg( GetHWND()
538 ,(MPARAM
)CMA_CXTREEINDENT
540 } // end of wxTreeCtrl::SetIndent
542 wxImageList
* wxTreeCtrl::GetImageList () const
544 return m_pImageListNormal
;
545 } // end of wxTreeCtrl::GetImageList
547 #if WXWIN_COMPATIBILITY_2_4
549 wxImageList
* wxTreeCtrl::GetImageList(int nVal
) const
551 return GetImageList();
554 void wxTreeCtrl::SetImageList(wxImageList
* pImageList
, int nVal
)
556 SetImageList(pImageList
);
559 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId
& rItem
) const
561 return GetItemImage(rItem
, wxTreeItemIcon_Selected
);
564 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId
& rItem
, int nImage
)
566 SetItemImage(rItem
, nImage
, wxTreeItemIcon_Selected
);
569 #endif // WXWIN_COMPATIBILITY_2_4
571 wxImageList
* wxTreeCtrl::GetStateImageList () const
573 return m_pImageListNormal
;
574 } // end of wxTreeCtrl::GetStateImageList
577 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE
578 // struct has the icon imbedded in it that it uses for the icon being
579 // displayed via the TREEITEMDESC member. Provided for interface
580 // compatability only
582 void wxTreeCtrl::SetAnyImageList (
583 wxImageList
* WXUNUSED(pImageList
)
584 , int WXUNUSED(nWhich
)
587 } // end of wxTreeCtrl::SetAnyImageList
589 void wxTreeCtrl::SetImageList (
590 wxImageList
* WXUNUSED(pImageList
)
593 if (m_bOwnsImageListNormal
)
594 delete m_pImageListNormal
;
595 m_bOwnsImageListNormal
= false;
596 } // end of wxTreeCtrl::SetImageList
598 void wxTreeCtrl::SetStateImageList (
599 wxImageList
* WXUNUSED(pImageList
)
602 if (m_bOwnsImageListState
)
603 delete m_pImageListState
;
604 m_bOwnsImageListState
= false;
605 } // end of wxTreeCtrl::SetStateImageList
607 void wxTreeCtrl::AssignImageList (
608 wxImageList
* WXUNUSED(pImageList
)
611 m_bOwnsImageListNormal
= true;
612 } // end of wxTreeCtrl::AssignImageList
614 void wxTreeCtrl::AssignStateImageList (
615 wxImageList
* WXUNUSED(pImageList
)
618 m_bOwnsImageListState
= true;
619 } // end of wxTreeCtrl::AssignStateImageList
621 size_t wxTreeCtrl::GetChildrenCount (
622 const wxTreeItemId
& rItem
626 TraverseCounter
vCounter( this
630 return vCounter
.GetCount() - 1;
631 } // end of wxTreeCtrl::GetChildrenCount
633 // ----------------------------------------------------------------------------
635 // ----------------------------------------------------------------------------
637 bool wxTreeCtrl::SetBackgroundColour (
638 const wxColour
& rColour
641 ULONG ulColor
= wxColourToRGB(rColour
);
643 if ( !wxWindowBase::SetBackgroundColour(rColour
) )
645 ::WinSetPresParam( GetHWND()
651 } // end of wxTreeCtrl::SetBackgroundColour
653 bool wxTreeCtrl::SetForegroundColour (
654 const wxColour
& rColour
657 ULONG ulColor
= wxColourToRGB(rColour
);
659 if (!wxWindowBase::SetForegroundColour(rColour
))
661 ::WinSetPresParam( GetHWND()
667 } // end of wxTreeCtrl::SetForegroundColour
669 // ----------------------------------------------------------------------------
671 // ----------------------------------------------------------------------------
673 wxString
wxTreeCtrl::GetItemText (
674 const wxTreeItemId
& rItem
677 wxChar zBuf
[512]; // the size is arbitrary...
678 wxTreeViewItem
vTvItem(rItem
);
680 if (!DoGetItem(&vTvItem
))
683 // Don't return some garbage which was on stack, but an empty string
688 strcpy(zBuf
, vTvItem
.m_vRecord
.pszTree
);
689 return wxString(zBuf
);
690 } // end of wxTreeCtrl::GetItemText
692 void wxTreeCtrl::SetItemText (
693 const wxTreeItemId
& rItem
694 , const wxString
& rsText
697 wxTreeViewItem
vTvItem(rItem
);
699 vTvItem
.m_vRecord
.pszTree
= (wxChar
*)rsText
.c_str(); // conversion is ok
701 } // end of wxTreeCtrl::SetItemText
704 // These functions under OS/2 PM are not needed. OS/2 containers in tree view
705 // provide for storing a custom expanded and collapsed icons and selected
706 // and non selected icons, natively. For instance, by default, a disk display
707 // will display a tree list of folder icons with "+" icons (collapsed) beside
708 // those folder which contain child members. Double clicking a folder changes
709 // the closed folder icon to an open folder icon with hatched selection
710 // highlighting indicating an ICON view container of the folder is open
711 // elsewhere on the desktop. So the below is not really needed, but we will
712 // simply return the appropriate icon requested out of OS/2's native PM
715 int wxTreeCtrl::DoGetItemImageFromData (
716 const wxTreeItemId
& WXUNUSED(rItem
)
717 , wxTreeItemIcon nWhich
721 // Image handles stored in CNRINFO.
725 ::WinSendMsg( GetHWND()
728 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
732 // We really only have two to chose from. If not custom (set in CNRINFO
733 // then return the handle to system bitmap). OS/2 automatically provides
734 // in_use and selected bitmaps/icons
738 case wxTreeItemIcon_Normal
:
739 if (vCnrInfo
.hbmCollapsed
== NULLHANDLE
)
740 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
);
741 return vCnrInfo
.hbmCollapsed
;
744 case wxTreeItemIcon_Expanded
:
745 if (vCnrInfo
.hbmExpanded
== NULLHANDLE
)
746 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
);
747 return vCnrInfo
.hbmExpanded
;
750 return vCnrInfo
.hbmCollapsed
;
754 void wxTreeCtrl::DoSetItemImageFromData (
755 const wxTreeItemId
& WXUNUSED(rItem
)
757 , wxTreeItemIcon nWhich
761 // Image handles stored in CNRINFO.
765 ::WinSendMsg( GetHWND()
768 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
770 if (nWhich
== wxTreeItemIcon_Normal
)
771 vCnrInfo
.hbmCollapsed
= (HBITMAP
)nImage
;
772 if (nWhich
== wxTreeItemIcon_Expanded
)
773 vCnrInfo
.hbmExpanded
= (HBITMAP
)nImage
;
774 ::WinSendMsg( GetHWND()
777 ,(MPARAM
)CMA_TREEBITMAP
779 } // end of wxTreeCtrl::DoSetItemImageFromData
782 void wxTreeCtrl::DoSetItemImages (
783 const wxTreeItemId
& rItem
788 } // end of wxTreeCtrl::DoSetItemImages
790 int wxTreeCtrl::GetItemImage (
791 const wxTreeItemId
& rItem
792 , wxTreeItemIcon nWhich
795 if (HasIndirectData(rItem
))
797 return DoGetItemImageFromData( rItem
804 ::WinSendMsg( GetHWND()
807 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
812 wxFAIL_MSG( wxT("unknown tree item image type") );
814 case wxTreeItemIcon_Normal
:
815 if (vCnrInfo
.hbmCollapsed
== NULLHANDLE
)
816 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
);
817 return vCnrInfo
.hbmCollapsed
;
820 case wxTreeItemIcon_Expanded
:
821 if (vCnrInfo
.hbmExpanded
== NULLHANDLE
)
822 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
);
823 return vCnrInfo
.hbmExpanded
;
825 case wxTreeItemIcon_Selected
:
826 case wxTreeItemIcon_SelectedExpanded
:
831 void wxTreeCtrl::SetItemImage (
832 const wxTreeItemId
& WXUNUSED(rItem
)
834 , wxTreeItemIcon nWhich
839 ::WinSendMsg( GetHWND()
842 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
846 case wxTreeItemIcon_Normal
:
847 vCnrInfo
.hbmCollapsed
= (HBITMAP
)nImage
;
850 case wxTreeItemIcon_Expanded
:
851 vCnrInfo
.hbmExpanded
= (HBITMAP
)nImage
;
855 wxFAIL_MSG( wxT("unknown tree item image type") );
857 ::WinSendMsg( GetHWND()
860 ,(MPARAM
)CMA_TREEBITMAP
862 } // end of wxTreeCtrl::SetItemImage
864 wxTreeItemData
* wxTreeCtrl::GetItemData (
865 const wxTreeItemId
& rItem
868 wxTreeViewItem
vTvItem(rItem
);
870 if (!DoGetItem(&vTvItem
))
875 return (wxTreeItemData
*)vTvItem
.m_ulUserData
;
876 } // end of wxTreeCtrl::GetItemData
878 void wxTreeCtrl::SetItemData (
879 const wxTreeItemId
& rItem
880 , wxTreeItemData
* pData
884 // first, associate this piece of data with this item
890 wxTreeViewItem
vTvItem(rItem
);
892 vTvItem
.m_ulUserData
= (ULONG
)pData
;
894 } // end of wxTreeCtrl::SetItemData
896 // The following two do nothing under OS/2
897 void wxTreeCtrl::SetIndirectItemData (
898 const wxTreeItemId
& WXUNUSED(rItem
)
899 , wxTreeItemIndirectData
* WXUNUSED(pData
)
902 } // end of wxTreeCtrl::SetIndirectItemData
904 bool wxTreeCtrl::HasIndirectData (
905 const wxTreeItemId
& WXUNUSED(rItem
)
909 } // end of wxTreeCtrl::HasIndirectData
911 // Irreleveant under OS/2 --- item either has child records or it doesn't.
912 void wxTreeCtrl::SetItemHasChildren (
913 const wxTreeItemId
& WXUNUSED(rItem
)
914 , bool WXUNUSED(bHas
)
917 } // end of wxTreeCtrl::SetItemHasChildren
919 // Irreleveant under OS/2 --- function of the font in PM
920 void wxTreeCtrl::SetItemBold (
921 const wxTreeItemId
& WXUNUSED(rItem
)
922 , bool WXUNUSED(bBold
)
925 } // end of wxTreeCtrl::SetItemBold
927 void wxTreeCtrl::SetItemDropHighlight (
928 const wxTreeItemId
& rItem
932 wxTreeViewItem
vTvItem(rItem
);
934 ::WinSendMsg( GetHWND()
935 ,CM_SETRECORDEMPHASIS
937 ,MPFROM2SHORT(bHighlight
, CRA_SELECTED
)
940 } // end of wxTreeCtrl::SetItemDropHighlight
942 void wxTreeCtrl::RefreshItem (
943 const wxTreeItemId
& rItem
946 wxTreeViewItem
vTvItem(rItem
);
949 // This just does a record invalidate causing it to be re-displayed
952 } // end of wxTreeCtrl::RefreshItem
954 wxColour
wxTreeCtrl::GetItemTextColour (
955 const wxTreeItemId
& rItem
958 long lId
= (long)rItem
.m_pItem
;
959 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
965 return pAttr
->GetTextColour();
966 } // end of wxTreeCtrl::GetItemTextColour
968 wxColour
wxTreeCtrl::GetItemBackgroundColour (
969 const wxTreeItemId
& rItem
972 long lId
= (long)rItem
.m_pItem
;
973 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
979 return pAttr
->GetBackgroundColour();
980 } // end of wxTreeCtrl::GetItemBackgroundColour
982 wxFont
wxTreeCtrl::GetItemFont (
983 const wxTreeItemId
& rItem
986 long lId
= (long)rItem
.m_pItem
;
987 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
993 return pAttr
->GetFont();
994 } // end of wxTreeCtrl::GetItemFont
996 void wxTreeCtrl::SetItemTextColour (
997 const wxTreeItemId
& rItem
998 , const wxColour
& rCol
1001 m_bHasAnyAttr
= true;
1003 long lId
= (long)rItem
.m_pItem
;
1004 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1008 pAttr
= new wxTreeItemAttr
;
1009 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1011 pAttr
->SetTextColour(rCol
);
1013 } // end of wxTreeCtrl::SetItemTextColour
1015 void wxTreeCtrl::SetItemBackgroundColour (
1016 const wxTreeItemId
& rItem
1017 , const wxColour
& rCol
1020 m_bHasAnyAttr
= true;
1022 long lId
= (long)rItem
.m_pItem
;
1023 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1027 pAttr
= new wxTreeItemAttr
;
1028 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1030 pAttr
->SetBackgroundColour(rCol
);
1032 } // end of wxTreeCtrl::SetItemBackgroundColour
1034 void wxTreeCtrl::SetItemFont (
1035 const wxTreeItemId
& rItem
1036 , const wxFont
& rFont
1039 m_bHasAnyAttr
= true;
1041 long lId
= (long)rItem
.m_pItem
;
1042 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1046 pAttr
= new wxTreeItemAttr
;
1047 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1049 pAttr
->SetFont(rFont
);
1051 } // end of wxTreeCtrl::SetItemFont
1053 // ----------------------------------------------------------------------------
1055 // ----------------------------------------------------------------------------
1057 bool wxTreeCtrl::IsVisible (
1058 const wxTreeItemId
& rItem
1061 // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
1063 RECTL vRectContainer
;
1064 wxRect vWxRectRecord
;
1065 wxRect vWxRectContainer
;
1066 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1069 QUERYRECORDRECT vQuery
;
1071 vQuery
.cb
= sizeof(QUERYRECORDRECT
);
1072 vQuery
.pRecord
= (PRECORDCORE
)pRecord
;
1073 vQuery
.fRightSplitWindow
= FALSE
;
1074 vQuery
.fsExtent
= CMA_TREEICON
;
1076 ::WinSendMsg( GetHWND()
1077 ,CM_QUERYVIEWPORTRECT
1078 ,MPFROMP(&vRectContainer
)
1079 ,MPFROM2SHORT(CMA_WINDOW
, FALSE
)
1081 ::WinSendMsg( GetHWND()
1083 ,MPFROMP(&vRectRecord
)
1086 vWxRectRecord
.SetLeft(vRectRecord
.xLeft
);
1087 vWxRectRecord
.SetTop(vRectRecord
.yTop
);
1088 vWxRectRecord
.SetRight(vRectRecord
.xRight
);
1089 vWxRectRecord
.SetBottom(vRectRecord
.yBottom
);
1091 vWxRectContainer
.SetLeft(vRectContainer
.xLeft
);
1092 vWxRectContainer
.SetTop(vRectContainer
.yTop
);
1093 vWxRectContainer
.SetRight(vRectContainer
.xRight
);
1094 vWxRectContainer
.SetBottom(vRectContainer
.yBottom
);
1095 return (vWxRectContainer
.Inside(wxPoint(vWxRectRecord
.x
, vWxRectRecord
.y
)));
1096 } // end of wxTreeCtrl::IsVisible
1098 bool wxTreeCtrl::ItemHasChildren (
1099 const wxTreeItemId
& rItem
1102 wxTreeViewItem
vTvItem(rItem
);
1103 DoGetItem(&vTvItem
);
1106 // A tree record with children will have one of these attributes
1108 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_EXPANDED
||
1109 vTvItem
.m_vRecord
.flRecordAttr
& CRA_COLLAPSED
) != 0;
1112 bool wxTreeCtrl::IsExpanded (
1113 const wxTreeItemId
& rItem
1116 wxTreeViewItem
vTvItem(rItem
);
1117 DoGetItem(&vTvItem
);
1119 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_EXPANDED
) != 0;
1120 } // end of wxTreeCtrl::IsExpanded
1122 bool wxTreeCtrl::IsSelected (
1123 const wxTreeItemId
& rItem
1126 wxTreeViewItem
vTvItem(rItem
);
1127 DoGetItem(&vTvItem
);
1129 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_SELECTED
) != 0;
1130 } // end of wxTreeCtrl::IsSelected
1133 bool wxTreeCtrl::IsBold (
1134 const wxTreeItemId
& rItem
1138 } // end of wxTreeCtrl::IsBold
1140 // ----------------------------------------------------------------------------
1142 // ----------------------------------------------------------------------------
1144 wxTreeItemId
wxTreeCtrl::GetRootItem () const
1146 PMYRECORD pRecord
= NULL
;
1148 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1151 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
1155 return wxTreeItemId(-1L);
1156 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1157 } // end of wxTreeCtrl::GetRootItem
1159 wxTreeItemId
wxTreeCtrl::GetSelection () const
1161 wxCHECK_MSG( !(m_windowStyle
& wxTR_MULTIPLE
), (long)(WXHTREEITEM
)0,
1162 wxT("this only works with single selection controls") );
1164 PMYRECORD pRecord
= NULL
;
1166 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1167 ,CM_QUERYRECORDEMPHASIS
1169 ,MPARAM(CRA_SELECTED
)
1172 return wxTreeItemId(-1L);
1173 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1174 } // end of wxTreeCtrl::GetSelection
1176 wxTreeItemId
wxTreeCtrl::GetItemParent (
1177 const wxTreeItemId
& rItem
1180 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1185 return wxTreeItemId(-1L);
1186 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1189 ,MPFROM2SHORT(CMA_PARENT
, CMA_ITEMORDER
)
1192 return wxTreeItemId(-1L);
1193 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1194 } // end of wxTreeCtrl::GetItemParent
1196 wxTreeItemId
wxTreeCtrl::GetFirstChild (
1197 const wxTreeItemId
& rItem
1201 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1206 return wxTreeItemId(-1L);
1207 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1210 ,MPFROM2SHORT(CMA_FIRSTCHILD
, CMA_ITEMORDER
)
1213 return wxTreeItemId(-1L);
1215 // Remember the last child returned in 'cookie'
1217 rCookie
= (long)pRecord
->m_ulItemId
;
1218 return wxTreeItemId(rCookie
);
1219 } // end of wxTreeCtrl::GetFirstChild
1221 wxTreeItemId
wxTreeCtrl::GetNextChild (
1222 const wxTreeItemId
& WXUNUSED(rItem
)
1226 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1231 return wxTreeItemId(-1L);
1232 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1235 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1238 return wxTreeItemId(-1L);
1239 rCookie
= (long)pRecord
->m_ulItemId
;
1240 return wxTreeItemId(rCookie
);
1241 } // end of wxTreeCtrl::GetNextChild
1243 wxTreeItemId
wxTreeCtrl::GetLastChild (
1244 const wxTreeItemId
& rItem
1247 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1252 return wxTreeItemId(-1L);
1253 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1256 ,MPFROM2SHORT(CMA_LASTCHILD
, CMA_ITEMORDER
)
1259 return wxTreeItemId(-1L);
1260 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1261 } // end of wxTreeCtrl::GetLastChild
1263 wxTreeItemId
wxTreeCtrl::GetNextSibling (
1264 const wxTreeItemId
& rItem
1267 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1272 return wxTreeItemId(-1L);
1273 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1276 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1279 return wxTreeItemId(-1L);
1280 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1281 } // end of wxTreeCtrl::GetNextSibling
1283 wxTreeItemId
wxTreeCtrl::GetPrevSibling (
1284 const wxTreeItemId
& rItem
1287 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1292 return wxTreeItemId(-1L);
1293 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1296 ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
)
1299 return wxTreeItemId(-1L);
1300 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1301 } // end of wxTreeCtrl::GetPrevSibling
1303 wxTreeItemId
wxTreeCtrl::GetFirstVisibleItem () const
1305 PMYRECORD pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1308 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
1311 return wxTreeItemId(-1L);
1313 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1314 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1317 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1320 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1323 return wxTreeItemId(-1L);
1324 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1325 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1327 return wxTreeItemId(-1L);
1328 } // end of wxTreeCtrl::GetFirstVisibleItem
1330 wxTreeItemId
wxTreeCtrl::GetNextVisible (
1331 const wxTreeItemId
& rItem
1334 wxASSERT_MSG(IsVisible(rItem
), wxT("The item you call GetNextVisible() for must be visible itself!"));
1336 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1341 return wxTreeItemId(-1L);
1344 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1347 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1350 return wxTreeItemId(-1L);
1351 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1352 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1354 return wxTreeItemId(-1L);
1355 } // end of wxTreeCtrl::GetNextVisible
1357 wxTreeItemId
wxTreeCtrl::GetPrevVisible (
1358 const wxTreeItemId
& rItem
1361 wxASSERT_MSG( IsVisible(rItem
), wxT("The item you call GetPrevVisible() for must be visible itself!"));
1363 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1368 return wxTreeItemId(-1L);
1371 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1374 ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
)
1377 return wxTreeItemId(-1L);
1378 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1379 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1381 return wxTreeItemId(-1L);
1382 } // end of wxTreeCtrl::GetPrevVisible
1384 // ----------------------------------------------------------------------------
1385 // multiple selections emulation -- under OS/2 checked tree items is not
1386 // supported, but multisel is. So we'll just check for selections here.
1387 // ----------------------------------------------------------------------------
1389 bool wxTreeCtrl::IsItemChecked (
1390 const wxTreeItemId
& rItem
1393 wxTreeViewItem
vTvItem(rItem
);
1395 DoGetItem(&vTvItem
);
1396 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_SELECTED
);
1397 } // end of wxTreeCtrl::IsItemChecked
1399 void wxTreeCtrl::SetItemCheck (
1400 const wxTreeItemId
& rItem
1404 wxTreeViewItem
vTvItem(rItem
);
1406 DoGetItem(&vTvItem
);
1407 ::WinSendMsg( GetHWND()
1408 ,CM_SETRECORDEMPHASIS
1410 ,MPFROM2SHORT(TRUE
, CRA_SELECTED
)
1412 DoSetItem(&vTvItem
);
1413 } // end of wxTreeCtrl::SetItemCheck
1415 size_t wxTreeCtrl::GetSelections (
1416 wxArrayTreeItemIds
& raSelections
1419 TraverseSelections
vSelector( this
1422 return vSelector
.GetCount();
1423 } // end of wxTreeCtrl::GetSelections
1425 // ----------------------------------------------------------------------------
1427 // ----------------------------------------------------------------------------
1429 wxTreeItemId
wxTreeCtrl::DoInsertItem (
1430 const wxTreeItemId
& rParent
1431 , wxTreeItemId vInsertAfter
1432 , const wxString
& rsText
1435 , wxTreeItemData
* pData
1438 PMYRECORD pRecordAfter
= FindOS2TreeRecordByID( GetHWND()
1439 ,vInsertAfter
.m_pItem
1442 PMYRECORD pRecordParent
= FindOS2TreeRecordByID( GetHWND()
1446 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1448 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
1451 RECORDINSERT vInsert
;
1453 vInsert
.cb
= sizeof(RECORDINSERT
);
1454 if (rParent
.m_pItem
== 0L)
1456 if (vInsertAfter
.m_pItem
== -1)
1457 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_END
;
1459 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
1460 vInsert
.pRecordParent
= NULL
;
1464 if (vInsertAfter
.m_pItem
== 0)
1465 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
1466 else if (vInsertAfter
.m_pItem
== -1)
1467 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_END
;
1469 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
1470 vInsert
.pRecordParent
= (PRECORDCORE
)pRecordParent
;
1472 vInsert
.fInvalidateRecord
= TRUE
;
1473 vInsert
.zOrder
= CMA_TOP
;
1474 vInsert
.cRecordsInsert
= 1;
1476 pRecord
->m_vRecord
.pszTree
= (wxChar
*)rsText
.c_str();
1477 pRecord
->m_vRecord
.hbmBitmap
= nImage
;
1478 pRecord
->m_ulItemId
= pRecordAfter
->m_ulItemId
+ 1;
1481 pRecord
->m_ulUserData
= (ULONG
)pData
;
1483 ::WinSendMsg( GetHWND()
1490 // OS/2 must mannually bump the index's of following records
1492 BumpTreeRecordIds( GetHWND()
1498 // Associate the application tree item with PM tree item handle
1500 pData
->SetId((long)pRecord
->m_ulItemId
);
1502 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1505 #if WXWIN_COMPATIBILITY_2_4
1507 // for compatibility only
1508 wxTreeItemId
wxTreeCtrl::InsertItem (
1509 const wxTreeItemId
& rParent
1510 , const wxString
& rsText
1516 return DoInsertItem( rParent
1517 ,wxTreeItemId(lInsertAfter
)
1523 } // end of wxTreeCtrl::InsertItem
1525 #endif // WXWIN_COMPATIBILITY_2_4
1527 wxTreeItemId
wxTreeCtrl::AddRoot (
1528 const wxString
& rsText
1530 , int nSelectedImage
1531 , wxTreeItemData
* pData
)
1534 return DoInsertItem( wxTreeItemId((long)0)
1535 ,wxTreeItemId((long)-1)
1541 } // end of wxTreeCtrl::AddRoot
1543 wxTreeItemId
wxTreeCtrl::PrependItem (
1544 const wxTreeItemId
& rParent
1545 , const wxString
& rsText
1547 , int nSelectedImage
1548 , wxTreeItemData
* pData
1551 return DoInsertItem( rParent
1552 ,wxTreeItemId((long)0)
1558 } // end of wxTreeCtrl::PrependItem
1560 wxTreeItemId
wxTreeCtrl::InsertItem (
1561 const wxTreeItemId
& rParent
1562 , const wxTreeItemId
& rIdPrevious
1563 , const wxString
& rsText
1565 , int nSelectedImage
1566 , wxTreeItemData
* pData
1569 return DoInsertItem( rParent
1576 } // end of wxTreeCtrl::InsertItem
1578 wxTreeItemId
wxTreeCtrl::InsertItem (
1579 const wxTreeItemId
& rParent
1581 , const wxString
& rsText
1583 , int nSelectedImage
1584 , wxTreeItemData
* pData
1587 return DoInsertItem( rParent
1588 ,wxTreeItemId((long)nIndex
)
1594 } // end of wxTreeCtrl::InsertItem
1596 wxTreeItemId
wxTreeCtrl::AppendItem (
1597 const wxTreeItemId
& rParent
1598 , const wxString
& rsText
1600 , int nSelectedImage
1601 , wxTreeItemData
* pData
1604 return DoInsertItem( rParent
1605 ,wxTreeItemId((long)-1)
1611 } // end of wxTreeCtrl::AppendItem
1613 void wxTreeCtrl::Delete (
1614 const wxTreeItemId
& rItem
1618 // OS/2 does not generate DELETEITEM events so do it here
1620 wxEventType vEventType
= wxEVT_NULL
;
1621 wxTreeEvent
vEvent( wxEVT_NULL
1624 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1627 vEvent
.SetEventObject(this);
1628 ::WinSendMsg( GetHWND()
1631 ,(MPARAM
)(CMA_FREE
| CMA_INVALIDATE
)
1633 vEvent
.m_item
= rItem
.m_pItem
;
1636 delete (wxTreeItemAttr
*)m_vAttrs
.Delete((long)rItem
.m_pItem
);
1638 vEvent
.SetEventType(vEventType
);
1639 GetEventHandler()->ProcessEvent(vEvent
);
1640 } // end of wxTreeCtrl::Delete
1642 // delete all children (but don't delete the item itself)
1643 void wxTreeCtrl::DeleteChildren (
1644 const wxTreeItemId
& rItem
1648 wxArrayLong aChildren
;
1649 wxTreeItemId vChild
= GetFirstChild( rItem
1653 while (vChild
.IsOk())
1655 aChildren
.Add((long)(WXHTREEITEM
)vChild
);
1656 vChild
= GetNextChild( rItem
1661 size_t nCount
= aChildren
.Count();
1663 for (size_t n
= 0; n
< nCount
; n
++)
1665 Delete(aChildren
[n
]);
1667 } // end of wxTreeCtrl::DeleteChildren
1669 void wxTreeCtrl::DeleteAllItems ()
1671 ::WinSendMsg( GetHWND()
1674 ,(MPARAM
)(CMA_FREE
| CMA_INVALIDATE
)
1676 } // end of wxTreeCtrl::DeleteAllItems
1678 void wxTreeCtrl::DoExpand (
1679 const wxTreeItemId
& rItem
1683 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1688 case wxTREE_EXPAND_EXPAND
:
1689 ::WinSendMsg( GetHWND()
1696 case wxTREE_EXPAND_COLLAPSE
:
1697 ::WinSendMsg( GetHWND()
1704 case wxTREE_EXPAND_COLLAPSE_RESET
:
1705 ::WinSendMsg( GetHWND()
1710 DeleteChildren(rItem
);
1713 case wxTREE_EXPAND_TOGGLE
:
1714 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_COLLAPSED
)
1715 ::WinSendMsg( GetHWND()
1720 else if (pRecord
->m_vRecord
.flRecordAttr
& CRA_EXPANDED
)
1721 ::WinSendMsg( GetHWND()
1729 } // end of wxTreeCtrl::DoExpand
1731 void wxTreeCtrl::Expand (
1732 const wxTreeItemId
& rItem
1736 ,wxTREE_EXPAND_EXPAND
1738 } // end of wxTreeCtrl::Expand
1740 void wxTreeCtrl::Collapse (
1741 const wxTreeItemId
& rItem
1745 ,wxTREE_EXPAND_COLLAPSE
1747 } // end of wxTreeCtrl::Collapse
1749 void wxTreeCtrl::CollapseAndReset (
1750 const wxTreeItemId
& rItem
1754 ,wxTREE_EXPAND_COLLAPSE_RESET
1756 } // end of wxTreeCtrl::CollapseAndReset
1758 void wxTreeCtrl::Toggle (
1759 const wxTreeItemId
& rItem
1763 ,wxTREE_EXPAND_TOGGLE
1765 } // end of wxTreeCtrl::Toggle
1767 #if WXWIN_COMPATIBILITY_2_4
1769 void wxTreeCtrl::ExpandItem (
1770 const wxTreeItemId
& rItem
1777 } // end of wxTreeCtrl::ExpandItem
1779 #endif // WXWIN_COMPATIBILITY_2_4
1781 void wxTreeCtrl::Unselect ()
1783 wxASSERT_MSG( !(m_windowStyle
& wxTR_MULTIPLE
),
1784 wxT("doesn't make sense, may be you want UnselectAll()?") );
1787 // Just remove the selection
1789 SelectItem(wxTreeItemId((long)0));
1790 } // end of wxTreeCtrl::Unselect
1792 void wxTreeCtrl::UnselectAll ()
1794 if (m_windowStyle
& wxTR_MULTIPLE
)
1796 wxArrayTreeItemIds aSelections
;
1797 size_t nCount
= GetSelections(aSelections
);
1799 for (size_t n
= 0; n
< nCount
; n
++)
1801 SetItemCheck( aSelections
[n
]
1809 // Just remove the selection
1813 } // end of wxTreeCtrl::UnselectAll
1815 void wxTreeCtrl::SelectItem (
1816 const wxTreeItemId
& rItem
1819 SetItemCheck(rItem
);
1820 } // end of wxTreeCtrl::SelectItem
1822 void wxTreeCtrl::EnsureVisible (
1823 const wxTreeItemId
& rItem
1826 wxTreeViewItem
vTvItem(rItem
);
1828 DoGetItem(&vTvItem
);
1829 if (!::WinSendMsg( GetHWND()
1830 ,CM_INVALIDATERECORD
1832 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1834 } // end of wxTreeCtrl::EnsureVisible
1836 void wxTreeCtrl::ScrollTo (
1837 const wxTreeItemId
& rItem
1840 wxTreeViewItem
vTvItem(rItem
);
1842 DoGetItem(&vTvItem
);
1843 if (!::WinSendMsg( GetHWND()
1844 ,CM_INVALIDATERECORD
1846 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1850 wxTextCtrl
* wxTreeCtrl::EditLabel (
1851 const wxTreeItemId
& rItem
1852 , wxClassInfo
* WXUNUSED(pTextControlClass
)
1856 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1860 vEdit
.cb
= sizeof(CNREDITDATA
);
1861 vEdit
.hwndCnr
= GetHWND();
1862 vEdit
.pRecord
= &pRecord
->m_vRecord
;
1863 vEdit
.pFieldInfo
= NULL
;
1864 vEdit
.ppszText
= NULL
;
1868 ::WinSendMsg( GetHWND()
1874 } // end of wxTreeCtrl::EditLabel
1876 // End label editing, optionally cancelling the edit
1877 void wxTreeCtrl::EndEditLabel (
1878 const wxTreeItemId
& WXUNUSED(rItem
)
1879 , bool WXUNUSED(bDiscardChanges
)
1882 ::WinSendMsg( GetHWND()
1887 } // end of wxTreeCtrl::EndEditLabel
1889 wxTreeItemId
wxTreeCtrl::HitTest (
1890 const wxPoint
& rPoint
1891 , int& WXUNUSED(rFlags
)
1894 PMYRECORD pRecord
= NULL
;
1895 QUERYRECFROMRECT vQueryRect
;
1900 // Get height for OS/2 point conversion
1902 ::WinSendMsg( GetHWND()
1903 ,CM_QUERYVIEWPORTRECT
1905 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1907 lHeight
= vRect
.yTop
- vRect
.yBottom
;
1910 // For now just try and get a record in the general vicinity and forget
1913 vRect
.xLeft
= rPoint
.x
- 2;
1914 vRect
.xRight
= rPoint
.x
+ 2;
1915 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
1916 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
1918 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1919 vQueryRect
.rect
= vRect
;
1920 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1922 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1923 ,CM_QUERYRECORDFROMRECT
1925 ,MPFROMP(&vQueryRect
)
1930 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1931 } // end of wxTreeCtrl::HitTest
1933 bool wxTreeCtrl::GetBoundingRect (
1934 const wxTreeItemId
& rItem
1940 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1943 QUERYRECORDRECT vQuery
;
1945 vQuery
.cb
= sizeof(QUERYRECORDRECT
);
1946 vQuery
.pRecord
= (PRECORDCORE
)pRecord
;
1947 vQuery
.fRightSplitWindow
= FALSE
;
1949 vQuery
.fsExtent
= CMA_TEXT
;
1951 vQuery
.fsExtent
= CMA_TREEICON
| CMA_TEXT
;
1953 if (!::WinSendMsg( GetHWND()
1955 ,MPFROMP(&vRectRecord
)
1959 rRect
.SetLeft(vRectRecord
.xLeft
);
1960 rRect
.SetTop(vRectRecord
.yTop
);
1961 rRect
.SetRight(vRectRecord
.xRight
);
1962 rRect
.SetBottom(vRectRecord
.yBottom
);
1964 } // end of wxTreeCtrl::GetBoundingRect
1966 // ----------------------------------------------------------------------------
1968 // ----------------------------------------------------------------------------
1970 SHORT EXPENTRY
InternalDataCompareTreeFunc (
1976 wxCHECK_MSG( p1
&& p2
, 0,
1977 wxT("sorting tree without data doesn't make sense") );
1979 wxTreeCtrl
* pTree
= (wxTreeCtrl
*)pStorage
;
1981 return pTree
->OnCompareItems( p1
->m_ulItemId
1984 } // end of wxTreeSortHelper::Compare
1986 int wxTreeCtrl::OnCompareItems (
1987 const wxTreeItemId
& rItem1
1988 , const wxTreeItemId
& rItem2
1991 return wxStrcmp( GetItemText(rItem1
)
1992 ,GetItemText(rItem2
)
1994 } // end of wxTreeCtrl::OnCompareItems
1996 void wxTreeCtrl::SortChildren (
1997 const wxTreeItemId
& rItem
2000 ::WinSendMsg( GetHWND()
2002 ,(PFN
)InternalDataCompareTreeFunc
2005 } // end of wxTreeCtrl::SortChildren
2007 // ----------------------------------------------------------------------------
2009 // ----------------------------------------------------------------------------
2011 bool wxTreeCtrl::OS2Command (
2016 if (uCmd
== CN_ENDEDIT
)
2018 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
2022 vEvent
.SetEventObject( this );
2023 ProcessCommand(vEvent
);
2026 else if (uCmd
== CN_KILLFOCUS
)
2028 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
2031 vEvent
.SetEventObject( this );
2032 ProcessCommand(vEvent
);
2037 } // end of wxTreeCtrl::OS2Command
2040 // TODO: Fully implement direct manipulation when I figure it out
2042 MRESULT
wxTreeCtrl::OS2WindowProc (
2048 bool bProcessed
= false;
2050 wxTreeEvent
vEvent( wxEVT_NULL
2053 wxEventType vEventType
= wxEVT_NULL
;
2054 PCNRDRAGINIT pDragInit
= NULL
;
2055 PCNREDITDATA pEditData
= NULL
;
2056 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
2058 vEvent
.SetEventObject(this);
2062 switch(SHORT2FROMMP(wParam
))
2065 pDragInit
= (PCNRDRAGINIT
)lParam
;
2068 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2070 vEventType
= wxEVT_COMMAND_TREE_BEGIN_DRAG
;
2071 vEvent
.m_item
= pRecord
->m_ulItemId
;
2072 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2073 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2078 pEditData
= (PCNREDITDATA
)lParam
;
2081 PMYRECORD pRecord
= (PMYRECORD
)pEditData
->pRecord
;
2083 vEventType
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
;
2084 vEvent
.m_item
= pRecord
->m_ulItemId
;
2085 vEvent
.m_label
= pRecord
->m_vRecord
.pszTree
;
2086 vEvent
.m_editCancelled
= false;
2091 pEditData
= (PCNREDITDATA
)lParam
;
2094 PMYRECORD pRecord
= (PMYRECORD
)pEditData
->pRecord
;
2096 vEventType
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
;
2097 vEvent
.m_item
= pRecord
->m_ulItemId
;
2098 vEvent
.m_label
= pRecord
->m_vRecord
.pszTree
;
2099 if (pRecord
->m_vRecord
.pszTree
== NULL
)
2101 vEvent
.m_editCancelled
= true;
2105 vEvent
.m_editCancelled
= false;
2112 PMYRECORD pRecord
= (PMYRECORD
)lParam
;
2114 vEventType
= gs_expandEvents
[IDX_EXPAND
][IDX_DONE
];
2115 vEvent
.m_item
= pRecord
->m_ulItemId
;
2119 vEvent
.SetEventType(vEventType
);
2120 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
2124 mRc
= wxControl::OS2WindowProc( uMsg
2129 } // end of wxTreeCtrl::OS2WindowProc
2131 #if WXWIN_COMPATIBILITY_2_2
2133 wxTreeItemId
wxTreeCtrl::GetParent(const wxTreeItemId
& item
) const
2135 return GetItemParent( item
);
2138 #endif // WXWIN_COMPATIBILITY_2_2
2140 #endif // wxUSE_TREECTRL