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 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 #if WXWIN_COMPATIBILITY_2_4 
 546 wxImageList
* wxTreeCtrl::GetImageList(int nVal
) const 
 548     return GetImageList(); 
 551 void wxTreeCtrl::SetImageList(wxImageList
* pImageList
, int nVal
) 
 553     SetImageList(pImageList
); 
 556 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId
& rItem
) const 
 558     return GetItemImage(rItem
, wxTreeItemIcon_Selected
); 
 561 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId
& rItem
, int nImage
) 
 563     SetItemImage(rItem
, nImage
, wxTreeItemIcon_Selected
); 
 566 #endif // WXWIN_COMPATIBILITY_2_4 
 568 wxImageList
* wxTreeCtrl::GetStateImageList () const 
 570     return m_pImageListNormal
; 
 571 } // end of wxTreeCtrl::GetStateImageList 
 574 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE 
 575 // struct has the icon imbedded in it that it uses for the icon being 
 576 // displayed via the TREEITEMDESC member.  Provided for interface 
 577 // compatibility only 
 579 void wxTreeCtrl::SetAnyImageList ( 
 580   wxImageList
*                      WXUNUSED(pImageList
) 
 581 , int                               WXUNUSED(nWhich
) 
 584 } // end of wxTreeCtrl::SetAnyImageList 
 586 void wxTreeCtrl::SetImageList ( 
 587   wxImageList
*                      WXUNUSED(pImageList
) 
 590     if (m_bOwnsImageListNormal
) 
 591         delete m_pImageListNormal
; 
 592     m_bOwnsImageListNormal 
= false; 
 593 } // end of wxTreeCtrl::SetImageList 
 595 void wxTreeCtrl::SetStateImageList ( 
 596   wxImageList
*                      WXUNUSED(pImageList
) 
 599     if (m_bOwnsImageListState
) 
 600         delete m_pImageListState
; 
 601     m_bOwnsImageListState 
= false; 
 602 } // end of wxTreeCtrl::SetStateImageList 
 604 void wxTreeCtrl::AssignImageList ( 
 605   wxImageList
*                      WXUNUSED(pImageList
) 
 608     m_bOwnsImageListNormal 
= true; 
 609 } // end of wxTreeCtrl::AssignImageList 
 611 void wxTreeCtrl::AssignStateImageList ( 
 612   wxImageList
*                      WXUNUSED(pImageList
) 
 615     m_bOwnsImageListState 
= true; 
 616 } // end of wxTreeCtrl::AssignStateImageList 
 618 size_t wxTreeCtrl::GetChildrenCount ( 
 619   const wxTreeItemId
&               rItem
 
 623     TraverseCounter                 
vCounter( this 
 627     return vCounter
.GetCount() - 1; 
 628 } // end of wxTreeCtrl::GetChildrenCount 
 630 // ---------------------------------------------------------------------------- 
 632 // ---------------------------------------------------------------------------- 
 634 bool wxTreeCtrl::SetBackgroundColour ( 
 635   const wxColour
&                   rColour
 
 638     ULONG                           ulColor 
= wxColourToRGB(rColour
); 
 640     if ( !wxWindowBase::SetBackgroundColour(rColour
) ) 
 642     ::WinSetPresParam( GetHWND() 
 648 } // end of wxTreeCtrl::SetBackgroundColour 
 650 bool wxTreeCtrl::SetForegroundColour ( 
 651   const wxColour
&                   rColour
 
 654     ULONG                           ulColor 
= wxColourToRGB(rColour
); 
 656     if (!wxWindowBase::SetForegroundColour(rColour
)) 
 658     ::WinSetPresParam( GetHWND() 
 664 } // end of wxTreeCtrl::SetForegroundColour 
 666 // ---------------------------------------------------------------------------- 
 668 // ---------------------------------------------------------------------------- 
 670 wxString 
wxTreeCtrl::GetItemText ( 
 671   const wxTreeItemId
&               rItem
 
 674     wxChar                          zBuf
[512];  // the size is arbitrary... 
 675     wxTreeViewItem                  
vTvItem(rItem
); 
 677     if (!DoGetItem(&vTvItem
)) 
 680         // Don't return some garbage which was on stack, but an empty string 
 685         strcpy(zBuf
, vTvItem
.m_vRecord
.pszTree
); 
 686     return wxString(zBuf
); 
 687 } // end of wxTreeCtrl::GetItemText 
 689 void wxTreeCtrl::SetItemText ( 
 690   const wxTreeItemId
&               rItem
 
 691 , const wxString
&                   rsText
 
 694     wxTreeViewItem                  
vTvItem(rItem
); 
 696     vTvItem
.m_vRecord
.pszTree 
= (wxChar 
*)rsText
.c_str();  // conversion is ok 
 698 } // end of wxTreeCtrl::SetItemText 
 701 // These functions under OS/2 PM are not needed.  OS/2 containers in tree view 
 702 // provide for storing a custom expanded and collapsed icons and selected 
 703 // and non selected icons, natively.  For instance, by default, a disk display 
 704 // will display a tree list of folder icons with "+" icons (collapsed) beside 
 705 // those folder which contain child members.  Double clicking a folder changes 
 706 // the closed folder icon to an open folder icon with hatched selection 
 707 // highlighting indicating an ICON view container of the folder is open 
 708 // elsewhere on the desktop.  So the below is not really needed, but we will 
 709 // simply return the appropriate icon requested out of OS/2's native PM 
 712 int wxTreeCtrl::DoGetItemImageFromData ( 
 713   const wxTreeItemId
&               WXUNUSED(rItem
) 
 714 , wxTreeItemIcon                    nWhich
 
 718     // Image handles stored in CNRINFO. 
 722     ::WinSendMsg( GetHWND() 
 725                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 729     // We really only have two to chose from.  If not custom (set in CNRINFO 
 730     // then return the handle to system bitmap).  OS/2 automatically provides 
 731     // in_use and selected bitmaps/icons 
 735         case wxTreeItemIcon_Normal
: 
 736             if (vCnrInfo
.hbmCollapsed 
== NULLHANDLE
) 
 737                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
); 
 738             return vCnrInfo
.hbmCollapsed
; 
 741         case wxTreeItemIcon_Expanded
: 
 742             if (vCnrInfo
.hbmExpanded 
== NULLHANDLE
) 
 743                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
); 
 744             return vCnrInfo
.hbmExpanded
; 
 747             return vCnrInfo
.hbmCollapsed
; 
 751 void wxTreeCtrl::DoSetItemImageFromData ( 
 752   const wxTreeItemId
&               WXUNUSED(rItem
) 
 754 , wxTreeItemIcon                    nWhich
 
 758     // Image handles stored in CNRINFO. 
 762     ::WinSendMsg( GetHWND() 
 765                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 767     if (nWhich 
== wxTreeItemIcon_Normal
) 
 768          vCnrInfo
.hbmCollapsed 
= (HBITMAP
)nImage
; 
 769     if (nWhich 
== wxTreeItemIcon_Expanded
) 
 770         vCnrInfo
.hbmExpanded 
= (HBITMAP
)nImage
; 
 771     ::WinSendMsg( GetHWND() 
 774                  ,(MPARAM
)CMA_TREEBITMAP
 
 776 } // end of wxTreeCtrl::DoSetItemImageFromData 
 779 void wxTreeCtrl::DoSetItemImages ( 
 780   const wxTreeItemId
&               rItem
 
 785 } // end of wxTreeCtrl::DoSetItemImages 
 787 int wxTreeCtrl::GetItemImage ( 
 788   const wxTreeItemId
&               rItem
 
 789 , wxTreeItemIcon                    nWhich
 
 792     if (HasIndirectData(rItem
)) 
 794         return DoGetItemImageFromData( rItem
 
 801     ::WinSendMsg( GetHWND() 
 804                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 809             wxFAIL_MSG( wxT("unknown tree item image type") ); 
 811         case wxTreeItemIcon_Normal
: 
 812             if (vCnrInfo
.hbmCollapsed 
== NULLHANDLE
) 
 813                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
); 
 814             return vCnrInfo
.hbmCollapsed
; 
 817         case wxTreeItemIcon_Expanded
: 
 818             if (vCnrInfo
.hbmExpanded 
== NULLHANDLE
) 
 819                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
); 
 820             return vCnrInfo
.hbmExpanded
; 
 822         case wxTreeItemIcon_Selected
: 
 823         case wxTreeItemIcon_SelectedExpanded
: 
 828 void wxTreeCtrl::SetItemImage ( 
 829   const wxTreeItemId
&               WXUNUSED(rItem
) 
 831 , wxTreeItemIcon                    nWhich
 
 836     ::WinSendMsg( GetHWND() 
 839                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 843         case wxTreeItemIcon_Normal
: 
 844             vCnrInfo
.hbmCollapsed 
= (HBITMAP
)nImage
; 
 847         case wxTreeItemIcon_Expanded
: 
 848             vCnrInfo
.hbmExpanded 
= (HBITMAP
)nImage
; 
 852             wxFAIL_MSG( wxT("unknown tree item image type") ); 
 854     ::WinSendMsg( GetHWND() 
 857                  ,(MPARAM
)CMA_TREEBITMAP
 
 859 } // end of wxTreeCtrl::SetItemImage 
 861 wxTreeItemData
* wxTreeCtrl::GetItemData ( 
 862   const wxTreeItemId
&               rItem
 
 865     wxTreeViewItem                  
vTvItem(rItem
); 
 867     if (!DoGetItem(&vTvItem
)) 
 872     return (wxTreeItemData 
*)vTvItem
.m_ulUserData
; 
 873 } // end of wxTreeCtrl::GetItemData 
 875 void wxTreeCtrl::SetItemData ( 
 876   const wxTreeItemId
&               rItem
 
 877 , wxTreeItemData
*                   pData
 
 881     // first, associate this piece of data with this item 
 887     wxTreeViewItem                  
vTvItem(rItem
); 
 889     vTvItem
.m_ulUserData 
= (ULONG
)pData
; 
 891 } // end of wxTreeCtrl::SetItemData 
 893 // The following two do nothing under OS/2 
 894 void wxTreeCtrl::SetIndirectItemData ( 
 895   const wxTreeItemId
&               WXUNUSED(rItem
) 
 896 , wxTreeItemIndirectData
*           WXUNUSED(pData
) 
 899 } // end of wxTreeCtrl::SetIndirectItemData 
 901 bool wxTreeCtrl::HasIndirectData ( 
 902   const wxTreeItemId
&               WXUNUSED(rItem
) 
 906 } // end of wxTreeCtrl::HasIndirectData 
 908 // Irreleveant under OS/2 --- item either has child records or it doesn't. 
 909 void wxTreeCtrl::SetItemHasChildren ( 
 910   const wxTreeItemId
&               WXUNUSED(rItem
) 
 911 , bool                              WXUNUSED(bHas
) 
 914 } // end of wxTreeCtrl::SetItemHasChildren 
 916 // Irreleveant under OS/2 --- function of the font in PM 
 917 void wxTreeCtrl::SetItemBold ( 
 918   const wxTreeItemId
&               WXUNUSED(rItem
) 
 919 , bool                              WXUNUSED(bBold
) 
 922 } // end of wxTreeCtrl::SetItemBold 
 924 void wxTreeCtrl::SetItemDropHighlight ( 
 925   const wxTreeItemId
&               rItem
 
 929     wxTreeViewItem                  
vTvItem(rItem
); 
 931     ::WinSendMsg( GetHWND() 
 932                  ,CM_SETRECORDEMPHASIS
 
 934                  ,MPFROM2SHORT(bHighlight
, CRA_SELECTED
) 
 937 } // end of wxTreeCtrl::SetItemDropHighlight 
 939 void wxTreeCtrl::RefreshItem ( 
 940   const wxTreeItemId
&               rItem
 
 943     wxTreeViewItem                  
vTvItem(rItem
); 
 946     // This just does a record invalidate causing it to be re-displayed 
 949 } // end of wxTreeCtrl::RefreshItem 
 951 wxColour 
wxTreeCtrl::GetItemTextColour ( 
 952   const wxTreeItemId
&               rItem
 
 955     long                            lId 
= (long)rItem
.m_pItem
; 
 956     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 962     return pAttr
->GetTextColour(); 
 963 } // end of wxTreeCtrl::GetItemTextColour 
 965 wxColour 
wxTreeCtrl::GetItemBackgroundColour ( 
 966   const wxTreeItemId
&               rItem
 
 969     long                            lId 
= (long)rItem
.m_pItem
; 
 970     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 976     return pAttr
->GetBackgroundColour(); 
 977 } // end of wxTreeCtrl::GetItemBackgroundColour 
 979 wxFont 
wxTreeCtrl::GetItemFont ( 
 980   const wxTreeItemId
&               rItem
 
 983     long                            lId 
= (long)rItem
.m_pItem
; 
 984     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 990     return pAttr
->GetFont(); 
 991 } // end of wxTreeCtrl::GetItemFont 
 993 void wxTreeCtrl::SetItemTextColour ( 
 994   const wxTreeItemId
&               rItem
 
 995 , const wxColour
&                   rCol
 
 998     m_bHasAnyAttr 
= true; 
1000     long                            lId 
= (long)rItem
.m_pItem
; 
1001     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
1005         pAttr 
= new wxTreeItemAttr
; 
1006         m_vAttrs
.Put(lId
, (wxObject 
*)pAttr
); 
1008     pAttr
->SetTextColour(rCol
); 
1010 } // end of wxTreeCtrl::SetItemTextColour 
1012 void wxTreeCtrl::SetItemBackgroundColour ( 
1013   const wxTreeItemId
&               rItem
 
1014 , const wxColour
&                   rCol
 
1017     m_bHasAnyAttr 
= true; 
1019     long                            lId 
= (long)rItem
.m_pItem
; 
1020     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
1024         pAttr 
= new wxTreeItemAttr
; 
1025         m_vAttrs
.Put(lId
, (wxObject 
*)pAttr
); 
1027     pAttr
->SetBackgroundColour(rCol
); 
1029 } // end of wxTreeCtrl::SetItemBackgroundColour 
1031 void wxTreeCtrl::SetItemFont ( 
1032   const wxTreeItemId
&               rItem
 
1033 , const wxFont
&                     rFont
 
1036     m_bHasAnyAttr 
= true; 
1038     long                            lId 
= (long)rItem
.m_pItem
; 
1039     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
1043         pAttr 
= new wxTreeItemAttr
; 
1044         m_vAttrs
.Put(lId
, (wxObject 
*)pAttr
); 
1046     pAttr
->SetFont(rFont
); 
1048 } // end of wxTreeCtrl::SetItemFont 
1050 // ---------------------------------------------------------------------------- 
1052 // ---------------------------------------------------------------------------- 
1054 bool wxTreeCtrl::IsVisible ( 
1055   const wxTreeItemId
&               rItem
 
1058     // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect 
1060     RECTL                           vRectContainer
; 
1061     wxRect                          vWxRectRecord
; 
1062     wxRect                          vWxRectContainer
; 
1063     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1066     QUERYRECORDRECT                 vQuery
; 
1068     vQuery
.cb                
= sizeof(QUERYRECORDRECT
); 
1069     vQuery
.pRecord           
= (PRECORDCORE
)pRecord
; 
1070     vQuery
.fRightSplitWindow 
= FALSE
; 
1071     vQuery
.fsExtent          
= CMA_TREEICON
; 
1073     ::WinSendMsg( GetHWND() 
1074                  ,CM_QUERYVIEWPORTRECT
 
1075                  ,MPFROMP(&vRectContainer
) 
1076                  ,MPFROM2SHORT(CMA_WINDOW
, FALSE
) 
1078     ::WinSendMsg( GetHWND() 
1080                  ,MPFROMP(&vRectRecord
) 
1083     vWxRectRecord
.SetLeft(vRectRecord
.xLeft
); 
1084     vWxRectRecord
.SetTop(vRectRecord
.yTop
); 
1085     vWxRectRecord
.SetRight(vRectRecord
.xRight
); 
1086     vWxRectRecord
.SetBottom(vRectRecord
.yBottom
); 
1088     vWxRectContainer
.SetLeft(vRectContainer
.xLeft
); 
1089     vWxRectContainer
.SetTop(vRectContainer
.yTop
); 
1090     vWxRectContainer
.SetRight(vRectContainer
.xRight
); 
1091     vWxRectContainer
.SetBottom(vRectContainer
.yBottom
); 
1092     return (vWxRectContainer
.Inside(wxPoint(vWxRectRecord
.x
, vWxRectRecord
.y
))); 
1093 } // end of wxTreeCtrl::IsVisible 
1095 bool wxTreeCtrl::ItemHasChildren ( 
1096   const wxTreeItemId
&               rItem
 
1099     wxTreeViewItem                  
vTvItem(rItem
); 
1100     DoGetItem(&vTvItem
); 
1103     // A tree record with children will have one of these attributes 
1105     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_EXPANDED 
|| 
1106             vTvItem
.m_vRecord
.flRecordAttr 
& CRA_COLLAPSED
) != 0; 
1109 bool wxTreeCtrl::IsExpanded ( 
1110   const wxTreeItemId
&               rItem
 
1113     wxTreeViewItem                  
vTvItem(rItem
); 
1114     DoGetItem(&vTvItem
); 
1116     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_EXPANDED
) != 0; 
1117 } // end of wxTreeCtrl::IsExpanded 
1119 bool wxTreeCtrl::IsSelected ( 
1120   const wxTreeItemId
&               rItem
 
1123     wxTreeViewItem                  
vTvItem(rItem
); 
1124     DoGetItem(&vTvItem
); 
1126     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_SELECTED
) != 0; 
1127 } // end of wxTreeCtrl::IsSelected 
1130 bool wxTreeCtrl::IsBold ( 
1131   const wxTreeItemId
&               rItem
 
1135 } // end of wxTreeCtrl::IsBold 
1137 // ---------------------------------------------------------------------------- 
1139 // ---------------------------------------------------------------------------- 
1141 wxTreeItemId 
wxTreeCtrl::GetRootItem () const 
1143     PMYRECORD                       pRecord 
= NULL
; 
1145     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1148                                                   ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
1152         return wxTreeItemId(-1L); 
1153     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1154 } // end of wxTreeCtrl::GetRootItem 
1156 wxTreeItemId 
wxTreeCtrl::GetSelection () const 
1158     wxCHECK_MSG( !(m_windowStyle 
& wxTR_MULTIPLE
), (long)(WXHTREEITEM
)0, 
1159                  wxT("this only works with single selection controls") ); 
1161     PMYRECORD                       pRecord 
= NULL
; 
1163     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1164                                                   ,CM_QUERYRECORDEMPHASIS
 
1166                                                   ,MPARAM(CRA_SELECTED
) 
1169         return wxTreeItemId(-1L); 
1170     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1171 } // end of wxTreeCtrl::GetSelection 
1173 wxTreeItemId 
wxTreeCtrl::GetItemParent ( 
1174   const wxTreeItemId
&               rItem
 
1177     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1182         return wxTreeItemId(-1L); 
1183     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1186                                                   ,MPFROM2SHORT(CMA_PARENT
, CMA_ITEMORDER
) 
1189         return wxTreeItemId(-1L); 
1190     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1191 } // end of wxTreeCtrl::GetItemParent 
1193 wxTreeItemId 
wxTreeCtrl::GetFirstChild ( 
1194   const wxTreeItemId
&               rItem
 
1198     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1203         return wxTreeItemId(-1L); 
1204     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1207                                                   ,MPFROM2SHORT(CMA_FIRSTCHILD
, CMA_ITEMORDER
) 
1210         return wxTreeItemId(-1L); 
1212     // Remember the last child returned in 'cookie' 
1214     rCookie 
= (long)pRecord
->m_ulItemId
; 
1215     return wxTreeItemId(rCookie
); 
1216 } // end of wxTreeCtrl::GetFirstChild 
1218 wxTreeItemId 
wxTreeCtrl::GetNextChild ( 
1219   const wxTreeItemId
&               WXUNUSED(rItem
) 
1223     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1228         return wxTreeItemId(-1L); 
1229     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1232                                                   ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1235         return wxTreeItemId(-1L); 
1236     rCookie 
= (long)pRecord
->m_ulItemId
; 
1237     return wxTreeItemId(rCookie
); 
1238 } // end of wxTreeCtrl::GetNextChild 
1240 wxTreeItemId 
wxTreeCtrl::GetLastChild ( 
1241   const wxTreeItemId
&               rItem
 
1244     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1249         return wxTreeItemId(-1L); 
1250     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1253                                                   ,MPFROM2SHORT(CMA_LASTCHILD
, CMA_ITEMORDER
) 
1256         return wxTreeItemId(-1L); 
1257     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1258 } // end of wxTreeCtrl::GetLastChild 
1260 wxTreeItemId 
wxTreeCtrl::GetNextSibling ( 
1261   const wxTreeItemId
&               rItem
 
1264     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1269         return wxTreeItemId(-1L); 
1270     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1273                                                   ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1276         return wxTreeItemId(-1L); 
1277     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1278 } // end of wxTreeCtrl::GetNextSibling 
1280 wxTreeItemId 
wxTreeCtrl::GetPrevSibling ( 
1281   const wxTreeItemId
&               rItem
 
1284     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1289         return wxTreeItemId(-1L); 
1290     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1293                                                   ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
) 
1296         return wxTreeItemId(-1L); 
1297     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1298 } // end of wxTreeCtrl::GetPrevSibling 
1300 wxTreeItemId 
wxTreeCtrl::GetFirstVisibleItem () const 
1302     PMYRECORD                       pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1305                                                                                   ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
1308         return wxTreeItemId(-1L); 
1310     if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1311         return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1314         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1317                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1320             return wxTreeItemId(-1L); 
1321         if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1322             return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1324     return wxTreeItemId(-1L); 
1325 } // end of wxTreeCtrl::GetFirstVisibleItem 
1327 wxTreeItemId 
wxTreeCtrl::GetNextVisible ( 
1328   const wxTreeItemId
&               rItem
 
1331     wxASSERT_MSG(IsVisible(rItem
), wxT("The item you call GetNextVisible() for must be visible itself!")); 
1333     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1338         return wxTreeItemId(-1L); 
1341         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1344                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1347             return wxTreeItemId(-1L); 
1348         if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1349             return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1351     return wxTreeItemId(-1L); 
1352 } // end of wxTreeCtrl::GetNextVisible 
1354 wxTreeItemId 
wxTreeCtrl::GetPrevVisible ( 
1355   const wxTreeItemId
&               rItem
 
1358     wxASSERT_MSG( IsVisible(rItem
), wxT("The item you call GetPrevVisible() for must be visible itself!")); 
1360     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1365         return wxTreeItemId(-1L); 
1368         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1371                                                       ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
) 
1374             return wxTreeItemId(-1L); 
1375         if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1376             return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1378     return wxTreeItemId(-1L); 
1379 } // end of wxTreeCtrl::GetPrevVisible 
1381 // ---------------------------------------------------------------------------- 
1382 // multiple selections emulation -- under OS/2 checked tree items is not 
1383 // supported, but multisel is.  So we'll just check for selections here. 
1384 // ---------------------------------------------------------------------------- 
1386 bool wxTreeCtrl::IsItemChecked ( 
1387   const wxTreeItemId
&               rItem
 
1390     wxTreeViewItem                  
vTvItem(rItem
); 
1392     DoGetItem(&vTvItem
); 
1393     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_SELECTED
); 
1394 } // end of wxTreeCtrl::IsItemChecked 
1396 void wxTreeCtrl::SetItemCheck ( 
1397   const wxTreeItemId
&               rItem
 
1401     wxTreeViewItem                  
vTvItem(rItem
); 
1403     DoGetItem(&vTvItem
); 
1404     ::WinSendMsg( GetHWND() 
1405                  ,CM_SETRECORDEMPHASIS
 
1407                  ,MPFROM2SHORT(TRUE
, CRA_SELECTED
) 
1409     DoSetItem(&vTvItem
); 
1410 } // end of wxTreeCtrl::SetItemCheck 
1412 size_t wxTreeCtrl::GetSelections ( 
1413   wxArrayTreeItemIds
&               raSelections
 
1416     TraverseSelections              
vSelector( this 
1419     return vSelector
.GetCount(); 
1420 } // end of wxTreeCtrl::GetSelections 
1422 // ---------------------------------------------------------------------------- 
1424 // ---------------------------------------------------------------------------- 
1426 wxTreeItemId 
wxTreeCtrl::DoInsertItem ( 
1427   const wxTreeItemId
&               rParent
 
1428 , wxTreeItemId                      vInsertAfter
 
1429 , const wxString
&                   rsText
 
1432 , wxTreeItemData
*                   pData
 
1435     PMYRECORD                       pRecordAfter 
= FindOS2TreeRecordByID( GetHWND() 
1436                                                                          ,vInsertAfter
.m_pItem
 
1439     PMYRECORD                       pRecordParent 
= FindOS2TreeRecordByID( GetHWND() 
1443     PMYRECORD                       pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1445                                                                       ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
)) 
1448     RECORDINSERT                    vInsert
; 
1450     vInsert
.cb                
= sizeof(RECORDINSERT
); 
1451     if (rParent
.m_pItem 
== 0L) 
1453         if (vInsertAfter
.m_pItem 
== -1) 
1454             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_END
; 
1456             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_FIRST
; 
1457         vInsert
.pRecordParent     
= NULL
; 
1461         if (vInsertAfter
.m_pItem 
== 0) 
1462             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_FIRST
; 
1463         else if (vInsertAfter
.m_pItem 
== -1) 
1464             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_END
; 
1466             vInsert
.pRecordOrder  
= (PRECORDCORE
)pRecordAfter
; 
1467         vInsert
.pRecordParent     
= (PRECORDCORE
)pRecordParent
; 
1469     vInsert
.fInvalidateRecord 
= TRUE
; 
1470     vInsert
.zOrder            
= CMA_TOP
; 
1471     vInsert
.cRecordsInsert    
= 1; 
1473     pRecord
->m_vRecord
.pszTree   
= (wxChar
*)rsText
.c_str(); 
1474     pRecord
->m_vRecord
.hbmBitmap 
= nImage
; 
1475     pRecord
->m_ulItemId 
= pRecordAfter
->m_ulItemId 
+ 1; 
1478         pRecord
->m_ulUserData 
= (ULONG
)pData
; 
1480     ::WinSendMsg( GetHWND() 
1487     // OS/2 must mannually bump the index's of following records 
1489     BumpTreeRecordIds( GetHWND() 
1495         // Associate the application tree item with PM tree item handle 
1497         pData
->SetId((long)pRecord
->m_ulItemId
); 
1499     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1502 #if WXWIN_COMPATIBILITY_2_4 
1504 // for compatibility only 
1505 wxTreeItemId 
wxTreeCtrl::InsertItem ( 
1506   const wxTreeItemId
&               rParent
 
1507 , const wxString
&                   rsText
 
1513     return DoInsertItem( rParent
 
1514                         ,wxTreeItemId(lInsertAfter
) 
1520 } // end of wxTreeCtrl::InsertItem 
1522 #endif // WXWIN_COMPATIBILITY_2_4 
1524 wxTreeItemId 
wxTreeCtrl::AddRoot ( 
1525   const wxString
&                   rsText
 
1527 , int                               nSelectedImage
 
1528 , wxTreeItemData
*                   pData
) 
1531     return DoInsertItem( wxTreeItemId((long)0) 
1532                         ,wxTreeItemId((long)-1) 
1538 } // end of wxTreeCtrl::AddRoot 
1540 wxTreeItemId 
wxTreeCtrl::PrependItem ( 
1541   const wxTreeItemId
&               rParent
 
1542 , const wxString
&                   rsText
 
1544 , int                               nSelectedImage
 
1545 , wxTreeItemData
*                   pData
 
1548     return DoInsertItem( rParent
 
1549                         ,wxTreeItemId((long)0) 
1555 } // end of wxTreeCtrl::PrependItem 
1557 wxTreeItemId 
wxTreeCtrl::InsertItem ( 
1558   const wxTreeItemId
&               rParent
 
1559 , const wxTreeItemId
&               rIdPrevious
 
1560 , const wxString
&                   rsText
 
1562 , int                               nSelectedImage
 
1563 , wxTreeItemData
*                   pData
 
1566     return DoInsertItem( rParent
 
1573 } // end of wxTreeCtrl::InsertItem 
1575 wxTreeItemId 
wxTreeCtrl::InsertItem ( 
1576   const wxTreeItemId
&               rParent
 
1578 , const wxString
&                   rsText
 
1580 , int                               nSelectedImage
 
1581 , wxTreeItemData
*                   pData
 
1584     return DoInsertItem( rParent
 
1585                         ,wxTreeItemId((long)nIndex
) 
1591 } // end of wxTreeCtrl::InsertItem 
1593 wxTreeItemId 
wxTreeCtrl::AppendItem ( 
1594   const wxTreeItemId
&               rParent
 
1595 , const wxString
&                   rsText
 
1597 , int                               nSelectedImage
 
1598 , wxTreeItemData
*                   pData
 
1601     return DoInsertItem( rParent
 
1602                         ,wxTreeItemId((long)-1) 
1608 } // end of wxTreeCtrl::AppendItem 
1610 void wxTreeCtrl::Delete ( 
1611   const wxTreeItemId
&               rItem
 
1615     // OS/2 does not generate DELETEITEM events so do it here 
1617     wxEventType                     vEventType 
= wxEVT_NULL
; 
1618     wxTreeEvent                     
vEvent( wxEVT_NULL
 
1621     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
1624     vEvent
.SetEventObject(this); 
1625     ::WinSendMsg( GetHWND() 
1628                  ,(MPARAM
)(CMA_FREE 
| CMA_INVALIDATE
) 
1630     vEvent
.m_item 
= rItem
.m_pItem
; 
1633         delete (wxTreeItemAttr 
*)m_vAttrs
.Delete((long)rItem
.m_pItem
); 
1635     vEvent
.SetEventType(vEventType
); 
1636     GetEventHandler()->ProcessEvent(vEvent
); 
1637 } // end of wxTreeCtrl::Delete 
1639 // delete all children (but don't delete the item itself) 
1640 void wxTreeCtrl::DeleteChildren ( 
1641   const wxTreeItemId
&               rItem
 
1645     wxArrayLong                     aChildren
; 
1646     wxTreeItemId                    vChild 
= GetFirstChild( rItem
 
1650     while (vChild
.IsOk()) 
1652         aChildren
.Add((long)(WXHTREEITEM
)vChild
); 
1653         vChild 
= GetNextChild( rItem
 
1658     size_t                          nCount 
= aChildren
.Count(); 
1660     for (size_t n 
= 0; n 
< nCount
; n
++) 
1662         Delete(aChildren
[n
]); 
1664 } // end of wxTreeCtrl::DeleteChildren 
1666 void wxTreeCtrl::DeleteAllItems () 
1668     ::WinSendMsg( GetHWND() 
1671                  ,(MPARAM
)(CMA_FREE 
| CMA_INVALIDATE
) 
1673 } // end of wxTreeCtrl::DeleteAllItems 
1675 void wxTreeCtrl::DoExpand ( 
1676   const wxTreeItemId
&               rItem
 
1680     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
1685         case wxTREE_EXPAND_EXPAND
: 
1686             ::WinSendMsg( GetHWND() 
1693         case wxTREE_EXPAND_COLLAPSE
: 
1694             ::WinSendMsg( GetHWND() 
1701         case wxTREE_EXPAND_COLLAPSE_RESET
: 
1702             ::WinSendMsg( GetHWND() 
1707             DeleteChildren(rItem
); 
1710         case wxTREE_EXPAND_TOGGLE
: 
1711             if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_COLLAPSED
) 
1712                 ::WinSendMsg( GetHWND() 
1717             else if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_EXPANDED
) 
1718                 ::WinSendMsg( GetHWND() 
1726 } // end of wxTreeCtrl::DoExpand 
1728 void wxTreeCtrl::Expand ( 
1729   const wxTreeItemId
&               rItem
 
1733              ,wxTREE_EXPAND_EXPAND
 
1735 } // end of wxTreeCtrl::Expand 
1737 void wxTreeCtrl::Collapse ( 
1738   const wxTreeItemId
&               rItem
 
1742              ,wxTREE_EXPAND_COLLAPSE
 
1744 } // end of wxTreeCtrl::Collapse 
1746 void wxTreeCtrl::CollapseAndReset ( 
1747   const wxTreeItemId
&               rItem
 
1751              ,wxTREE_EXPAND_COLLAPSE_RESET
 
1753 } // end of wxTreeCtrl::CollapseAndReset 
1755 void wxTreeCtrl::Toggle ( 
1756   const wxTreeItemId
&               rItem
 
1760              ,wxTREE_EXPAND_TOGGLE
 
1762 } // end of wxTreeCtrl::Toggle 
1764 #if WXWIN_COMPATIBILITY_2_4 
1766 void wxTreeCtrl::ExpandItem ( 
1767   const wxTreeItemId
&               rItem
 
1774 } // end of wxTreeCtrl::ExpandItem 
1776 #endif // WXWIN_COMPATIBILITY_2_4 
1778 void wxTreeCtrl::Unselect () 
1780     wxASSERT_MSG( !(m_windowStyle 
& wxTR_MULTIPLE
), 
1781                   wxT("doesn't make sense, may be you want UnselectAll()?") ); 
1784     // Just remove the selection 
1786     SelectItem(wxTreeItemId((long)0)); 
1787 } // end of wxTreeCtrl::Unselect 
1789 void wxTreeCtrl::UnselectAll () 
1791     if (m_windowStyle 
& wxTR_MULTIPLE
) 
1793         wxArrayTreeItemIds          aSelections
; 
1794         size_t                      nCount 
= GetSelections(aSelections
); 
1796         for (size_t n 
= 0; n 
< nCount
; n
++) 
1798             SetItemCheck( aSelections
[n
] 
1806         // Just remove the selection 
1810 } // end of wxTreeCtrl::UnselectAll 
1812 void wxTreeCtrl::SelectItem ( 
1813   const wxTreeItemId
&               rItem
 
1816     SetItemCheck(rItem
); 
1817 } // end of wxTreeCtrl::SelectItem 
1819 void wxTreeCtrl::EnsureVisible ( 
1820   const wxTreeItemId
&               rItem
 
1823     wxTreeViewItem                  
vTvItem(rItem
); 
1825     DoGetItem(&vTvItem
); 
1826     if (!::WinSendMsg( GetHWND() 
1827                       ,CM_INVALIDATERECORD
 
1829                       ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1831 } // end of wxTreeCtrl::EnsureVisible 
1833 void wxTreeCtrl::ScrollTo ( 
1834   const wxTreeItemId
&               rItem
 
1837     wxTreeViewItem                  
vTvItem(rItem
); 
1839     DoGetItem(&vTvItem
); 
1840     if (!::WinSendMsg( GetHWND() 
1841                       ,CM_INVALIDATERECORD
 
1843                       ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1847 wxTextCtrl
* wxTreeCtrl::EditLabel ( 
1848   const wxTreeItemId
&               rItem
 
1849 , wxClassInfo
*                      WXUNUSED(pTextControlClass
) 
1853     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
1857     vEdit
.cb         
= sizeof(CNREDITDATA
); 
1858     vEdit
.hwndCnr    
= GetHWND(); 
1859     vEdit
.pRecord    
= &pRecord
->m_vRecord
; 
1860     vEdit
.pFieldInfo 
= NULL
; 
1861     vEdit
.ppszText   
= NULL
; 
1865     ::WinSendMsg( GetHWND() 
1871 } // end of wxTreeCtrl::EditLabel 
1873 // End label editing, optionally cancelling the edit 
1874 void wxTreeCtrl::EndEditLabel ( 
1875   const wxTreeItemId
&               WXUNUSED(rItem
) 
1876 , bool                              WXUNUSED(bDiscardChanges
) 
1879     ::WinSendMsg( GetHWND() 
1884 } // end of wxTreeCtrl::EndEditLabel 
1886 wxTreeItemId 
wxTreeCtrl::HitTest ( 
1887   const wxPoint
&                    rPoint
 
1888 , int&                              WXUNUSED(rFlags
) 
1891     PMYRECORD                       pRecord 
= NULL
; 
1892     QUERYRECFROMRECT                vQueryRect
; 
1897     // Get height for OS/2 point conversion 
1899     ::WinSendMsg( GetHWND() 
1900                  ,CM_QUERYVIEWPORTRECT
 
1902                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
1904     lHeight 
= vRect
.yTop 
- vRect
.yBottom
; 
1907     // For now just try and get a record in the general vicinity and forget 
1910     vRect
.xLeft   
= rPoint
.x 
- 2; 
1911     vRect
.xRight  
= rPoint
.x 
+ 2; 
1912     vRect
.yTop    
= (lHeight 
- rPoint
.y
) + 2; 
1913     vRect
.yBottom 
= (lHeight 
- rPoint
.y
) - 2; 
1915     vQueryRect
.cb 
= sizeof(QUERYRECFROMRECT
); 
1916     vQueryRect
.rect 
= vRect
; 
1917     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
1919     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1920                                       ,CM_QUERYRECORDFROMRECT
 
1922                                       ,MPFROMP(&vQueryRect
) 
1927     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1928 } // end of wxTreeCtrl::HitTest 
1930 bool wxTreeCtrl::GetBoundingRect ( 
1931   const wxTreeItemId
&               rItem
 
1937     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1940     QUERYRECORDRECT                 vQuery
; 
1942     vQuery
.cb                
= sizeof(QUERYRECORDRECT
); 
1943     vQuery
.pRecord           
= (PRECORDCORE
)pRecord
; 
1944     vQuery
.fRightSplitWindow 
= FALSE
; 
1946         vQuery
.fsExtent          
= CMA_TEXT
; 
1948         vQuery
.fsExtent          
= CMA_TREEICON 
| CMA_TEXT
; 
1950     if (!::WinSendMsg( GetHWND() 
1952                       ,MPFROMP(&vRectRecord
) 
1956     rRect
.SetLeft(vRectRecord
.xLeft
); 
1957     rRect
.SetTop(vRectRecord
.yTop
); 
1958     rRect
.SetRight(vRectRecord
.xRight
); 
1959     rRect
.SetBottom(vRectRecord
.yBottom
); 
1961 } // end of wxTreeCtrl::GetBoundingRect 
1963 // ---------------------------------------------------------------------------- 
1965 // ---------------------------------------------------------------------------- 
1967 SHORT EXPENTRY 
InternalDataCompareTreeFunc ( 
1973     wxCHECK_MSG( p1 
&& p2
, 0, 
1974                  wxT("sorting tree without data doesn't make sense") ); 
1976     wxTreeCtrl
*                     pTree 
= (wxTreeCtrl
*)pStorage
; 
1978     return pTree
->OnCompareItems( p1
->m_ulItemId
 
1981 } // end of wxTreeSortHelper::Compare 
1983 int wxTreeCtrl::OnCompareItems ( 
1984   const wxTreeItemId
&               rItem1
 
1985 , const wxTreeItemId
&               rItem2
 
1988     return wxStrcmp( GetItemText(rItem1
) 
1989                     ,GetItemText(rItem2
) 
1991 } // end of wxTreeCtrl::OnCompareItems 
1993 void wxTreeCtrl::SortChildren ( 
1994   const wxTreeItemId
&               rItem
 
1997     ::WinSendMsg( GetHWND() 
1999                  ,(PFN
)InternalDataCompareTreeFunc
 
2002 } // end of wxTreeCtrl::SortChildren 
2004 // ---------------------------------------------------------------------------- 
2006 // ---------------------------------------------------------------------------- 
2008 bool wxTreeCtrl::OS2Command ( 
2013     if (uCmd 
== CN_ENDEDIT
) 
2015         wxCommandEvent              
vEvent( wxEVT_COMMAND_TEXT_UPDATED
 
2019         vEvent
.SetEventObject( this ); 
2020         ProcessCommand(vEvent
); 
2023     else if (uCmd 
== CN_KILLFOCUS
) 
2025         wxCommandEvent              
vEvent( wxEVT_KILL_FOCUS
 
2028         vEvent
.SetEventObject( this ); 
2029         ProcessCommand(vEvent
); 
2034 } // end of wxTreeCtrl::OS2Command 
2037 // TODO:  Fully implement direct manipulation when I figure it out 
2039 MRESULT 
wxTreeCtrl::OS2WindowProc ( 
2045     bool                            bProcessed 
= false; 
2047     wxTreeEvent                     
vEvent( wxEVT_NULL
 
2050     wxEventType                     vEventType 
= wxEVT_NULL
; 
2051     PCNRDRAGINIT                    pDragInit 
= NULL
; 
2052     PCNREDITDATA                    pEditData 
= NULL
; 
2053     PNOTIFYRECORDENTER              pNotifyEnter 
= NULL
; 
2055     vEvent
.SetEventObject(this); 
2059             switch(SHORT2FROMMP(wParam
)) 
2062                     pDragInit 
= (PCNRDRAGINIT
)lParam
; 
2065                         PMYRECORD       pRecord 
= (PMYRECORD
)pDragInit
->pRecord
; 
2067                         vEventType 
= wxEVT_COMMAND_TREE_BEGIN_DRAG
; 
2068                         vEvent
.m_item        
= pRecord
->m_ulItemId
; 
2069                         vEvent
.m_pointDrag
.x 
= pDragInit
->x
; 
2070                         vEvent
.m_pointDrag
.y 
= pDragInit
->y
; 
2075                     pEditData 
= (PCNREDITDATA
)lParam
; 
2078                         PMYRECORD       pRecord 
= (PMYRECORD
)pEditData
->pRecord
; 
2080                         vEventType 
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
; 
2081                         vEvent
.m_item 
= pRecord
->m_ulItemId
; 
2082                         vEvent
.m_label 
= pRecord
->m_vRecord
.pszTree
; 
2083                         vEvent
.m_editCancelled 
= false; 
2088                     pEditData 
= (PCNREDITDATA
)lParam
; 
2091                         PMYRECORD       pRecord 
= (PMYRECORD
)pEditData
->pRecord
; 
2093                         vEventType 
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
; 
2094                         vEvent
.m_item 
= pRecord
->m_ulItemId
; 
2095                         vEvent
.m_label 
= pRecord
->m_vRecord
.pszTree
; 
2096                         if (pRecord
->m_vRecord
.pszTree 
== NULL
) 
2098                             vEvent
.m_editCancelled 
= true; 
2102                             vEvent
.m_editCancelled 
= false; 
2109                         PMYRECORD       pRecord 
= (PMYRECORD
)lParam
; 
2111                         vEventType 
= gs_expandEvents
[IDX_EXPAND
][IDX_DONE
]; 
2112                         vEvent
.m_item 
= pRecord
->m_ulItemId
; 
2116             vEvent
.SetEventType(vEventType
); 
2117             bProcessed 
= GetEventHandler()->ProcessEvent(vEvent
); 
2121         mRc 
= wxControl::OS2WindowProc( uMsg
 
2126 } // end of wxTreeCtrl::OS2WindowProc 
2128 #endif // wxUSE_TREECTRL