1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/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/treectrl.h"
32 #include "wx/dynarray.h"
35 #include "wx/settings.h"
38 #include "wx/os2/private.h"
40 #include "wx/imaglist.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()
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 wxDECLARE_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 unsigned int wxTreeCtrl::GetCount () const
499 ::WinSendMsg( GetHWND()
502 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
505 return (unsigned int)vCnrInfo
.cRecords
;
506 } // end of wxTreeCtrl::GetCount
508 unsigned int wxTreeCtrl::GetIndent () const
512 ::WinSendMsg( GetHWND()
515 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
517 return (unsigned int)vCnrInfo
.cxTreeIndent
;
518 } // end of wxTreeCtrl::GetIndent
520 void wxTreeCtrl::SetIndent (
526 ::WinSendMsg( GetHWND()
529 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
531 vCnrInfo
.cxTreeIndent
= (LONG
)uIndent
;
532 ::WinSendMsg( GetHWND()
535 ,(MPARAM
)CMA_CXTREEINDENT
537 } // end of wxTreeCtrl::SetIndent
539 wxImageList
* wxTreeCtrl::GetImageList () const
541 return m_pImageListNormal
;
542 } // end of wxTreeCtrl::GetImageList
544 wxImageList
* wxTreeCtrl::GetStateImageList () const
546 return m_pImageListNormal
;
547 } // end of wxTreeCtrl::GetStateImageList
550 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE
551 // struct has the icon imbedded in it that it uses for the icon being
552 // displayed via the TREEITEMDESC member. Provided for interface
553 // compatibility only
555 void wxTreeCtrl::SetAnyImageList (
556 wxImageList
* WXUNUSED(pImageList
)
557 , int WXUNUSED(nWhich
)
560 } // end of wxTreeCtrl::SetAnyImageList
562 void wxTreeCtrl::SetImageList (
563 wxImageList
* WXUNUSED(pImageList
)
566 if (m_bOwnsImageListNormal
)
567 delete m_pImageListNormal
;
568 m_bOwnsImageListNormal
= false;
569 } // end of wxTreeCtrl::SetImageList
571 void wxTreeCtrl::SetStateImageList (
572 wxImageList
* WXUNUSED(pImageList
)
575 if (m_bOwnsImageListState
)
576 delete m_pImageListState
;
577 m_bOwnsImageListState
= false;
578 } // end of wxTreeCtrl::SetStateImageList
580 void wxTreeCtrl::AssignImageList (
581 wxImageList
* WXUNUSED(pImageList
)
584 m_bOwnsImageListNormal
= true;
585 } // end of wxTreeCtrl::AssignImageList
587 void wxTreeCtrl::AssignStateImageList (
588 wxImageList
* WXUNUSED(pImageList
)
591 m_bOwnsImageListState
= true;
592 } // end of wxTreeCtrl::AssignStateImageList
594 size_t wxTreeCtrl::GetChildrenCount (
595 const wxTreeItemId
& rItem
599 TraverseCounter
vCounter( this
603 return vCounter
.GetCount() - 1;
604 } // end of wxTreeCtrl::GetChildrenCount
606 // ----------------------------------------------------------------------------
608 // ----------------------------------------------------------------------------
610 bool wxTreeCtrl::SetBackgroundColour (
611 const wxColour
& rColour
614 ULONG ulColor
= wxColourToRGB(rColour
);
616 if ( !wxWindowBase::SetBackgroundColour(rColour
) )
618 ::WinSetPresParam( GetHWND()
624 } // end of wxTreeCtrl::SetBackgroundColour
626 bool wxTreeCtrl::SetForegroundColour (
627 const wxColour
& rColour
630 ULONG ulColor
= wxColourToRGB(rColour
);
632 if (!wxWindowBase::SetForegroundColour(rColour
))
634 ::WinSetPresParam( GetHWND()
640 } // end of wxTreeCtrl::SetForegroundColour
642 // ----------------------------------------------------------------------------
644 // ----------------------------------------------------------------------------
646 wxString
wxTreeCtrl::GetItemText (
647 const wxTreeItemId
& rItem
650 wxChar zBuf
[512]; // the size is arbitrary...
651 wxTreeViewItem
vTvItem(rItem
);
653 if (!DoGetItem(&vTvItem
))
656 // Don't return some garbage which was on stack, but an empty string
661 strcpy(zBuf
, vTvItem
.m_vRecord
.pszTree
);
662 return wxString(zBuf
);
663 } // end of wxTreeCtrl::GetItemText
665 void wxTreeCtrl::SetItemText (
666 const wxTreeItemId
& rItem
667 , const wxString
& rsText
670 wxTreeViewItem
vTvItem(rItem
);
672 vTvItem
.m_vRecord
.pszTree
= (wxChar
*)rsText
.c_str(); // conversion is ok
674 } // end of wxTreeCtrl::SetItemText
677 // These functions under OS/2 PM are not needed. OS/2 containers in tree view
678 // provide for storing a custom expanded and collapsed icons and selected
679 // and non selected icons, natively. For instance, by default, a disk display
680 // will display a tree list of folder icons with "+" icons (collapsed) beside
681 // those folder which contain child members. Double clicking a folder changes
682 // the closed folder icon to an open folder icon with hatched selection
683 // highlighting indicating an ICON view container of the folder is open
684 // elsewhere on the desktop. So the below is not really needed, but we will
685 // simply return the appropriate icon requested out of OS/2's native PM
688 int wxTreeCtrl::DoGetItemImageFromData (
689 const wxTreeItemId
& WXUNUSED(rItem
)
690 , wxTreeItemIcon nWhich
694 // Image handles stored in CNRINFO.
698 ::WinSendMsg( GetHWND()
701 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
705 // We really only have two to chose from. If not custom (set in CNRINFO
706 // then return the handle to system bitmap). OS/2 automatically provides
707 // in_use and selected bitmaps/icons
711 case wxTreeItemIcon_Normal
:
712 if (vCnrInfo
.hbmCollapsed
== NULLHANDLE
)
713 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
);
714 return vCnrInfo
.hbmCollapsed
;
717 case wxTreeItemIcon_Expanded
:
718 if (vCnrInfo
.hbmExpanded
== NULLHANDLE
)
719 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
);
720 return vCnrInfo
.hbmExpanded
;
723 return vCnrInfo
.hbmCollapsed
;
727 void wxTreeCtrl::DoSetItemImageFromData (
728 const wxTreeItemId
& WXUNUSED(rItem
)
730 , wxTreeItemIcon nWhich
734 // Image handles stored in CNRINFO.
738 ::WinSendMsg( GetHWND()
741 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
743 if (nWhich
== wxTreeItemIcon_Normal
)
744 vCnrInfo
.hbmCollapsed
= (HBITMAP
)nImage
;
745 if (nWhich
== wxTreeItemIcon_Expanded
)
746 vCnrInfo
.hbmExpanded
= (HBITMAP
)nImage
;
747 ::WinSendMsg( GetHWND()
750 ,(MPARAM
)CMA_TREEBITMAP
752 } // end of wxTreeCtrl::DoSetItemImageFromData
755 void wxTreeCtrl::DoSetItemImages (
756 const wxTreeItemId
& rItem
761 } // end of wxTreeCtrl::DoSetItemImages
763 int wxTreeCtrl::GetItemImage (
764 const wxTreeItemId
& rItem
765 , wxTreeItemIcon nWhich
768 if (HasIndirectData(rItem
))
770 return DoGetItemImageFromData( rItem
777 ::WinSendMsg( GetHWND()
780 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
785 wxFAIL_MSG( wxT("unknown tree item image type") );
787 case wxTreeItemIcon_Normal
:
788 if (vCnrInfo
.hbmCollapsed
== NULLHANDLE
)
789 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
);
790 return vCnrInfo
.hbmCollapsed
;
793 case wxTreeItemIcon_Expanded
:
794 if (vCnrInfo
.hbmExpanded
== NULLHANDLE
)
795 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
);
796 return vCnrInfo
.hbmExpanded
;
798 case wxTreeItemIcon_Selected
:
799 case wxTreeItemIcon_SelectedExpanded
:
804 void wxTreeCtrl::SetItemImage (
805 const wxTreeItemId
& WXUNUSED(rItem
)
807 , wxTreeItemIcon nWhich
812 ::WinSendMsg( GetHWND()
815 ,(MPARAM
)(USHORT
)sizeof(CNRINFO
)
819 case wxTreeItemIcon_Normal
:
820 vCnrInfo
.hbmCollapsed
= (HBITMAP
)nImage
;
823 case wxTreeItemIcon_Expanded
:
824 vCnrInfo
.hbmExpanded
= (HBITMAP
)nImage
;
828 wxFAIL_MSG( wxT("unknown tree item image type") );
830 ::WinSendMsg( GetHWND()
833 ,(MPARAM
)CMA_TREEBITMAP
835 } // end of wxTreeCtrl::SetItemImage
837 wxTreeItemData
* wxTreeCtrl::GetItemData (
838 const wxTreeItemId
& rItem
841 wxTreeViewItem
vTvItem(rItem
);
843 if (!DoGetItem(&vTvItem
))
848 return (wxTreeItemData
*)vTvItem
.m_ulUserData
;
849 } // end of wxTreeCtrl::GetItemData
851 void wxTreeCtrl::SetItemData (
852 const wxTreeItemId
& rItem
853 , wxTreeItemData
* pData
857 // first, associate this piece of data with this item
863 wxTreeViewItem
vTvItem(rItem
);
865 vTvItem
.m_ulUserData
= (ULONG
)pData
;
867 } // end of wxTreeCtrl::SetItemData
869 // The following two do nothing under OS/2
870 void wxTreeCtrl::SetIndirectItemData (
871 const wxTreeItemId
& WXUNUSED(rItem
)
872 , wxTreeItemIndirectData
* WXUNUSED(pData
)
875 } // end of wxTreeCtrl::SetIndirectItemData
877 bool wxTreeCtrl::HasIndirectData (
878 const wxTreeItemId
& WXUNUSED(rItem
)
882 } // end of wxTreeCtrl::HasIndirectData
884 // Irreleveant under OS/2 --- item either has child records or it doesn't.
885 void wxTreeCtrl::SetItemHasChildren (
886 const wxTreeItemId
& WXUNUSED(rItem
)
887 , bool WXUNUSED(bHas
)
890 } // end of wxTreeCtrl::SetItemHasChildren
892 // Irreleveant under OS/2 --- function of the font in PM
893 void wxTreeCtrl::SetItemBold (
894 const wxTreeItemId
& WXUNUSED(rItem
)
895 , bool WXUNUSED(bBold
)
898 } // end of wxTreeCtrl::SetItemBold
900 void wxTreeCtrl::SetItemDropHighlight (
901 const wxTreeItemId
& rItem
905 wxTreeViewItem
vTvItem(rItem
);
907 ::WinSendMsg( GetHWND()
908 ,CM_SETRECORDEMPHASIS
910 ,MPFROM2SHORT(bHighlight
, CRA_SELECTED
)
913 } // end of wxTreeCtrl::SetItemDropHighlight
915 void wxTreeCtrl::RefreshItem (
916 const wxTreeItemId
& rItem
919 wxTreeViewItem
vTvItem(rItem
);
922 // This just does a record invalidate causing it to be re-displayed
925 } // end of wxTreeCtrl::RefreshItem
927 wxColour
wxTreeCtrl::GetItemTextColour (
928 const wxTreeItemId
& rItem
931 long lId
= (long)rItem
.m_pItem
;
932 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
938 return pAttr
->GetTextColour();
939 } // end of wxTreeCtrl::GetItemTextColour
941 wxColour
wxTreeCtrl::GetItemBackgroundColour (
942 const wxTreeItemId
& rItem
945 long lId
= (long)rItem
.m_pItem
;
946 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
952 return pAttr
->GetBackgroundColour();
953 } // end of wxTreeCtrl::GetItemBackgroundColour
955 wxFont
wxTreeCtrl::GetItemFont (
956 const wxTreeItemId
& rItem
959 long lId
= (long)rItem
.m_pItem
;
960 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
966 return pAttr
->GetFont();
967 } // end of wxTreeCtrl::GetItemFont
969 void wxTreeCtrl::SetItemTextColour (
970 const wxTreeItemId
& rItem
971 , const wxColour
& rCol
974 m_bHasAnyAttr
= true;
976 long lId
= (long)rItem
.m_pItem
;
977 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
981 pAttr
= new wxTreeItemAttr
;
982 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
984 pAttr
->SetTextColour(rCol
);
986 } // end of wxTreeCtrl::SetItemTextColour
988 void wxTreeCtrl::SetItemBackgroundColour (
989 const wxTreeItemId
& rItem
990 , const wxColour
& rCol
993 m_bHasAnyAttr
= true;
995 long lId
= (long)rItem
.m_pItem
;
996 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1000 pAttr
= new wxTreeItemAttr
;
1001 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1003 pAttr
->SetBackgroundColour(rCol
);
1005 } // end of wxTreeCtrl::SetItemBackgroundColour
1007 void wxTreeCtrl::SetItemFont (
1008 const wxTreeItemId
& rItem
1009 , const wxFont
& rFont
1012 m_bHasAnyAttr
= true;
1014 long lId
= (long)rItem
.m_pItem
;
1015 wxTreeItemAttr
* pAttr
= (wxTreeItemAttr
*)m_vAttrs
.Get(lId
);
1019 pAttr
= new wxTreeItemAttr
;
1020 m_vAttrs
.Put(lId
, (wxObject
*)pAttr
);
1022 pAttr
->SetFont(rFont
);
1024 } // end of wxTreeCtrl::SetItemFont
1026 // ----------------------------------------------------------------------------
1028 // ----------------------------------------------------------------------------
1030 bool wxTreeCtrl::IsVisible (
1031 const wxTreeItemId
& rItem
1034 // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
1036 RECTL vRectContainer
;
1037 wxRect vWxRectRecord
;
1038 wxRect vWxRectContainer
;
1039 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1042 QUERYRECORDRECT vQuery
;
1044 vQuery
.cb
= sizeof(QUERYRECORDRECT
);
1045 vQuery
.pRecord
= (PRECORDCORE
)pRecord
;
1046 vQuery
.fRightSplitWindow
= FALSE
;
1047 vQuery
.fsExtent
= CMA_TREEICON
;
1049 ::WinSendMsg( GetHWND()
1050 ,CM_QUERYVIEWPORTRECT
1051 ,MPFROMP(&vRectContainer
)
1052 ,MPFROM2SHORT(CMA_WINDOW
, FALSE
)
1054 ::WinSendMsg( GetHWND()
1056 ,MPFROMP(&vRectRecord
)
1059 vWxRectRecord
.SetLeft(vRectRecord
.xLeft
);
1060 vWxRectRecord
.SetTop(vRectRecord
.yTop
);
1061 vWxRectRecord
.SetRight(vRectRecord
.xRight
);
1062 vWxRectRecord
.SetBottom(vRectRecord
.yBottom
);
1064 vWxRectContainer
.SetLeft(vRectContainer
.xLeft
);
1065 vWxRectContainer
.SetTop(vRectContainer
.yTop
);
1066 vWxRectContainer
.SetRight(vRectContainer
.xRight
);
1067 vWxRectContainer
.SetBottom(vRectContainer
.yBottom
);
1068 return (vWxRectContainer
.Contains(wxPoint(vWxRectRecord
.x
, vWxRectRecord
.y
)));
1069 } // end of wxTreeCtrl::IsVisible
1071 bool wxTreeCtrl::ItemHasChildren (
1072 const wxTreeItemId
& rItem
1075 wxTreeViewItem
vTvItem(rItem
);
1076 DoGetItem(&vTvItem
);
1079 // A tree record with children will have one of these attributes
1081 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_EXPANDED
||
1082 vTvItem
.m_vRecord
.flRecordAttr
& CRA_COLLAPSED
) != 0;
1085 bool wxTreeCtrl::IsExpanded (
1086 const wxTreeItemId
& rItem
1089 wxTreeViewItem
vTvItem(rItem
);
1090 DoGetItem(&vTvItem
);
1092 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_EXPANDED
) != 0;
1093 } // end of wxTreeCtrl::IsExpanded
1095 bool wxTreeCtrl::IsSelected (
1096 const wxTreeItemId
& rItem
1099 wxTreeViewItem
vTvItem(rItem
);
1100 DoGetItem(&vTvItem
);
1102 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_SELECTED
) != 0;
1103 } // end of wxTreeCtrl::IsSelected
1106 bool wxTreeCtrl::IsBold (
1107 const wxTreeItemId
& rItem
1111 } // end of wxTreeCtrl::IsBold
1113 // ----------------------------------------------------------------------------
1115 // ----------------------------------------------------------------------------
1117 wxTreeItemId
wxTreeCtrl::GetRootItem () const
1119 PMYRECORD pRecord
= NULL
;
1121 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1124 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
1128 return wxTreeItemId(-1L);
1129 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1130 } // end of wxTreeCtrl::GetRootItem
1132 wxTreeItemId
wxTreeCtrl::GetSelection () const
1134 wxCHECK_MSG( !(m_windowStyle
& wxTR_MULTIPLE
), (long)(WXHTREEITEM
)0,
1135 wxT("this only works with single selection controls") );
1137 PMYRECORD pRecord
= NULL
;
1139 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1140 ,CM_QUERYRECORDEMPHASIS
1142 ,MPARAM(CRA_SELECTED
)
1145 return wxTreeItemId(-1L);
1146 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1147 } // end of wxTreeCtrl::GetSelection
1149 wxTreeItemId
wxTreeCtrl::GetItemParent (
1150 const wxTreeItemId
& rItem
1153 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1158 return wxTreeItemId(-1L);
1159 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1162 ,MPFROM2SHORT(CMA_PARENT
, CMA_ITEMORDER
)
1165 return wxTreeItemId(-1L);
1166 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1167 } // end of wxTreeCtrl::GetItemParent
1169 wxTreeItemId
wxTreeCtrl::GetFirstChild (
1170 const wxTreeItemId
& rItem
1174 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1179 return wxTreeItemId(-1L);
1180 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1183 ,MPFROM2SHORT(CMA_FIRSTCHILD
, CMA_ITEMORDER
)
1186 return wxTreeItemId(-1L);
1188 // Remember the last child returned in 'cookie'
1190 rCookie
= (long)pRecord
->m_ulItemId
;
1191 return wxTreeItemId(rCookie
);
1192 } // end of wxTreeCtrl::GetFirstChild
1194 wxTreeItemId
wxTreeCtrl::GetNextChild (
1195 const wxTreeItemId
& WXUNUSED(rItem
)
1199 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1204 return wxTreeItemId(-1L);
1205 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1208 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1211 return wxTreeItemId(-1L);
1212 rCookie
= (long)pRecord
->m_ulItemId
;
1213 return wxTreeItemId(rCookie
);
1214 } // end of wxTreeCtrl::GetNextChild
1216 wxTreeItemId
wxTreeCtrl::GetLastChild (
1217 const wxTreeItemId
& rItem
1220 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1225 return wxTreeItemId(-1L);
1226 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1229 ,MPFROM2SHORT(CMA_LASTCHILD
, CMA_ITEMORDER
)
1232 return wxTreeItemId(-1L);
1233 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1234 } // end of wxTreeCtrl::GetLastChild
1236 wxTreeItemId
wxTreeCtrl::GetNextSibling (
1237 const wxTreeItemId
& rItem
1240 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1245 return wxTreeItemId(-1L);
1246 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1249 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1252 return wxTreeItemId(-1L);
1253 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1254 } // end of wxTreeCtrl::GetNextSibling
1256 wxTreeItemId
wxTreeCtrl::GetPrevSibling (
1257 const wxTreeItemId
& rItem
1260 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1265 return wxTreeItemId(-1L);
1266 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1269 ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
)
1272 return wxTreeItemId(-1L);
1273 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1274 } // end of wxTreeCtrl::GetPrevSibling
1276 wxTreeItemId
wxTreeCtrl::GetFirstVisibleItem () const
1278 PMYRECORD pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1281 ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
)
1284 return wxTreeItemId(-1L);
1286 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1287 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1290 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1293 ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
)
1296 return wxTreeItemId(-1L);
1297 if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
)))
1298 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1300 return wxTreeItemId(-1L);
1301 } // end of wxTreeCtrl::GetFirstVisibleItem
1303 wxTreeItemId
wxTreeCtrl::GetNextVisible (
1304 const wxTreeItemId
& rItem
1307 wxASSERT_MSG(IsVisible(rItem
), wxT("The item you call GetNextVisible() for must be visible itself!"));
1309 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1314 return wxTreeItemId(-1L);
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::GetNextVisible
1330 wxTreeItemId
wxTreeCtrl::GetPrevVisible (
1331 const wxTreeItemId
& rItem
1334 wxASSERT_MSG( IsVisible(rItem
), wxT("The item you call GetPrevVisible() for must be visible itself!"));
1336 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1341 return wxTreeItemId(-1L);
1344 pRecord
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND()
1347 ,MPFROM2SHORT(CMA_PREV
, 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::GetPrevVisible
1357 // ----------------------------------------------------------------------------
1358 // multiple selections emulation -- under OS/2 checked tree items is not
1359 // supported, but multisel is. So we'll just check for selections here.
1360 // ----------------------------------------------------------------------------
1362 bool wxTreeCtrl::IsItemChecked (
1363 const wxTreeItemId
& rItem
1366 wxTreeViewItem
vTvItem(rItem
);
1368 DoGetItem(&vTvItem
);
1369 return (vTvItem
.m_vRecord
.flRecordAttr
& CRA_SELECTED
);
1370 } // end of wxTreeCtrl::IsItemChecked
1372 void wxTreeCtrl::SetItemCheck (
1373 const wxTreeItemId
& rItem
1377 wxTreeViewItem
vTvItem(rItem
);
1379 DoGetItem(&vTvItem
);
1380 ::WinSendMsg( GetHWND()
1381 ,CM_SETRECORDEMPHASIS
1383 ,MPFROM2SHORT(TRUE
, CRA_SELECTED
)
1385 DoSetItem(&vTvItem
);
1386 } // end of wxTreeCtrl::SetItemCheck
1388 size_t wxTreeCtrl::GetSelections (
1389 wxArrayTreeItemIds
& raSelections
1392 TraverseSelections
vSelector( this
1395 return vSelector
.GetCount();
1396 } // end of wxTreeCtrl::GetSelections
1398 // ----------------------------------------------------------------------------
1400 // ----------------------------------------------------------------------------
1402 wxTreeItemId
wxTreeCtrl::DoInsertItem (
1403 const wxTreeItemId
& rParent
1404 , wxTreeItemId vInsertAfter
1405 , const wxString
& rsText
1408 , wxTreeItemData
* pData
1411 PMYRECORD pRecordAfter
= FindOS2TreeRecordByID( GetHWND()
1412 ,vInsertAfter
.m_pItem
1415 PMYRECORD pRecordParent
= FindOS2TreeRecordByID( GetHWND()
1419 PMYRECORD pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1421 ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
))
1424 RECORDINSERT vInsert
;
1426 vInsert
.cb
= sizeof(RECORDINSERT
);
1427 if (rParent
.m_pItem
== 0L)
1429 if (vInsertAfter
.m_pItem
== -1)
1430 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_END
;
1432 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
1433 vInsert
.pRecordParent
= NULL
;
1437 if (vInsertAfter
.m_pItem
== 0)
1438 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_FIRST
;
1439 else if (vInsertAfter
.m_pItem
== -1)
1440 vInsert
.pRecordOrder
= (PRECORDCORE
)CMA_END
;
1442 vInsert
.pRecordOrder
= (PRECORDCORE
)pRecordAfter
;
1443 vInsert
.pRecordParent
= (PRECORDCORE
)pRecordParent
;
1445 vInsert
.fInvalidateRecord
= TRUE
;
1446 vInsert
.zOrder
= CMA_TOP
;
1447 vInsert
.cRecordsInsert
= 1;
1449 pRecord
->m_vRecord
.pszTree
= (wxChar
*)rsText
.c_str();
1450 pRecord
->m_vRecord
.hbmBitmap
= nImage
;
1451 pRecord
->m_ulItemId
= pRecordAfter
->m_ulItemId
+ 1;
1454 pRecord
->m_ulUserData
= (ULONG
)pData
;
1456 ::WinSendMsg( GetHWND()
1463 // OS/2 must mannually bump the index's of following records
1465 BumpTreeRecordIds( GetHWND()
1471 // Associate the application tree item with PM tree item handle
1473 pData
->SetId((long)pRecord
->m_ulItemId
);
1475 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1478 wxTreeItemId
wxTreeCtrl::AddRoot (
1479 const wxString
& rsText
1481 , int nSelectedImage
1482 , wxTreeItemData
* pData
)
1485 return DoInsertItem( wxTreeItemId((long)0)
1486 ,wxTreeItemId((long)-1)
1492 } // end of wxTreeCtrl::AddRoot
1494 wxTreeItemId
wxTreeCtrl::PrependItem (
1495 const wxTreeItemId
& rParent
1496 , const wxString
& rsText
1498 , int nSelectedImage
1499 , wxTreeItemData
* pData
1502 return DoInsertItem( rParent
1503 ,wxTreeItemId((long)0)
1509 } // end of wxTreeCtrl::PrependItem
1511 wxTreeItemId
wxTreeCtrl::InsertItem (
1512 const wxTreeItemId
& rParent
1513 , const wxTreeItemId
& rIdPrevious
1514 , const wxString
& rsText
1516 , int nSelectedImage
1517 , wxTreeItemData
* pData
1520 return DoInsertItem( rParent
1527 } // end of wxTreeCtrl::InsertItem
1529 wxTreeItemId
wxTreeCtrl::InsertItem (
1530 const wxTreeItemId
& rParent
1532 , const wxString
& rsText
1534 , int nSelectedImage
1535 , wxTreeItemData
* pData
1538 return DoInsertItem( rParent
1539 ,wxTreeItemId((long)nIndex
)
1545 } // end of wxTreeCtrl::InsertItem
1547 wxTreeItemId
wxTreeCtrl::AppendItem (
1548 const wxTreeItemId
& rParent
1549 , const wxString
& rsText
1551 , int nSelectedImage
1552 , wxTreeItemData
* pData
1555 return DoInsertItem( rParent
1556 ,wxTreeItemId((long)-1)
1562 } // end of wxTreeCtrl::AppendItem
1564 void wxTreeCtrl::Delete (
1565 const wxTreeItemId
& rItem
1569 // OS/2 does not generate DELETEITEM events so do it here
1571 wxEventType vEventType
= wxEVT_NULL
;
1572 wxTreeEvent
vEvent( wxEVT_NULL
1575 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1578 vEvent
.SetEventObject(this);
1579 ::WinSendMsg( GetHWND()
1582 ,(MPARAM
)(CMA_FREE
| CMA_INVALIDATE
)
1584 vEvent
.m_item
= rItem
.m_pItem
;
1587 delete (wxTreeItemAttr
*)m_vAttrs
.Delete((long)rItem
.m_pItem
);
1589 vEvent
.SetEventType(vEventType
);
1590 HandleWindowEvent(vEvent
);
1591 } // end of wxTreeCtrl::Delete
1593 // delete all children (but don't delete the item itself)
1594 void wxTreeCtrl::DeleteChildren (
1595 const wxTreeItemId
& rItem
1599 wxArrayLong aChildren
;
1600 wxTreeItemId vChild
= GetFirstChild( rItem
1604 while (vChild
.IsOk())
1606 aChildren
.Add((long)(WXHTREEITEM
)vChild
);
1607 vChild
= GetNextChild( rItem
1612 size_t nCount
= aChildren
.Count();
1614 for (size_t n
= 0; n
< nCount
; n
++)
1616 Delete(aChildren
[n
]);
1618 } // end of wxTreeCtrl::DeleteChildren
1620 void wxTreeCtrl::DeleteAllItems ()
1622 ::WinSendMsg( GetHWND()
1625 ,(MPARAM
)(CMA_FREE
| CMA_INVALIDATE
)
1627 } // end of wxTreeCtrl::DeleteAllItems
1629 void wxTreeCtrl::DoExpand (
1630 const wxTreeItemId
& rItem
1634 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1639 case wxTREE_EXPAND_EXPAND
:
1640 ::WinSendMsg( GetHWND()
1647 case wxTREE_EXPAND_COLLAPSE
:
1648 ::WinSendMsg( GetHWND()
1655 case wxTREE_EXPAND_COLLAPSE_RESET
:
1656 ::WinSendMsg( GetHWND()
1661 DeleteChildren(rItem
);
1664 case wxTREE_EXPAND_TOGGLE
:
1665 if (pRecord
->m_vRecord
.flRecordAttr
& CRA_COLLAPSED
)
1666 ::WinSendMsg( GetHWND()
1671 else if (pRecord
->m_vRecord
.flRecordAttr
& CRA_EXPANDED
)
1672 ::WinSendMsg( GetHWND()
1680 } // end of wxTreeCtrl::DoExpand
1682 void wxTreeCtrl::Expand (
1683 const wxTreeItemId
& rItem
1687 ,wxTREE_EXPAND_EXPAND
1689 } // end of wxTreeCtrl::Expand
1691 void wxTreeCtrl::Collapse (
1692 const wxTreeItemId
& rItem
1696 ,wxTREE_EXPAND_COLLAPSE
1698 } // end of wxTreeCtrl::Collapse
1700 void wxTreeCtrl::CollapseAndReset (
1701 const wxTreeItemId
& rItem
1705 ,wxTREE_EXPAND_COLLAPSE_RESET
1707 } // end of wxTreeCtrl::CollapseAndReset
1709 void wxTreeCtrl::Toggle (
1710 const wxTreeItemId
& rItem
1714 ,wxTREE_EXPAND_TOGGLE
1716 } // end of wxTreeCtrl::Toggle
1718 void wxTreeCtrl::Unselect ()
1720 wxASSERT_MSG( !(m_windowStyle
& wxTR_MULTIPLE
),
1721 wxT("doesn't make sense, may be you want UnselectAll()?") );
1724 // Just remove the selection
1726 SelectItem(wxTreeItemId((long)0));
1727 } // end of wxTreeCtrl::Unselect
1729 void wxTreeCtrl::UnselectAll ()
1731 if (m_windowStyle
& wxTR_MULTIPLE
)
1733 wxArrayTreeItemIds aSelections
;
1734 size_t nCount
= GetSelections(aSelections
);
1736 for (size_t n
= 0; n
< nCount
; n
++)
1738 SetItemCheck( aSelections
[n
]
1746 // Just remove the selection
1750 } // end of wxTreeCtrl::UnselectAll
1752 void wxTreeCtrl::SelectItem (
1753 const wxTreeItemId
& rItem
1756 SetItemCheck(rItem
);
1757 } // end of wxTreeCtrl::SelectItem
1759 void wxTreeCtrl::EnsureVisible (
1760 const wxTreeItemId
& rItem
1763 wxTreeViewItem
vTvItem(rItem
);
1765 DoGetItem(&vTvItem
);
1766 if (!::WinSendMsg( GetHWND()
1767 ,CM_INVALIDATERECORD
1769 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1771 } // end of wxTreeCtrl::EnsureVisible
1773 void wxTreeCtrl::ScrollTo (
1774 const wxTreeItemId
& rItem
1777 wxTreeViewItem
vTvItem(rItem
);
1779 DoGetItem(&vTvItem
);
1780 if (!::WinSendMsg( GetHWND()
1781 ,CM_INVALIDATERECORD
1783 ,MPFROM2SHORT(1, CMA_ERASE
| CMA_REPOSITION
| CMA_TEXTCHANGED
)
1787 wxTextCtrl
* wxTreeCtrl::EditLabel (
1788 const wxTreeItemId
& rItem
1789 , wxClassInfo
* WXUNUSED(pTextControlClass
)
1793 PMYRECORD pRecord
= FindOS2TreeRecordByID( GetHWND()
1797 vEdit
.cb
= sizeof(CNREDITDATA
);
1798 vEdit
.hwndCnr
= GetHWND();
1799 vEdit
.pRecord
= &pRecord
->m_vRecord
;
1800 vEdit
.pFieldInfo
= NULL
;
1801 vEdit
.ppszText
= NULL
;
1805 ::WinSendMsg( GetHWND()
1811 } // end of wxTreeCtrl::EditLabel
1813 // End label editing, optionally cancelling the edit
1814 void wxTreeCtrl::EndEditLabel (
1815 const wxTreeItemId
& WXUNUSED(rItem
)
1816 , bool WXUNUSED(bDiscardChanges
)
1819 ::WinSendMsg( GetHWND()
1824 } // end of wxTreeCtrl::EndEditLabel
1826 wxTreeItemId
wxTreeCtrl::HitTest (
1827 const wxPoint
& rPoint
1828 , int& WXUNUSED(rFlags
)
1831 PMYRECORD pRecord
= NULL
;
1832 QUERYRECFROMRECT vQueryRect
;
1837 // Get height for OS/2 point conversion
1839 ::WinSendMsg( GetHWND()
1840 ,CM_QUERYVIEWPORTRECT
1842 ,MPFROM2SHORT(CMA_WINDOW
, TRUE
)
1844 lHeight
= vRect
.yTop
- vRect
.yBottom
;
1847 // For now just try and get a record in the general vicinity and forget
1850 vRect
.xLeft
= rPoint
.x
- 2;
1851 vRect
.xRight
= rPoint
.x
+ 2;
1852 vRect
.yTop
= (lHeight
- rPoint
.y
) + 2;
1853 vRect
.yBottom
= (lHeight
- rPoint
.y
) - 2;
1855 vQueryRect
.cb
= sizeof(QUERYRECFROMRECT
);
1856 vQueryRect
.rect
= vRect
;
1857 vQueryRect
.fsSearch
= CMA_PARTIAL
;
1859 pRecord
= (PMYRECORD
)::WinSendMsg( GetHWND()
1860 ,CM_QUERYRECORDFROMRECT
1862 ,MPFROMP(&vQueryRect
)
1867 return wxTreeItemId((long)pRecord
->m_ulItemId
);
1868 } // end of wxTreeCtrl::HitTest
1870 bool wxTreeCtrl::GetBoundingRect (
1871 const wxTreeItemId
& rItem
1877 PMYRECORD pRecord
= FindOS2TreeRecordByID ( GetHWND()
1880 QUERYRECORDRECT vQuery
;
1882 vQuery
.cb
= sizeof(QUERYRECORDRECT
);
1883 vQuery
.pRecord
= (PRECORDCORE
)pRecord
;
1884 vQuery
.fRightSplitWindow
= FALSE
;
1886 vQuery
.fsExtent
= CMA_TEXT
;
1888 vQuery
.fsExtent
= CMA_TREEICON
| CMA_TEXT
;
1890 if (!::WinSendMsg( GetHWND()
1892 ,MPFROMP(&vRectRecord
)
1896 rRect
.SetLeft(vRectRecord
.xLeft
);
1897 rRect
.SetTop(vRectRecord
.yTop
);
1898 rRect
.SetRight(vRectRecord
.xRight
);
1899 rRect
.SetBottom(vRectRecord
.yBottom
);
1901 } // end of wxTreeCtrl::GetBoundingRect
1903 // ----------------------------------------------------------------------------
1905 // ----------------------------------------------------------------------------
1907 SHORT EXPENTRY
InternalDataCompareTreeFunc (
1913 wxCHECK_MSG( p1
&& p2
, 0,
1914 wxT("sorting tree without data doesn't make sense") );
1916 wxTreeCtrl
* pTree
= (wxTreeCtrl
*)pStorage
;
1918 return pTree
->OnCompareItems( p1
->m_ulItemId
1921 } // end of wxTreeSortHelper::Compare
1923 int wxTreeCtrl::OnCompareItems (
1924 const wxTreeItemId
& rItem1
1925 , const wxTreeItemId
& rItem2
1928 return wxStrcmp( GetItemText(rItem1
)
1929 ,GetItemText(rItem2
)
1931 } // end of wxTreeCtrl::OnCompareItems
1933 void wxTreeCtrl::SortChildren (
1934 const wxTreeItemId
& rItem
1937 ::WinSendMsg( GetHWND()
1939 ,(PFN
)InternalDataCompareTreeFunc
1942 } // end of wxTreeCtrl::SortChildren
1944 // ----------------------------------------------------------------------------
1946 // ----------------------------------------------------------------------------
1948 bool wxTreeCtrl::OS2Command (
1953 if (uCmd
== CN_ENDEDIT
)
1955 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
1959 vEvent
.SetEventObject( this );
1960 ProcessCommand(vEvent
);
1963 else if (uCmd
== CN_KILLFOCUS
)
1965 wxCommandEvent
vEvent( wxEVT_KILL_FOCUS
1968 vEvent
.SetEventObject( this );
1969 ProcessCommand(vEvent
);
1974 } // end of wxTreeCtrl::OS2Command
1977 // TODO: Fully implement direct manipulation when I figure it out
1979 MRESULT
wxTreeCtrl::OS2WindowProc (
1985 bool bProcessed
= false;
1987 wxTreeEvent
vEvent( wxEVT_NULL
1990 wxEventType vEventType
= wxEVT_NULL
;
1991 PCNRDRAGINIT pDragInit
= NULL
;
1992 PCNREDITDATA pEditData
= NULL
;
1993 PNOTIFYRECORDENTER pNotifyEnter
= NULL
;
1995 vEvent
.SetEventObject(this);
1999 switch(SHORT2FROMMP(wParam
))
2002 pDragInit
= (PCNRDRAGINIT
)lParam
;
2005 PMYRECORD pRecord
= (PMYRECORD
)pDragInit
->pRecord
;
2007 vEventType
= wxEVT_COMMAND_TREE_BEGIN_DRAG
;
2008 vEvent
.m_item
= pRecord
->m_ulItemId
;
2009 vEvent
.m_pointDrag
.x
= pDragInit
->x
;
2010 vEvent
.m_pointDrag
.y
= pDragInit
->y
;
2015 pEditData
= (PCNREDITDATA
)lParam
;
2018 PMYRECORD pRecord
= (PMYRECORD
)pEditData
->pRecord
;
2020 vEventType
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
;
2021 vEvent
.m_item
= pRecord
->m_ulItemId
;
2022 vEvent
.m_label
= pRecord
->m_vRecord
.pszTree
;
2023 vEvent
.m_editCancelled
= false;
2028 pEditData
= (PCNREDITDATA
)lParam
;
2031 PMYRECORD pRecord
= (PMYRECORD
)pEditData
->pRecord
;
2033 vEventType
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
;
2034 vEvent
.m_item
= pRecord
->m_ulItemId
;
2035 vEvent
.m_label
= pRecord
->m_vRecord
.pszTree
;
2036 if (pRecord
->m_vRecord
.pszTree
== NULL
)
2038 vEvent
.m_editCancelled
= true;
2042 vEvent
.m_editCancelled
= false;
2049 PMYRECORD pRecord
= (PMYRECORD
)lParam
;
2051 vEventType
= gs_expandEvents
[IDX_EXPAND
][IDX_DONE
];
2052 vEvent
.m_item
= pRecord
->m_ulItemId
;
2056 vEvent
.SetEventType(vEventType
);
2057 bProcessed
= HandleWindowEvent(vEvent
);
2061 mRc
= wxControl::OS2WindowProc( uMsg
2066 } // end of wxTreeCtrl::OS2WindowProc
2068 #endif // wxUSE_TREECTRL