]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/treectrl.cpp
Don't assert if the path is not absolute in wxFileDialog::SetPath().
[wxWidgets.git] / src / os2 / treectrl.cpp
index 8671b38c71030beedf1894bdeef675da04f76c82..edd074f652817b923376b77920d8828c05876779 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
-// Name:        treectrl.cpp
-// Purpose:     wxTreeCtrl. See also Robert's generic wxTreeCtrl.
-// Author:      David Webster
-// Modified by:
-// Created:     10/17/99
+// Name:        src/os2/treectrl.cpp
+// Purpose:     wxTreeCtrl
+// Author:      Julian Smart
+// Modified by: Vadim Zeitlin to be less MSW-specific on 10.10.98
+// Created:     1997
 // RCS-ID:      $Id$
-// Copyright:   (c) David
+// Copyright:   (c) Julian Smart
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
-#include "wx/window.h"
-#include "wx/os2/private.h"
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#if wxUSE_TREECTRL
 
-#include "wx/log.h"
-#include "wx/dynarray.h"
-#include "wx/imaglist.h"
 #include "wx/treectrl.h"
-#include "wx/settings.h"
 
-// Bug in headers, sometimes
-#ifndef TVIS_FOCUSED
-    #define TVIS_FOCUSED            0x0001
+#ifndef WX_PRECOMP
+    #include "wx/dynarray.h"
+    #include "wx/log.h"
+    #include "wx/app.h"
+    #include "wx/settings.h"
 #endif
 
+#include "wx/os2/private.h"
+
+#include "wx/imaglist.h"
+
+// a macro to hide the ugliness of nested casts
+#define HITEM(item)     (HTREEITEM)(WXHTREEITEM)(item)
+
+// the native control doesn't support multiple selections under MSW and we
+// have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
+// checkboxes be the selection status (checked == selected) or by really
+// emulating everything, i.e. intercepting mouse and key events &c. The first
+// approach is much easier but doesn't work with comctl32.dll < 4.71 and also
+// looks quite ugly.
+#define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
 
-struct wxTreeViewItem// ??? : public TV_ITEM
+typedef struct _MYRECORD
+{
+    RECORDCORE                      m_vRecord;
+    ULONG                           m_ulItemId;
+    ULONG                           m_ulUserData;
+} MYRECORD, *PMYRECORD;
+
+struct wxTreeViewItem : public MYRECORD
 {
-    wxTreeViewItem(const wxTreeItemId& item,    // the item handle
-                   UINT mask_,                  // fields which are valid
-                   UINT stateMask_ = 0)         // for TVIF_STATE only
+    wxTreeViewItem(const wxTreeItemId& rItem)
     {
-        // hItem member is always valid
-        mask = mask_; // | TVIF_HANDLE;
-        stateMask = stateMask_;
-        hItem = /*(HTREEITEM)*/ (WXHTREEITEM) item;
+        m_ulItemId = (ULONG)rItem.m_pItem;
     }
-    // OS/2 subs
-    UINT          mask;
-    UINT          stateMask;
-    WXHTREEITEM   hItem;
-};
+}; // end of STRUCT wxTreeViewItem
 
-// a class which encapsulates the tree traversal logic: it vists all (unless
-// OnVisit() returns FALSE) items under the given one
-class wxTreeTraversal
+class wxTreeItemInternalData
 {
 public:
-    wxTreeTraversal(const wxTreeCtrl *tree)
+
+    wxTreeItemInternalData() {}
+    ~wxTreeItemInternalData()
+    {
+        if(m_pAttr)
+        {
+            delete m_pAttr;
+            m_pAttr = NULL;
+        }
+    }
+
+    wxTreeItemAttr*                 m_pAttr;
+    WXLPARAM                        m_lParam; // user data
+#if defined(C_CM_COS232)
+    PMYRECORD                       m_pMyRecord; // so we can set the m_ulUserData to 0 when this is deleted
+#endif
+}; // end of CLASS wxTreeItemInternalData
+
+void BumpTreeRecordIds (
+  HWND                              hWnd
+, PMYRECORD                         pRecord
+)
+{
+    while(pRecord)
     {
-        m_tree = tree;
+        pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
+                                                      ,CM_QUERYRECORD
+                                                      ,MPFROMP(pRecord)
+                                                      ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+                                                     ));
+        if (pRecord)
+            pRecord->m_ulItemId++;
     }
+} // end of BumpTreeRecordIds
+
+PMYRECORD FindOS2TreeRecordByID (
+  HWND                              hWnd
+, long                              lItemId
+)
+{
+    PMYRECORD                       pRecord = NULL;
+    CNRINFO                         vCnrInfo;
+    unsigned long                   i;
+
+    if (!::WinSendMsg( hWnd
+                      ,CM_QUERYCNRINFO
+                      ,MPFROMP(&vCnrInfo)
+                      ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                     ))
+        return NULL;
+    for (i = 0; i < vCnrInfo.cRecords; i++)
+    {
+        if (i == 0)
+            pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
+                                                          ,CM_QUERYRECORD
+                                                          ,MPFROMP(pRecord)
+                                                          ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
+                                                         ));
+        else
+            pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
+                                                          ,CM_QUERYRECORD
+                                                          ,MPFROMP(pRecord)
+                                                          ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+                                                         ));
+        if (!pRecord)
+            return NULL;
+        if (pRecord->m_ulItemId == (ULONG)lItemId)
+            break;
+    }
+    return pRecord;
+} // end of FindOS2ListRecordByID
+
 
-    // do traverse the tree: visit all items (recursively by default) under the
-    // given one; return TRUE if all items were traversed or FALSE if the
-    // traversal was aborted because OnVisit returned FALSE
-    bool DoTraverse(const wxTreeItemId& root, bool recursively = TRUE);
 
-    // override this function to do whatever is needed for each item, return
-    // FALSE to stop traversing
-    virtual bool OnVisit(const wxTreeItemId& item) = 0;
+class wxTreeTraversal
+{
+public:
+    wxTreeTraversal(const wxTreeCtrl* pTree)
+    {
+        m_pTree = pTree;
+    }
+
+    //
+    // Do traverse the tree: visit all items (recursively by default) under the
+    // given one; return true if all items were traversed or false if the
+    // traversal was aborted because OnVisit returned false
+    //
+    bool DoTraverse( const wxTreeItemId& rRoot
+                    ,bool                bRecursively = true
+                   );
+
+    //
+    // Override this function to do whatever is needed for each item, return
+    // false to stop traversing
+    //
+    virtual bool OnVisit(const wxTreeItemId& rItem) = 0;
 
 protected:
-    const wxTreeCtrl *GetTree() const { return m_tree; }
+    const wxTreeCtrl* GetTree(void) const { return m_pTree; }
 
 private:
-    bool Traverse(const wxTreeItemId& root, bool recursively);
+    bool Traverse( const wxTreeItemId& rRoot
+                  ,bool                bRecursively
+                 );
 
-    const wxTreeCtrl *m_tree;
-};
+    const wxTreeCtrl*               m_pTree;
+    wxDECLARE_NO_COPY_CLASS(wxTreeTraversal);
+}; // end of CLASS wxTreeTraversal
 
-// internal class for getting the selected items
+//
+// Internal class for getting the selected items
+//
 class TraverseSelections : public wxTreeTraversal
 {
 public:
-    TraverseSelections(const wxTreeCtrl *tree,
-                       wxArrayTreeItemIds& selections)
-        : wxTreeTraversal(tree), m_selections(selections)
-        {
-            m_selections.Empty();
-
-            DoTraverse(tree->GetRootItem());
-        }
+    TraverseSelections( const wxTreeCtrl*   pTree
+                       ,wxArrayTreeItemIds& raSelections
+                      )
+                      : wxTreeTraversal(pTree)
+                      , m_aSelections(raSelections)
+    {
+        m_aSelections.Empty();
+        DoTraverse(pTree->GetRootItem());
+    }
 
-    virtual bool OnVisit(const wxTreeItemId& item)
+    virtual bool OnVisit(const wxTreeItemId& rItem)
     {
-        if ( GetTree()->IsItemChecked(item) )
+        //
+        // Can't visit a virtual node.
+        //
+        if ((GetTree()->GetRootItem() == rItem) && (GetTree()->GetWindowStyle() & wxTR_HIDE_ROOT))
         {
-            m_selections.Add(item);
+            return true;
         }
-
-        return TRUE;
-    }
-
-private:
-    wxArrayTreeItemIds& m_selections;
-};
-
-// internal class for counting tree items
-class TraverseCounter : public wxTreeTraversal
-{
-public:
-    TraverseCounter(const wxTreeCtrl *tree,
-                    const wxTreeItemId& root,
-                    bool recursively)
-        : wxTreeTraversal(tree)
+        PMYRECORD                   pRecord = FindOS2TreeRecordByID( (HWND)GetTree()->GetHWND()
+                                                                    ,rItem.m_pItem
+                                                                   );
+        if (pRecord->m_vRecord.flRecordAttr & CRA_SELECTED)
         {
-            m_count = 0;
-
-            DoTraverse(root, recursively);
+            m_aSelections.Add(rItem);
         }
-
-    virtual bool OnVisit(const wxTreeItemId& item)
-    {
-        m_count++;
-
-        return TRUE;
+        return true;
     }
 
-    size_t GetCount() const { return m_count; }
+    size_t GetCount(void) const { return m_aSelections.GetCount(); }
 
 private:
-    size_t m_count;
-};
+    wxArrayTreeItemIds&             m_aSelections;
+}; // end of CLASS TraverseSelections
 
-// ----------------------------------------------------------------------------
-// This class is needed for support of different images: the Win32 common
-// control natively supports only 2 images (the normal one and another for the
-// selected state). We wish to provide support for 2 more of them for folder
-// items (i.e. those which have children): for expanded state and for expanded
-// selected state. For this we use this structure to store the additional items
-// images.
 //
-// There is only one problem with this: when we retrieve the item's data, we
-// don't know whether we get a pointer to wxTreeItemData or
-// wxTreeItemIndirectData. So we have to maintain a list of all items which
-// have indirect data inside the listctrl itself.
-// ----------------------------------------------------------------------------
-class wxTreeItemIndirectData
+// Internal class for counting tree items
+//
+class TraverseCounter : public wxTreeTraversal
 {
 public:
-    // ctor associates this data with the item and the real item data becomes
-    // available through our GetData() method
-    wxTreeItemIndirectData(wxTreeCtrl *tree, const wxTreeItemId& item)
+    TraverseCounter( const wxTreeCtrl*   pTree
+                    ,const wxTreeItemId& rRoot
+                    ,bool                bRecursively
+                   )
+                   : wxTreeTraversal(pTree)
     {
-        for ( size_t n = 0; n < WXSIZEOF(m_images); n++ )
-        {
-            m_images[n] = -1;
-        }
-
-        // save the old data
-        m_data = tree->GetItemData(item);
-
-        // and set ourselves as the new one
-        tree->SetIndirectItemData(item, this);
+        m_nCount = 0;
+        DoTraverse(rRoot, bRecursively);
     }
 
-    // dtor deletes the associated data as well
-    ~wxTreeItemIndirectData() { delete m_data; }
-
-    // accessors
-        // get the real data associated with the item
-    wxTreeItemData *GetData() const { return m_data; }
-        // change it
-    void SetData(wxTreeItemData *data) { m_data = data; }
+    virtual bool OnVisit(const wxTreeItemId& WXUNUSED(rItem))
+    {
+        m_nCount++;
+        return true;
+    }
 
-        // do we have such image?
-    bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; }
-        // get image
-    int GetImage(wxTreeItemIcon which) const { return m_images[which]; }
-        // change it
-    void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
+    size_t GetCount(void) const { return m_nCount; }
 
 private:
-    // all the images associated with the item
-    int m_images[wxTreeItemIcon_Max];
-
-    wxTreeItemData *m_data;
-};
+    size_t                          m_nCount;
+}; // end of CLASS TraverseCounter
 
 // ----------------------------------------------------------------------------
-// macros
+// wxWin macros
 // ----------------------------------------------------------------------------
 
-#if !USE_SHARED_LIBRARY
-    IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
-#endif
+IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
 
 // ----------------------------------------------------------------------------
-// variables
+// constants
 // ----------------------------------------------------------------------------
 
-// handy table for sending events
-static const wxEventType g_events[2][2] =
+// indices in gs_expandEvents table below
+enum
+{
+    IDX_COLLAPSE,
+    IDX_EXPAND,
+    IDX_WHAT_MAX
+};
+
+enum
+{
+    IDX_DONE,
+    IDX_DOING,
+    IDX_HOW_MAX
+};
+
+// handy table for sending events - it has to be initialized during run-time
+// now so can't be const any more
+static /* const */ wxEventType gs_expandEvents[IDX_WHAT_MAX][IDX_HOW_MAX];
+
+/*
+   but logically it's a const table with the following entries:
+=
 {
     { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
     { wxEVT_COMMAND_TREE_ITEM_EXPANDED,  wxEVT_COMMAND_TREE_ITEM_EXPANDING  }
 };
+*/
 
 // ============================================================================
 // implementation
@@ -211,1479 +300,1773 @@ static const wxEventType g_events[2][2] =
 // tree traversal
 // ----------------------------------------------------------------------------
 
-bool wxTreeTraversal::DoTraverse(const wxTreeItemId& root, bool recursively)
-{
-    if ( !OnVisit(root) )
-        return FALSE;
-
-    return Traverse(root, recursively);
-}
-
-bool wxTreeTraversal::Traverse(const wxTreeItemId& root, bool recursively)
-{
-    long cookie;
-    wxTreeItemId child = m_tree->GetFirstChild(root, cookie);
-    while ( child.IsOk() )
+bool wxTreeTraversal::DoTraverse (
+  const wxTreeItemId&               rRoot
+, bool                              bRecursively
+)
+{
+    if (!OnVisit(rRoot))
+        return false;
+
+    return Traverse( rRoot
+                    ,bRecursively
+                   );
+} // end of wxTreeTraversal::DoTraverse
+
+bool wxTreeTraversal::Traverse (
+  const wxTreeItemId&               rRoot
+, bool                              bRecursively
+)
+{
+    long                            lCookie;
+    wxTreeItemId                    vChild = m_pTree->GetFirstChild( rRoot
+                                                                    ,lCookie
+                                                                   );
+    while (vChild.IsOk())
     {
-        // depth first traversal
-        if ( recursively && !Traverse(child, TRUE) )
-            return FALSE;
-
-        if ( !OnVisit(child) )
-            return FALSE;
-
-        child = m_tree->GetNextChild(root, cookie);
+        //
+        // Depth first traversal
+        //
+        if (bRecursively && !Traverse(vChild, true))
+            return false;
+        if (!OnVisit(vChild))
+            return false;
+        vChild = m_pTree->GetNextChild( rRoot
+                                       ,lCookie
+                                      );
     }
-
-    return TRUE;
-}
+    return true;
+} // end of wxTreeTraversal::Traverse
 
 // ----------------------------------------------------------------------------
 // construction and destruction
 // ----------------------------------------------------------------------------
 
-void wxTreeCtrl::Init()
-{
-    m_imageListNormal = NULL;
-    m_imageListState = NULL;
-    m_textCtrl = NULL;
-}
+void wxTreeCtrl::Init ()
+{
+    m_pImageListNormal     = NULL;
+    m_pImageListState      = NULL;
+    m_bOwnsImageListNormal = false;
+    m_bOwnsImageListState  = false;
+    m_bHasAnyAttr          = false;
+    m_pDragImage           = NULL;
+
+    //
+    // Initialize the global array of events now as it can't be done statically
+    // with the wxEVT_XXX values being allocated during run-time only
+    //
+    gs_expandEvents[IDX_COLLAPSE][IDX_DONE]  = wxEVT_COMMAND_TREE_ITEM_COLLAPSED;
+    gs_expandEvents[IDX_COLLAPSE][IDX_DOING] = wxEVT_COMMAND_TREE_ITEM_COLLAPSING;
+    gs_expandEvents[IDX_EXPAND][IDX_DONE]    = wxEVT_COMMAND_TREE_ITEM_EXPANDED;
+    gs_expandEvents[IDX_EXPAND][IDX_DOING]   = wxEVT_COMMAND_TREE_ITEM_EXPANDING;
+} // end of wxTreeCtrl::Init
+
+bool wxTreeCtrl::Create (
+  wxWindow*                         pParent
+, wxWindowID                        vId
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+, long                              lStyle
+, const wxValidator&                rValidator
+, const wxString&                   rsName
+)
+{
+    CNRINFO                         vCnrInfo;
 
-bool wxTreeCtrl::Create(wxWindow *parent,
-                        wxWindowID id,
-                        const wxPoint& pos,
-                        const wxSize& size,
-                        long style,
-                        const wxValidator& validator,
-                        const wxString& name)
-{
     Init();
+    if (!CreateControl( pParent
+                       ,vId
+                       ,rPos
+                       ,rSize
+                       ,lStyle
+                       ,rValidator
+                       ,rsName
+                      ))
+        return false;
 
-    if ( !CreateControl(parent, id, pos, size, style, validator, name) )
-        return FALSE;
-// TODO:
-/*
-    DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
-                   TVS_HASLINES | TVS_SHOWSELALWAYS;
-
-    if ( m_windowStyle & wxTR_HAS_BUTTONS )
-        wstyle |= TVS_HASBUTTONS;
-
-    if ( m_windowStyle & wxTR_EDIT_LABELS )
-        wstyle |= TVS_EDITLABELS;
+    DWORD                           dwStyle = WS_VISIBLE | WS_TABSTOP;
 
-    if ( m_windowStyle & wxTR_LINES_AT_ROOT )
-        wstyle |= TVS_LINESATROOT;
-
-    if ( m_windowStyle & wxTR_MULTIPLE )
-        wstyle |= TVS_CHECKBOXES;
+    if (m_windowStyle & wxCLIP_SIBLINGS)
+        dwStyle |= WS_CLIPSIBLINGS;
 
     // Create the tree control.
-    if ( !OS2CreateControl(WC_TREEVIEW, wstyle) )
-        return FALSE;
-*/
-    SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
+    if (!OS2CreateControl( "CONTAINER"
+                          ,dwStyle
+                         ))
+        return false;
+
+    //
+    // Now set the display attributes to show a TREE/ICON view of the
+    // OS/2 Container
+    //
+    if (!::WinSendMsg( GetHWND()
+                      ,CM_QUERYCNRINFO
+                      ,MPFROMP(&vCnrInfo)
+                      ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                     ))
+
+    vCnrInfo.flWindowAttr = CV_TREE|CV_ICON;
+    vCnrInfo.flWindowAttr |= CA_DRAWBITMAP;
+    if (m_windowStyle & wxTR_NO_LINES)
+        vCnrInfo.flWindowAttr |= CA_TREELINE;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_SETCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)CMA_FLWINDOWATTR
+                );
+
+    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
     SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
-
-    // VZ: this is some experimental code which may be used to get the
-    //     TVS_CHECKBOXES style functionality for comctl32.dll < 4.71.
-    //     AFAIK, the standard DLL does about the same thing anyhow.
-#if 0
-    if ( m_windowStyle & wxTR_MULTIPLE )
+    SetFont(*wxSMALL_FONT);
+    SetXComp(0);
+    SetYComp(0);
+    SetSize( rPos.x
+            ,rPos.y
+            ,rSize.x
+            ,rSize.y
+           );
+    return true;
+} // end of wxTreeCtrl::Create
+
+wxTreeCtrl::~wxTreeCtrl ()
+{
+    //
+    // Delete any attributes
+    //
+    if (m_bHasAnyAttr)
     {
-        wxBitmap bmp;
-
-        // create the DC compatible with the current screen
-        HDC hdcMem = CreateCompatibleDC(NULL);
-
-        // create a mono bitmap of the standard size
-        int x = GetSystemMetrics(SM_CXMENUCHECK);
-        int y = GetSystemMetrics(SM_CYMENUCHECK);
-        wxImageList imagelistCheckboxes(x, y, FALSE, 2);
-        HBITMAP hbmpCheck = CreateBitmap(x, y,   // bitmap size
-                                         1,      // # of color planes
-                                         1,      // # bits needed for one pixel
-                                         0);     // array containing colour data
-        SelectObject(hdcMem, hbmpCheck);
-
-        // then draw a check mark into it
-        RECT rect = { 0, 0, x, y };
-        if ( !::DrawFrameControl(hdcMem, &rect,
-                                 DFC_BUTTON,
-                                 DFCS_BUTTONCHECK | DFCS_CHECKED) )
-        {
-            wxLogLastError(wxT("DrawFrameControl(check)"));
-        }
-
-        bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
-        imagelistCheckboxes.Add(bmp);
-
-        if ( !::DrawFrameControl(hdcMem, &rect,
-                                 DFC_BUTTON,
-                                 DFCS_BUTTONCHECK) )
+        for (wxNode* pNode = m_vAttrs.Next(); pNode; pNode = m_vAttrs.Next())
         {
-            wxLogLastError(wxT("DrawFrameControl(uncheck)"));
+            delete (wxTreeItemAttr *)pNode->Data();
         }
-
-        bmp.SetHBITMAP((WXHBITMAP)hbmpCheck);
-        imagelistCheckboxes.Add(bmp);
-
-        // clean up
-        ::DeleteDC(hdcMem);
-
-        // set the imagelist
-        SetStateImageList(&imagelistCheckboxes);
+        m_bHasAnyAttr = false;
     }
-#endif // 0
-
-    SetSize(pos.x, pos.y, size.x, size.y);
-
-    return TRUE;
-}
-
-wxTreeCtrl::~wxTreeCtrl()
-{
     DeleteTextCtrl();
 
-    // delete user data to prevent memory leaks
-//    DeleteAllItems();
-}
+    //
+    // Delete user data to prevent memory leaks
+    // also deletes hidden root node storage.
+    //
+    DeleteAllItems();
+    if (m_bOwnsImageListNormal)
+        delete m_pImageListNormal;
+    if (m_bOwnsImageListState)
+        delete m_pImageListState;
+} // end of wxTreeCtrl::~wxTreeCtrl
 
 // ----------------------------------------------------------------------------
 // accessors
 // ----------------------------------------------------------------------------
 
-// simple wrappers which add error checking in debug mode
-
-bool wxTreeCtrl::DoGetItem(wxTreeViewItem* tvItem) const
+//
+// simple wrappers which add error checking in debug mode.  These methods
+// assume the items are properly filled out already.  If not, you get errors
+//
+bool wxTreeCtrl::DoGetItem (
+  wxTreeViewItem*                   pTvItem
+) const
 {
-// TODO:
-/*
-    if ( !TreeView_GetItem(GetHwnd(), tvItem) )
-    {
-        wxLogLastError("TreeView_GetItem");
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID( GetHWND()
+                                                                    ,pTvItem->m_ulItemId
+                                                                   );
 
-        return FALSE;
+    if (!pRecord)
+    {
+        wxLogLastError(wxT("Item not obtained"));
+        return false;
     }
-*/
-    return TRUE;
-}
-
-void wxTreeCtrl::DoSetItem(wxTreeViewItem* tvItem)
-{
-// TODO:
-/*
-    if ( TreeView_SetItem(GetHwnd(), tvItem) == -1 )
+    return true;
+} // end of wxTreeCtrl::DoGetItem
+
+void wxTreeCtrl::DoSetItem (
+  wxTreeViewItem*                   pTvItem
+)
+{
+    //
+    // Just invalidate the record to redisplay it
+    //
+    if (!::WinSendMsg( GetHWND()
+                      ,CM_INVALIDATERECORD
+                      ,MPFROMP(pTvItem)
+                      ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
+                     ));
     {
-        wxLogLastError("TreeView_SetItem");
+        wxLogLastError(wxT("CM_INVALIDATERECORD"));
     }
-*/
-}
+} // end of wxTreeCtrl::DoSetItem
 
-size_t wxTreeCtrl::GetCount() const
+unsigned int wxTreeCtrl::GetCount () const
 {
-//    return (size_t)TreeView_GetCount(GetHwnd());
-    return 0;
-}
+    CNRINFO  vCnrInfo;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+
+    return (unsigned int)vCnrInfo.cRecords;
+} // end of wxTreeCtrl::GetCount
 
-unsigned int wxTreeCtrl::GetIndent() const
+unsigned int wxTreeCtrl::GetIndent () const
 {
-//    return TreeView_GetIndent(GetHwnd());
-    return 0;
-}
+    CNRINFO                         vCnrInfo;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+    return (unsigned int)vCnrInfo.cxTreeIndent;
+} // end of wxTreeCtrl::GetIndent
 
-void wxTreeCtrl::SetIndent(unsigned int indent)
+void wxTreeCtrl::SetIndent (
+  unsigned int                  uIndent
+)
 {
-//    TreeView_SetIndent(GetHwnd(), indent);
-}
+    CNRINFO                         vCnrInfo;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+    vCnrInfo.cxTreeIndent = (LONG)uIndent;
+    ::WinSendMsg( GetHWND()
+                 ,CM_SETCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)CMA_CXTREEINDENT
+                );
+} // end of wxTreeCtrl::SetIndent
 
-wxImageList *wxTreeCtrl::GetImageList() const
+wxImageList* wxTreeCtrl::GetImageList () const
 {
-    return m_imageListNormal;
-}
+    return m_pImageListNormal;
+} // end of wxTreeCtrl::GetImageList
 
-wxImageList *wxTreeCtrl::GetStateImageList() const
+wxImageList* wxTreeCtrl::GetStateImageList () const
 {
-    return m_imageListNormal;
-}
+    return m_pImageListNormal;
+} // end of wxTreeCtrl::GetStateImageList
+
+//
+// The SETS of imagelists really do nothing under OS2 as a RECORDCORE
+// struct has the icon imbedded in it that it uses for the icon being
+// displayed via the TREEITEMDESC member.  Provided for interface
+// compatibility only
+//
+void wxTreeCtrl::SetAnyImageList (
+  wxImageList*                      WXUNUSED(pImageList)
+, int                               WXUNUSED(nWhich)
+)
+{
+} // end of wxTreeCtrl::SetAnyImageList
 
-void wxTreeCtrl::SetAnyImageList(wxImageList *imageList, int which)
+void wxTreeCtrl::SetImageList (
+  wxImageList*                      WXUNUSED(pImageList)
+)
 {
-    // no error return
-// TODO:
-/*
-    TreeView_SetImageList(GetHwnd(),
-                          imageList ? imageList->GetHIMAGELIST() : 0,
-                          which);
-*/
-}
+    if (m_bOwnsImageListNormal)
+        delete m_pImageListNormal;
+    m_bOwnsImageListNormal = false;
+} // end of wxTreeCtrl::SetImageList
 
-void wxTreeCtrl::SetImageList(wxImageList *imageList)
+void wxTreeCtrl::SetStateImageList (
+  wxImageList*                      WXUNUSED(pImageList)
+)
 {
-//    SetAnyImageList(m_imageListNormal = imageList, TVSIL_NORMAL);
-}
+    if (m_bOwnsImageListState)
+        delete m_pImageListState;
+    m_bOwnsImageListState = false;
+} // end of wxTreeCtrl::SetStateImageList
 
-void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
+void wxTreeCtrl::AssignImageList (
+  wxImageList*                      WXUNUSED(pImageList)
+)
 {
-//    SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
-}
+    m_bOwnsImageListNormal = true;
+} // end of wxTreeCtrl::AssignImageList
 
-size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
-                                    bool recursively) const
+void wxTreeCtrl::AssignStateImageList (
+  wxImageList*                      WXUNUSED(pImageList)
+)
 {
-    TraverseCounter counter(this, item, recursively);
+    m_bOwnsImageListState = true;
+} // end of wxTreeCtrl::AssignStateImageList
 
-    return counter.GetCount() - 1;
-}
+size_t wxTreeCtrl::GetChildrenCount (
+  const wxTreeItemId&               rItem
+, bool                              bRecursively
+) const
+{
+    TraverseCounter                 vCounter( this
+                                             ,rItem
+                                             ,bRecursively
+                                            );
+    return vCounter.GetCount() - 1;
+} // end of wxTreeCtrl::GetChildrenCount
+
+// ----------------------------------------------------------------------------
+// control colours
+// ----------------------------------------------------------------------------
+
+bool wxTreeCtrl::SetBackgroundColour (
+  const wxColour&                   rColour
+)
+{
+    ULONG                           ulColor = wxColourToRGB(rColour);
+
+    if ( !wxWindowBase::SetBackgroundColour(rColour) )
+        return false;
+    ::WinSetPresParam( GetHWND()
+                      ,PP_BACKGROUNDCOLOR
+                      ,sizeof(ULONG)
+                      ,&ulColor
+                     );
+    return true;
+} // end of wxTreeCtrl::SetBackgroundColour
+
+bool wxTreeCtrl::SetForegroundColour (
+  const wxColour&                   rColour
+)
+{
+    ULONG                           ulColor = wxColourToRGB(rColour);
+
+    if (!wxWindowBase::SetForegroundColour(rColour))
+        return false;
+    ::WinSetPresParam( GetHWND()
+                      ,PP_FOREGROUNDCOLOR
+                      ,sizeof(ULONG)
+                      ,&ulColor
+                     );
+    return true;
+} // end of wxTreeCtrl::SetForegroundColour
 
 // ----------------------------------------------------------------------------
 // Item access
 // ----------------------------------------------------------------------------
 
-wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const
+wxString wxTreeCtrl::GetItemText (
+  const wxTreeItemId&               rItem
+) const
 {
-    wxChar buf[512];  // the size is arbitrary...
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_TEXT);
-    tvItem.pszText = buf;
-    tvItem.cchTextMax = WXSIZEOF(buf);
-    if ( !DoGetItem(&tvItem) )
+    wxChar                          zBuf[512];  // the size is arbitrary...
+    wxTreeViewItem                  vTvItem(rItem);
+
+    if (!DoGetItem(&vTvItem))
     {
-        // don't return some garbage which was on stack, but an empty string
-        buf[0] = wxT('\0');
+        //
+        // Don't return some garbage which was on stack, but an empty string
+        //
+        zBuf[0] = wxT('\0');
     }
-*/
-    return wxString(buf);
-}
+    else
+        strcpy(zBuf, vTvItem.m_vRecord.pszTree);
+    return wxString(zBuf);
+} // end of wxTreeCtrl::GetItemText
 
-void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
+void wxTreeCtrl::SetItemText (
+  const wxTreeItemId&               rItem
+, const wxString&                   rsText
+)
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_TEXT);
-    tvItem.pszText = (wxChar *)text.c_str();  // conversion is ok
-    DoSetItem(&tvItem);
-*/
-}
+    wxTreeViewItem                  vTvItem(rItem);
 
-int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item,
-                                       wxTreeItemIcon which) const
-{
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_PARAM);
-    if ( !DoGetItem(&tvItem) )
-    {
-        return -1;
-    }
-    return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which);
-*/
-    return -1;
-}
+    vTvItem.m_vRecord.pszTree = (wxChar *)rsText.c_str();  // conversion is ok
+    DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemText
 
-void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
-                                        int image,
-                                        wxTreeItemIcon which) const
-{
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_PARAM);
-    if ( !DoGetItem(&tvItem) )
+//
+// These functions under OS/2 PM are not needed.  OS/2 containers in tree view
+// provide for storing a custom expanded and collapsed icons and selected
+// and non selected icons, natively.  For instance, by default, a disk display
+// will display a tree list of folder icons with "+" icons (collapsed) beside
+// those folder which contain child members.  Double clicking a folder changes
+// the closed folder icon to an open folder icon with hatched selection
+// highlighting indicating an ICON view container of the folder is open
+// elsewhere on the desktop.  So the below is not really needed, but we will
+// simply return the appropriate icon requested out of OS/2's native PM
+// data structures.
+//
+int wxTreeCtrl::DoGetItemImageFromData (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, wxTreeItemIcon                    nWhich
+) const
+{
+    //
+    // Image handles stored in CNRINFO.
+    //
+    CNRINFO                         vCnrInfo;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+
+    //
+    // We really only have two to chose from.  If not custom (set in CNRINFO
+    // then return the handle to system bitmap).  OS/2 automatically provides
+    // in_use and selected bitmaps/icons
+    //
+    switch(nWhich)
     {
-        return;
-    }
-
-    wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam);
+        case wxTreeItemIcon_Normal:
+            if (vCnrInfo.hbmCollapsed == NULLHANDLE)
+                return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
+            return vCnrInfo.hbmCollapsed;
 
-    data->SetImage(image, which);
 
-    // make sure that we have selected images as well
-    if ( which == wxTreeItemIcon_Normal &&
-         !data->HasImage(wxTreeItemIcon_Selected) )
-    {
-        data->SetImage(image, wxTreeItemIcon_Selected);
-    }
+        case wxTreeItemIcon_Expanded:
+            if (vCnrInfo.hbmExpanded == NULLHANDLE)
+                return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
+            return vCnrInfo.hbmExpanded;
 
-    if ( which == wxTreeItemIcon_Expanded &&
-         !data->HasImage(wxTreeItemIcon_SelectedExpanded) )
-    {
-        data->SetImage(image, wxTreeItemIcon_SelectedExpanded);
+        default:
+            return vCnrInfo.hbmCollapsed;
     }
-*/
 }
 
-void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
-                                 int image,
-                                 int imageSel)
-{
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_IMAGE | TVIF_SELECTEDIMAGE);
-    tvItem.iSelectedImage = imageSel;
-    tvItem.iImage = image;
-    DoSetItem(&tvItem);
-*/
-}
-
-int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
-                             wxTreeItemIcon which) const
-{
-    if ( HasIndirectData(item) )
+void wxTreeCtrl::DoSetItemImageFromData (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, int                               nImage
+, wxTreeItemIcon                    nWhich
+) const
+{
+    //
+    // Image handles stored in CNRINFO.
+    //
+    CNRINFO                         vCnrInfo;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+    if (nWhich == wxTreeItemIcon_Normal)
+         vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
+    if (nWhich == wxTreeItemIcon_Expanded)
+        vCnrInfo.hbmExpanded = (HBITMAP)nImage;
+    ::WinSendMsg( GetHWND()
+                 ,CM_SETCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)CMA_TREEBITMAP
+                );
+} // end of wxTreeCtrl::DoSetItemImageFromData
+
+// Useless for OS/2
+void wxTreeCtrl::DoSetItemImages (
+  const wxTreeItemId&               rItem
+, int                               nImage
+, int                               nImageSel
+)
+{
+} // end of wxTreeCtrl::DoSetItemImages
+
+int wxTreeCtrl::GetItemImage (
+  const wxTreeItemId&               rItem
+, wxTreeItemIcon                    nWhich
+) const
+{
+    if (HasIndirectData(rItem))
     {
-        return DoGetItemImageFromData(item, which);
+        return DoGetItemImageFromData( rItem
+                                      ,nWhich
+                                     );
     }
 
-    UINT mask;
-    switch ( which )
+    CNRINFO                         vCnrInfo;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+    switch (nWhich)
     {
         default:
             wxFAIL_MSG( wxT("unknown tree item image type") );
 
         case wxTreeItemIcon_Normal:
-//            mask = TVIF_IMAGE;
-            break;
+            if (vCnrInfo.hbmCollapsed == NULLHANDLE)
+                return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
+            return vCnrInfo.hbmCollapsed;
 
-        case wxTreeItemIcon_Selected:
-//            mask = TVIF_SELECTEDIMAGE;
-            break;
 
         case wxTreeItemIcon_Expanded:
+            if (vCnrInfo.hbmExpanded == NULLHANDLE)
+                return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
+            return vCnrInfo.hbmExpanded;
+
+        case wxTreeItemIcon_Selected:
         case wxTreeItemIcon_SelectedExpanded:
             return -1;
     }
-
-    wxTreeViewItem tvItem(item, mask);
-    DoGetItem(&tvItem);
-
-//    return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
-    return FALSE;
 }
 
-void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
-                              wxTreeItemIcon which)
+void wxTreeCtrl::SetItemImage (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, int                               nImage
+, wxTreeItemIcon                    nWhich
+)
 {
-    int imageNormal, imageSel;
-    switch ( which )
-    {
-        default:
-            wxFAIL_MSG( wxT("unknown tree item image type") );
+    CNRINFO                         vCnrInfo;
 
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)(USHORT)sizeof(CNRINFO)
+                );
+    switch (nWhich)
+    {
         case wxTreeItemIcon_Normal:
-            imageNormal = image;
-            imageSel = GetItemSelectedImage(item);
-            break;
-
-        case wxTreeItemIcon_Selected:
-            imageNormal = GetItemImage(item);
-            imageSel = image;
+            vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
             break;
 
         case wxTreeItemIcon_Expanded:
-        case wxTreeItemIcon_SelectedExpanded:
-            if ( !HasIndirectData(item) )
-            {
-                // we need to get the old images first, because after we create
-                // the wxTreeItemIndirectData GetItemXXXImage() will use it to
-                // get the images
-                imageNormal = GetItemImage(item);
-                imageSel = GetItemSelectedImage(item);
-
-                // if it doesn't have it yet, add it
-                wxTreeItemIndirectData *data = new
-                    wxTreeItemIndirectData(this, item);
-
-                // copy the data to the new location
-                data->SetImage(imageNormal, wxTreeItemIcon_Normal);
-                data->SetImage(imageSel, wxTreeItemIcon_Selected);
-            }
-
-            DoSetItemImageFromData(item, image, which);
-
-            // reset the normal/selected images because we won't use them any
-            // more - now they're stored inside the indirect data
-//            imageSel = I_IMAGECALLBACK;
+            vCnrInfo.hbmExpanded = (HBITMAP)nImage;
             break;
-    }
 
-    // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
-    //     change both normal and selected image - otherwise the change simply
-    //     doesn't take place!
-    DoSetItemImages(item, imageNormal, imageSel);
-}
+        default:
+            wxFAIL_MSG( wxT("unknown tree item image type") );
+    }
+    ::WinSendMsg( GetHWND()
+                 ,CM_SETCNRINFO
+                 ,MPFROMP(&vCnrInfo)
+                 ,(MPARAM)CMA_TREEBITMAP
+                );
+} // end of wxTreeCtrl::SetItemImage
 
-wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
+wxTreeItemData* wxTreeCtrl::GetItemData (
+  const wxTreeItemId&               rItem
+) const
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_PARAM);
-    if ( !DoGetItem(&tvItem) )
+    wxTreeViewItem                  vTvItem(rItem);
+
+    if (!DoGetItem(&vTvItem))
     {
         return NULL;
     }
 
-    if ( HasIndirectData(item) )
-    {
-        return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData();
-    }
-    else
-    {
-        return (wxTreeItemData *)tvItem.lParam;
-    }
-*/
-    return 0;
-}
+    return (wxTreeItemData *)vTvItem.m_ulUserData;
+} // end of wxTreeCtrl::GetItemData
 
-void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
+void wxTreeCtrl::SetItemData (
+  const wxTreeItemId&               rItem
+, wxTreeItemData*                   pData
+)
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_PARAM);
-
-    if ( HasIndirectData(item) )
-    {
-        if ( DoGetItem(&tvItem) )
-        {
-            ((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data);
-        }
-        else
-        {
-            wxFAIL_MSG( wxT("failed to change tree items data") );
-        }
-    }
-    else
+    //
+    // first, associate this piece of data with this item
+    if (pData)
     {
-        tvItem.lParam = (MPARAM)data;
-        DoSetItem(&tvItem);
+        pData->SetId(rItem);
     }
-*/
-}
 
-void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
-                                     wxTreeItemIndirectData *data)
-{
-    // this should never happen because it's unnecessary and will probably lead
-    // to crash too because the code elsewhere supposes that the pointer the
-    // wxTreeItemIndirectData has is a real wxItemData and not
-    // wxTreeItemIndirectData as well
-    wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
+    wxTreeViewItem                  vTvItem(rItem);
 
-    SetItemData(item, (wxTreeItemData *)data);
+    vTvItem.m_ulUserData = (ULONG)pData;
+    DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemData
 
-    m_itemsWithIndirectData.Add(item);
-}
+// The following two do nothing under OS/2
+void wxTreeCtrl::SetIndirectItemData (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, wxTreeItemIndirectData*           WXUNUSED(pData)
+)
+{
+} // end of wxTreeCtrl::SetIndirectItemData
 
-bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
+bool wxTreeCtrl::HasIndirectData (
+  const wxTreeItemId&               WXUNUSED(rItem)
+) const
 {
-    return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND;
-}
+    return false;
+} // end of wxTreeCtrl::HasIndirectData
 
-void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
+// Irreleveant under OS/2 --- item either has child records or it doesn't.
+void wxTreeCtrl::SetItemHasChildren (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, bool                              WXUNUSED(bHas)
+)
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_CHILDREN);
-    tvItem.cChildren = (int)has;
-    DoSetItem(&tvItem);
-*/
-}
+} // end of wxTreeCtrl::SetItemHasChildren
 
-void wxTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
+// Irreleveant under OS/2 --- function of the font in PM
+void wxTreeCtrl::SetItemBold (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, bool                              WXUNUSED(bBold)
+)
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
-    tvItem.state = bold ? TVIS_BOLD : 0;
-    DoSetItem(&tvItem);
-*/
-}
+} // end of wxTreeCtrl::SetItemBold
 
-void wxTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, bool highlight)
+void wxTreeCtrl::SetItemDropHighlight (
+  const wxTreeItemId&               rItem
+, bool                              bHighlight
+)
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_DROPHILITED);
-    tvItem.state = highlight ? TVIS_DROPHILITED : 0;
-    DoSetItem(&tvItem);
-*/
-}
+    wxTreeViewItem                  vTvItem(rItem);
 
-// ----------------------------------------------------------------------------
-// Item status
-// ----------------------------------------------------------------------------
+    ::WinSendMsg( GetHWND()
+                 ,CM_SETRECORDEMPHASIS
+                 ,MPFROMP(&vTvItem)
+                 ,MPFROM2SHORT(bHighlight, CRA_SELECTED)
+                );
+    DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemDropHighlight
 
-bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const
+void wxTreeCtrl::RefreshItem (
+  const wxTreeItemId&               rItem
+)
 {
-    // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
-// TODO:
-/*
-    RECT rect;
-    return SendMessage(GetHwnd(), TVM_GETITEMRECT, FALSE, (LPARAM)&rect) != 0;
-*/
-    return FALSE;
-}
+    wxTreeViewItem                  vTvItem(rItem);
 
-bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const
+    //
+    // This just does a record invalidate causing it to be re-displayed
+    //
+    DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::RefreshItem
+
+wxColour wxTreeCtrl::GetItemTextColour (
+  const wxTreeItemId&               rItem
+) const
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_CHILDREN);
-    DoGetItem(&tvItem);
+    long                            lId = (long)rItem.m_pItem;
+    wxTreeItemAttr*                 pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
 
-    return tvItem.cChildren != 0;
-*/
-    return FALSE;
-}
+    if (!pAttr)
+    {
+        return wxNullColour;
+    }
+    return pAttr->GetTextColour();
+} // end of wxTreeCtrl::GetItemTextColour
 
-bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const
+wxColour wxTreeCtrl::GetItemBackgroundColour (
+  const wxTreeItemId&               rItem
+) const
 {
-    // probably not a good idea to put it here
-    //wxASSERT( ItemHasChildren(item) );
+    long                            lId = (long)rItem.m_pItem;
+    wxTreeItemAttr*                 pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
 
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDED);
-    DoGetItem(&tvItem);
-
-    return (tvItem.state & TVIS_EXPANDED) != 0;
-*/
-    return FALSE;
-}
+    if (!pAttr)
+    {
+        return wxNullColour;
+    }
+    return pAttr->GetBackgroundColour();
+} // end of wxTreeCtrl::GetItemBackgroundColour
 
-bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const
+wxFont wxTreeCtrl::GetItemFont (
+  const wxTreeItemId&               rItem
+) const
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_SELECTED);
-    DoGetItem(&tvItem);
+    long                            lId = (long)rItem.m_pItem;
+    wxTreeItemAttr*                 pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
 
-    return (tvItem.state & TVIS_SELECTED) != 0;
-*/
-    return FALSE;
-}
+    if (!pAttr)
+    {
+        return wxNullFont;
+    }
+    return pAttr->GetFont();
+} // end of wxTreeCtrl::GetItemFont
 
-bool wxTreeCtrl::IsBold(const wxTreeItemId& item) const
+void wxTreeCtrl::SetItemTextColour (
+  const wxTreeItemId&               rItem
+, const wxColour&                   rCol
+)
 {
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_BOLD);
-    DoGetItem(&tvItem);
+    m_bHasAnyAttr = true;
 
-    return (tvItem.state & TVIS_BOLD) != 0;
-*/
-    return FALSE;
-}
+    long                            lId = (long)rItem.m_pItem;
+    wxTreeItemAttr*                 pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
 
-// ----------------------------------------------------------------------------
-// navigation
-// ----------------------------------------------------------------------------
+    if (!pAttr)
+    {
+        pAttr = new wxTreeItemAttr;
+        m_vAttrs.Put(lId, (wxObject *)pAttr);
+    }
+    pAttr->SetTextColour(rCol);
+    RefreshItem(rItem);
+} // end of wxTreeCtrl::SetItemTextColour
 
-wxTreeItemId wxTreeCtrl::GetRootItem() const
+void wxTreeCtrl::SetItemBackgroundColour (
+  const wxTreeItemId&               rItem
+, const wxColour&                   rCol
+)
 {
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetRoot(GetHwnd()));
-    return 0;
-}
+    m_bHasAnyAttr = true;
 
-wxTreeItemId wxTreeCtrl::GetSelection() const
-{
-    wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (WXHTREEITEM)0,
-                 wxT("this only works with single selection controls") );
+    long                            lId = (long)rItem.m_pItem;
+    wxTreeItemAttr*                 pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
 
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetSelection(GetHwnd()));
-    return 0;
-}
+    if (!pAttr)
+    {
+        pAttr = new wxTreeItemAttr;
+        m_vAttrs.Put(lId, (wxObject *)pAttr);
+    }
+    pAttr->SetBackgroundColour(rCol);
+    RefreshItem(rItem);
+} // end of wxTreeCtrl::SetItemBackgroundColour
 
-wxTreeItemId wxTreeCtrl::GetParent(const wxTreeItemId& item) const
+void wxTreeCtrl::SetItemFont (
+  const wxTreeItemId&               rItem
+, const wxFont&                     rFont
+)
 {
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetParent(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
-    return 0;
-}
+    m_bHasAnyAttr = true;
 
-wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item,
-                                       long& _cookie) const
-{
-// TODO:
-/*
-    // remember the last child returned in 'cookie'
-    _cookie = (long)TreeView_GetChild(GetHwnd(), (HTREEITEM) (WXHTREEITEM)item);
+    long                            lId = (long)rItem.m_pItem;
+    wxTreeItemAttr*                 pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
 
-    return wxTreeItemId((WXHTREEITEM)_cookie);
-*/
-    return 0;
-}
+    if (!pAttr)
+    {
+        pAttr = new wxTreeItemAttr;
+        m_vAttrs.Put(lId, (wxObject *)pAttr);
+    }
+    pAttr->SetFont(rFont);
+    RefreshItem(rItem);
+} // end of wxTreeCtrl::SetItemFont
 
-wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
-                                      long& _cookie) const
+// ----------------------------------------------------------------------------
+// Item status
+// ----------------------------------------------------------------------------
+
+bool wxTreeCtrl::IsVisible (
+  const wxTreeItemId&               rItem
+) const
 {
-    wxTreeItemId l = 0; //wxTreeItemId((WXHTREEITEM)TreeView_GetNextSibling(GetHwnd(),
-//                                   (HTREEITEM)(WXHTREEITEM)_cookie));
-    _cookie = (long)l;
+    // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
+    RECTL                           vRectRecord;
+    RECTL                           vRectContainer;
+    wxRect                          vWxRectRecord;
+    wxRect                          vWxRectContainer;
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+    QUERYRECORDRECT                 vQuery;
+
+    vQuery.cb                = sizeof(QUERYRECORDRECT);
+    vQuery.pRecord           = (PRECORDCORE)pRecord;
+    vQuery.fRightSplitWindow = FALSE;
+    vQuery.fsExtent          = CMA_TREEICON;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYVIEWPORTRECT
+                 ,MPFROMP(&vRectContainer)
+                 ,MPFROM2SHORT(CMA_WINDOW, FALSE)
+                );
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYRECORDRECT
+                 ,MPFROMP(&vRectRecord)
+                 ,MPFROMP(&vQuery)
+                );
+    vWxRectRecord.SetLeft(vRectRecord.xLeft);
+    vWxRectRecord.SetTop(vRectRecord.yTop);
+    vWxRectRecord.SetRight(vRectRecord.xRight);
+    vWxRectRecord.SetBottom(vRectRecord.yBottom);
+
+    vWxRectContainer.SetLeft(vRectContainer.xLeft);
+    vWxRectContainer.SetTop(vRectContainer.yTop);
+    vWxRectContainer.SetRight(vRectContainer.xRight);
+    vWxRectContainer.SetBottom(vRectContainer.yBottom);
+    return (vWxRectContainer.Contains(wxPoint(vWxRectRecord.x, vWxRectRecord.y)));
+} // end of wxTreeCtrl::IsVisible
+
+bool wxTreeCtrl::ItemHasChildren (
+  const wxTreeItemId&               rItem
+) const
+{
+    wxTreeViewItem                  vTvItem(rItem);
+    DoGetItem(&vTvItem);
+
+    //
+    // A tree record with children will have one of these attributes
+    //
+    return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED ||
+            vTvItem.m_vRecord.flRecordAttr & CRA_COLLAPSED) != 0;
+}
+
+bool wxTreeCtrl::IsExpanded (
+  const wxTreeItemId&               rItem
+) const
+{
+    wxTreeViewItem                  vTvItem(rItem);
+    DoGetItem(&vTvItem);
+
+    return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED) != 0;
+} // end of wxTreeCtrl::IsExpanded
+
+bool wxTreeCtrl::IsSelected (
+  const wxTreeItemId&               rItem
+) const
+{
+    wxTreeViewItem                  vTvItem(rItem);
+    DoGetItem(&vTvItem);
+
+    return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED) != 0;
+} // end of wxTreeCtrl::IsSelected
+
+// Not supported
+bool wxTreeCtrl::IsBold (
+  const wxTreeItemId&               rItem
+) const
+{
+    return false;
+} // end of wxTreeCtrl::IsBold
 
-    return l;
-}
+// ----------------------------------------------------------------------------
+// navigation
+// ----------------------------------------------------------------------------
 
-wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const
+wxTreeItemId wxTreeCtrl::GetRootItem () const
 {
-    // can this be done more efficiently?
-    long cookie;
+    PMYRECORD                       pRecord = NULL;
 
-    wxTreeItemId childLast,
-    child = GetFirstChild(item, cookie);
-    while ( child.IsOk() )
-    {
-        childLast = child;
-        child = GetNextChild(item, cookie);
-    }
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
+                                                 ));
 
-    return childLast;
-}
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetRootItem
 
-wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
+wxTreeItemId wxTreeCtrl::GetSelection () const
 {
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetNextSibling(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
-    return 0;
-}
+    wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (long)(WXHTREEITEM)0,
+                 wxT("this only works with single selection controls") );
 
-wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const
-{
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevSibling(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
-    return 0;
-}
+    PMYRECORD                       pRecord = NULL;
+
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORDEMPHASIS
+                                                  ,MPARAM(CMA_FIRST)
+                                                  ,MPARAM(CRA_SELECTED)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetSelection
+
+wxTreeItemId wxTreeCtrl::GetItemParent (
+  const wxTreeItemId&               rItem
+) const
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetItemParent
+
+wxTreeItemId wxTreeCtrl::GetFirstChild (
+  const wxTreeItemId&               rItem
+, long&                             rCookie
+) const
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    //
+    // Remember the last child returned in 'cookie'
+    //
+    rCookie = (long)pRecord->m_ulItemId;
+    return wxTreeItemId(rCookie);
+} // end of wxTreeCtrl::GetFirstChild
+
+wxTreeItemId wxTreeCtrl::GetNextChild (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, long&                             rCookie
+) const
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rCookie
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    rCookie = (long)pRecord->m_ulItemId;
+    return wxTreeItemId(rCookie);
+} // end of wxTreeCtrl::GetNextChild
+
+wxTreeItemId wxTreeCtrl::GetLastChild (
+  const wxTreeItemId&               rItem
+) const
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_LASTCHILD, CMA_ITEMORDER)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetLastChild
+
+wxTreeItemId wxTreeCtrl::GetNextSibling (
+  const wxTreeItemId&               rItem
+) const
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetNextSibling
+
+wxTreeItemId wxTreeCtrl::GetPrevSibling (
+  const wxTreeItemId&               rItem
+) const
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                  ,CM_QUERYRECORD
+                                                  ,MPFROMP(pRecord)
+                                                  ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
+                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::GetPrevSibling
+
+wxTreeItemId wxTreeCtrl::GetFirstVisibleItem () const
+{
+    PMYRECORD                       pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                                                  ,CM_QUERYRECORD
+                                                                                  ,MPFROMP(pRecord)
+                                                                                  ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
+                                                                                 ));
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+
+    if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+        return wxTreeItemId((long)pRecord->m_ulItemId);
+    while(pRecord)
+    {
+        pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                      ,CM_QUERYRECORD
+                                                      ,MPFROMP(pRecord)
+                                                      ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+                                                     ));
+        if (!pRecord)
+            return wxTreeItemId(-1L);
+        if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+            return wxTreeItemId((long)pRecord->m_ulItemId);
+    }
+    return wxTreeItemId(-1L);
+} // end of wxTreeCtrl::GetFirstVisibleItem
 
-wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const
+wxTreeItemId wxTreeCtrl::GetNextVisible (
+  const wxTreeItemId&               rItem
+) const
 {
-//     return wxTreeItemId((WXHTREEITEM) TreeView_GetFirstVisible(GetHwnd()));
-    return 0;
-}
+    wxASSERT_MSG(IsVisible(rItem), wxT("The item you call GetNextVisible() for must be visible itself!"));
 
-wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
-{
-    wxASSERT_MSG( IsVisible(item), wxT("The item you call GetNextVisible() "
-                                      "for must be visible itself!"));
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
 
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetNextVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
-    return 0;
-}
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    while(pRecord)
+    {
+        pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                      ,CM_QUERYRECORD
+                                                      ,MPFROMP(pRecord)
+                                                      ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
+                                                     ));
+        if (!pRecord)
+            return wxTreeItemId(-1L);
+        if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+            return wxTreeItemId((long)pRecord->m_ulItemId);
+    }
+    return wxTreeItemId(-1L);
+} // end of wxTreeCtrl::GetNextVisible
 
-wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
+wxTreeItemId wxTreeCtrl::GetPrevVisible (
+  const wxTreeItemId&               rItem
+) const
 {
-    wxASSERT_MSG( IsVisible(item), wxT("The item you call GetPrevVisible() "
-                                      "for must be visible itself!"));
+    wxASSERT_MSG( IsVisible(rItem), wxT("The item you call GetPrevVisible() for must be visible itself!"));
 
-//    return wxTreeItemId((WXHTREEITEM) TreeView_GetPrevVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item));
-     return 0;
-}
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+
+    if (!pRecord)
+        return wxTreeItemId(-1L);
+    while(pRecord)
+    {
+        pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
+                                                      ,CM_QUERYRECORD
+                                                      ,MPFROMP(pRecord)
+                                                      ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
+                                                     ));
+        if (!pRecord)
+            return wxTreeItemId(-1L);
+        if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
+            return wxTreeItemId((long)pRecord->m_ulItemId);
+    }
+    return wxTreeItemId(-1L);
+} // end of wxTreeCtrl::GetPrevVisible
 
 // ----------------------------------------------------------------------------
-// multiple selections emulation
+// multiple selections emulation -- under OS/2 checked tree items is not
+// supported, but multisel is.  So we'll just check for selections here.
 // ----------------------------------------------------------------------------
 
-bool wxTreeCtrl::IsItemChecked(const wxTreeItemId& item) const
+bool wxTreeCtrl::IsItemChecked (
+  const wxTreeItemId&               rItem
+) const
 {
-    // receive the desired information.
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
-    DoGetItem(&tvItem);
+    wxTreeViewItem                  vTvItem(rItem);
 
-    // state image indices are 1 based
-    return ((tvItem.state >> 12) - 1) == 1;
-*/
-    return FALSE;
-}
+    DoGetItem(&vTvItem);
+    return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED);
+} // end of wxTreeCtrl::IsItemChecked
 
-void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check)
+void wxTreeCtrl::SetItemCheck (
+  const wxTreeItemId&               rItem
+, bool                              bCheck
+)
 {
-    // receive the desired information.
-// TODO:
-/*
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_STATEIMAGEMASK);
+    wxTreeViewItem                  vTvItem(rItem);
 
-    // state images are one-based
-    tvItem.state = (check ? 2 : 1) << 12;
+    DoGetItem(&vTvItem);
+    ::WinSendMsg( GetHWND()
+                 ,CM_SETRECORDEMPHASIS
+                 ,MPFROMP(&vTvItem)
+                 ,MPFROM2SHORT(TRUE, CRA_SELECTED)
+                );
+    DoSetItem(&vTvItem);
+} // end of wxTreeCtrl::SetItemCheck
 
-    DoSetItem(&tvItem);
-*/
-}
-
-size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const
+size_t wxTreeCtrl::GetSelections (
+  wxArrayTreeItemIds&               raSelections
+) const
 {
-    TraverseSelections selector(this, selections);
-
-    return selections.GetCount();
-}
+    TraverseSelections              vSelector( this
+                                              ,raSelections
+                                             );
+    return vSelector.GetCount();
+} // end of wxTreeCtrl::GetSelections
 
 // ----------------------------------------------------------------------------
 // Usual operations
 // ----------------------------------------------------------------------------
 
-wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent,
-                                      wxTreeItemId hInsertAfter,
-                                      const wxString& text,
-                                      int image, int selectedImage,
-                                      wxTreeItemData *data)
-{
-// TODO:
-/*
-    TV_INSERTSTRUCT tvIns;
-    tvIns.hParent = (HTREEITEM) (WXHTREEITEM)parent;
-    tvIns.hInsertAfter = (HTREEITEM) (WXHTREEITEM) hInsertAfter;
-
-    // this is how we insert the item as the first child: supply a NULL
-    // hInsertAfter
-    if ( !tvIns.hInsertAfter )
-    {
-        tvIns.hInsertAfter = TVI_FIRST;
-    }
-
-    UINT mask = 0;
-    if ( !text.IsEmpty() )
+wxTreeItemId wxTreeCtrl::DoInsertItem (
+  const wxTreeItemId&               rParent
+, wxTreeItemId                      vInsertAfter
+, const wxString&                   rsText
+, int                               nImage
+, int                               selectedImage
+, wxTreeItemData*                   pData
+)
+{
+    PMYRECORD                       pRecordAfter = FindOS2TreeRecordByID( GetHWND()
+                                                                         ,vInsertAfter.m_pItem
+                                                                        );
+
+    PMYRECORD                       pRecordParent = FindOS2TreeRecordByID( GetHWND()
+                                                                          ,rParent.m_pItem
+                                                                         );
+
+    PMYRECORD                       pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
+                                                                      ,CM_ALLOCRECORD
+                                                                      ,MPFROMLONG(sizeof(MYRECORD) - sizeof(RECORDCORE))
+                                                                      ,MPFROMLONG(1)
+                                                                     );
+    RECORDINSERT                    vInsert;
+
+    vInsert.cb                = sizeof(RECORDINSERT);
+    if (rParent.m_pItem == 0L)
     {
-        mask |= TVIF_TEXT;
-        tvIns.item.pszText = (wxChar *)text.c_str();  // cast is ok
-    }
-
-    if ( image != -1 )
-    {
-        mask |= TVIF_IMAGE;
-        tvIns.item.iImage = image;
-
-        if ( selectedImage == -1 )
-        {
-            // take the same image for selected icon if not specified
-            selectedImage = image;
-        }
-    }
-
-    if ( selectedImage != -1 )
-    {
-        mask |= TVIF_SELECTEDIMAGE;
-        tvIns.item.iSelectedImage = selectedImage;
+        if (vInsertAfter.m_pItem == -1)
+            vInsert.pRecordOrder      = (PRECORDCORE)CMA_END;
+        else
+            vInsert.pRecordOrder      = (PRECORDCORE)CMA_FIRST;
+        vInsert.pRecordParent     = NULL;
     }
-
-    if ( data != NULL )
+    else
     {
-        mask |= TVIF_PARAM;
-        tvIns.item.lParam = (LPARAM)data;
+        if (vInsertAfter.m_pItem == 0)
+            vInsert.pRecordOrder      = (PRECORDCORE)CMA_FIRST;
+        else if (vInsertAfter.m_pItem == -1)
+            vInsert.pRecordOrder      = (PRECORDCORE)CMA_END;
+        else
+            vInsert.pRecordOrder  = (PRECORDCORE)pRecordAfter;
+        vInsert.pRecordParent     = (PRECORDCORE)pRecordParent;
     }
-
-    tvIns.item.mask = mask;
-
-    HTREEITEM id = (HTREEITEM) TreeView_InsertItem(GetHwnd(), &tvIns);
-    if ( id == 0 )
+    vInsert.fInvalidateRecord = TRUE;
+    vInsert.zOrder            = CMA_TOP;
+    vInsert.cRecordsInsert    = 1;
+
+    pRecord->m_vRecord.pszTree   = (wxChar*)rsText.c_str();
+    pRecord->m_vRecord.hbmBitmap = nImage;
+    pRecord->m_ulItemId = pRecordAfter->m_ulItemId + 1;
+    if (pData != NULL)
     {
-        wxLogLastError("TreeView_InsertItem");
+        pRecord->m_ulUserData = (ULONG)pData;
     }
-
-    if ( data != NULL )
+    ::WinSendMsg( GetHWND()
+                 ,CM_INSERTRECORD
+                 ,MPFROMP(pRecord)
+                 ,MPFROMP(&vInsert)
+                );
+
+    //
+    // OS/2 must mannually bump the index's of following records
+    //
+    BumpTreeRecordIds( GetHWND()
+                  ,pRecord
+                 );
+    if (pData != NULL)
     {
-        // associate the application tree item with Win32 tree item handle
-        data->SetId((WXHTREEITEM)id);
+        //
+        // Associate the application tree item with PM tree item handle
+        //
+        pData->SetId((long)pRecord->m_ulItemId);
     }
-
-    return wxTreeItemId((WXHTREEITEM)id);
-*/
-    return 0;
-}
-
-// for compatibility only
-wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent,
-                                    const wxString& text,
-                                    int image, int selImage,
-                                    long insertAfter)
-{
-    return DoInsertItem(parent, (WXHTREEITEM)insertAfter, text,
-                        image, selImage, NULL);
-}
-
-wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text,
-                                 int image, int selectedImage,
-                                 wxTreeItemData *data)
-{
-    return DoInsertItem(wxTreeItemId((WXHTREEITEM) 0), (WXHTREEITEM) 0,
-                        text, image, selectedImage, data);
-}
-
-wxTreeItemId wxTreeCtrl::PrependItem(const wxTreeItemId& parent,
-                                     const wxString& text,
-                                     int image, int selectedImage,
-                                     wxTreeItemData *data)
-{
-// TODO:
-/*
-    return DoInsertItem(parent, (WXHTREEITEM) TVI_FIRST,
-                        text, image, selectedImage, data);
-*/
-    return 0;
-}
-
-wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parent,
-                                    const wxTreeItemId& idPrevious,
-                                    const wxString& text,
-                                    int image, int selectedImage,
-                                    wxTreeItemData *data)
-{
-    return DoInsertItem(parent, idPrevious, text, image, selectedImage, data);
-}
-
-wxTreeItemId wxTreeCtrl::AppendItem(const wxTreeItemId& parent,
-                                    const wxString& text,
-                                    int image, int selectedImage,
-                                    wxTreeItemData *data)
-{
-// TODO:
-/*
-    return DoInsertItem(parent, (WXHTREEITEM) TVI_LAST,
-                        text, image, selectedImage, data);
-*/
-    return 0;
-}
-
-void wxTreeCtrl::Delete(const wxTreeItemId& item)
-{
-// TODO:
-/*
-    if ( !TreeView_DeleteItem(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item) )
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+}
+
+wxTreeItemId wxTreeCtrl::AddRoot (
+  const wxString&                   rsText
+, int                               nImage
+, int                               nSelectedImage
+, wxTreeItemData*                   pData)
+{
+
+    return DoInsertItem( wxTreeItemId((long)0)
+                        ,wxTreeItemId((long)-1)
+                        ,rsText
+                        ,nImage
+                        ,nSelectedImage
+                        ,pData
+                       );
+} // end of wxTreeCtrl::AddRoot
+
+wxTreeItemId wxTreeCtrl::PrependItem (
+  const wxTreeItemId&               rParent
+, const wxString&                   rsText
+, int                               nImage
+, int                               nSelectedImage
+, wxTreeItemData*                   pData
+)
+{
+    return DoInsertItem( rParent
+                        ,wxTreeItemId((long)0)
+                        ,rsText
+                        ,nImage
+                        ,nSelectedImage
+                        ,pData
+                       );
+} // end of wxTreeCtrl::PrependItem
+
+wxTreeItemId wxTreeCtrl::InsertItem (
+  const wxTreeItemId&               rParent
+, const wxTreeItemId&               rIdPrevious
+, const wxString&                   rsText
+, int                               nImage
+, int                               nSelectedImage
+, wxTreeItemData*                   pData
+)
+{
+    return DoInsertItem( rParent
+                        ,rIdPrevious
+                        ,rsText
+                        ,nImage
+                        ,nSelectedImage
+                        ,pData
+                       );
+} // end of wxTreeCtrl::InsertItem
+
+wxTreeItemId wxTreeCtrl::InsertItem (
+  const wxTreeItemId&               rParent
+, size_t                            nIndex
+, const wxString&                   rsText
+, int                               nImage
+, int                               nSelectedImage
+, wxTreeItemData*                   pData
+)
+{
+    return DoInsertItem( rParent
+                        ,wxTreeItemId((long)nIndex)
+                        ,rsText
+                        ,nImage
+                        ,nSelectedImage
+                        ,pData
+                       );
+} // end of wxTreeCtrl::InsertItem
+
+wxTreeItemId wxTreeCtrl::AppendItem (
+  const wxTreeItemId&               rParent
+, const wxString&                   rsText
+, int                               nImage
+, int                               nSelectedImage
+, wxTreeItemData*                   pData
+)
+{
+    return DoInsertItem( rParent
+                        ,wxTreeItemId((long)-1)
+                        ,rsText
+                        ,nImage
+                        ,nSelectedImage
+                        ,pData
+                       );
+} // end of wxTreeCtrl::AppendItem
+
+void wxTreeCtrl::Delete (
+  const wxTreeItemId&               rItem
+)
+{
+    //
+    // OS/2 does not generate DELETEITEM events so do it here
+    //
+    wxEventType                     vEventType = wxEVT_NULL;
+    wxTreeEvent                     vEvent( wxEVT_NULL
+                                           ,m_windowId
+                                          );
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID( GetHWND()
+                                                                    ,rItem.m_pItem
+                                                                   );
+    vEvent.SetEventObject(this);
+    ::WinSendMsg( GetHWND()
+                 ,CM_REMOVERECORD
+                 ,MPFROMP(pRecord)
+                 ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
+                );
+    vEvent.m_item = rItem.m_pItem;
+    if (m_bHasAnyAttr)
     {
-        wxLogLastError("TreeView_DeleteItem");
+        delete (wxTreeItemAttr *)m_vAttrs.Delete((long)rItem.m_pItem);
     }
-*/
-}
+    vEvent.SetEventType(vEventType);
+    HandleWindowEvent(vEvent);
+} // end of wxTreeCtrl::Delete
 
 // delete all children (but don't delete the item itself)
-void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
+void wxTreeCtrl::DeleteChildren (
+  const wxTreeItemId&               rItem
+)
 {
-    long cookie;
+    long                            lCookie;
+    wxArrayLong                     aChildren;
+    wxTreeItemId                    vChild = GetFirstChild( rItem
+                                                           ,lCookie
+                                                          );
 
-    wxArrayLong children;
-    wxTreeItemId child = GetFirstChild(item, cookie);
-    while ( child.IsOk() )
+    while (vChild.IsOk())
     {
-        children.Add((long)(WXHTREEITEM)child);
-
-        child = GetNextChild(item, cookie);
+        aChildren.Add((long)(WXHTREEITEM)vChild);
+        vChild = GetNextChild( rItem
+                              ,lCookie
+                             );
     }
 
-    size_t nCount = children.Count();
-// TODO:
-/*
-    for ( size_t n = 0; n < nCount; n++ )
-    {
-        if ( !TreeView_DeleteItem(GetHwnd(), (HTREEITEM)children[n]) )
-        {
-            wxLogLastError("TreeView_DeleteItem");
-        }
-    }
-*/
-}
+    size_t                          nCount = aChildren.Count();
 
-void wxTreeCtrl::DeleteAllItems()
-{
-// TODO:
-/*
-    if ( !TreeView_DeleteAllItems(GetHwnd()) )
+    for (size_t n = 0; n < nCount; n++)
     {
-        wxLogLastError("TreeView_DeleteAllItems");
+        Delete(aChildren[n]);
     }
-*/
-}
-
-void wxTreeCtrl::DoExpand(const wxTreeItemId& item, int flag)
-{
-// TODO:
-/*
-    wxASSERT_MSG( flag == TVE_COLLAPSE ||
-                  flag == (TVE_COLLAPSE | TVE_COLLAPSERESET) ||
-                  flag == TVE_EXPAND   ||
-                  flag == TVE_TOGGLE,
-                  wxT("Unknown flag in wxTreeCtrl::DoExpand") );
-
-    // TreeView_Expand doesn't send TVN_ITEMEXPAND(ING) messages, so we must
-    // emulate them. This behaviour has changed slightly with comctl32.dll
-    // v 4.70 - now it does send them but only the first time. To maintain
-    // compatible behaviour and also in order to not have surprises with the
-    // future versions, don't rely on this and still do everything ourselves.
-    // To avoid that the messages be sent twice when the item is expanded for
-    // the first time we must clear TVIS_EXPANDEDONCE style manually.
-
-    wxTreeViewItem tvItem(item, TVIF_STATE, TVIS_EXPANDEDONCE);
-    tvItem.state = 0;
-    DoSetItem(&tvItem);
-
-    if ( TreeView_Expand(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item, flag) != 0 )
+} // end of wxTreeCtrl::DeleteChildren
+
+void wxTreeCtrl::DeleteAllItems ()
+{
+    ::WinSendMsg( GetHWND()
+                 ,CM_REMOVERECORD
+                 ,NULL                // Remove all
+                 ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
+                );
+} // end of wxTreeCtrl::DeleteAllItems
+
+void wxTreeCtrl::DoExpand (
+  const wxTreeItemId&               rItem
+, int                               nFlag
+)
+{
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID( GetHWND()
+                                                                    ,rItem.m_pItem
+                                                                   );
+    switch(nFlag)
     {
-        wxTreeEvent event(wxEVT_NULL, m_windowId);
-        event.m_item = item;
+        case wxTREE_EXPAND_EXPAND:
+            ::WinSendMsg( GetHWND()
+                         ,CM_EXPANDTREE
+                         ,MPFROMP(pRecord)
+                         ,NULL
+                        );
+            break;
 
-        bool isExpanded = IsExpanded(item);
+        case wxTREE_EXPAND_COLLAPSE:
+            ::WinSendMsg( GetHWND()
+                         ,CM_COLLAPSETREE
+                         ,MPFROMP(pRecord)
+                         ,NULL
+                        );
+            break;
 
-        event.SetEventObject(this);
+        case wxTREE_EXPAND_COLLAPSE_RESET:
+            ::WinSendMsg( GetHWND()
+                         ,CM_COLLAPSETREE
+                         ,MPFROMP(pRecord)
+                         ,NULL
+                        );
+            DeleteChildren(rItem);
+            break;
 
-        // FIXME return value of {EXPAND|COLLAPS}ING event handler is discarded
-        event.SetEventType(g_events[isExpanded][TRUE]);
-        GetEventHandler()->ProcessEvent(event);
+        case wxTREE_EXPAND_TOGGLE:
+            if (pRecord->m_vRecord.flRecordAttr & CRA_COLLAPSED)
+                ::WinSendMsg( GetHWND()
+                             ,CM_EXPANDTREE
+                             ,MPFROMP(pRecord)
+                             ,NULL
+                            );
+            else if (pRecord->m_vRecord.flRecordAttr & CRA_EXPANDED)
+                ::WinSendMsg( GetHWND()
+                             ,CM_COLLAPSETREE
+                             ,MPFROMP(pRecord)
+                             ,NULL
+                            );
+            break;
 
-        event.SetEventType(g_events[isExpanded][FALSE]);
-        GetEventHandler()->ProcessEvent(event);
     }
-    //else: change didn't took place, so do nothing at all
-*/
-}
-
-void wxTreeCtrl::Expand(const wxTreeItemId& item)
-{
-//    DoExpand(item, TVE_EXPAND);
-}
+} // end of wxTreeCtrl::DoExpand
 
-void wxTreeCtrl::Collapse(const wxTreeItemId& item)
+void wxTreeCtrl::Expand (
+  const wxTreeItemId&               rItem
+)
 {
-//    DoExpand(item, TVE_COLLAPSE);
-}
+    DoExpand( rItem
+             ,wxTREE_EXPAND_EXPAND
+            );
+} // end of wxTreeCtrl::Expand
 
-void wxTreeCtrl::CollapseAndReset(const wxTreeItemId& item)
+void wxTreeCtrl::Collapse (
+  const wxTreeItemId&               rItem
+)
 {
-//    DoExpand(item, TVE_COLLAPSE | TVE_COLLAPSERESET);
-}
+    DoExpand( rItem
+             ,wxTREE_EXPAND_COLLAPSE
+            );
+} // end of wxTreeCtrl::Collapse
 
-void wxTreeCtrl::Toggle(const wxTreeItemId& item)
+void wxTreeCtrl::CollapseAndReset (
+  const wxTreeItemId&               rItem
+)
 {
-//    DoExpand(item, TVE_TOGGLE);
-}
+    DoExpand( rItem
+             ,wxTREE_EXPAND_COLLAPSE_RESET
+            );
+} // end of wxTreeCtrl::CollapseAndReset
 
-void wxTreeCtrl::ExpandItem(const wxTreeItemId& item, int action)
+void wxTreeCtrl::Toggle (
+  const wxTreeItemId&               rItem
+)
 {
-//    DoExpand(item, action);
-}
+    DoExpand( rItem
+             ,wxTREE_EXPAND_TOGGLE
+            );
+} // end of wxTreeCtrl::Toggle
 
-void wxTreeCtrl::Unselect()
+void wxTreeCtrl::Unselect ()
 {
-    wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE), wxT("doesn't make sense") );
+    wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE),
+                  wxT("doesn't make sense, may be you want UnselectAll()?") );
 
-    // just remove the selection
-//    SelectItem(wxTreeItemId((WXHTREEITEM) 0));
-}
+    //
+    // Just remove the selection
+    //
+    SelectItem(wxTreeItemId((long)0));
+} // end of wxTreeCtrl::Unselect
 
-void wxTreeCtrl::UnselectAll()
+void wxTreeCtrl::UnselectAll ()
 {
-    if ( m_windowStyle & wxTR_MULTIPLE )
+    if (m_windowStyle & wxTR_MULTIPLE)
     {
-        wxArrayTreeItemIds selections;
-        size_t count = GetSelections(selections);
-        for ( size_t n = 0; n < count; n++ )
+        wxArrayTreeItemIds          aSelections;
+        size_t                      nCount = GetSelections(aSelections);
+
+        for (size_t n = 0; n < nCount; n++)
         {
-            SetItemCheck(selections[n], FALSE);
+            SetItemCheck( aSelections[n]
+                         ,false
+                        );
         }
     }
     else
     {
-        // just remove the selection
+        //
+        // Just remove the selection
+        //
         Unselect();
     }
-}
-
-void wxTreeCtrl::SelectItem(const wxTreeItemId& item)
-{
-    if ( m_windowStyle & wxTR_MULTIPLE )
-    {
-        // selecting the item means checking it
-        SetItemCheck(item);
-    }
-    else
-    {
-        // inspite of the docs (MSDN Jan 99 edition), we don't seem to receive
-        // the notification from the control (i.e. TVN_SELCHANG{ED|ING}), so
-        // send them ourselves
-
-        wxTreeEvent event(wxEVT_NULL, m_windowId);
-        event.m_item = item;
-        event.SetEventObject(this);
-
-        event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGING);
-// TODO:
-/*
-        if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
-        {
-            if ( !TreeView_SelectItem(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
-            {
-                wxLogLastError("TreeView_SelectItem");
-            }
-            else
-            {
-                event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED);
-                (void)GetEventHandler()->ProcessEvent(event);
-            }
-        }
-        //else: program vetoed the change
-*/
-    }
-}
-
-void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item)
-{
-    // no error return
-//    TreeView_EnsureVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item);
-}
-
-void wxTreeCtrl::ScrollTo(const wxTreeItemId& item)
-{
-// TODO:
-/*
-    if ( !TreeView_SelectSetFirstVisible(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item) )
-    {
-        wxLogLastError("TreeView_SelectSetFirstVisible");
-    }
-*/
-}
-
-wxTextCtrl* wxTreeCtrl::GetEditControl() const
-{
-    return m_textCtrl;
-}
-
-void wxTreeCtrl::DeleteTextCtrl()
-{
-    if ( m_textCtrl )
-    {
-        m_textCtrl->UnsubclassWin();
-        m_textCtrl->SetHWND(0);
-        delete m_textCtrl;
-        m_textCtrl = NULL;
-    }
-}
-
-wxTextCtrl* wxTreeCtrl::EditLabel(const wxTreeItemId& item,
-                                  wxClassInfo* textControlClass)
-{
-    wxASSERT( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)) );
-
-// TODO:
-/*
-    HWND hWnd = (HWND) TreeView_EditLabel(GetHwnd(), (HTREEITEM) (WXHTREEITEM) item);
-
-    // this is not an error - the TVN_BEGINLABELEDIT handler might have
-    // returned FALSE
-    if ( !hWnd )
-    {
-        return NULL;
-    }
-
-    DeleteTextCtrl();
-
-    m_textCtrl = (wxTextCtrl *)textControlClass->CreateObject();
-    m_textCtrl->SetHWND((WXHWND)hWnd);
-    m_textCtrl->SubclassWin((WXHWND)hWnd);
-*/
-    return m_textCtrl;
-}
+} // end of wxTreeCtrl::UnselectAll
+
+void wxTreeCtrl::SelectItem (
+  const wxTreeItemId&               rItem
+)
+{
+    SetItemCheck(rItem);
+} // end of wxTreeCtrl::SelectItem
+
+void wxTreeCtrl::EnsureVisible (
+  const wxTreeItemId&               rItem
+)
+{
+    wxTreeViewItem                  vTvItem(rItem);
+
+    DoGetItem(&vTvItem);
+    if (!::WinSendMsg( GetHWND()
+                      ,CM_INVALIDATERECORD
+                      ,MPFROMP(&vTvItem)
+                      ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
+                     ));
+} // end of wxTreeCtrl::EnsureVisible
+
+void wxTreeCtrl::ScrollTo (
+  const wxTreeItemId&               rItem
+)
+{
+    wxTreeViewItem                  vTvItem(rItem);
+
+    DoGetItem(&vTvItem);
+    if (!::WinSendMsg( GetHWND()
+                      ,CM_INVALIDATERECORD
+                      ,MPFROMP(&vTvItem)
+                      ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
+                     ));
+}
+
+wxTextCtrl* wxTreeCtrl::EditLabel (
+  const wxTreeItemId&               rItem
+, wxClassInfo*                      WXUNUSED(pTextControlClass)
+)
+{
+    CNREDITDATA                     vEdit;
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID( GetHWND()
+                                                                    ,rItem.m_pItem
+                                                                   );
+
+    vEdit.cb         = sizeof(CNREDITDATA);
+    vEdit.hwndCnr    = GetHWND();
+    vEdit.pRecord    = &pRecord->m_vRecord;
+    vEdit.pFieldInfo = NULL;
+    vEdit.ppszText   = NULL;
+    vEdit.cbText     = 0;
+    vEdit.id         = 0;
+
+    ::WinSendMsg( GetHWND()
+                 ,CM_OPENEDIT
+                 ,MPFROMP(&vEdit)
+                 ,(MPARAM)0
+                );
+    return NULL;
+} // end of wxTreeCtrl::EditLabel
 
 // End label editing, optionally cancelling the edit
-void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges)
-{
-//    TreeView_EndEditLabelNow(GetHwnd(), discardChanges);
-
-    DeleteTextCtrl();
-}
-
-wxTreeItemId wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
-{
-// TODO:
-/*
-    TV_HITTESTINFO hitTestInfo;
-    hitTestInfo.pt.x = (int)point.x;
-    hitTestInfo.pt.y = (int)point.y;
-
-    TreeView_HitTest(GetHwnd(), &hitTestInfo);
-
-    flags = 0;
-
-    // avoid repetition
-    #define TRANSLATE_FLAG(flag) if ( hitTestInfo.flags & TVHT_##flag ) \
-                                    flags |= wxTREE_HITTEST_##flag
-
-    TRANSLATE_FLAG(ABOVE);
-    TRANSLATE_FLAG(BELOW);
-    TRANSLATE_FLAG(NOWHERE);
-    TRANSLATE_FLAG(ONITEMBUTTON);
-    TRANSLATE_FLAG(ONITEMICON);
-    TRANSLATE_FLAG(ONITEMINDENT);
-    TRANSLATE_FLAG(ONITEMLABEL);
-    TRANSLATE_FLAG(ONITEMRIGHT);
-    TRANSLATE_FLAG(ONITEMSTATEICON);
-    TRANSLATE_FLAG(TOLEFT);
-    TRANSLATE_FLAG(TORIGHT);
-
-    #undef TRANSLATE_FLAG
-
-    return wxTreeItemId((WXHTREEITEM) hitTestInfo.hItem);
-*/
-    return 0;
-}
-
-bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
-                                 wxRect& rect,
-                                 bool textOnly) const
-{
-// TODO:
-/*
-    RECT rc;
-    if ( TreeView_GetItemRect(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item,
-                              &rc, textOnly) )
-    {
-        rect = wxRect(wxPoint(rc.left, rc.top), wxPoint(rc.right, rc.bottom));
-
-        return TRUE;
-    }
+void wxTreeCtrl::EndEditLabel (
+  const wxTreeItemId&               WXUNUSED(rItem)
+, bool                              WXUNUSED(bDiscardChanges)
+)
+{
+    ::WinSendMsg( GetHWND()
+                 ,CM_CLOSEEDIT
+                 ,(MPARAM)0
+                 ,(MPARAM)0
+                );
+} // end of wxTreeCtrl::EndEditLabel
+
+wxTreeItemId wxTreeCtrl::HitTest (
+  const wxPoint&                    rPoint
+, int&                              WXUNUSED(rFlags)
+)
+{
+    PMYRECORD                       pRecord = NULL;
+    QUERYRECFROMRECT                vQueryRect;
+    RECTL                           vRect;
+    long                            lHeight;
+
+    //
+    // Get height for OS/2 point conversion
+    //
+    ::WinSendMsg( GetHWND()
+                 ,CM_QUERYVIEWPORTRECT
+                 ,MPFROMP(&vRect)
+                 ,MPFROM2SHORT(CMA_WINDOW, TRUE)
+                );
+    lHeight = vRect.yTop - vRect.yBottom;
+
+    //
+    // For now just try and get a record in the general vicinity and forget
+    // the flag
+    //
+    vRect.xLeft   = rPoint.x - 2;
+    vRect.xRight  = rPoint.x + 2;
+    vRect.yTop    = (lHeight - rPoint.y) + 2;
+    vRect.yBottom = (lHeight - rPoint.y) - 2;
+
+    vQueryRect.cb = sizeof(QUERYRECFROMRECT);
+    vQueryRect.rect = vRect;
+    vQueryRect.fsSearch = CMA_PARTIAL;
+
+    pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
+                                      ,CM_QUERYRECORDFROMRECT
+                                      ,(MPARAM)CMA_FIRST
+                                      ,MPFROMP(&vQueryRect)
+                                    );
+
+    if (!pRecord)
+        return -1L;
+    return wxTreeItemId((long)pRecord->m_ulItemId);
+} // end of wxTreeCtrl::HitTest
+
+bool wxTreeCtrl::GetBoundingRect (
+  const wxTreeItemId&               rItem
+, wxRect&                           rRect
+, bool                              bTextOnly
+) const
+{
+    RECTL                           vRectRecord;
+    PMYRECORD                       pRecord = FindOS2TreeRecordByID ( GetHWND()
+                                                                     ,rItem.m_pItem
+                                                                    );
+    QUERYRECORDRECT                 vQuery;
+
+    vQuery.cb                = sizeof(QUERYRECORDRECT);
+    vQuery.pRecord           = (PRECORDCORE)pRecord;
+    vQuery.fRightSplitWindow = FALSE;
+    if (bTextOnly)
+        vQuery.fsExtent          = CMA_TEXT;
     else
-    {
-        // couldn't retrieve rect: for example, item isn't visible
-        return FALSE;
-    }
-*/
-    return FALSE;
-}
+        vQuery.fsExtent          = CMA_TREEICON | CMA_TEXT;
+
+    if (!::WinSendMsg( GetHWND()
+                      ,CM_QUERYRECORDRECT
+                      ,MPFROMP(&vRectRecord)
+                      ,MPFROMP(&vQuery)
+                     ))
+        return false;
+    rRect.SetLeft(vRectRecord.xLeft);
+    rRect.SetTop(vRectRecord.yTop);
+    rRect.SetRight(vRectRecord.xRight);
+    rRect.SetBottom(vRectRecord.yBottom);
+    return true;
+} // end of wxTreeCtrl::GetBoundingRect
 
 // ----------------------------------------------------------------------------
 // sorting stuff
 // ----------------------------------------------------------------------------
 
-static int TreeView_CompareCallback(wxTreeItemData *pItem1,
-                                    wxTreeItemData *pItem2,
-                                    wxTreeCtrl *tree)
+SHORT EXPENTRY InternalDataCompareTreeFunc (
+  PMYRECORD                         p1
+, PMYRECORD                         p2
+, PVOID                             pStorage
+)
 {
-    wxCHECK_MSG( pItem1 && pItem2, 0,
+    wxCHECK_MSG( p1 && p2, 0,
                  wxT("sorting tree without data doesn't make sense") );
 
-    return tree->OnCompareItems(pItem1->GetId(), pItem2->GetId());
-}
+    wxTreeCtrl*                     pTree = (wxTreeCtrl*)pStorage;
 
-int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
-                               const wxTreeItemId& item2)
+    return pTree->OnCompareItems( p1->m_ulItemId
+                                 ,p2->m_ulItemId
+                                );
+} // end of wxTreeSortHelper::Compare
+
+int wxTreeCtrl::OnCompareItems (
+  const wxTreeItemId&               rItem1
+, const wxTreeItemId&               rItem2
+)
 {
-    return wxStrcmp(GetItemText(item1), GetItemText(item2));
-}
+    return wxStrcmp( GetItemText(rItem1)
+                    ,GetItemText(rItem2)
+                   );
+} // end of wxTreeCtrl::OnCompareItems
 
-void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
+void wxTreeCtrl::SortChildren (
+  const wxTreeItemId&               rItem
+)
 {
-    // rely on the fact that TreeView_SortChildren does the same thing as our
-    // default behaviour, i.e. sorts items alphabetically and so call it
-    // directly if we're not in derived class (much more efficient!)
-// TODO:
-/*
-    if ( GetClassInfo() == CLASSINFO(wxTreeCtrl) )
-    {
-        TreeView_SortChildren(GetHwnd(), (HTREEITEM)(WXHTREEITEM)item, 0);
-    }
-    else
-    {
-        TV_SORTCB tvSort;
-        tvSort.hParent = (HTREEITEM)(WXHTREEITEM)item;
-        tvSort.lpfnCompare = (PFNTVCOMPARE)TreeView_CompareCallback;
-        tvSort.lParam = (LPARAM)this;
-        TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0);
-    }
-*/
-}
+    ::WinSendMsg( GetHWND()
+                 ,CM_SORTRECORD
+                 ,(PFN)InternalDataCompareTreeFunc
+                 ,NULL
+                );
+} // end of wxTreeCtrl::SortChildren
 
 // ----------------------------------------------------------------------------
 // implementation
 // ----------------------------------------------------------------------------
 
-bool wxTreeCtrl::OS2Command(WXUINT cmd, WXWORD id)
+bool wxTreeCtrl::OS2Command (
+  WXUINT                            uCmd
+, WXWORD                            wId
+)
 {
-// TODO:
-/*
-    if ( cmd == EN_UPDATE )
+    if (uCmd == CN_ENDEDIT)
     {
-        wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
-        event.SetEventObject( this );
-        ProcessCommand(event);
+        wxCommandEvent              vEvent( wxEVT_COMMAND_TEXT_UPDATED
+                                           ,wId
+                                          );
+
+        vEvent.SetEventObject( this );
+        ProcessCommand(vEvent);
+        return true;
     }
-    else if ( cmd == EN_KILLFOCUS )
+    else if (uCmd == CN_KILLFOCUS)
     {
-        wxCommandEvent event(wxEVT_KILL_FOCUS, id);
-        event.SetEventObject( this );
-        ProcessCommand(event);
+        wxCommandEvent              vEvent( wxEVT_KILL_FOCUS
+                                           ,wId
+                                          );
+        vEvent.SetEventObject( this );
+        ProcessCommand(vEvent);
+        return true;
     }
     else
-    {
-        // nothing done
-        return FALSE;
-    }
-
-    // command processed
-    return TRUE;
-*/
-    return FALSE;
-}
+        return false;
+} // end of wxTreeCtrl::OS2Command
 
-// process WM_NOTIFY Windows message
-bool wxTreeCtrl::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
-{
-// TODO:
-/*
-    wxTreeEvent event(wxEVT_NULL, m_windowId);
-    wxEventType eventType = wxEVT_NULL;
-    NMHDR *hdr = (NMHDR *)lParam;
-
-    switch ( hdr->code )
-    {
-        case NM_RCLICK:
-        {
-            if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
-                return TRUE;
-
-            TV_HITTESTINFO tvhti;
-            ::GetCursorPos(&(tvhti.pt));
-            ::ScreenToClient(GetHwnd(),&(tvhti.pt));
-            if ( TreeView_HitTest(GetHwnd(),&tvhti) )
-            {
-                if( tvhti.flags & TVHT_ONITEM )
-                {
-                    event.m_item = (WXHTREEITEM) tvhti.hItem;
-                    eventType=wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK;
-                }
-            }
-            break;
-        }
-
-        case TVN_BEGINDRAG:
-            eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
-            // fall through
-
-        case TVN_BEGINRDRAG:
-            {
-                if ( eventType == wxEVT_NULL )
-                    eventType = wxEVT_COMMAND_TREE_BEGIN_RDRAG;
-                //else: left drag, already set above
-
-                NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
-
-                event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
-                event.m_pointDrag = wxPoint(tv->ptDrag.x, tv->ptDrag.y);
-                break;
-            }
-
-        case TVN_BEGINLABELEDIT:
-            {
-                eventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
-                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-
-                event.m_item = (WXHTREEITEM) info->item.hItem;
-                event.m_label = info->item.pszText;
-                break;
-            }
-
-        case TVN_DELETEITEM:
-            {
-                eventType = wxEVT_COMMAND_TREE_DELETE_ITEM;
-                NM_TREEVIEW *tv = (NM_TREEVIEW *)lParam;
-
-                event.m_item = (WXHTREEITEM) tv->itemOld.hItem;
-                break;
-            }
-
-        case TVN_ENDLABELEDIT:
-            {
-                eventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
-                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-
-                event.m_item = (WXHTREEITEM)info->item.hItem;
-                event.m_label = info->item.pszText;
-                break;
-            }
-
-        case TVN_GETDISPINFO:
-            eventType = wxEVT_COMMAND_TREE_GET_INFO;
-            // fall through
-
-        case TVN_SETDISPINFO:
-            {
-                if ( eventType == wxEVT_NULL )
-                    eventType = wxEVT_COMMAND_TREE_SET_INFO;
-                //else: get, already set above
-
-                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-
-                event.m_item = (WXHTREEITEM) info->item.hItem;
-                break;
-            }
-
-        case TVN_ITEMEXPANDING:
-            event.m_code = FALSE;
-            // fall through
-
-        case TVN_ITEMEXPANDED:
-            {
-                NM_TREEVIEW* tv = (NM_TREEVIEW*)lParam;
-
-                bool expand = FALSE;
-                switch ( tv->action )
-                {
-                    case TVE_EXPAND:
-                        expand = TRUE;
-                        break;
-
-                    case TVE_COLLAPSE:
-                        expand = FALSE;
-                        break;
-
-                    default:
-                        wxLogDebug(wxT("unexpected code %d in TVN_ITEMEXPAND "
-                                      "message"), tv->action);
-                }
-
-                bool ing = ((int)hdr->code == TVN_ITEMEXPANDING);
-                eventType = g_events[expand][ing];
-
-                event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
-                break;
-            }
-
-        case TVN_KEYDOWN:
-            {
-                eventType = wxEVT_COMMAND_TREE_KEY_DOWN;
-                TV_KEYDOWN *info = (TV_KEYDOWN *)lParam;
-
-                event.m_code = wxCharCodeMSWToWX(info->wVKey);
-
-                // a separate event for this case
-                if ( info->wVKey == VK_SPACE || info->wVKey == VK_RETURN )
-                {
-                    wxTreeEvent event2(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
-                                       m_windowId);
-                    event2.SetEventObject(this);
-
-                    GetEventHandler()->ProcessEvent(event2);
-                }
-                break;
-            }
-
-        case TVN_SELCHANGED:
-            eventType = wxEVT_COMMAND_TREE_SEL_CHANGED;
-            // fall through
-
-        case TVN_SELCHANGING:
-            {
-                if ( eventType == wxEVT_NULL )
-                    eventType = wxEVT_COMMAND_TREE_SEL_CHANGING;
-                //else: already set above
-
-                NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
-
-                event.m_item = (WXHTREEITEM) tv->itemNew.hItem;
-                event.m_itemOld = (WXHTREEITEM) tv->itemOld.hItem;
-                break;
-            }
-
-        default:
-            return wxControl::MSWOnNotify(idCtrl, lParam, result);
-    }
-
-    event.SetEventObject(this);
-    event.SetEventType(eventType);
-
-    bool processed = GetEventHandler()->ProcessEvent(event);
-
-    // post processing
-    switch ( hdr->code )
+//
+// TODO:  Fully implement direct manipulation when I figure it out
+//
+MRESULT wxTreeCtrl::OS2WindowProc (
+  WXUINT                            uMsg
+, WXWPARAM                          wParam
+, WXLPARAM                          lParam
+)
+{
+    bool                            bProcessed = false;
+    MRESULT                         mRc = 0;
+    wxTreeEvent                     vEvent( wxEVT_NULL
+                                           ,m_windowId
+                                          );
+    wxEventType                     vEventType = wxEVT_NULL;
+    PCNRDRAGINIT                    pDragInit = NULL;
+    PCNREDITDATA                    pEditData = NULL;
+    PNOTIFYRECORDENTER              pNotifyEnter = NULL;
+
+    vEvent.SetEventObject(this);
+    switch (uMsg)
     {
-        case TVN_DELETEITEM:
-            {
-                // NB: we might process this message using wxWindows event
-                //     tables, but due to overhead of wxWin event system we
-                //     prefer to do it here ourself (otherwise deleting a tree
-                //     with many items is just too slow)
-                NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
-
-                wxTreeItemId item = event.m_item;
-                if ( HasIndirectData(item) )
-                {
-                    wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
-                                                        tv->itemOld.lParam;
-                    delete data; // can't be NULL here
-
-                    m_itemsWithIndirectData.Remove(item);
-                }
-                else
-                {
-                    wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam;
-                    delete data; // may be NULL, ok
-                }
-
-                processed = TRUE; // Make sure we don't get called twice
-            }
-            break;
-
-        case TVN_BEGINLABELEDIT:
-            // return TRUE to cancel label editing
-            *result = !event.IsAllowed();
-            break;
-
-        case TVN_ENDLABELEDIT:
-            // return TRUE to set the label to the new string
-            *result = event.IsAllowed();
-
-            // ensure that we don't have the text ctrl which is going to be
-            // deleted any more
-            DeleteTextCtrl();
-            break;
-
-        case TVN_SELCHANGING:
-        case TVN_ITEMEXPANDING:
-            // return TRUE to prevent the action from happening
-            *result = !event.IsAllowed();
-            break;
-
-        case TVN_GETDISPINFO:
-            // NB: so far the user can't set the image himself anyhow, so do it
-            //     anyway - but this may change later
-            if ( 1 // !processed && )
+        case WM_CONTROL:
+            switch(SHORT2FROMMP(wParam))
             {
-                wxTreeItemId item = event.m_item;
-                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
-                if ( info->item.mask & TVIF_IMAGE )
-                {
-                    info->item.iImage =
-                        DoGetItemImageFromData
-                        (
-                         item,
-                         IsExpanded(item) ? wxTreeItemIcon_Expanded
-                                          : wxTreeItemIcon_Normal
-                        );
-                }
-                if ( info->item.mask & TVIF_SELECTEDIMAGE )
-                {
-                    info->item.iSelectedImage =
-                        DoGetItemImageFromData
-                        (
-                         item,
-                         IsExpanded(item) ? wxTreeItemIcon_SelectedExpanded
-                                          : wxTreeItemIcon_Selected
-                        );
-                }
+                case CN_INITDRAG:
+                    pDragInit = (PCNRDRAGINIT)lParam;
+                    if (pDragInit)
+                    {
+                        PMYRECORD       pRecord = (PMYRECORD)pDragInit->pRecord;
+
+                        vEventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
+                        vEvent.m_item        = pRecord->m_ulItemId;
+                        vEvent.m_pointDrag.x = pDragInit->x;
+                        vEvent.m_pointDrag.y = pDragInit->y;
+                    }
+                    break;
+
+                case CN_BEGINEDIT:
+                    pEditData = (PCNREDITDATA)lParam;
+                    if (pEditData)
+                    {
+                        PMYRECORD       pRecord = (PMYRECORD)pEditData->pRecord;
+
+                        vEventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
+                        vEvent.m_item = pRecord->m_ulItemId;
+                        vEvent.m_label = pRecord->m_vRecord.pszTree;
+                        vEvent.m_editCancelled = false;
+                    }
+                    break;
+
+                case CN_ENDEDIT:
+                    pEditData = (PCNREDITDATA)lParam;
+                    if (pEditData)
+                    {
+                        PMYRECORD       pRecord = (PMYRECORD)pEditData->pRecord;
+
+                        vEventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
+                        vEvent.m_item = pRecord->m_ulItemId;
+                        vEvent.m_label = pRecord->m_vRecord.pszTree;
+                        if (pRecord->m_vRecord.pszTree == NULL)
+                        {
+                            vEvent.m_editCancelled = true;
+                        }
+                        else
+                        {
+                            vEvent.m_editCancelled = false;
+                        }
+                    }
+                    break;
+
+                case CN_EXPANDTREE:
+                    {
+                        PMYRECORD       pRecord = (PMYRECORD)lParam;
+
+                        vEventType = gs_expandEvents[IDX_EXPAND][IDX_DONE];
+                        vEvent.m_item = pRecord->m_ulItemId;
+                    }
+                    break;
             }
+            vEvent.SetEventType(vEventType);
+            bProcessed = HandleWindowEvent(vEvent);
             break;
-
-        //default:
-            // for the other messages the return value is ignored and there is
-            // nothing special to do
     }
-
-    return processed;
-*/
-    return FALSE;
-}
-
-// ----------------------------------------------------------------------------
-// Tree event
-// ----------------------------------------------------------------------------
-
-IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
-
-wxTreeEvent::wxTreeEvent(wxEventType commandType, int id)
-           : wxNotifyEvent(commandType, id)
-{
-    m_code = 0;
-    m_itemOld = 0;
-}
-
+    if (!bProcessed)
+        mRc = wxControl::OS2WindowProc( uMsg
+                                       ,wParam
+                                       ,lParam
+                                      );
+    return mRc;
+} // end of wxTreeCtrl::OS2WindowProc
+
+#endif // wxUSE_TREECTRL