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 // ---------------------------------------------------------------------------- 
 259 // ---------------------------------------------------------------------------- 
 261 // indices in gs_expandEvents table below 
 276 // handy table for sending events - it has to be initialized during run-time 
 277 // now so can't be const any more 
 278 static /* const */ wxEventType gs_expandEvents
[IDX_WHAT_MAX
][IDX_HOW_MAX
]; 
 281    but logically it's a const table with the following entries: 
 284     { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING }, 
 285     { wxEVT_COMMAND_TREE_ITEM_EXPANDED,  wxEVT_COMMAND_TREE_ITEM_EXPANDING  } 
 289 // ============================================================================ 
 291 // ============================================================================ 
 293 // ---------------------------------------------------------------------------- 
 295 // ---------------------------------------------------------------------------- 
 297 bool wxTreeTraversal::DoTraverse ( 
 298   const wxTreeItemId
&               rRoot
 
 305     return Traverse( rRoot
 
 308 } // end of wxTreeTraversal::DoTraverse 
 310 bool wxTreeTraversal::Traverse ( 
 311   const wxTreeItemId
&               rRoot
 
 316     wxTreeItemId                    vChild 
= m_pTree
->GetFirstChild( rRoot
 
 319     while (vChild
.IsOk()) 
 322         // Depth first traversal 
 324         if (bRecursively 
&& !Traverse(vChild
, true)) 
 326         if (!OnVisit(vChild
)) 
 328         vChild 
= m_pTree
->GetNextChild( rRoot
 
 333 } // end of wxTreeTraversal::Traverse 
 335 // ---------------------------------------------------------------------------- 
 336 // construction and destruction 
 337 // ---------------------------------------------------------------------------- 
 339 void wxTreeCtrl::Init () 
 341     m_pImageListNormal     
= NULL
; 
 342     m_pImageListState      
= NULL
; 
 343     m_bOwnsImageListNormal 
= false; 
 344     m_bOwnsImageListState  
= false; 
 345     m_bHasAnyAttr          
= false; 
 349     // Initialize the global array of events now as it can't be done statically 
 350     // with the wxEVT_XXX values being allocated during run-time only 
 352     gs_expandEvents
[IDX_COLLAPSE
][IDX_DONE
]  = wxEVT_COMMAND_TREE_ITEM_COLLAPSED
; 
 353     gs_expandEvents
[IDX_COLLAPSE
][IDX_DOING
] = wxEVT_COMMAND_TREE_ITEM_COLLAPSING
; 
 354     gs_expandEvents
[IDX_EXPAND
][IDX_DONE
]    = wxEVT_COMMAND_TREE_ITEM_EXPANDED
; 
 355     gs_expandEvents
[IDX_EXPAND
][IDX_DOING
]   = wxEVT_COMMAND_TREE_ITEM_EXPANDING
; 
 356 } // end of wxTreeCtrl::Init 
 358 bool wxTreeCtrl::Create ( 
 361 , const wxPoint
&                    rPos
 
 362 , const wxSize
&                     rSize
 
 364 , const wxValidator
&                rValidator
 
 365 , const wxString
&                   rsName
 
 371     if (!CreateControl( pParent
 
 381     DWORD                           dwStyle 
= WS_VISIBLE 
| WS_TABSTOP
; 
 383     if (m_windowStyle 
& wxCLIP_SIBLINGS
) 
 384         dwStyle 
|= WS_CLIPSIBLINGS
; 
 386     // Create the tree control. 
 387     if (!OS2CreateControl( "CONTAINER" 
 393     // Now set the display attributes to show a TREE/ICON view of the 
 396     if (!::WinSendMsg( GetHWND() 
 399                       ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 402     vCnrInfo
.flWindowAttr 
= CV_TREE
|CV_ICON
; 
 403     vCnrInfo
.flWindowAttr 
|= CA_DRAWBITMAP
; 
 404     if (m_windowStyle 
& wxTR_NO_LINES
) 
 405         vCnrInfo
.flWindowAttr 
|= CA_TREELINE
; 
 407     ::WinSendMsg( GetHWND() 
 410                  ,(MPARAM
)CMA_FLWINDOWATTR
 
 413     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 414     SetForegroundColour(wxWindow::GetParent()->GetForegroundColour()); 
 415     SetFont(*wxSMALL_FONT
); 
 424 } // end of wxTreeCtrl::Create 
 426 wxTreeCtrl::~wxTreeCtrl () 
 429     // Delete any attributes 
 433         for (wxNode
* pNode 
= m_vAttrs
.Next(); pNode
; pNode 
= m_vAttrs
.Next()) 
 435             delete (wxTreeItemAttr 
*)pNode
->Data(); 
 437         m_bHasAnyAttr 
= false; 
 442     // Delete user data to prevent memory leaks 
 443     // also deletes hidden root node storage. 
 446     if (m_bOwnsImageListNormal
) 
 447         delete m_pImageListNormal
; 
 448     if (m_bOwnsImageListState
) 
 449         delete m_pImageListState
; 
 450 } // end of wxTreeCtrl::~wxTreeCtrl 
 452 // ---------------------------------------------------------------------------- 
 454 // ---------------------------------------------------------------------------- 
 457 // simple wrappers which add error checking in debug mode.  These methods 
 458 // assume the items are properly filled out already.  If not, you get errors 
 460 bool wxTreeCtrl::DoGetItem ( 
 461   wxTreeViewItem
*                   pTvItem
 
 464     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
 470         wxLogLastError(wxT("Item not obtained")); 
 474 } // end of wxTreeCtrl::DoGetItem 
 476 void wxTreeCtrl::DoSetItem ( 
 477   wxTreeViewItem
*                   pTvItem
 
 481     // Just invalidate the record to redisplay it 
 483     if (!::WinSendMsg( GetHWND() 
 486                       ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
 489         wxLogLastError(wxT("CM_INVALIDATERECORD")); 
 491 } // end of wxTreeCtrl::DoSetItem 
 493 unsigned int wxTreeCtrl::GetCount () const 
 497     ::WinSendMsg( GetHWND() 
 500                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 503     return (unsigned int)vCnrInfo
.cRecords
; 
 504 } // end of wxTreeCtrl::GetCount 
 506 unsigned int wxTreeCtrl::GetIndent () const 
 510     ::WinSendMsg( GetHWND() 
 513                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 515     return (unsigned int)vCnrInfo
.cxTreeIndent
; 
 516 } // end of wxTreeCtrl::GetIndent 
 518 void wxTreeCtrl::SetIndent ( 
 524     ::WinSendMsg( GetHWND() 
 527                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 529     vCnrInfo
.cxTreeIndent 
= (LONG
)uIndent
; 
 530     ::WinSendMsg( GetHWND() 
 533                  ,(MPARAM
)CMA_CXTREEINDENT
 
 535 } // end of wxTreeCtrl::SetIndent 
 537 wxImageList
* wxTreeCtrl::GetImageList () const 
 539     return m_pImageListNormal
; 
 540 } // end of wxTreeCtrl::GetImageList 
 542 wxImageList
* wxTreeCtrl::GetStateImageList () const 
 544     return m_pImageListNormal
; 
 545 } // end of wxTreeCtrl::GetStateImageList 
 548 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE 
 549 // struct has the icon imbedded in it that it uses for the icon being 
 550 // displayed via the TREEITEMDESC member.  Provided for interface 
 551 // compatibility only 
 553 void wxTreeCtrl::SetAnyImageList ( 
 554   wxImageList
*                      WXUNUSED(pImageList
) 
 555 , int                               WXUNUSED(nWhich
) 
 558 } // end of wxTreeCtrl::SetAnyImageList 
 560 void wxTreeCtrl::SetImageList ( 
 561   wxImageList
*                      WXUNUSED(pImageList
) 
 564     if (m_bOwnsImageListNormal
) 
 565         delete m_pImageListNormal
; 
 566     m_bOwnsImageListNormal 
= false; 
 567 } // end of wxTreeCtrl::SetImageList 
 569 void wxTreeCtrl::SetStateImageList ( 
 570   wxImageList
*                      WXUNUSED(pImageList
) 
 573     if (m_bOwnsImageListState
) 
 574         delete m_pImageListState
; 
 575     m_bOwnsImageListState 
= false; 
 576 } // end of wxTreeCtrl::SetStateImageList 
 578 void wxTreeCtrl::AssignImageList ( 
 579   wxImageList
*                      WXUNUSED(pImageList
) 
 582     m_bOwnsImageListNormal 
= true; 
 583 } // end of wxTreeCtrl::AssignImageList 
 585 void wxTreeCtrl::AssignStateImageList ( 
 586   wxImageList
*                      WXUNUSED(pImageList
) 
 589     m_bOwnsImageListState 
= true; 
 590 } // end of wxTreeCtrl::AssignStateImageList 
 592 size_t wxTreeCtrl::GetChildrenCount ( 
 593   const wxTreeItemId
&               rItem
 
 597     TraverseCounter                 
vCounter( this 
 601     return vCounter
.GetCount() - 1; 
 602 } // end of wxTreeCtrl::GetChildrenCount 
 604 // ---------------------------------------------------------------------------- 
 606 // ---------------------------------------------------------------------------- 
 608 bool wxTreeCtrl::SetBackgroundColour ( 
 609   const wxColour
&                   rColour
 
 612     ULONG                           ulColor 
= wxColourToRGB(rColour
); 
 614     if ( !wxWindowBase::SetBackgroundColour(rColour
) ) 
 616     ::WinSetPresParam( GetHWND() 
 622 } // end of wxTreeCtrl::SetBackgroundColour 
 624 bool wxTreeCtrl::SetForegroundColour ( 
 625   const wxColour
&                   rColour
 
 628     ULONG                           ulColor 
= wxColourToRGB(rColour
); 
 630     if (!wxWindowBase::SetForegroundColour(rColour
)) 
 632     ::WinSetPresParam( GetHWND() 
 638 } // end of wxTreeCtrl::SetForegroundColour 
 640 // ---------------------------------------------------------------------------- 
 642 // ---------------------------------------------------------------------------- 
 644 wxString 
wxTreeCtrl::GetItemText ( 
 645   const wxTreeItemId
&               rItem
 
 648     wxChar                          zBuf
[512];  // the size is arbitrary... 
 649     wxTreeViewItem                  
vTvItem(rItem
); 
 651     if (!DoGetItem(&vTvItem
)) 
 654         // Don't return some garbage which was on stack, but an empty string 
 659         strcpy(zBuf
, vTvItem
.m_vRecord
.pszTree
); 
 660     return wxString(zBuf
); 
 661 } // end of wxTreeCtrl::GetItemText 
 663 void wxTreeCtrl::SetItemText ( 
 664   const wxTreeItemId
&               rItem
 
 665 , const wxString
&                   rsText
 
 668     wxTreeViewItem                  
vTvItem(rItem
); 
 670     vTvItem
.m_vRecord
.pszTree 
= (wxChar 
*)rsText
.c_str();  // conversion is ok 
 672 } // end of wxTreeCtrl::SetItemText 
 675 // These functions under OS/2 PM are not needed.  OS/2 containers in tree view 
 676 // provide for storing a custom expanded and collapsed icons and selected 
 677 // and non selected icons, natively.  For instance, by default, a disk display 
 678 // will display a tree list of folder icons with "+" icons (collapsed) beside 
 679 // those folder which contain child members.  Double clicking a folder changes 
 680 // the closed folder icon to an open folder icon with hatched selection 
 681 // highlighting indicating an ICON view container of the folder is open 
 682 // elsewhere on the desktop.  So the below is not really needed, but we will 
 683 // simply return the appropriate icon requested out of OS/2's native PM 
 686 int wxTreeCtrl::DoGetItemImageFromData ( 
 687   const wxTreeItemId
&               WXUNUSED(rItem
) 
 688 , wxTreeItemIcon                    nWhich
 
 692     // Image handles stored in CNRINFO. 
 696     ::WinSendMsg( GetHWND() 
 699                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 703     // We really only have two to chose from.  If not custom (set in CNRINFO 
 704     // then return the handle to system bitmap).  OS/2 automatically provides 
 705     // in_use and selected bitmaps/icons 
 709         case wxTreeItemIcon_Normal
: 
 710             if (vCnrInfo
.hbmCollapsed 
== NULLHANDLE
) 
 711                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
); 
 712             return vCnrInfo
.hbmCollapsed
; 
 715         case wxTreeItemIcon_Expanded
: 
 716             if (vCnrInfo
.hbmExpanded 
== NULLHANDLE
) 
 717                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
); 
 718             return vCnrInfo
.hbmExpanded
; 
 721             return vCnrInfo
.hbmCollapsed
; 
 725 void wxTreeCtrl::DoSetItemImageFromData ( 
 726   const wxTreeItemId
&               WXUNUSED(rItem
) 
 728 , wxTreeItemIcon                    nWhich
 
 732     // Image handles stored in CNRINFO. 
 736     ::WinSendMsg( GetHWND() 
 739                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 741     if (nWhich 
== wxTreeItemIcon_Normal
) 
 742          vCnrInfo
.hbmCollapsed 
= (HBITMAP
)nImage
; 
 743     if (nWhich 
== wxTreeItemIcon_Expanded
) 
 744         vCnrInfo
.hbmExpanded 
= (HBITMAP
)nImage
; 
 745     ::WinSendMsg( GetHWND() 
 748                  ,(MPARAM
)CMA_TREEBITMAP
 
 750 } // end of wxTreeCtrl::DoSetItemImageFromData 
 753 void wxTreeCtrl::DoSetItemImages ( 
 754   const wxTreeItemId
&               rItem
 
 759 } // end of wxTreeCtrl::DoSetItemImages 
 761 int wxTreeCtrl::GetItemImage ( 
 762   const wxTreeItemId
&               rItem
 
 763 , wxTreeItemIcon                    nWhich
 
 766     if (HasIndirectData(rItem
)) 
 768         return DoGetItemImageFromData( rItem
 
 775     ::WinSendMsg( GetHWND() 
 778                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 783             wxFAIL_MSG( wxT("unknown tree item image type") ); 
 785         case wxTreeItemIcon_Normal
: 
 786             if (vCnrInfo
.hbmCollapsed 
== NULLHANDLE
) 
 787                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEPLUS
); 
 788             return vCnrInfo
.hbmCollapsed
; 
 791         case wxTreeItemIcon_Expanded
: 
 792             if (vCnrInfo
.hbmExpanded 
== NULLHANDLE
) 
 793                 return (int)::WinGetSysBitmap(HWND_DESKTOP
, SBMP_TREEMINUS
); 
 794             return vCnrInfo
.hbmExpanded
; 
 796         case wxTreeItemIcon_Selected
: 
 797         case wxTreeItemIcon_SelectedExpanded
: 
 802 void wxTreeCtrl::SetItemImage ( 
 803   const wxTreeItemId
&               WXUNUSED(rItem
) 
 805 , wxTreeItemIcon                    nWhich
 
 810     ::WinSendMsg( GetHWND() 
 813                  ,(MPARAM
)(USHORT
)sizeof(CNRINFO
) 
 817         case wxTreeItemIcon_Normal
: 
 818             vCnrInfo
.hbmCollapsed 
= (HBITMAP
)nImage
; 
 821         case wxTreeItemIcon_Expanded
: 
 822             vCnrInfo
.hbmExpanded 
= (HBITMAP
)nImage
; 
 826             wxFAIL_MSG( wxT("unknown tree item image type") ); 
 828     ::WinSendMsg( GetHWND() 
 831                  ,(MPARAM
)CMA_TREEBITMAP
 
 833 } // end of wxTreeCtrl::SetItemImage 
 835 wxTreeItemData
* wxTreeCtrl::GetItemData ( 
 836   const wxTreeItemId
&               rItem
 
 839     wxTreeViewItem                  
vTvItem(rItem
); 
 841     if (!DoGetItem(&vTvItem
)) 
 846     return (wxTreeItemData 
*)vTvItem
.m_ulUserData
; 
 847 } // end of wxTreeCtrl::GetItemData 
 849 void wxTreeCtrl::SetItemData ( 
 850   const wxTreeItemId
&               rItem
 
 851 , wxTreeItemData
*                   pData
 
 855     // first, associate this piece of data with this item 
 861     wxTreeViewItem                  
vTvItem(rItem
); 
 863     vTvItem
.m_ulUserData 
= (ULONG
)pData
; 
 865 } // end of wxTreeCtrl::SetItemData 
 867 // The following two do nothing under OS/2 
 868 void wxTreeCtrl::SetIndirectItemData ( 
 869   const wxTreeItemId
&               WXUNUSED(rItem
) 
 870 , wxTreeItemIndirectData
*           WXUNUSED(pData
) 
 873 } // end of wxTreeCtrl::SetIndirectItemData 
 875 bool wxTreeCtrl::HasIndirectData ( 
 876   const wxTreeItemId
&               WXUNUSED(rItem
) 
 880 } // end of wxTreeCtrl::HasIndirectData 
 882 // Irreleveant under OS/2 --- item either has child records or it doesn't. 
 883 void wxTreeCtrl::SetItemHasChildren ( 
 884   const wxTreeItemId
&               WXUNUSED(rItem
) 
 885 , bool                              WXUNUSED(bHas
) 
 888 } // end of wxTreeCtrl::SetItemHasChildren 
 890 // Irreleveant under OS/2 --- function of the font in PM 
 891 void wxTreeCtrl::SetItemBold ( 
 892   const wxTreeItemId
&               WXUNUSED(rItem
) 
 893 , bool                              WXUNUSED(bBold
) 
 896 } // end of wxTreeCtrl::SetItemBold 
 898 void wxTreeCtrl::SetItemDropHighlight ( 
 899   const wxTreeItemId
&               rItem
 
 903     wxTreeViewItem                  
vTvItem(rItem
); 
 905     ::WinSendMsg( GetHWND() 
 906                  ,CM_SETRECORDEMPHASIS
 
 908                  ,MPFROM2SHORT(bHighlight
, CRA_SELECTED
) 
 911 } // end of wxTreeCtrl::SetItemDropHighlight 
 913 void wxTreeCtrl::RefreshItem ( 
 914   const wxTreeItemId
&               rItem
 
 917     wxTreeViewItem                  
vTvItem(rItem
); 
 920     // This just does a record invalidate causing it to be re-displayed 
 923 } // end of wxTreeCtrl::RefreshItem 
 925 wxColour 
wxTreeCtrl::GetItemTextColour ( 
 926   const wxTreeItemId
&               rItem
 
 929     long                            lId 
= (long)rItem
.m_pItem
; 
 930     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 936     return pAttr
->GetTextColour(); 
 937 } // end of wxTreeCtrl::GetItemTextColour 
 939 wxColour 
wxTreeCtrl::GetItemBackgroundColour ( 
 940   const wxTreeItemId
&               rItem
 
 943     long                            lId 
= (long)rItem
.m_pItem
; 
 944     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 950     return pAttr
->GetBackgroundColour(); 
 951 } // end of wxTreeCtrl::GetItemBackgroundColour 
 953 wxFont 
wxTreeCtrl::GetItemFont ( 
 954   const wxTreeItemId
&               rItem
 
 957     long                            lId 
= (long)rItem
.m_pItem
; 
 958     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 964     return pAttr
->GetFont(); 
 965 } // end of wxTreeCtrl::GetItemFont 
 967 void wxTreeCtrl::SetItemTextColour ( 
 968   const wxTreeItemId
&               rItem
 
 969 , const wxColour
&                   rCol
 
 972     m_bHasAnyAttr 
= true; 
 974     long                            lId 
= (long)rItem
.m_pItem
; 
 975     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 979         pAttr 
= new wxTreeItemAttr
; 
 980         m_vAttrs
.Put(lId
, (wxObject 
*)pAttr
); 
 982     pAttr
->SetTextColour(rCol
); 
 984 } // end of wxTreeCtrl::SetItemTextColour 
 986 void wxTreeCtrl::SetItemBackgroundColour ( 
 987   const wxTreeItemId
&               rItem
 
 988 , const wxColour
&                   rCol
 
 991     m_bHasAnyAttr 
= true; 
 993     long                            lId 
= (long)rItem
.m_pItem
; 
 994     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
 998         pAttr 
= new wxTreeItemAttr
; 
 999         m_vAttrs
.Put(lId
, (wxObject 
*)pAttr
); 
1001     pAttr
->SetBackgroundColour(rCol
); 
1003 } // end of wxTreeCtrl::SetItemBackgroundColour 
1005 void wxTreeCtrl::SetItemFont ( 
1006   const wxTreeItemId
&               rItem
 
1007 , const wxFont
&                     rFont
 
1010     m_bHasAnyAttr 
= true; 
1012     long                            lId 
= (long)rItem
.m_pItem
; 
1013     wxTreeItemAttr
*                 pAttr 
= (wxTreeItemAttr 
*)m_vAttrs
.Get(lId
); 
1017         pAttr 
= new wxTreeItemAttr
; 
1018         m_vAttrs
.Put(lId
, (wxObject 
*)pAttr
); 
1020     pAttr
->SetFont(rFont
); 
1022 } // end of wxTreeCtrl::SetItemFont 
1024 // ---------------------------------------------------------------------------- 
1026 // ---------------------------------------------------------------------------- 
1028 bool wxTreeCtrl::IsVisible ( 
1029   const wxTreeItemId
&               rItem
 
1032     // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect 
1034     RECTL                           vRectContainer
; 
1035     wxRect                          vWxRectRecord
; 
1036     wxRect                          vWxRectContainer
; 
1037     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1040     QUERYRECORDRECT                 vQuery
; 
1042     vQuery
.cb                
= sizeof(QUERYRECORDRECT
); 
1043     vQuery
.pRecord           
= (PRECORDCORE
)pRecord
; 
1044     vQuery
.fRightSplitWindow 
= FALSE
; 
1045     vQuery
.fsExtent          
= CMA_TREEICON
; 
1047     ::WinSendMsg( GetHWND() 
1048                  ,CM_QUERYVIEWPORTRECT
 
1049                  ,MPFROMP(&vRectContainer
) 
1050                  ,MPFROM2SHORT(CMA_WINDOW
, FALSE
) 
1052     ::WinSendMsg( GetHWND() 
1054                  ,MPFROMP(&vRectRecord
) 
1057     vWxRectRecord
.SetLeft(vRectRecord
.xLeft
); 
1058     vWxRectRecord
.SetTop(vRectRecord
.yTop
); 
1059     vWxRectRecord
.SetRight(vRectRecord
.xRight
); 
1060     vWxRectRecord
.SetBottom(vRectRecord
.yBottom
); 
1062     vWxRectContainer
.SetLeft(vRectContainer
.xLeft
); 
1063     vWxRectContainer
.SetTop(vRectContainer
.yTop
); 
1064     vWxRectContainer
.SetRight(vRectContainer
.xRight
); 
1065     vWxRectContainer
.SetBottom(vRectContainer
.yBottom
); 
1066     return (vWxRectContainer
.Contains(wxPoint(vWxRectRecord
.x
, vWxRectRecord
.y
))); 
1067 } // end of wxTreeCtrl::IsVisible 
1069 bool wxTreeCtrl::ItemHasChildren ( 
1070   const wxTreeItemId
&               rItem
 
1073     wxTreeViewItem                  
vTvItem(rItem
); 
1074     DoGetItem(&vTvItem
); 
1077     // A tree record with children will have one of these attributes 
1079     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_EXPANDED 
|| 
1080             vTvItem
.m_vRecord
.flRecordAttr 
& CRA_COLLAPSED
) != 0; 
1083 bool wxTreeCtrl::IsExpanded ( 
1084   const wxTreeItemId
&               rItem
 
1087     wxTreeViewItem                  
vTvItem(rItem
); 
1088     DoGetItem(&vTvItem
); 
1090     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_EXPANDED
) != 0; 
1091 } // end of wxTreeCtrl::IsExpanded 
1093 bool wxTreeCtrl::IsSelected ( 
1094   const wxTreeItemId
&               rItem
 
1097     wxTreeViewItem                  
vTvItem(rItem
); 
1098     DoGetItem(&vTvItem
); 
1100     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_SELECTED
) != 0; 
1101 } // end of wxTreeCtrl::IsSelected 
1104 bool wxTreeCtrl::IsBold ( 
1105   const wxTreeItemId
&               rItem
 
1109 } // end of wxTreeCtrl::IsBold 
1111 // ---------------------------------------------------------------------------- 
1113 // ---------------------------------------------------------------------------- 
1115 wxTreeItemId 
wxTreeCtrl::GetRootItem () const 
1117     PMYRECORD                       pRecord 
= NULL
; 
1119     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1122                                                   ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
1126         return wxTreeItemId(-1L); 
1127     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1128 } // end of wxTreeCtrl::GetRootItem 
1130 wxTreeItemId 
wxTreeCtrl::GetSelection () const 
1132     wxCHECK_MSG( !(m_windowStyle 
& wxTR_MULTIPLE
), (long)(WXHTREEITEM
)0, 
1133                  wxT("this only works with single selection controls") ); 
1135     PMYRECORD                       pRecord 
= NULL
; 
1137     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1138                                                   ,CM_QUERYRECORDEMPHASIS
 
1140                                                   ,MPARAM(CRA_SELECTED
) 
1143         return wxTreeItemId(-1L); 
1144     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1145 } // end of wxTreeCtrl::GetSelection 
1147 wxTreeItemId 
wxTreeCtrl::GetItemParent ( 
1148   const wxTreeItemId
&               rItem
 
1151     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1156         return wxTreeItemId(-1L); 
1157     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1160                                                   ,MPFROM2SHORT(CMA_PARENT
, CMA_ITEMORDER
) 
1163         return wxTreeItemId(-1L); 
1164     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1165 } // end of wxTreeCtrl::GetItemParent 
1167 wxTreeItemId 
wxTreeCtrl::GetFirstChild ( 
1168   const wxTreeItemId
&               rItem
 
1172     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1177         return wxTreeItemId(-1L); 
1178     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1181                                                   ,MPFROM2SHORT(CMA_FIRSTCHILD
, CMA_ITEMORDER
) 
1184         return wxTreeItemId(-1L); 
1186     // Remember the last child returned in 'cookie' 
1188     rCookie 
= (long)pRecord
->m_ulItemId
; 
1189     return wxTreeItemId(rCookie
); 
1190 } // end of wxTreeCtrl::GetFirstChild 
1192 wxTreeItemId 
wxTreeCtrl::GetNextChild ( 
1193   const wxTreeItemId
&               WXUNUSED(rItem
) 
1197     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1202         return wxTreeItemId(-1L); 
1203     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1206                                                   ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1209         return wxTreeItemId(-1L); 
1210     rCookie 
= (long)pRecord
->m_ulItemId
; 
1211     return wxTreeItemId(rCookie
); 
1212 } // end of wxTreeCtrl::GetNextChild 
1214 wxTreeItemId 
wxTreeCtrl::GetLastChild ( 
1215   const wxTreeItemId
&               rItem
 
1218     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1223         return wxTreeItemId(-1L); 
1224     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1227                                                   ,MPFROM2SHORT(CMA_LASTCHILD
, CMA_ITEMORDER
) 
1230         return wxTreeItemId(-1L); 
1231     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1232 } // end of wxTreeCtrl::GetLastChild 
1234 wxTreeItemId 
wxTreeCtrl::GetNextSibling ( 
1235   const wxTreeItemId
&               rItem
 
1238     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1243         return wxTreeItemId(-1L); 
1244     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1247                                                   ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1250         return wxTreeItemId(-1L); 
1251     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1252 } // end of wxTreeCtrl::GetNextSibling 
1254 wxTreeItemId 
wxTreeCtrl::GetPrevSibling ( 
1255   const wxTreeItemId
&               rItem
 
1258     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1263         return wxTreeItemId(-1L); 
1264     pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1267                                                   ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
) 
1270         return wxTreeItemId(-1L); 
1271     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1272 } // end of wxTreeCtrl::GetPrevSibling 
1274 wxTreeItemId 
wxTreeCtrl::GetFirstVisibleItem () const 
1276     PMYRECORD                       pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1279                                                                                   ,MPFROM2SHORT(CMA_FIRST
, CMA_ITEMORDER
) 
1282         return wxTreeItemId(-1L); 
1284     if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1285         return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1288         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1291                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1294             return wxTreeItemId(-1L); 
1295         if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1296             return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1298     return wxTreeItemId(-1L); 
1299 } // end of wxTreeCtrl::GetFirstVisibleItem 
1301 wxTreeItemId 
wxTreeCtrl::GetNextVisible ( 
1302   const wxTreeItemId
&               rItem
 
1305     wxASSERT_MSG(IsVisible(rItem
), wxT("The item you call GetNextVisible() for must be visible itself!")); 
1307     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1312         return wxTreeItemId(-1L); 
1315         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1318                                                       ,MPFROM2SHORT(CMA_NEXT
, CMA_ITEMORDER
) 
1321             return wxTreeItemId(-1L); 
1322         if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1323             return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1325     return wxTreeItemId(-1L); 
1326 } // end of wxTreeCtrl::GetNextVisible 
1328 wxTreeItemId 
wxTreeCtrl::GetPrevVisible ( 
1329   const wxTreeItemId
&               rItem
 
1332     wxASSERT_MSG( IsVisible(rItem
), wxT("The item you call GetPrevVisible() for must be visible itself!")); 
1334     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1339         return wxTreeItemId(-1L); 
1342         pRecord 
= (PMYRECORD
)PVOIDFROMMR(::WinSendMsg( GetHWND() 
1345                                                       ,MPFROM2SHORT(CMA_PREV
, CMA_ITEMORDER
) 
1348             return wxTreeItemId(-1L); 
1349         if (IsVisible(wxTreeItemId((long)pRecord
->m_ulItemId
))) 
1350             return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1352     return wxTreeItemId(-1L); 
1353 } // end of wxTreeCtrl::GetPrevVisible 
1355 // ---------------------------------------------------------------------------- 
1356 // multiple selections emulation -- under OS/2 checked tree items is not 
1357 // supported, but multisel is.  So we'll just check for selections here. 
1358 // ---------------------------------------------------------------------------- 
1360 bool wxTreeCtrl::IsItemChecked ( 
1361   const wxTreeItemId
&               rItem
 
1364     wxTreeViewItem                  
vTvItem(rItem
); 
1366     DoGetItem(&vTvItem
); 
1367     return (vTvItem
.m_vRecord
.flRecordAttr 
& CRA_SELECTED
); 
1368 } // end of wxTreeCtrl::IsItemChecked 
1370 void wxTreeCtrl::SetItemCheck ( 
1371   const wxTreeItemId
&               rItem
 
1375     wxTreeViewItem                  
vTvItem(rItem
); 
1377     DoGetItem(&vTvItem
); 
1378     ::WinSendMsg( GetHWND() 
1379                  ,CM_SETRECORDEMPHASIS
 
1381                  ,MPFROM2SHORT(TRUE
, CRA_SELECTED
) 
1383     DoSetItem(&vTvItem
); 
1384 } // end of wxTreeCtrl::SetItemCheck 
1386 size_t wxTreeCtrl::GetSelections ( 
1387   wxArrayTreeItemIds
&               raSelections
 
1390     TraverseSelections              
vSelector( this 
1393     return vSelector
.GetCount(); 
1394 } // end of wxTreeCtrl::GetSelections 
1396 // ---------------------------------------------------------------------------- 
1398 // ---------------------------------------------------------------------------- 
1400 wxTreeItemId 
wxTreeCtrl::DoInsertItem ( 
1401   const wxTreeItemId
&               rParent
 
1402 , wxTreeItemId                      vInsertAfter
 
1403 , const wxString
&                   rsText
 
1406 , wxTreeItemData
*                   pData
 
1409     PMYRECORD                       pRecordAfter 
= FindOS2TreeRecordByID( GetHWND() 
1410                                                                          ,vInsertAfter
.m_pItem
 
1413     PMYRECORD                       pRecordParent 
= FindOS2TreeRecordByID( GetHWND() 
1417     PMYRECORD                       pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1419                                                                       ,MPFROMLONG(sizeof(MYRECORD
) - sizeof(RECORDCORE
)) 
1422     RECORDINSERT                    vInsert
; 
1424     vInsert
.cb                
= sizeof(RECORDINSERT
); 
1425     if (rParent
.m_pItem 
== 0L) 
1427         if (vInsertAfter
.m_pItem 
== -1) 
1428             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_END
; 
1430             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_FIRST
; 
1431         vInsert
.pRecordParent     
= NULL
; 
1435         if (vInsertAfter
.m_pItem 
== 0) 
1436             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_FIRST
; 
1437         else if (vInsertAfter
.m_pItem 
== -1) 
1438             vInsert
.pRecordOrder      
= (PRECORDCORE
)CMA_END
; 
1440             vInsert
.pRecordOrder  
= (PRECORDCORE
)pRecordAfter
; 
1441         vInsert
.pRecordParent     
= (PRECORDCORE
)pRecordParent
; 
1443     vInsert
.fInvalidateRecord 
= TRUE
; 
1444     vInsert
.zOrder            
= CMA_TOP
; 
1445     vInsert
.cRecordsInsert    
= 1; 
1447     pRecord
->m_vRecord
.pszTree   
= (wxChar
*)rsText
.c_str(); 
1448     pRecord
->m_vRecord
.hbmBitmap 
= nImage
; 
1449     pRecord
->m_ulItemId 
= pRecordAfter
->m_ulItemId 
+ 1; 
1452         pRecord
->m_ulUserData 
= (ULONG
)pData
; 
1454     ::WinSendMsg( GetHWND() 
1461     // OS/2 must mannually bump the index's of following records 
1463     BumpTreeRecordIds( GetHWND() 
1469         // Associate the application tree item with PM tree item handle 
1471         pData
->SetId((long)pRecord
->m_ulItemId
); 
1473     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1476 wxTreeItemId 
wxTreeCtrl::AddRoot ( 
1477   const wxString
&                   rsText
 
1479 , int                               nSelectedImage
 
1480 , wxTreeItemData
*                   pData
) 
1483     return DoInsertItem( wxTreeItemId((long)0) 
1484                         ,wxTreeItemId((long)-1) 
1490 } // end of wxTreeCtrl::AddRoot 
1492 wxTreeItemId 
wxTreeCtrl::PrependItem ( 
1493   const wxTreeItemId
&               rParent
 
1494 , const wxString
&                   rsText
 
1496 , int                               nSelectedImage
 
1497 , wxTreeItemData
*                   pData
 
1500     return DoInsertItem( rParent
 
1501                         ,wxTreeItemId((long)0) 
1507 } // end of wxTreeCtrl::PrependItem 
1509 wxTreeItemId 
wxTreeCtrl::InsertItem ( 
1510   const wxTreeItemId
&               rParent
 
1511 , const wxTreeItemId
&               rIdPrevious
 
1512 , const wxString
&                   rsText
 
1514 , int                               nSelectedImage
 
1515 , wxTreeItemData
*                   pData
 
1518     return DoInsertItem( rParent
 
1525 } // end of wxTreeCtrl::InsertItem 
1527 wxTreeItemId 
wxTreeCtrl::InsertItem ( 
1528   const wxTreeItemId
&               rParent
 
1530 , const wxString
&                   rsText
 
1532 , int                               nSelectedImage
 
1533 , wxTreeItemData
*                   pData
 
1536     return DoInsertItem( rParent
 
1537                         ,wxTreeItemId((long)nIndex
) 
1543 } // end of wxTreeCtrl::InsertItem 
1545 wxTreeItemId 
wxTreeCtrl::AppendItem ( 
1546   const wxTreeItemId
&               rParent
 
1547 , const wxString
&                   rsText
 
1549 , int                               nSelectedImage
 
1550 , wxTreeItemData
*                   pData
 
1553     return DoInsertItem( rParent
 
1554                         ,wxTreeItemId((long)-1) 
1560 } // end of wxTreeCtrl::AppendItem 
1562 void wxTreeCtrl::Delete ( 
1563   const wxTreeItemId
&               rItem
 
1567     // OS/2 does not generate DELETEITEM events so do it here 
1569     wxEventType                     vEventType 
= wxEVT_NULL
; 
1570     wxTreeEvent                     
vEvent( wxEVT_NULL
 
1573     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
1576     vEvent
.SetEventObject(this); 
1577     ::WinSendMsg( GetHWND() 
1580                  ,(MPARAM
)(CMA_FREE 
| CMA_INVALIDATE
) 
1582     vEvent
.m_item 
= rItem
.m_pItem
; 
1585         delete (wxTreeItemAttr 
*)m_vAttrs
.Delete((long)rItem
.m_pItem
); 
1587     vEvent
.SetEventType(vEventType
); 
1588     HandleWindowEvent(vEvent
); 
1589 } // end of wxTreeCtrl::Delete 
1591 // delete all children (but don't delete the item itself) 
1592 void wxTreeCtrl::DeleteChildren ( 
1593   const wxTreeItemId
&               rItem
 
1597     wxArrayLong                     aChildren
; 
1598     wxTreeItemId                    vChild 
= GetFirstChild( rItem
 
1602     while (vChild
.IsOk()) 
1604         aChildren
.Add((long)(WXHTREEITEM
)vChild
); 
1605         vChild 
= GetNextChild( rItem
 
1610     size_t                          nCount 
= aChildren
.Count(); 
1612     for (size_t n 
= 0; n 
< nCount
; n
++) 
1614         Delete(aChildren
[n
]); 
1616 } // end of wxTreeCtrl::DeleteChildren 
1618 void wxTreeCtrl::DeleteAllItems () 
1620     ::WinSendMsg( GetHWND() 
1623                  ,(MPARAM
)(CMA_FREE 
| CMA_INVALIDATE
) 
1625 } // end of wxTreeCtrl::DeleteAllItems 
1627 void wxTreeCtrl::DoExpand ( 
1628   const wxTreeItemId
&               rItem
 
1632     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
1637         case wxTREE_EXPAND_EXPAND
: 
1638             ::WinSendMsg( GetHWND() 
1645         case wxTREE_EXPAND_COLLAPSE
: 
1646             ::WinSendMsg( GetHWND() 
1653         case wxTREE_EXPAND_COLLAPSE_RESET
: 
1654             ::WinSendMsg( GetHWND() 
1659             DeleteChildren(rItem
); 
1662         case wxTREE_EXPAND_TOGGLE
: 
1663             if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_COLLAPSED
) 
1664                 ::WinSendMsg( GetHWND() 
1669             else if (pRecord
->m_vRecord
.flRecordAttr 
& CRA_EXPANDED
) 
1670                 ::WinSendMsg( GetHWND() 
1678 } // end of wxTreeCtrl::DoExpand 
1680 void wxTreeCtrl::Expand ( 
1681   const wxTreeItemId
&               rItem
 
1685              ,wxTREE_EXPAND_EXPAND
 
1687 } // end of wxTreeCtrl::Expand 
1689 void wxTreeCtrl::Collapse ( 
1690   const wxTreeItemId
&               rItem
 
1694              ,wxTREE_EXPAND_COLLAPSE
 
1696 } // end of wxTreeCtrl::Collapse 
1698 void wxTreeCtrl::CollapseAndReset ( 
1699   const wxTreeItemId
&               rItem
 
1703              ,wxTREE_EXPAND_COLLAPSE_RESET
 
1705 } // end of wxTreeCtrl::CollapseAndReset 
1707 void wxTreeCtrl::Toggle ( 
1708   const wxTreeItemId
&               rItem
 
1712              ,wxTREE_EXPAND_TOGGLE
 
1714 } // end of wxTreeCtrl::Toggle 
1716 void wxTreeCtrl::Unselect () 
1718     wxASSERT_MSG( !(m_windowStyle 
& wxTR_MULTIPLE
), 
1719                   wxT("doesn't make sense, may be you want UnselectAll()?") ); 
1722     // Just remove the selection 
1724     SelectItem(wxTreeItemId((long)0)); 
1725 } // end of wxTreeCtrl::Unselect 
1727 void wxTreeCtrl::UnselectAll () 
1729     if (m_windowStyle 
& wxTR_MULTIPLE
) 
1731         wxArrayTreeItemIds          aSelections
; 
1732         size_t                      nCount 
= GetSelections(aSelections
); 
1734         for (size_t n 
= 0; n 
< nCount
; n
++) 
1736             SetItemCheck( aSelections
[n
] 
1744         // Just remove the selection 
1748 } // end of wxTreeCtrl::UnselectAll 
1750 void wxTreeCtrl::SelectItem ( 
1751   const wxTreeItemId
&               rItem
 
1754     SetItemCheck(rItem
); 
1755 } // end of wxTreeCtrl::SelectItem 
1757 void wxTreeCtrl::EnsureVisible ( 
1758   const wxTreeItemId
&               rItem
 
1761     wxTreeViewItem                  
vTvItem(rItem
); 
1763     DoGetItem(&vTvItem
); 
1764     if (!::WinSendMsg( GetHWND() 
1765                       ,CM_INVALIDATERECORD
 
1767                       ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1769 } // end of wxTreeCtrl::EnsureVisible 
1771 void wxTreeCtrl::ScrollTo ( 
1772   const wxTreeItemId
&               rItem
 
1775     wxTreeViewItem                  
vTvItem(rItem
); 
1777     DoGetItem(&vTvItem
); 
1778     if (!::WinSendMsg( GetHWND() 
1779                       ,CM_INVALIDATERECORD
 
1781                       ,MPFROM2SHORT(1, CMA_ERASE 
| CMA_REPOSITION 
| CMA_TEXTCHANGED
) 
1785 wxTextCtrl
* wxTreeCtrl::EditLabel ( 
1786   const wxTreeItemId
&               rItem
 
1787 , wxClassInfo
*                      WXUNUSED(pTextControlClass
) 
1791     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID( GetHWND() 
1795     vEdit
.cb         
= sizeof(CNREDITDATA
); 
1796     vEdit
.hwndCnr    
= GetHWND(); 
1797     vEdit
.pRecord    
= &pRecord
->m_vRecord
; 
1798     vEdit
.pFieldInfo 
= NULL
; 
1799     vEdit
.ppszText   
= NULL
; 
1803     ::WinSendMsg( GetHWND() 
1809 } // end of wxTreeCtrl::EditLabel 
1811 // End label editing, optionally cancelling the edit 
1812 void wxTreeCtrl::EndEditLabel ( 
1813   const wxTreeItemId
&               WXUNUSED(rItem
) 
1814 , bool                              WXUNUSED(bDiscardChanges
) 
1817     ::WinSendMsg( GetHWND() 
1822 } // end of wxTreeCtrl::EndEditLabel 
1824 wxTreeItemId 
wxTreeCtrl::HitTest ( 
1825   const wxPoint
&                    rPoint
 
1826 , int&                              WXUNUSED(rFlags
) 
1829     PMYRECORD                       pRecord 
= NULL
; 
1830     QUERYRECFROMRECT                vQueryRect
; 
1835     // Get height for OS/2 point conversion 
1837     ::WinSendMsg( GetHWND() 
1838                  ,CM_QUERYVIEWPORTRECT
 
1840                  ,MPFROM2SHORT(CMA_WINDOW
, TRUE
) 
1842     lHeight 
= vRect
.yTop 
- vRect
.yBottom
; 
1845     // For now just try and get a record in the general vicinity and forget 
1848     vRect
.xLeft   
= rPoint
.x 
- 2; 
1849     vRect
.xRight  
= rPoint
.x 
+ 2; 
1850     vRect
.yTop    
= (lHeight 
- rPoint
.y
) + 2; 
1851     vRect
.yBottom 
= (lHeight 
- rPoint
.y
) - 2; 
1853     vQueryRect
.cb 
= sizeof(QUERYRECFROMRECT
); 
1854     vQueryRect
.rect 
= vRect
; 
1855     vQueryRect
.fsSearch 
= CMA_PARTIAL
; 
1857     pRecord 
= (PMYRECORD
)::WinSendMsg( GetHWND() 
1858                                       ,CM_QUERYRECORDFROMRECT
 
1860                                       ,MPFROMP(&vQueryRect
) 
1865     return wxTreeItemId((long)pRecord
->m_ulItemId
); 
1866 } // end of wxTreeCtrl::HitTest 
1868 bool wxTreeCtrl::GetBoundingRect ( 
1869   const wxTreeItemId
&               rItem
 
1875     PMYRECORD                       pRecord 
= FindOS2TreeRecordByID ( GetHWND() 
1878     QUERYRECORDRECT                 vQuery
; 
1880     vQuery
.cb                
= sizeof(QUERYRECORDRECT
); 
1881     vQuery
.pRecord           
= (PRECORDCORE
)pRecord
; 
1882     vQuery
.fRightSplitWindow 
= FALSE
; 
1884         vQuery
.fsExtent          
= CMA_TEXT
; 
1886         vQuery
.fsExtent          
= CMA_TREEICON 
| CMA_TEXT
; 
1888     if (!::WinSendMsg( GetHWND() 
1890                       ,MPFROMP(&vRectRecord
) 
1894     rRect
.SetLeft(vRectRecord
.xLeft
); 
1895     rRect
.SetTop(vRectRecord
.yTop
); 
1896     rRect
.SetRight(vRectRecord
.xRight
); 
1897     rRect
.SetBottom(vRectRecord
.yBottom
); 
1899 } // end of wxTreeCtrl::GetBoundingRect 
1901 // ---------------------------------------------------------------------------- 
1903 // ---------------------------------------------------------------------------- 
1905 SHORT EXPENTRY 
InternalDataCompareTreeFunc ( 
1911     wxCHECK_MSG( p1 
&& p2
, 0, 
1912                  wxT("sorting tree without data doesn't make sense") ); 
1914     wxTreeCtrl
*                     pTree 
= (wxTreeCtrl
*)pStorage
; 
1916     return pTree
->OnCompareItems( p1
->m_ulItemId
 
1919 } // end of wxTreeSortHelper::Compare 
1921 int wxTreeCtrl::OnCompareItems ( 
1922   const wxTreeItemId
&               rItem1
 
1923 , const wxTreeItemId
&               rItem2
 
1926     return wxStrcmp( GetItemText(rItem1
) 
1927                     ,GetItemText(rItem2
) 
1929 } // end of wxTreeCtrl::OnCompareItems 
1931 void wxTreeCtrl::SortChildren ( 
1932   const wxTreeItemId
&               rItem
 
1935     ::WinSendMsg( GetHWND() 
1937                  ,(PFN
)InternalDataCompareTreeFunc
 
1940 } // end of wxTreeCtrl::SortChildren 
1942 // ---------------------------------------------------------------------------- 
1944 // ---------------------------------------------------------------------------- 
1946 bool wxTreeCtrl::OS2Command ( 
1951     if (uCmd 
== CN_ENDEDIT
) 
1953         wxCommandEvent              
vEvent( wxEVT_COMMAND_TEXT_UPDATED
 
1957         vEvent
.SetEventObject( this ); 
1958         ProcessCommand(vEvent
); 
1961     else if (uCmd 
== CN_KILLFOCUS
) 
1963         wxCommandEvent              
vEvent( wxEVT_KILL_FOCUS
 
1966         vEvent
.SetEventObject( this ); 
1967         ProcessCommand(vEvent
); 
1972 } // end of wxTreeCtrl::OS2Command 
1975 // TODO:  Fully implement direct manipulation when I figure it out 
1977 MRESULT 
wxTreeCtrl::OS2WindowProc ( 
1983     bool                            bProcessed 
= false; 
1985     wxTreeEvent                     
vEvent( wxEVT_NULL
 
1988     wxEventType                     vEventType 
= wxEVT_NULL
; 
1989     PCNRDRAGINIT                    pDragInit 
= NULL
; 
1990     PCNREDITDATA                    pEditData 
= NULL
; 
1991     PNOTIFYRECORDENTER              pNotifyEnter 
= NULL
; 
1993     vEvent
.SetEventObject(this); 
1997             switch(SHORT2FROMMP(wParam
)) 
2000                     pDragInit 
= (PCNRDRAGINIT
)lParam
; 
2003                         PMYRECORD       pRecord 
= (PMYRECORD
)pDragInit
->pRecord
; 
2005                         vEventType 
= wxEVT_COMMAND_TREE_BEGIN_DRAG
; 
2006                         vEvent
.m_item        
= pRecord
->m_ulItemId
; 
2007                         vEvent
.m_pointDrag
.x 
= pDragInit
->x
; 
2008                         vEvent
.m_pointDrag
.y 
= pDragInit
->y
; 
2013                     pEditData 
= (PCNREDITDATA
)lParam
; 
2016                         PMYRECORD       pRecord 
= (PMYRECORD
)pEditData
->pRecord
; 
2018                         vEventType 
= wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
; 
2019                         vEvent
.m_item 
= pRecord
->m_ulItemId
; 
2020                         vEvent
.m_label 
= pRecord
->m_vRecord
.pszTree
; 
2021                         vEvent
.m_editCancelled 
= false; 
2026                     pEditData 
= (PCNREDITDATA
)lParam
; 
2029                         PMYRECORD       pRecord 
= (PMYRECORD
)pEditData
->pRecord
; 
2031                         vEventType 
= wxEVT_COMMAND_TREE_END_LABEL_EDIT
; 
2032                         vEvent
.m_item 
= pRecord
->m_ulItemId
; 
2033                         vEvent
.m_label 
= pRecord
->m_vRecord
.pszTree
; 
2034                         if (pRecord
->m_vRecord
.pszTree 
== NULL
) 
2036                             vEvent
.m_editCancelled 
= true; 
2040                             vEvent
.m_editCancelled 
= false; 
2047                         PMYRECORD       pRecord 
= (PMYRECORD
)lParam
; 
2049                         vEventType 
= gs_expandEvents
[IDX_EXPAND
][IDX_DONE
]; 
2050                         vEvent
.m_item 
= pRecord
->m_ulItemId
; 
2054             vEvent
.SetEventType(vEventType
); 
2055             bProcessed 
= HandleWindowEvent(vEvent
); 
2059         mRc 
= wxControl::OS2WindowProc( uMsg
 
2064 } // end of wxTreeCtrl::OS2WindowProc 
2066 #endif // wxUSE_TREECTRL