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 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/os2/private.h"
33 #include "wx/dynarray.h"
34 #include "wx/imaglist.h"
35 #include "wx/settings.h"
36 #include "wx/os2/treectrl.h"
38 // a macro to hide the ugliness of nested casts
39 #define HITEM(item) (HTREEITEM)(WXHTREEITEM)(item)
41 // the native control doesn't support multiple selections under MSW and we
42 // have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
43 // checkboxes be the selection status (checked == selected) or by really
44 // emulating everything, i.e. intercepting mouse and key events &c. The first
45 // approach is much easier but doesn't work with comctl32.dll < 4.71 and also
47 #define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 typedef struct _MYRECORD
62 } MYRECORD
, *PMYRECORD
;
64 struct wxTreeViewItem
: public MYRECORD
66 wxTreeViewItem(const wxTreeItemId
& rItem
)
68 m_ulItemId
= (ULONG
)rItem
.m_pItem
;
70 }; // end of STRUCT wxTreeViewItem
72 class wxTreeItemInternalData
76 wxTreeItemInternalData() {}
77 ~wxTreeItemInternalData()
86 wxTreeItemAttr
* m_pAttr
;
87 WXLPARAM m_lParam
; // user data
88 #if defined(C_CM_COS232)
89 PMYRECORD m_pMyRecord
; // so we can set the m_ulUserData to 0 when this is deleted
91 }; // end of CLASS wxTreeItemInternalData
93 void BumpTreeRecordIds (
100 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
103 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
106 pRecord
->m_ulItemId
++;
108 } // end of BumpTreeRecordIds
110 PMYRECORD
FindOS2TreeRecordByID (
115 PMYRECORD pRecord
= NULL
;
119 if (!::WinSendMsg( hWnd
122 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
125 for (i
= 0; i
< vCnrInfo
.cRecords
; i
++)
128 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
131 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
134 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( hWnd
137 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
141 if (pRecord
->m_ulItemId
== (ULONG
)lItemId
)
145 } // end of FindOS2ListRecordByID
149 class wxTreeTraversal
152 wxTreeTraversal(const wxTreeCtrl
* pTree
)
158 // Do traverse the tree: visit all items (recursively by default) under the
159 // given one; return true if all items were traversed or false if the
160 // traversal was aborted because OnVisit returned false
162 bool DoTraverse( const wxTreeItemId
& rRoot
163 ,bool bRecursively
= true
167 // Override this function to do whatever is needed for each item, return
168 // false to stop traversing
170 virtual bool OnVisit(const wxTreeItemId
& rItem
) = 0;
173 const wxTreeCtrl
* GetTree(void) const { return m_pTree
; }
176 bool Traverse( const wxTreeItemId
& rRoot
180 const wxTreeCtrl
* m_pTree
;
181 DECLARE_NO_COPY_CLASS(wxTreeTraversal
)
182 }; // end of CLASS wxTreeTraversal
185 // Internal class for getting the selected items
187 class TraverseSelections
: public wxTreeTraversal
190 TraverseSelections( const wxTreeCtrl
* pTree
191 ,wxArrayTreeItemIds
& raSelections
193 : wxTreeTraversal(pTree
)
194 , m_aSelections(raSelections
)
196 m_aSelections
.Empty();
197 DoTraverse(pTree
->GetRootItem());
200 virtual bool OnVisit(const wxTreeItemId
& rItem
)
203 // Can't visit a virtual node.
205 if ((GetTree()->GetRootItem() == rItem
) && (GetTree()->GetWindowStyle() & wxTR_HIDE_ROOT
))
209 PMYRECORD pRecord
= FindOS2TreeRecordByID( (HWND
)GetTree()->GetHWND()
212 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_SELECTED
)
214 m_aSelections
.Add(rItem
);
219 size_t GetCount(void) const { return m_aSelections
.GetCount(); }
222 wxArrayTreeItemIds
& m_aSelections
;
223 }; // end of CLASS TraverseSelections
226 // Internal class for counting tree items
228 class TraverseCounter
: public wxTreeTraversal
231 TraverseCounter( const wxTreeCtrl
* pTree
232 ,const wxTreeItemId
& rRoot
235 : wxTreeTraversal(pTree
)
238 DoTraverse(rRoot
, bRecursively
);
241 virtual bool OnVisit(const wxTreeItemId
& WXUNUSED(rItem
))
247 size_t GetCount(void) const { return m_nCount
; }
251 }; // end of CLASS TraverseCounter
253 // ----------------------------------------------------------------------------
255 // ----------------------------------------------------------------------------
257 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
, wxControl
)
259 // ----------------------------------------------------------------------------
261 // ----------------------------------------------------------------------------
263 // indices in gs_expandEvents table below
278 // handy table for sending events - it has to be initialized during run-time
279 // now so can't be const any more
280 static /* const */ wxEventType gs_expandEvents
[IDX_WHAT_MAX
][IDX_HOW_MAX
];
283 but logically it's a const table with the following entries:
286 { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
287 { wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxEVT_COMMAND_TREE_ITEM_EXPANDING }
291 // ============================================================================
293 // ============================================================================
295 // ----------------------------------------------------------------------------
297 // ----------------------------------------------------------------------------
299 bool wxTreeTraversal::DoTraverse (
300 const wxTreeItemId
& rRoot
307 return Traverse( rRoot
310 } // end of wxTreeTraversal::DoTraverse
312 bool wxTreeTraversal::Traverse (
313 const wxTreeItemId
& rRoot
318 wxTreeItemId vChild
= m_pTree
->GetFirstChild( rRoot
321 while (vChild
.IsOk())
324 // Depth first traversal
326 if (bRecursively
&& !Traverse(vChild
, true))
328 if (!OnVisit(vChild
))
330 vChild
= m_pTree
->GetNextChild( rRoot
335 } // end of wxTreeTraversal::Traverse
337 // ----------------------------------------------------------------------------
338 // construction and destruction
339 // ----------------------------------------------------------------------------
341 void wxTreeCtrl::Init ()
343 m_pImageListNormal
= NULL
;
344 m_pImageListState
= NULL
;
345 m_bOwnsImageListNormal
= false;
346 m_bOwnsImageListState
= false;
347 m_bHasAnyAttr
= false;
351 // Initialize the global array of events now as it can't be done statically
352 // with the wxEVT_XXX values being allocated during run-time only
354 gs_expandEvents
[IDX_COLLAPSE
][IDX_DONE
] = wxEVT_COMMAND_TREE_ITEM_COLLAPSED
;
355 gs_expandEvents
[IDX_COLLAPSE
][IDX_DOING
] = wxEVT_COMMAND_TREE_ITEM_COLLAPSING
;
356 gs_expandEvents
[IDX_EXPAND
][IDX_DONE
] = wxEVT_COMMAND_TREE_ITEM_EXPANDED
;
357 gs_expandEvents
[IDX_EXPAND
][IDX_DOING
] = wxEVT_COMMAND_TREE_ITEM_EXPANDING
;
358 } // end of wxTreeCtrl::Init
360 bool wxTreeCtrl::Create (
363 , const wxPoint
& rPos
364 , const wxSize
& rSize
366 , const wxValidator
& rValidator
367 , const wxString
& rsName
373 if (!CreateControl( pParent
383 DWORD dwStyle
= WS_VISIBLE
| WS_TABSTOP
;
385 if (m_windowStyle
& wxCLIP_SIBLINGS
)
386 dwStyle
|= WS_CLIPSIBLINGS
;
388 // Create the tree control.
389 if (!OS2CreateControl( "CONTAINER"
395 // Now set the display attributes to show a TREE/ICON view of the
398 if (!::WinSendMsg( GetHWND()
401 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
404 vCnrInfo
.flWindowAttr
= CV_TREE
|CV_ICON
;
405 vCnrInfo
.flWindowAttr
|= CA_DRAWBITMAP
;
406 if (m_windowStyle
& wxTR_NO_LINES
)
407 vCnrInfo
.flWindowAttr
|= CA_TREELINE
;
409 ::WinSendMsg( GetHWND()
412 ,(MPARAM
)CMA_FLWINDOWATTR
415 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
416 SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
417 SetFont(*wxSMALL_FONT
);
426 } // end of wxTreeCtrl::Create
428 wxTreeCtrl::~wxTreeCtrl ()
431 // Delete any attributes
435 for (wxNode
* pNode
= m_vAttrs
.Next(); pNode
; pNode
= m_vAttrs
.Next())
437 delete (wxTreeItemAttr
*)pNode
->Data();
439 m_bHasAnyAttr
= false;
444 // Delete user data to prevent memory leaks
445 // also deletes hidden root node storage.
448 if (m_bOwnsImageListNormal
)
449 delete m_pImageListNormal
;
450 if (m_bOwnsImageListState
)
451 delete m_pImageListState
;
452 } // end of wxTreeCtrl::~wxTreeCtrl
454 // ----------------------------------------------------------------------------
456 // ----------------------------------------------------------------------------
459 // simple wrappers which add error checking in debug mode. These methods
460 // assume the items are properly filled out already. If not, you get errors
462 bool wxTreeCtrl::DoGetItem (
463 wxTreeViewItem
* pTvItem
466 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
472 wxLogLastError(wxT("Item not obtained"));
476 } // end of wxTreeCtrl::DoGetItem
478 void wxTreeCtrl::DoSetItem (
479 wxTreeViewItem
* pTvItem
483 // Just invalidate the record to redisplay it
485 if (!::WinSendMsg( GetHWND()
488 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
491 wxLogLastError(wxT("CM_INVALIDATERECORD"));
493 } // end of wxTreeCtrl::DoSetItem
495 size_t wxTreeCtrl::GetCount () const
499 ::WinSendMsg( GetHWND()
502 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
504 return (size_t)vCnrInfo
.cRecords
;
505 } // end of wxTreeCtrl::GetCount
507 unsigned int wxTreeCtrl::GetIndent () const
511 ::WinSendMsg( GetHWND()
514 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
516 return (unsigned int)vCnrInfo
.cxTreeIndent
;
517 } // end of wxTreeCtrl::GetIndent
519 void wxTreeCtrl::SetIndent (
525 ::WinSendMsg( GetHWND()
528 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
530 vCnrInfo
.cxTreeIndent
= (LONG
)uIndent
;
531 ::WinSendMsg( GetHWND()
534 ,(MPARAM
)CMA_CXTREEINDENT
536 } // end of wxTreeCtrl::SetIndent
538 wxImageList
* wxTreeCtrl::GetImageList () const
540 return m_pImageListNormal
;
541 } // end of wxTreeCtrl::GetImageList
543 #if WXWIN_COMPATIBILITY_2_4
545 wxImageList
* wxTreeCtrl::GetImageList(int nVal
) const
547 return GetImageList();
550 void wxTreeCtrl::SetImageList(wxImageList
* pImageList
, int nVal
)
552 SetImageList(pImageList
);
555 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId
& rItem
) const
557 return GetItemImage(rItem
, wxTreeItemIcon_Selected
);
560 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId
& rItem
, int nImage
)
562 SetItemImage(rItem
, nImage
, wxTreeItemIcon_Selected
);
565 #endif // WXWIN_COMPATIBILITY_2_4
567 wxImageList
* wxTreeCtrl::GetStateImageList () const
569 return m_pImageListNormal
;
570 } // end of wxTreeCtrl::GetStateImageList
573 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE
574 // struct has the icon imbedded in it that it uses for the icon being
575 // displayed via the TREEITEMDESC member. Provided for interface
576 // compatibility only
578 void wxTreeCtrl::SetAnyImageList (
579 wxImageList
* WXUNUSED(pImageList
)
580 , int WXUNUSED(nWhich
)
583 } // end of wxTreeCtrl::SetAnyImageList
585 void wxTreeCtrl::SetImageList (
586 wxImageList
* WXUNUSED(pImageList
)
589 if (m_bOwnsImageListNormal
)
590 delete m_pImageListNormal
;
591 m_bOwnsImageListNormal
= false;
592 } // end of wxTreeCtrl::SetImageList
594 void wxTreeCtrl::SetStateImageList (
595 wxImageList
* WXUNUSED(pImageList
)
598 if (m_bOwnsImageListState
)
599 delete m_pImageListState
;
600 m_bOwnsImageListState
= false;
601 } // end of wxTreeCtrl::SetStateImageList
603 void wxTreeCtrl::AssignImageList (
604 wxImageList
* WXUNUSED(pImageList
)
607 m_bOwnsImageListNormal
= true;
608 } // end of wxTreeCtrl::AssignImageList
610 void wxTreeCtrl::AssignStateImageList (
611 wxImageList
* WXUNUSED(pImageList
)
614 m_bOwnsImageListState
= true;
615 } // end of wxTreeCtrl::AssignStateImageList
617 size_t wxTreeCtrl::GetChildrenCount (
618 const wxTreeItemId
& rItem
622 TraverseCounter
vCounter( this
626 return vCounter
.GetCount() - 1;
627 } // end of wxTreeCtrl::GetChildrenCount
629 // ----------------------------------------------------------------------------
631 // ----------------------------------------------------------------------------
633 bool wxTreeCtrl::SetBackgroundColour (
634 const wxColour
& rColour
637 ULONG ulColor
= wxColourToRGB(rColour
);
639 if ( !wxWindowBase::SetBackgroundColour(rColour
) )
641 ::WinSetPresParam( GetHWND()
647 } // end of wxTreeCtrl::SetBackgroundColour
649 bool wxTreeCtrl::SetForegroundColour (
650 const wxColour
& rColour
653 ULONG ulColor
= wxColourToRGB(rColour
);
655 if (!wxWindowBase::SetForegroundColour(rColour
))
657 ::WinSetPresParam( GetHWND()
663 } // end of wxTreeCtrl::SetForegroundColour
665 // ----------------------------------------------------------------------------
667 // ----------------------------------------------------------------------------
669 wxString
wxTreeCtrl::GetItemText (
670 const wxTreeItemId
& rItem
673 wxChar zBuf
[512]; // the size is arbitrary...
674 wxTreeViewItem
vTvItem(rItem
);
676 if (!DoGetItem(&vTvItem
))
679 // Don't return some garbage which was on stack, but an empty string
684 strcpy(zBuf
, vTvItem
.m_vRecord
.pszTree
);
685 return wxString(zBuf
);
686 } // end of wxTreeCtrl::GetItemText
688 void wxTreeCtrl::SetItemText (
689 const wxTreeItemId
& rItem
690 , const wxString
& rsText
693 wxTreeViewItem
vTvItem(rItem
);
695 vTvItem
.m_vRecord
.pszTree
= (wxChar
*)rsText
.c_str(); // conversion is ok
697 } // end of wxTreeCtrl::SetItemText
700 // These functions under OS/2 PM are not needed. OS/2 containers in tree view
701 // provide for storing a custom expanded and collapsed icons and selected
702 // and non selected icons, natively. For instance, by default, a disk display
703 // will display a tree list of folder icons with "+" icons (collapsed) beside
704 // those folder which contain child members. Double clicking a folder changes
705 // the closed folder icon to an open folder icon with hatched selection
706 // highlighting indicating an ICON view container of the folder is open
707 // elsewhere on the desktop. So the below is not really needed, but we will
708 // simply return the appropriate icon requested out of OS/2's native PM
711 int wxTreeCtrl::DoGetItemImageFromData (
712 const wxTreeItemId
& WXUNUSED(rItem
)
713 , wxTreeItemIcon nWhich
717 // Image handles stored in CNRINFO.
721 ::WinSendMsg( GetHWND()
724 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
728 // We really only have two to chose from. If not custom (set in CNRINFO
729 // then return the handle to system bitmap). OS/2 automatically provides
730 // in_use and selected bitmaps/icons
734 case wxTreeItemIcon_Normal
:
735 if (vCnrInfo
.hbmCollapsed
== NULLHANDLE
)
736 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
);
737 return vCnrInfo
.hbmCollapsed
;
740 case wxTreeItemIcon_Expanded
:
741 if (vCnrInfo
.hbmExpanded
== NULLHANDLE
)
742 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
);
743 return vCnrInfo
.hbmExpanded
;
746 return vCnrInfo
.hbmCollapsed
;
750 void wxTreeCtrl::DoSetItemImageFromData (
751 const wxTreeItemId
& WXUNUSED(rItem
)
753 , wxTreeItemIcon nWhich
757 // Image handles stored in CNRINFO.
761 ::WinSendMsg( GetHWND()
764 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
766 if (nWhich
== wxTreeItemIcon_Normal
)
767 vCnrInfo
.hbmCollapsed
= (HBITMAP
)nImage
;
768 if (nWhich
== wxTreeItemIcon_Expanded
)
769 vCnrInfo
.hbmExpanded
= (HBITMAP
)nImage
;
770 ::WinSendMsg( GetHWND()
773 ,(MPARAM
)CMA_TREEBITMAP
775 } // end of wxTreeCtrl::DoSetItemImageFromData
778 void wxTreeCtrl::DoSetItemImages (
779 const wxTreeItemId
& rItem
784 } // end of wxTreeCtrl::DoSetItemImages
786 int wxTreeCtrl::GetItemImage (
787 const wxTreeItemId
& rItem
788 , wxTreeItemIcon nWhich
791 if (HasIndirectData(rItem
))
793 return DoGetItemImageFromData( rItem
800 ::WinSendMsg( GetHWND()
803 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
808 wxFAIL_MSG( wxT("unknown tree item image type") );
810 case wxTreeItemIcon_Normal
:
811 if (vCnrInfo
.hbmCollapsed
== NULLHANDLE
)
812 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
);
813 return vCnrInfo
.hbmCollapsed
;
816 case wxTreeItemIcon_Expanded
:
817 if (vCnrInfo
.hbmExpanded
== NULLHANDLE
)
818 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
);
819 return vCnrInfo
.hbmExpanded
;
821 case wxTreeItemIcon_Selected
:
822 case wxTreeItemIcon_SelectedExpanded
:
827 void wxTreeCtrl::SetItemImage (
828 const wxTreeItemId
& WXUNUSED(rItem
)
830 , wxTreeItemIcon nWhich
835 ::WinSendMsg( GetHWND()
838 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
842 case wxTreeItemIcon_Normal
:
843 vCnrInfo
.hbmCollapsed
= (HBITMAP
)nImage
;
846 case wxTreeItemIcon_Expanded
:
847 vCnrInfo
.hbmExpanded
= (HBITMAP
)nImage
;
851 wxFAIL_MSG( wxT("unknown tree item image type") );
853 ::WinSendMsg( GetHWND()
856 ,(MPARAM
)CMA_TREEBITMAP
858 } // end of wxTreeCtrl::SetItemImage
860 wxTreeItemData
* wxTreeCtrl::GetItemData (
861 const wxTreeItemId
& rItem
864 wxTreeViewItem
vTvItem(rItem
);
866 if (!DoGetItem(&vTvItem
))
871 return (wxTreeItemData
*)vTvItem
.m_ulUserData
;
872 } // end of wxTreeCtrl::GetItemData
874 void wxTreeCtrl::SetItemData (
875 const wxTreeItemId
& rItem
876 , wxTreeItemData
* pData
880 // first, associate this piece of data with this item
886 wxTreeViewItem
vTvItem(rItem
);
888 vTvItem
.m_ulUserData
= (ULONG
)pData
;
890 } // end of wxTreeCtrl::SetItemData
892 // The following two do nothing under OS/2
893 void wxTreeCtrl::SetIndirectItemData (
894 const wxTreeItemId
& WXUNUSED(rItem
)
895 , wxTreeItemIndirectData
* WXUNUSED(pData
)
898 } // end of wxTreeCtrl::SetIndirectItemData
900 bool wxTreeCtrl::HasIndirectData (
901 const wxTreeItemId
& WXUNUSED(rItem
)
905 } // end of wxTreeCtrl::HasIndirectData
907 // Irreleveant under OS/2 --- item either has child records or it doesn't.
908 void wxTreeCtrl::SetItemHasChildren (
909 const wxTreeItemId
& WXUNUSED(rItem
)
910 , bool WXUNUSED(bHas
)
913 } // end of wxTreeCtrl::SetItemHasChildren
915 // Irreleveant under OS/2 --- function of the font in PM
916 void wxTreeCtrl::SetItemBold (
917 const wxTreeItemId
& WXUNUSED(rItem
)
918 , bool WXUNUSED(bBold
)
921 } // end of wxTreeCtrl::SetItemBold
923 void wxTreeCtrl::SetItemDropHighlight (
924 const wxTreeItemId
& rItem
928 wxTreeViewItem
vTvItem(rItem
);
930 ::WinSendMsg( GetHWND()
931 ,CM_SETRECORDEMPHASIS
933 ,MPFROM2SHORT(bHighlight
, CRA_SELECTED
)
936 } // end of wxTreeCtrl::SetItemDropHighlight
938 void wxTreeCtrl::RefreshItem (
939 const wxTreeItemId
& rItem
942 wxTreeViewItem
vTvItem(rItem
);
945 // This just does a record invalidate causing it to be re-displayed
948 } // end of wxTreeCtrl::RefreshItem
950 wxColour
wxTreeCtrl::GetItemTextColour (
951 const wxTreeItemId
& rItem
954 long lId
= (long)rItem
.m_pItem
;
955 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
961 return pAttr
->GetTextColour();
962 } // end of wxTreeCtrl::GetItemTextColour
964 wxColour
wxTreeCtrl::GetItemBackgroundColour (
965 const wxTreeItemId
& rItem
968 long lId
= (long)rItem
.m_pItem
;
969 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
975 return pAttr
->GetBackgroundColour();
976 } // end of wxTreeCtrl::GetItemBackgroundColour
978 wxFont
wxTreeCtrl::GetItemFont (
979 const wxTreeItemId
& rItem
982 long lId
= (long)rItem
.m_pItem
;
983 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
989 return pAttr
->GetFont();
990 } // end of wxTreeCtrl::GetItemFont
992 void wxTreeCtrl::SetItemTextColour (
993 const wxTreeItemId
& rItem
994 , const wxColour
& rCol
997 m_bHasAnyAttr
= true;
999 long lId
= (long)rItem
.m_pItem
;
1000 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1004 pAttr
= new wxTreeItemAttr
;
1005 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1007 pAttr
->SetTextColour(rCol
);
1009 } // end of wxTreeCtrl::SetItemTextColour
1011 void wxTreeCtrl::SetItemBackgroundColour (
1012 const wxTreeItemId
& rItem
1013 , const wxColour
& rCol
1016 m_bHasAnyAttr
= true;
1018 long lId
= (long)rItem
.m_pItem
;
1019 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1023 pAttr
= new wxTreeItemAttr
;
1024 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1026 pAttr
->SetBackgroundColour(rCol
);
1028 } // end of wxTreeCtrl::SetItemBackgroundColour
1030 void wxTreeCtrl::SetItemFont (
1031 const wxTreeItemId
& rItem
1032 , const wxFont
& rFont
1035 m_bHasAnyAttr
= true;
1037 long lId
= (long)rItem
.m_pItem
;
1038 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1042 pAttr
= new wxTreeItemAttr
;
1043 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1045 pAttr
->SetFont(rFont
);
1047 } // end of wxTreeCtrl::SetItemFont
1049 // ----------------------------------------------------------------------------
1051 // ----------------------------------------------------------------------------
1053 bool wxTreeCtrl::IsVisible (
1054 const wxTreeItemId
& rItem
1057 // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
1059 RECTL vRectContainer
;
1060 wxRect vWxRectRecord
;
1061 wxRect vWxRectContainer
;
1062 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1065 QUERYRECORDRECT vQuery
;
1067 vQuery
.cb
= sizeof(QUERYRECORDRECT
);
1068 vQuery
.pRecord
= (PRECORDCORE
)pRecord
;
1069 vQuery
.fRightSplitWindow
= FALSE
;
1070 vQuery
.fsExtent
= CMA_TREEICON
;
1072 ::WinSendMsg( GetHWND()
1073 ,CM_QUERYVIEWPORTRECT
1074 ,MPFROMP(&vRectContainer
)
1075 ,MPFROM2SHORT(CMA_WINDOW
, FALSE
)
1077 ::WinSendMsg( GetHWND()
1079 ,MPFROMP(&vRectRecord
)
1082 vWxRectRecord
.SetLeft(vRectRecord
.xLeft
);
1083 vWxRectRecord
.SetTop(vRectRecord
.yTop
);
1084 vWxRectRecord
.SetRight(vRectRecord
.xRight
);
1085 vWxRectRecord
.SetBottom(vRectRecord
.yBottom
);
1087 vWxRectContainer
.SetLeft(vRectContainer
.xLeft
);
1088 vWxRectContainer
.SetTop(vRectContainer
.yTop
);
1089 vWxRectContainer
.SetRight(vRectContainer
.xRight
);
1090 vWxRectContainer
.SetBottom(vRectContainer
.yBottom
);
1091 return (vWxRectContainer
.Inside(wxPoint(vWxRectRecord
.x
, vWxRectRecord
.y
)));
1092 } // end of wxTreeCtrl::IsVisible
1094 bool wxTreeCtrl::ItemHasChildren (
1095 const wxTreeItemId
& rItem
1098 wxTreeViewItem
vTvItem(rItem
);
1099 DoGetItem(&vTvItem
);
1102 // A tree record with children will have one of these attributes
1104 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_EXPANDED
||
1105 vTvItem
.m_vRecord
.flRecordAttr
& CRA_COLLAPSED
) != 0;
1108 bool wxTreeCtrl::IsExpanded (
1109 const wxTreeItemId
& rItem
1112 wxTreeViewItem
vTvItem(rItem
);
1113 DoGetItem(&vTvItem
);
1115 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_EXPANDED
) != 0;
1116 } // end of wxTreeCtrl::IsExpanded
1118 bool wxTreeCtrl::IsSelected (
1119 const wxTreeItemId
& rItem
1122 wxTreeViewItem
vTvItem(rItem
);
1123 DoGetItem(&vTvItem
);
1125 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_SELECTED
) != 0;
1126 } // end of wxTreeCtrl::IsSelected
1129 bool wxTreeCtrl::IsBold (
1130 const wxTreeItemId
& rItem
1134 } // end of wxTreeCtrl::IsBold
1136 // ----------------------------------------------------------------------------
1138 // ----------------------------------------------------------------------------
1140 wxTreeItemId
wxTreeCtrl::GetRootItem () const
1142 PMYRECORD pRecord
= NULL
;
1144 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1147 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
1151 return wxTreeItemId(-1L);
1152 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1153 } // end of wxTreeCtrl::GetRootItem
1155 wxTreeItemId
wxTreeCtrl::GetSelection () const
1157 wxCHECK_MSG( !(m_windowStyle
& wxTR_MULTIPLE
), (long)(WXHTREEITEM
)0,
1158 wxT("this only works with single selection controls") );
1160 PMYRECORD pRecord
= NULL
;
1162 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1163 ,CM_QUERYRECORDEMPHASIS
1165 ,MPARAM(CRA_SELECTED
)
1168 return wxTreeItemId(-1L);
1169 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1170 } // end of wxTreeCtrl::GetSelection
1172 wxTreeItemId
wxTreeCtrl::GetItemParent (
1173 const wxTreeItemId
& rItem
1176 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1181 return wxTreeItemId(-1L);
1182 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1185 ,MPFROM2SHORT(CMA_PARENT
, CMA_ITEMORDER
)
1188 return wxTreeItemId(-1L);
1189 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1190 } // end of wxTreeCtrl::GetItemParent
1192 wxTreeItemId
wxTreeCtrl::GetFirstChild (
1193 const wxTreeItemId
& rItem
1197 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1202 return wxTreeItemId(-1L);
1203 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1206 ,MPFROM2SHORT(CMA_FIRSTCHILD
, CMA_ITEMORDER
)
1209 return wxTreeItemId(-1L);
1211 // Remember the last child returned in 'cookie'
1213 rCookie
= (long)pRecord
->m_ulItemId
;
1214 return wxTreeItemId(rCookie
);
1215 } // end of wxTreeCtrl::GetFirstChild
1217 wxTreeItemId
wxTreeCtrl::GetNextChild (
1218 const wxTreeItemId
& WXUNUSED(rItem
)
1222 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1227 return wxTreeItemId(-1L);
1228 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1231 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1234 return wxTreeItemId(-1L);
1235 rCookie
= (long)pRecord
->m_ulItemId
;
1236 return wxTreeItemId(rCookie
);
1237 } // end of wxTreeCtrl::GetNextChild
1239 wxTreeItemId
wxTreeCtrl::GetLastChild (
1240 const wxTreeItemId
& rItem
1243 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1248 return wxTreeItemId(-1L);
1249 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1252 ,MPFROM2SHORT(CMA_LASTCHILD
, CMA_ITEMORDER
)
1255 return wxTreeItemId(-1L);
1256 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1257 } // end of wxTreeCtrl::GetLastChild
1259 wxTreeItemId
wxTreeCtrl::GetNextSibling (
1260 const wxTreeItemId
& rItem
1263 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1268 return wxTreeItemId(-1L);
1269 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1272 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1275 return wxTreeItemId(-1L);
1276 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1277 } // end of wxTreeCtrl::GetNextSibling
1279 wxTreeItemId
wxTreeCtrl::GetPrevSibling (
1280 const wxTreeItemId
& rItem
1283 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1288 return wxTreeItemId(-1L);
1289 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1292 ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
)
1295 return wxTreeItemId(-1L);
1296 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1297 } // end of wxTreeCtrl::GetPrevSibling
1299 wxTreeItemId
wxTreeCtrl::GetFirstVisibleItem () const
1301 PMYRECORD pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1304 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
1307 return wxTreeItemId(-1L);
1309 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1310 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1313 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1316 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1319 return wxTreeItemId(-1L);
1320 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1321 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1323 return wxTreeItemId(-1L);
1324 } // end of wxTreeCtrl::GetFirstVisibleItem
1326 wxTreeItemId
wxTreeCtrl::GetNextVisible (
1327 const wxTreeItemId
& rItem
1330 wxASSERT_MSG(IsVisible(rItem
), wxT("The item you call GetNextVisible() for must be visible itself!"));
1332 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1337 return wxTreeItemId(-1L);
1340 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1343 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1346 return wxTreeItemId(-1L);
1347 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1348 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1350 return wxTreeItemId(-1L);
1351 } // end of wxTreeCtrl::GetNextVisible
1353 wxTreeItemId
wxTreeCtrl::GetPrevVisible (
1354 const wxTreeItemId
& rItem
1357 wxASSERT_MSG( IsVisible(rItem
), wxT("The item you call GetPrevVisible() for must be visible itself!"));
1359 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1364 return wxTreeItemId(-1L);
1367 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1370 ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
)
1373 return wxTreeItemId(-1L);
1374 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1375 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1377 return wxTreeItemId(-1L);
1378 } // end of wxTreeCtrl::GetPrevVisible
1380 // ----------------------------------------------------------------------------
1381 // multiple selections emulation -- under OS/2 checked tree items is not
1382 // supported, but multisel is. So we'll just check for selections here.
1383 // ----------------------------------------------------------------------------
1385 bool wxTreeCtrl::IsItemChecked (
1386 const wxTreeItemId
& rItem
1389 wxTreeViewItem
vTvItem(rItem
);
1391 DoGetItem(&vTvItem
);
1392 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_SELECTED
);
1393 } // end of wxTreeCtrl::IsItemChecked
1395 void wxTreeCtrl::SetItemCheck (
1396 const wxTreeItemId
& rItem
1400 wxTreeViewItem
vTvItem(rItem
);
1402 DoGetItem(&vTvItem
);
1403 ::WinSendMsg( GetHWND()
1404 ,CM_SETRECORDEMPHASIS
1406 ,MPFROM2SHORT(TRUE
, CRA_SELECTED
)
1408 DoSetItem(&vTvItem
);
1409 } // end of wxTreeCtrl::SetItemCheck
1411 size_t wxTreeCtrl::GetSelections (
1412 wxArrayTreeItemIds
& raSelections
1415 TraverseSelections
vSelector( this
1418 return vSelector
.GetCount();
1419 } // end of wxTreeCtrl::GetSelections
1421 // ----------------------------------------------------------------------------
1423 // ----------------------------------------------------------------------------
1425 wxTreeItemId
wxTreeCtrl::DoInsertItem (
1426 const wxTreeItemId
& rParent
1427 , wxTreeItemId vInsertAfter
1428 , const wxString
& rsText
1431 , wxTreeItemData
* pData
1434 PMYRECORD pRecordAfter
= FindOS2TreeRecordByID( GetHWND()
1435 ,vInsertAfter
.m_pItem
1438 PMYRECORD pRecordParent
= FindOS2TreeRecordByID( GetHWND()
1442 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1444 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
1447 RECORDINSERT vInsert
;
1449 vInsert
.cb
= sizeof(RECORDINSERT
);
1450 if (rParent
.m_pItem
== 0L)
1452 if (vInsertAfter
.m_pItem
== -1)
1453 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_END
;
1455 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
1456 vInsert
.pRecordParent
= NULL
;
1460 if (vInsertAfter
.m_pItem
== 0)
1461 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
1462 else if (vInsertAfter
.m_pItem
== -1)
1463 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_END
;
1465 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
1466 vInsert
.pRecordParent
= (PRECORDCORE
)pRecordParent
;
1468 vInsert
.fInvalidateRecord
= TRUE
;
1469 vInsert
.zOrder
= CMA_TOP
;
1470 vInsert
.cRecordsInsert
= 1;
1472 pRecord
->m_vRecord
.pszTree
= (wxChar
*)rsText
.c_str();
1473 pRecord
->m_vRecord
.hbmBitmap
= nImage
;
1474 pRecord
->m_ulItemId
= pRecordAfter
->m_ulItemId
+ 1;
1477 pRecord
->m_ulUserData
= (ULONG
)pData
;
1479 ::WinSendMsg( GetHWND()
1486 // OS/2 must mannually bump the index's of following records
1488 BumpTreeRecordIds( GetHWND()
1494 // Associate the application tree item with PM tree item handle
1496 pData
->SetId((long)pRecord
->m_ulItemId
);
1498 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1501 #if WXWIN_COMPATIBILITY_2_4
1503 // for compatibility only
1504 wxTreeItemId
wxTreeCtrl::InsertItem (
1505 const wxTreeItemId
& rParent
1506 , const wxString
& rsText
1512 return DoInsertItem( rParent
1513 ,wxTreeItemId(lInsertAfter
)
1519 } // end of wxTreeCtrl::InsertItem
1521 #endif // WXWIN_COMPATIBILITY_2_4
1523 wxTreeItemId
wxTreeCtrl::AddRoot (
1524 const wxString
& rsText
1526 , int nSelectedImage
1527 , wxTreeItemData
* pData
)
1530 return DoInsertItem( wxTreeItemId((long)0)
1531 ,wxTreeItemId((long)-1)
1537 } // end of wxTreeCtrl::AddRoot
1539 wxTreeItemId
wxTreeCtrl::PrependItem (
1540 const wxTreeItemId
& rParent
1541 , const wxString
& rsText
1543 , int nSelectedImage
1544 , wxTreeItemData
* pData
1547 return DoInsertItem( rParent
1548 ,wxTreeItemId((long)0)
1554 } // end of wxTreeCtrl::PrependItem
1556 wxTreeItemId
wxTreeCtrl::InsertItem (
1557 const wxTreeItemId
& rParent
1558 , const wxTreeItemId
& rIdPrevious
1559 , const wxString
& rsText
1561 , int nSelectedImage
1562 , wxTreeItemData
* pData
1565 return DoInsertItem( rParent
1572 } // end of wxTreeCtrl::InsertItem
1574 wxTreeItemId
wxTreeCtrl::InsertItem (
1575 const wxTreeItemId
& rParent
1577 , const wxString
& rsText
1579 , int nSelectedImage
1580 , wxTreeItemData
* pData
1583 return DoInsertItem( rParent
1584 ,wxTreeItemId((long)nIndex
)
1590 } // end of wxTreeCtrl::InsertItem
1592 wxTreeItemId
wxTreeCtrl::AppendItem (
1593 const wxTreeItemId
& rParent
1594 , const wxString
& rsText
1596 , int nSelectedImage
1597 , wxTreeItemData
* pData
1600 return DoInsertItem( rParent
1601 ,wxTreeItemId((long)-1)
1607 } // end of wxTreeCtrl::AppendItem
1609 void wxTreeCtrl::Delete (
1610 const wxTreeItemId
& rItem
1614 // OS/2 does not generate DELETEITEM events so do it here
1616 wxEventType vEventType
= wxEVT_NULL
;
1617 wxTreeEvent
vEvent( wxEVT_NULL
1620 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1623 vEvent
.SetEventObject(this);
1624 ::WinSendMsg( GetHWND()
1627 ,(MPARAM
)(CMA_FREE
| CMA_INVALIDATE
)
1629 vEvent
.m_item
= rItem
.m_pItem
;
1632 delete (wxTreeItemAttr
*)m_vAttrs
.Delete((long)rItem
.m_pItem
);
1634 vEvent
.SetEventType(vEventType
);
1635 GetEventHandler()->ProcessEvent(vEvent
);
1636 } // end of wxTreeCtrl::Delete
1638 // delete all children (but don't delete the item itself)
1639 void wxTreeCtrl::DeleteChildren (
1640 const wxTreeItemId
& rItem
1644 wxArrayLong aChildren
;
1645 wxTreeItemId vChild
= GetFirstChild( rItem
1649 while (vChild
.IsOk())
1651 aChildren
.Add((long)(WXHTREEITEM
)vChild
);
1652 vChild
= GetNextChild( rItem
1657 size_t nCount
= aChildren
.Count();
1659 for (size_t n
= 0; n
< nCount
; n
++)
1661 Delete(aChildren
[n
]);
1663 } // end of wxTreeCtrl::DeleteChildren
1665 void wxTreeCtrl::DeleteAllItems ()
1667 ::WinSendMsg( GetHWND()
1670 ,(MPARAM
)(CMA_FREE
| CMA_INVALIDATE
)
1672 } // end of wxTreeCtrl::DeleteAllItems
1674 void wxTreeCtrl::DoExpand (
1675 const wxTreeItemId
& rItem
1679 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1684 case wxTREE_EXPAND_EXPAND
:
1685 ::WinSendMsg( GetHWND()
1692 case wxTREE_EXPAND_COLLAPSE
:
1693 ::WinSendMsg( GetHWND()
1700 case wxTREE_EXPAND_COLLAPSE_RESET
:
1701 ::WinSendMsg( GetHWND()
1706 DeleteChildren(rItem
);
1709 case wxTREE_EXPAND_TOGGLE
:
1710 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_COLLAPSED
)
1711 ::WinSendMsg( GetHWND()
1716 else if (pRecord
->m_vRecord
.flRecordAttr
& CRA_EXPANDED
)
1717 ::WinSendMsg( GetHWND()
1725 } // end of wxTreeCtrl::DoExpand
1727 void wxTreeCtrl::Expand (
1728 const wxTreeItemId
& rItem
1732 ,wxTREE_EXPAND_EXPAND
1734 } // end of wxTreeCtrl::Expand
1736 void wxTreeCtrl::Collapse (
1737 const wxTreeItemId
& rItem
1741 ,wxTREE_EXPAND_COLLAPSE
1743 } // end of wxTreeCtrl::Collapse
1745 void wxTreeCtrl::CollapseAndReset (
1746 const wxTreeItemId
& rItem
1750 ,wxTREE_EXPAND_COLLAPSE_RESET
1752 } // end of wxTreeCtrl::CollapseAndReset
1754 void wxTreeCtrl::Toggle (
1755 const wxTreeItemId
& rItem
1759 ,wxTREE_EXPAND_TOGGLE
1761 } // end of wxTreeCtrl::Toggle
1763 #if WXWIN_COMPATIBILITY_2_4
1765 void wxTreeCtrl::ExpandItem (
1766 const wxTreeItemId
& rItem
1773 } // end of wxTreeCtrl::ExpandItem
1775 #endif // WXWIN_COMPATIBILITY_2_4
1777 void wxTreeCtrl::Unselect ()
1779 wxASSERT_MSG( !(m_windowStyle
& wxTR_MULTIPLE
),
1780 wxT("doesn't make sense, may be you want UnselectAll()?") );
1783 // Just remove the selection
1785 SelectItem(wxTreeItemId((long)0));
1786 } // end of wxTreeCtrl::Unselect
1788 void wxTreeCtrl::UnselectAll ()
1790 if (m_windowStyle
& wxTR_MULTIPLE
)
1792 wxArrayTreeItemIds aSelections
;
1793 size_t nCount
= GetSelections(aSelections
);
1795 for (size_t n
= 0; n
< nCount
; n
++)
1797 SetItemCheck( aSelections
[n
]
1805 // Just remove the selection
1809 } // end of wxTreeCtrl::UnselectAll
1811 void wxTreeCtrl::SelectItem (
1812 const wxTreeItemId
& rItem
1815 SetItemCheck(rItem
);
1816 } // end of wxTreeCtrl::SelectItem
1818 void wxTreeCtrl::EnsureVisible (
1819 const wxTreeItemId
& rItem
1822 wxTreeViewItem
vTvItem(rItem
);
1824 DoGetItem(&vTvItem
);
1825 if (!::WinSendMsg( GetHWND()
1826 ,CM_INVALIDATERECORD
1828 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1830 } // end of wxTreeCtrl::EnsureVisible
1832 void wxTreeCtrl::ScrollTo (
1833 const wxTreeItemId
& rItem
1836 wxTreeViewItem
vTvItem(rItem
);
1838 DoGetItem(&vTvItem
);
1839 if (!::WinSendMsg( GetHWND()
1840 ,CM_INVALIDATERECORD
1842 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1846 wxTextCtrl
* wxTreeCtrl::EditLabel (
1847 const wxTreeItemId
& rItem
1848 , wxClassInfo
* WXUNUSED(pTextControlClass
)
1852 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1856 vEdit
.cb
= sizeof(CNREDITDATA
);
1857 vEdit
.hwndCnr
= GetHWND();
1858 vEdit
.pRecord
= &pRecord
->m_vRecord
;
1859 vEdit
.pFieldInfo
= NULL
;
1860 vEdit
.ppszText
= NULL
;
1864 ::WinSendMsg( GetHWND()
1870 } // end of wxTreeCtrl::EditLabel
1872 // End label editing, optionally cancelling the edit
1873 void wxTreeCtrl::EndEditLabel (
1874 const wxTreeItemId
& WXUNUSED(rItem
)
1875 , bool WXUNUSED(bDiscardChanges
)
1878 ::WinSendMsg( GetHWND()
1883 } // end of wxTreeCtrl::EndEditLabel
1885 wxTreeItemId
wxTreeCtrl::HitTest (
1886 const wxPoint
& rPoint
1887 , int& WXUNUSED(rFlags
)
1890 PMYRECORD pRecord
= NULL
;
1891 QUERYRECFROMRECT vQueryRect
;
1896 // Get height for OS/2 point conversion
1898 ::WinSendMsg( GetHWND()
1899 ,CM_QUERYVIEWPORTRECT
1901 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1903 lHeight
= vRect
.yTop
- vRect
.yBottom
;
1906 // For now just try and get a record in the general vicinity and forget
1909 vRect
.xLeft
= rPoint
.x
- 2;
1910 vRect
.xRight
= rPoint
.x
+ 2;
1911 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
1912 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
1914 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1915 vQueryRect
.rect
= vRect
;
1916 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1918 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1919 ,CM_QUERYRECORDFROMRECT
1921 ,MPFROMP(&vQueryRect
)
1926 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1927 } // end of wxTreeCtrl::HitTest
1929 bool wxTreeCtrl::GetBoundingRect (
1930 const wxTreeItemId
& rItem
1936 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1939 QUERYRECORDRECT vQuery
;
1941 vQuery
.cb
= sizeof(QUERYRECORDRECT
);
1942 vQuery
.pRecord
= (PRECORDCORE
)pRecord
;
1943 vQuery
.fRightSplitWindow
= FALSE
;
1945 vQuery
.fsExtent
= CMA_TEXT
;
1947 vQuery
.fsExtent
= CMA_TREEICON
| CMA_TEXT
;
1949 if (!::WinSendMsg( GetHWND()
1951 ,MPFROMP(&vRectRecord
)
1955 rRect
.SetLeft(vRectRecord
.xLeft
);
1956 rRect
.SetTop(vRectRecord
.yTop
);
1957 rRect
.SetRight(vRectRecord
.xRight
);
1958 rRect
.SetBottom(vRectRecord
.yBottom
);
1960 } // end of wxTreeCtrl::GetBoundingRect
1962 // ----------------------------------------------------------------------------
1964 // ----------------------------------------------------------------------------
1966 SHORT EXPENTRY
InternalDataCompareTreeFunc (
1972 wxCHECK_MSG( p1
&& p2
, 0,
1973 wxT("sorting tree without data doesn't make sense") );
1975 wxTreeCtrl
* pTree
= (wxTreeCtrl
*)pStorage
;
1977 return pTree
->OnCompareItems( p1
->m_ulItemId
1980 } // end of wxTreeSortHelper::Compare
1982 int wxTreeCtrl::OnCompareItems (
1983 const wxTreeItemId
& rItem1
1984 , const wxTreeItemId
& rItem2
1987 return wxStrcmp( GetItemText(rItem1
)
1988 ,GetItemText(rItem2
)
1990 } // end of wxTreeCtrl::OnCompareItems
1992 void wxTreeCtrl::SortChildren (
1993 const wxTreeItemId
& rItem
1996 ::WinSendMsg( GetHWND()
1998 ,(PFN
)InternalDataCompareTreeFunc
2001 } // end of wxTreeCtrl::SortChildren
2003 // ----------------------------------------------------------------------------
2005 // ----------------------------------------------------------------------------
2007 bool wxTreeCtrl::OS2Command (
2012 if (uCmd
== CN_ENDEDIT
)
2014 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
2018 vEvent
.SetEventObject( this );
2019 ProcessCommand(vEvent
);
2022 else if (uCmd
== CN_KILLFOCUS
)
2024 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
2027 vEvent
.SetEventObject( this );
2028 ProcessCommand(vEvent
);
2033 } // end of wxTreeCtrl::OS2Command
2036 // TODO: Fully implement direct manipulation when I figure it out
2038 MRESULT
wxTreeCtrl::OS2WindowProc (
2044 bool bProcessed
= false;
2046 wxTreeEvent
vEvent( wxEVT_NULL
2049 wxEventType vEventType
= wxEVT_NULL
;
2050 PCNRDRAGINIT pDragInit
= NULL
;
2051 PCNREDITDATA pEditData
= NULL
;
2052 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
2054 vEvent
.SetEventObject(this);
2058 switch(SHORT2FROMMP(wParam
))
2061 pDragInit
= (PCNRDRAGINIT
)lParam
;
2064 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2066 vEventType
= wxEVT_COMMAND_TREE_BEGIN_DRAG
;
2067 vEvent
.m_item
= pRecord
->m_ulItemId
;
2068 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2069 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2074 pEditData
= (PCNREDITDATA
)lParam
;
2077 PMYRECORD pRecord
= (PMYRECORD
)pEditData
->pRecord
;
2079 vEventType
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
;
2080 vEvent
.m_item
= pRecord
->m_ulItemId
;
2081 vEvent
.m_label
= pRecord
->m_vRecord
.pszTree
;
2082 vEvent
.m_editCancelled
= false;
2087 pEditData
= (PCNREDITDATA
)lParam
;
2090 PMYRECORD pRecord
= (PMYRECORD
)pEditData
->pRecord
;
2092 vEventType
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
;
2093 vEvent
.m_item
= pRecord
->m_ulItemId
;
2094 vEvent
.m_label
= pRecord
->m_vRecord
.pszTree
;
2095 if (pRecord
->m_vRecord
.pszTree
== NULL
)
2097 vEvent
.m_editCancelled
= true;
2101 vEvent
.m_editCancelled
= false;
2108 PMYRECORD pRecord
= (PMYRECORD
)lParam
;
2110 vEventType
= gs_expandEvents
[IDX_EXPAND
][IDX_DONE
];
2111 vEvent
.m_item
= pRecord
->m_ulItemId
;
2115 vEvent
.SetEventType(vEventType
);
2116 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
2120 mRc
= wxControl::OS2WindowProc( uMsg
2125 } // end of wxTreeCtrl::OS2WindowProc
2127 #if WXWIN_COMPATIBILITY_2_2
2129 wxTreeItemId
wxTreeCtrl::GetParent(const wxTreeItemId
& item
) const
2131 return GetItemParent( item
);
2134 #endif // WXWIN_COMPATIBILITY_2_2
2136 #endif // wxUSE_TREECTRL