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