]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/toolbar.cpp
Compilation fix.
[wxWidgets.git] / src / os2 / toolbar.cpp
index 718318b17c275f2e23079a81cf80246f87241325..1d296bda352325ba9a4cd6ea23543287780b985f 100644 (file)
@@ -3,7 +3,7 @@
 // Purpose:     wxToolBar
 // Author:      David Webster
 // Modified by:
-// Created:     10/17/99
+// Created:     06/30/02
 // RCS-ID:      $Id$
 // Copyright:   (c) David Webster
 // Licence:     wxWindows licence
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
+#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
+
 #ifndef WX_PRECOMP
-#include "wx/wx.h"
+    #include "wx/settings.h"
+    #include "wx/window.h"
+    #include "wx/frame.h"
+    #include "wx/app.h"
+    #include "wx/dcclient.h"
+    #include "wx/dcmemory.h"
 #endif
 
-#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR
+#include "wx/tooltip.h"
+#include "wx/toolbar.h"
 
-#include "malloc.h"
-#define INCL_PM
-#include <os2.h>
+bool                                wxToolBar::m_bInitialized = FALSE;
 
-#include "wx/toolbar.h"
-#include "wx/app.h"
-#include "wx/os2/private.h"
-
-// Styles
-#ifndef TBSTYLE_FLAT
-#define TBSTYLE_LIST            0x1000
-#define TBSTYLE_FLAT            0x0800
-#define TBSTYLE_TRANSPARENT     0x8000
-#endif
- // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
 
-// Messages
-#ifndef TB_GETSTYLE
-#define TB_GETSTYLE             (WM_USER + 57)
-#define TB_SETSTYLE             (WM_USER + 56)
-#endif
+class wxToolBarTool : public wxToolBarToolBase
+{
+public:
+    inline wxToolBarTool( wxToolBar*      pTbar
+                         ,int             vId
+                         ,const wxString& rsLabel
+                         ,const wxBitmap& rBitmap1
+                         ,const wxBitmap& rBitmap2
+                         ,wxItemKind      vKind
+                         ,wxObject*       pClientData
+                         ,const wxString& rsShortHelpString
+                         ,const wxString& rsLongHelpString
+                        ) : wxToolBarToolBase( pTbar
+                                              ,vId
+                                              ,rsLabel
+                                              ,rBitmap1
+                                              ,rBitmap2
+                                              ,vKind
+                                              ,pClientData
+                                              ,rsShortHelpString
+                                              ,rsLongHelpString
+                                             )
+    {
+    }
 
-/* Hint from a newsgroup for custom flatbar drawing:
-Set the TBSTYLE_CUSTOMERASE style, then handle the
-NM_CUSTOMDRAW message and do your custom drawing.
-*/
+    inline wxToolBarTool( wxToolBar* pTbar
+                         ,wxControl* pControl
+                        ) : wxToolBarToolBase( pTbar
+                                              ,pControl
+                                             )
+    {
+    }
+
+    void SetSize(const wxSize& rSize)
+    {
+        m_vWidth = rSize.x;
+        m_vHeight = rSize.y;
+    }
+
+    wxCoord GetWidth(void) const { return m_vWidth; }
+    wxCoord GetHeight(void) const { return m_vHeight; }
 
-#define DEFAULTBITMAPX   16
-#define DEFAULTBITMAPY   15
-#define DEFAULTBUTTONX   24
-#define DEFAULTBUTTONY   24
-#define DEFAULTBARHEIGHT 27
+    wxCoord                         m_vX;
+    wxCoord                         m_vY;
+    wxCoord                         m_vWidth;
+    wxCoord                         m_vHeight;
+}; // end of CLASS wxToolBarTool
+
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
 
 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
 
 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
+    EVT_SIZE(wxToolBar::OnSize)
+    EVT_PAINT(wxToolBar::OnPaint)
+    EVT_KILL_FOCUS(wxToolBar::OnKillFocus)
     EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
-    EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged)
+    EVT_TIMER(-1, wxToolBar::OnTimer)
 END_EVENT_TABLE()
 
-static void wxMapBitmap(HBITMAP hBitmap, int width, int height);
-
-wxToolBar::wxToolBar()
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// tool bar tools creation
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase* wxToolBar::CreateTool(
+  int                               nId
+, const wxString&                   rsLabel
+, const wxBitmap&                   rBmpNormal
+, const wxBitmap&                   rBmpDisabled
+, wxItemKind                        eKind
+, wxObject*                         pClientData
+, const wxString&                   rsShortHelp
+, const wxString&                   rsLongHelp
+)
 {
-  m_maxWidth = -1;
-  m_maxHeight = -1;
-  m_hBitmap = 0;
-  m_defaultWidth = DEFAULTBITMAPX;
-  m_defaultHeight = DEFAULTBITMAPY;
-}
-
-bool wxToolBar::Create(wxWindow *parent,
-                         wxWindowID id,
-                         const wxPoint& pos,
-                         const wxSize& size,
-                         long style,
-                         const wxString& name)
+    return new wxToolBarTool( this
+                             ,nId
+                             ,rsLabel
+                             ,rBmpNormal
+                             ,rBmpDisabled
+                             ,eKind
+                             ,pClientData
+                             ,rsShortHelp
+                             ,rsLongHelp
+                            );
+} // end of wxToolBarSimple::CreateTool
+
+wxToolBarToolBase *wxToolBar::CreateTool(
+  wxControl*                        pControl
+)
 {
-  m_hWnd = 0;
-  m_backgroundColour = *wxWHITE; //TODO: wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
-//                                GetGValue(GetSysColor(COLOR_BTNFACE)),
-//                                GetBValue(GetSysColor(COLOR_BTNFACE)));
-  m_foregroundColour = *wxBLACK ;
-
-  wxASSERT_MSG( (style & wxTB_VERTICAL) == 0,
-                wxT("Sorry, wxToolBar under Windows 95 only "
-                   "supports horizontal orientation.") );
-
-  m_maxWidth = -1;
-  m_maxHeight = -1;
-
-  m_hBitmap = 0;
-
-  m_defaultWidth = DEFAULTBITMAPX;
-  m_defaultHeight = DEFAULTBITMAPY;
-  SetName(name);
-
-  m_windowStyle = style;
-
-  SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
-  SetParent(parent);
-
-  int x = pos.x;
-  int y = pos.y;
-  int width = size.x;
-  int height = size.y;
-
-  if (width <= 0)
-    width = 100;
-  if (height <= 0)
-    height = 30;
-  if (x < 0)
-    x = 0;
-  if (y < 0)
-    y = 0;
-
-  m_windowId = (id < 0 ? NewControlId() : id);
-  DWORD msflags = 0;
-// TODO:
-/*
-  if (style & wxBORDER)
-    msflags |= WS_BORDER;
-  msflags |= WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS;
-
-  if (style & wxTB_FLAT)
-  {
-    if (wxTheApp->GetComCtl32Version() > 400)
-        msflags |= TBSTYLE_FLAT;
-  }
-
-  bool want3D;
-  WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
-
-  // Even with extended styles, need to combine with WS_BORDER
-  // for them to look right.
-  if ( want3D || wxStyleHasBorder(m_windowStyle) )
-      msflags |= WS_BORDER;
-
-  // Create the toolbar control.
-  HWND hWndToolbar = CreateWindowEx
-                     (
-                      exStyle,                  // Extended styles.
-                      TOOLBARCLASSNAME,         // Class name for the toolbar.
-                      wxT(""),                   // No default text.
-                      msflags,                  // Styles
-                      x, y, width, height,      // Standard toolbar size and position.
-                      (HWND) parent->GetHWND(), // Parent window of the toolbar.
-                      (HMENU)m_windowId,        // Toolbar ID.
-                      wxGetInstance(),          // Current instance.
-                      NULL                      // No class data.
-                     );
-
-  wxCHECK_MSG( hWndToolbar, FALSE, wxT("Toolbar creation failed") );
-
-  // Toolbar-specific initialisation
-  ::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE,
-                (WPARAM)sizeof(TBBUTTON), (LPARAM)0);
-  m_hWnd = (WXHWND) hWndToolbar;
-
-  if (parent)
-      parent->AddChild(this);
-
-  SubclassWin((WXHWND)hWndToolbar);
-
-  return TRUE;
-*/
-  return FALSE;
-}
+    return new wxToolBarTool( this
+                             ,pControl
+                            );
+} // end of wxToolBarSimple::CreateTool
 
-wxToolBar::~wxToolBar()
+// ----------------------------------------------------------------------------
+// wxToolBarSimple creation
+// ----------------------------------------------------------------------------
+
+void wxToolBar::Init()
+{
+    m_nCurrentRowsOrColumns = 0;
+
+    m_vLastX = m_vLastY = 0;
+    m_vMaxWidth = m_vMaxHeight = 0;
+    m_nPressedTool = m_nCurrentTool = -1;
+    m_vXPos = m_vYPos = -1;
+    m_vTextX = m_vTextY = 0;
+
+    m_toolPacking = 1;
+    m_toolSeparation = 5;
+
+    m_defaultWidth = 16;
+    m_defaultHeight = 15;
+
+    m_pToolTip = NULL;
+} // end of wxToolBar::Init
+
+wxToolBarToolBase* wxToolBar::DoAddTool(
+  int                               vId
+, const wxString&                   rsLabel
+, const wxBitmap&                   rBitmap
+, const wxBitmap&                   rBmpDisabled
+, wxItemKind                        eKind
+, const wxString&                   rsShortHelp
+, const wxString&                   rsLongHelp
+, wxObject*                         pClientData
+, wxCoord                           vXPos
+, wxCoord                           vYPos
+)
+{
+    //
+    // Rememeber the position for DoInsertTool()
+    //
+    m_vXPos = vXPos;
+    m_vYPos = vYPos;
+
+    return wxToolBarBase::DoAddTool( vId
+                                    ,rsLabel
+                                    ,rBitmap
+                                    ,rBmpDisabled
+                                    ,eKind
+                                    ,rsShortHelp
+                                    ,rsLongHelp
+                                    ,pClientData
+                                    ,vXPos
+                                    ,vYPos
+                                   );
+} // end of wxToolBar::DoAddTool
+
+bool wxToolBar::DeleteTool(
+  int                               nId
+)
 {
-  UnsubclassWin();
+    bool                            bOk = wxToolBarBase::DeleteTool(nId);
 
-  if (m_hBitmap)
-  {
-//    ::DeleteObject((HBITMAP) m_hBitmap);
-    m_hBitmap = 0;
-  }
-}
+    if (bOk)
+    {
+        Realize();
+    }
+    return bOk;
+} // end of wxToolBar::DeleteTool
 
-bool wxToolBar::CreateTools()
+bool wxToolBar::DeleteToolByPos(
+  size_t                            nPos
+)
 {
-  if (m_tools.Number() == 0)
-    return FALSE;
-
-  HBITMAP oldToolBarBitmap = (HBITMAP) m_hBitmap;
-
-  int totalBitmapWidth = (int)(m_defaultWidth * m_tools.Number());
-  int totalBitmapHeight = (int)m_defaultHeight;
-
-// TODO:
-/*
-  // Create a bitmap for all the tool bitmaps
-  HDC dc = ::GetDC(NULL);
-  m_hBitmap = (WXHBITMAP) ::CreateCompatibleBitmap(dc, totalBitmapWidth, totalBitmapHeight);
-  ::ReleaseDC(NULL, dc);
-
-  // Now blit all the tools onto this bitmap
-  HDC memoryDC = ::CreateCompatibleDC(NULL);
-  HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, (HBITMAP) m_hBitmap);
-
-  HDC memoryDC2 = ::CreateCompatibleDC(NULL);
-  int x = 0;
-  wxNode *node = m_tools.First();
-  int noButtons = 0;
-  while (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    if ((tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) && tool->m_bitmap1.Ok() && tool->m_bitmap1.GetHBITMAP())
-    {
-//      wxPalette *palette = tool->m_bitmap1->GetPalette();
-
-      HBITMAP oldBitmap2 = (HBITMAP) ::SelectObject(memoryDC2, (HBITMAP) tool->m_bitmap1.GetHBITMAP());
-      // int bltResult =
-      BitBlt(memoryDC, x, 0, (int) m_defaultWidth, (int) m_defaultHeight, memoryDC2,
-                        0, 0, SRCCOPY);
-      ::SelectObject(memoryDC2, oldBitmap2);
-      x += (int)m_defaultWidth;
-      noButtons ++;
-    }
-    node = node->Next();
-  }
-  ::SelectObject(memoryDC, oldBitmap);
-  ::DeleteDC(memoryDC);
-  ::DeleteDC(memoryDC2);
-
-  // Map to system colours
-  wxMapBitmap((HBITMAP) m_hBitmap, totalBitmapWidth, totalBitmapHeight);
-
-  if ( oldToolBarBitmap )
-  {
-    TBREPLACEBITMAP replaceBitmap;
-    replaceBitmap.hInstOld = NULL;
-    replaceBitmap.hInstNew = NULL;
-    replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
-    replaceBitmap.nIDNew = (UINT) (HBITMAP) m_hBitmap;
-    replaceBitmap.nButtons = noButtons;
-    if (::SendMessage((HWND) GetHWND(), TB_REPLACEBITMAP, (WPARAM) 0, (LPARAM) &replaceBitmap) == -1)
-    {
-      wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
-    }
-
-    ::DeleteObject((HBITMAP) oldToolBarBitmap);
-
-    // Now delete all the buttons
-    int i = 0;
-    while ( TRUE )
-    {
-        // TODO: What about separators???? They don't have an id!
-        if ( ! ::SendMessage( (HWND) GetHWND(), TB_DELETEBUTTON, i, 0 ) )
-            break;
-    }
-  }
-  else
-  {
-    TBADDBITMAP addBitmap;
-    addBitmap.hInst = 0;
-    addBitmap.nID = (UINT)m_hBitmap;
-    if (::SendMessage((HWND) GetHWND(), TB_ADDBITMAP, (WPARAM) noButtons, (LPARAM) &addBitmap) == -1)
-    {
-      wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
-    }
-  }
-
-  // Now add the buttons.
-  TBBUTTON buttons[50];
-
-  node = m_tools.First();
-  int i = 0;
-  int bitmapId = 0;
-  while (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR)
-    {
-      buttons[i].iBitmap = 0;
-      buttons[i].idCommand = 0;
-
-      buttons[i].fsState = TBSTATE_ENABLED;
-      buttons[i].fsStyle = TBSTYLE_SEP;
-      buttons[i].dwData = 0L;
-      buttons[i].iString = 0;
+    bool                            bOk = wxToolBarBase::DeleteToolByPos(nPos);
+
+    if (bOk)
+    {
+        Realize();
     }
-    else
+    return bOk;
+} // end of wxToolBar::DeleteTool
+
+wxToolBarToolBase* wxToolBar::InsertControl(
+  size_t                            nPos
+, wxControl*                        pControl
+)
+{
+    wxToolBarToolBase*              pTool = wxToolBarBase::InsertControl( nPos
+                                                                         ,pControl
+                                                                        );
+    if (m_bInitialized)
     {
-      buttons[i].iBitmap = bitmapId;
-      buttons[i].idCommand = tool->m_index;
+        Realize();
+        Refresh();
+    }
+    return pTool;
+} // end of wxToolBar::InsertControl
 
-      buttons[i].fsState = 0;
-      if (tool->m_enabled)
-        buttons[i].fsState |= TBSTATE_ENABLED;
-      if (tool->m_toggleState)
-        buttons[i].fsState |= TBSTATE_CHECKED;
-      buttons[i].fsStyle = tool->m_isToggle ? TBSTYLE_CHECK : TBSTYLE_BUTTON;
-      buttons[i].dwData = 0L;
-      buttons[i].iString = 0;
+wxToolBarToolBase* wxToolBar::InsertSeparator(
+  size_t                            nPos
+)
+{
+    wxToolBarToolBase*              pTool = wxToolBarBase::InsertSeparator(nPos);
 
-      bitmapId ++;
+    if (m_bInitialized)
+    {
+        Realize();
+        Refresh();
     }
+    return pTool;
+} // end of wxToolBar::InsertSeparator
+
+wxToolBarToolBase* wxToolBar::InsertTool(
+  size_t                            nPos
+, int                               nId
+, const wxString&                   rsLabel
+, const wxBitmap&                   rBitmap
+, const wxBitmap&                   rBmpDisabled
+, wxItemKind                        eKind
+, const wxString&                   rsShortHelp
+, const wxString&                   rsLongHelp
+, wxObject*                         pClientData
+)
+{
+    wxToolBarToolBase*              pTool = wxToolBarBase::InsertTool( nPos
+                                                                      ,nId
+                                                                      ,rsLabel
+                                                                      ,rBitmap
+                                                                      ,rBmpDisabled
+                                                                      ,eKind
+                                                                      ,rsShortHelp
+                                                                      ,rsLongHelp
+                                                                      ,pClientData
+                                                                     );
+    if (m_bInitialized)
+    {
+        Realize();
+        Refresh();
+    }
+    return pTool;
+} // end of wxToolBar::InsertTool
 
-    i ++;
-    node = node->Next();
-  }
+bool wxToolBar::DoInsertTool(
+  size_t                            WXUNUSED(nPos)
+, wxToolBarToolBase*                pToolBase
+)
+{
+    wxToolBarTool*                  pTool = (wxToolBarTool *)pToolBase;
 
-  long rc = ::SendMessage((HWND) GetHWND(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)& buttons);
+    pTool->m_vX = m_vXPos;
+    if (pTool->m_vX == -1)
+        pTool->m_vX = m_xMargin;
 
-  wxCHECK_MSG( rc, FALSE, wxT("failed to add buttons to the toolbar") );
+    pTool->m_vY = m_vYPos;
+    if (pTool->m_vY == -1)
+        pTool->m_vX = m_yMargin;
 
-  (void)::SendMessage((HWND) GetHWND(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0);
+    pTool->SetSize(GetToolSize());
 
-  SetRows(m_maxRows);
-*/
-  return TRUE;
-}
+    if (pTool->IsButton())
+    {
+        //
+        // Calculate reasonable max size in case Layout() not called
+        //
+        if ((pTool->m_vX + pTool->GetNormalBitmap().GetWidth() + m_xMargin) > m_vMaxWidth)
+            m_vMaxWidth = (wxCoord)((pTool->m_vX + pTool->GetWidth() + m_xMargin));
+
+        if ((pTool->m_vY + pTool->GetNormalBitmap().GetHeight() + m_yMargin) > m_vMaxHeight)
+            m_vMaxHeight = (wxCoord)((pTool->m_vY + pTool->GetHeight() + m_yMargin));
+    }
+    return TRUE;
+} // end of wxToolBar::DoInsertTool
 
-bool wxToolBar::OS2Command(WXUINT cmd, WXWORD id)
+bool wxToolBar::DoDeleteTool(
+  size_t                            WXUNUSED(nPos)
+, wxToolBarToolBase*                pTool
+)
 {
-  wxNode *node = m_tools.Find((long)id);
-  if (!node)
-    return FALSE;
-  wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-// TODO:
-/*
- if (tool->m_isToggle)
-    tool->m_toggleState = (1 == (1 & (int)::SendMessage((HWND) GetHWND(), TB_GETSTATE, (WPARAM) id, (LPARAM) 0)));
-
-  BOOL ret = OnLeftClick((int)id, tool->m_toggleState);
-  if (ret == FALSE && tool->m_isToggle)
-  {
-    tool->m_toggleState = !tool->m_toggleState;
-    ::SendMessage((HWND) GetHWND(), TB_CHECKBUTTON, (WPARAM)id, (LPARAM)MAKELONG(tool->m_toggleState, 0));
-  }
-  return TRUE;
-*/
-  return FALSE;
-}
-
-bool wxToolBar::OS2OnNotify(int WXUNUSED(idCtrl),
-                            WXLPARAM lParam,
-                            WXLPARAM *result)
+    pTool->Detach();
+    Refresh();
+    return TRUE;
+} // end of wxToolBar::DoDeleteTool
+
+bool wxToolBar::Create(
+  wxWindow*                         pParent
+, wxWindowID                        vId
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+, long                              lStyle
+, const wxString&                   rsName
+)
 {
-// TODO:
-/*
-    // First check if this applies to us
-    NMHDR *hdr = (NMHDR *)lParam;
-
-    // the tooltips control created by the toolbar is sometimes Unicode, even in
-    // an ANSI application
-    int code = (int)hdr->code;
-    if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) )
+    if ( !wxWindow::Create( pParent
+                           ,vId
+                           ,rPos
+                           ,rSize
+                           ,lStyle
+                           ,rsName
+                          ))
         return FALSE;
 
-    HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
-    if ( toolTipWnd != hdr->hwndFrom )
-        return FALSE;
+    // Set it to grey (or other 3D face colour)
+    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
+    SetFont(*wxSMALL_FONT);
 
-    LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
-    int id = (int)ttText->hdr.idFrom;
-    wxNode *node = m_tools.Find((long)id);
-    if (!node)
-        return FALSE;
+    if (GetWindowStyleFlag() & wxTB_VERTICAL)
+    {
+        m_vLastX = 7;
+        m_vLastY = 3;
 
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
+        m_maxRows = 32000;      // a lot
+        m_maxCols = 1;
+    }
+    else
+    {
+        m_vLastX = 3;
+        m_vLastY = 7;
 
-    const wxString& help = tool->m_shortHelpString;
+        m_maxRows = 1;
+        m_maxCols = 32000;      // a lot
+    }
+    SetCursor(*wxSTANDARD_CURSOR);
+
+    //
+    // The toolbar's tools, if they have labels and the winTB_TEXT
+    // style is set, then we need to take into account the size of
+    // the text when drawing tool bitmaps and the text
+    //
+    if (HasFlag(wxTB_TEXT))
+    {
+        wxClientDC                  vDC(this);
 
-    if ( !help.IsEmpty() )
+        vDC.SetFont(GetFont());
+        vDC.GetTextExtent( "XXXX"
+                          ,&m_vTextX
+                          ,&m_vTextY
+                         );
+    }
+
+    //
+    // Position it
+    //
+    int                             nX      = rPos.x;
+    int                             nY      = rPos.y;
+    int                             nWidth  = rSize.x;
+    int                             nHeight = rSize.y;
+    wxFrame*                        pFrame = wxDynamicCast(GetParent(), wxFrame);
+
+    if (lStyle & wxTB_HORIZONTAL)
     {
-        if ( code == TTN_NEEDTEXTA )
+        if (nWidth <= 0)
+        {
+            nWidth = pParent->GetClientSize().x;
+        }
+        if (nHeight <= 0)
         {
-            ttText->lpszText = (wxChar *)help.c_str();
+            if (lStyle & wxTB_TEXT)
+                nHeight = m_defaultHeight + m_vTextY;
+            else
+                nHeight = m_defaultHeight;
+        }
+    }
+    else
+    {
+        if (nHeight <= 0)
+        {
+            nHeight = pParent->GetClientSize().y;
+        }
+        if (nWidth <= 0)
+        {
+            if (lStyle & wxTB_TEXT)
+                nWidth = m_vTextX + (int)(m_vTextX/2); // a little margin
+            else
+                nWidth = m_defaultWidth + (int)(m_defaultWidth/2); // a little margin
+        }
+    }
+    if (nX < 0)
+        nX = 0;
+    if (nY < 0)
+        nY = 0;
+
+    SetSize( nX
+            ,nY
+            ,nWidth
+            ,nHeight
+           );
+    return TRUE;
+} // end of wxToolBar::Create
+
+wxToolBar::~wxToolBar()
+{
+    if (m_pToolTip)
+    {
+        delete m_pToolTip;
+        m_pToolTip = NULL;
+    }
+} // end of wxToolBar::~wxToolBar
+
+bool wxToolBar::Realize()
+{
+    int                             nMaxToolWidth  = 0;
+    int                             nMaxToolHeight = 0;
+    int                             nX;
+    int                             nY;
+
+    m_nCurrentRowsOrColumns = 0;
+    m_vLastX               = m_xMargin;
+    m_vLastY               = m_yMargin;
+    m_vMaxWidth            = 0;
+    m_vMaxHeight           = 0;
+
+
+    //
+    // Find the maximum tool width and height
+    //
+    wxToolBarToolsList::Node*       pNode = m_tools.GetFirst();
+
+    while (pNode )
+    {
+        wxToolBarTool*              pTool = (wxToolBarTool *)pNode->GetData();
+
+        if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
+        {
+            //
+            // Set the height according to the font and the border size
+            //
+            if (pTool->GetWidth() > m_vTextX)
+                nMaxToolWidth = pTool->GetWidth() + 4;
+            else
+                nMaxToolWidth = m_vTextX;
+            if (pTool->GetHeight() + m_vTextY > nMaxToolHeight)
+                nMaxToolHeight = pTool->GetHeight() + m_vTextY;
+        }
+        else
+        {
+            if (pTool->GetWidth() > nMaxToolWidth )
+                nMaxToolWidth = pTool->GetWidth() + 4;
+            if (pTool->GetHeight() > nMaxToolHeight)
+                nMaxToolHeight = pTool->GetHeight();
+        }
+        pNode = pNode->GetNext();
+    }
+
+    wxCoord                         vTbWidth = 0L;
+    wxCoord                         vTbHeight = 0L;
+
+    GetSize( &vTbWidth
+            ,&vTbHeight
+           );
+    if (vTbHeight < nMaxToolHeight)
+    {
+        SetSize( -1L
+                ,-1L
+                ,vTbWidth
+                ,nMaxToolHeight + 4
+               );
+        if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
+        {
+            wxFrame*            pFrame = wxDynamicCast(GetParent(), wxFrame);
+
+            if (pFrame)
+                pFrame->PositionToolBar();
+        }
+    }
+
+    int                             nSeparatorSize = m_toolSeparation;
+
+    pNode = m_tools.GetFirst();
+    while (pNode)
+    {
+        wxToolBarTool*              pTool = (wxToolBarTool *)pNode->GetData();
+
+        if (pTool->IsSeparator())
+        {
+            if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
+            {
+                pTool->m_vX = m_vLastX + nSeparatorSize;
+                pTool->m_vHeight = m_defaultHeight + m_vTextY;
+                if (m_nCurrentRowsOrColumns >= m_maxCols)
+                    m_vLastY += nSeparatorSize;
+                else
+                    m_vLastX += nSeparatorSize * 4;
+            }
+            else
+            {
+                pTool->m_vY = m_vLastY + nSeparatorSize;
+                pTool->m_vHeight = m_defaultHeight + m_vTextY;
+                if (m_nCurrentRowsOrColumns >= m_maxRows)
+                    m_vLastX += nSeparatorSize;
+                else
+                    m_vLastY += nSeparatorSize * 4;
+            }
+        }
+        else if (pTool->IsButton())
+        {
+            if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
+            {
+                if (m_nCurrentRowsOrColumns >= m_maxCols)
+                {
+                    m_nCurrentRowsOrColumns = 0;
+                    m_vLastX                = m_xMargin;
+                    m_vLastY               += nMaxToolHeight + m_toolPacking;
+                }
+                pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2)));
+                if (HasFlag(wxTB_TEXT))
+                    pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment
+                else
+                    pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
+                m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation;
+            }
+            else
+            {
+                if (m_nCurrentRowsOrColumns >= m_maxRows)
+                {
+                    m_nCurrentRowsOrColumns = 0;
+                    m_vLastX               += (nMaxToolWidth + m_toolPacking);
+                    m_vLastY                = m_yMargin;
+                }
+                pTool->m_vX = m_vLastX + pTool->GetWidth();
+                if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+                    pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking;
+                else
+                    pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
+                m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation;
+            }
+            m_nCurrentRowsOrColumns++;
         }
-#if (_WIN32_IE >= 0x0300)
         else
         {
-            // FIXME this is a temp hack only until I understand better what
-            //       must be done in both ANSI and Unicode builds
-
-            size_t lenAnsi = help.Len();
-            #ifdef __MWERKS__
-                // MetroWerks doesn't like calling mbstowcs with NULL argument
-                size_t lenUnicode = 2*lenAnsi;
-            #else
-                size_t lenUnicode = mbstowcs(NULL, help, lenAnsi);
-            #endif
-
-            // using the pointer of right type avoids us doing all sorts of
-            // pointer arithmetics ourselves
-            wchar_t *dst = (wchar_t *)ttText->szText,
-                    *pwz = new wchar_t[lenUnicode + 1];
-            mbstowcs(pwz, help, lenAnsi + 1);
-            memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
-
-            // put the terminating _wide_ NUL
-            dst[lenUnicode] = 0;
-
-            delete [] pwz;
+            // TODO: support the controls
         }
-#endif // _WIN32_IE >= 0x0300
+
+        if (m_vLastX > m_maxWidth)
+            m_maxWidth = m_vLastX;
+        if (m_vLastY > m_maxHeight)
+            m_maxHeight = m_vLastY;
+
+        pNode = pNode->GetNext();
     }
 
-    // For backward compatibility...
-    OnMouseEnter(tool->m_index);
+    if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+        m_maxWidth += nMaxToolWidth;
+    else
+        m_maxHeight += nMaxToolHeight;
 
+    m_maxWidth += m_xMargin;
+    m_maxHeight += m_yMargin;
+    m_bInitialized = TRUE;
     return TRUE;
-*/
-    return FALSE;
-}
+} // end of wxToolBar::Realize
 
-void wxToolBar::SetToolBitmapSize(const wxSize& size)
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
+
+void wxToolBar::OnPaint (
+  wxPaintEvent&                     WXUNUSED(rEvent)
+)
 {
-  m_defaultWidth = size.x;
-  m_defaultHeight = size.y;
-//  ::SendMessage((HWND) GetHWND(), TB_SETBITMAPSIZE, 0, (LPARAM) MAKELONG ((int)size.x, (int)size.y));
-}
+    wxPaintDC                       vDc(this);
+
+    PrepareDC(vDc);
+
+    static int                      nCount = 0;
+
+    //
+    // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
+    //
+    if (nCount > 0)
+        return;
+    nCount++;
+
+    ::WinFillRect(vDc.GetHPS(), &vDc.m_vRclPaint, GetBackgroundColour().GetPixel());
+    for ( wxToolBarToolsList::Node* pNode = m_tools.GetFirst();
+          pNode;
+          pNode = pNode->GetNext() )
+    {
+        wxToolBarTool*              pTool = (wxToolBarTool*)pNode->GetData();
+
+        if (pTool->IsButton() )
+            DrawTool(vDc, pTool);
+        if (pTool->IsSeparator())
+        {
+            wxPen                   vDarkGreyPen( wxColour(85, 85, 85)
+                                                 ,1
+                                                 ,wxSOLID
+                                                );
+            int                     nX;
+            int                     nY;
+            int                     nHeight = 0;
+            int                     nWidth = 0;
+
+            vDc.SetPen(vDarkGreyPen);
+            if (HasFlag(wxTB_TEXT))
+            {
+                if (HasFlag(wxTB_HORIZONTAL))
+                {
+                    nX = pTool->m_vX;
+                    nY = pTool->m_vY - (m_vTextY - 6);
+                    nHeight = (m_vTextY - 2) + pTool->GetHeight();
+                }
+                else
+                {
+                    nX = pTool->m_vX + m_xMargin + 10;
+                    nY = pTool->m_vY + m_vTextY + m_toolSeparation;
+                    nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
+                }
+            }
+            else
+            {
+                nX = pTool->m_vX;
+                nY = pTool->m_vY;
+                if (HasFlag(wxTB_HORIZONTAL))
+                    nHeight = pTool->GetHeight() - 2;
+                else
+                {
+                    nX += m_xMargin + 10;
+                    nY +=  m_yMargin + m_toolSeparation;
+                    nWidth = pTool->GetWidth();
+                }
+            }
+            vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
+        }
+    }
+    nCount--;
+} // end of wxToolBar::OnPaint
 
-void wxToolBar::SetRows(int nRows)
+void wxToolBar::OnSize (
+  wxSizeEvent&                      WXUNUSED(rEvent)
+)
 {
-// TODO:
-/*
-  RECT rect;
-  ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(nRows, TRUE), (LPARAM) & rect);
-  m_maxWidth = (rect.right - rect.left + 2);
-  m_maxHeight = (rect.bottom - rect.top + 2);
-*/
-}
-
-wxSize wxToolBar::GetMaxSize() const
+#if wxUSE_CONSTRAINTS
+    if (GetAutoLayout())
+        Layout();
+#endif
+} // end of wxToolBar::OnSize
+
+void wxToolBar::OnKillFocus(
+  wxFocusEvent&                     WXUNUSED(rEvent)
+)
 {
-// TODO:
-/*
-  if ((m_maxWidth == -1) || (m_maxHeight == -1))
-  {
-    RECT rect;
-    ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(m_maxRows, TRUE), (LPARAM) & rect);
-    ((wxToolBar *)this)->m_maxWidth = (rect.right - rect.left + 2); // ???
-    ((wxToolBar *)this)->m_maxHeight = (rect.bottom - rect.top + 2); // ???
-  }
-*/
-  return wxSize(m_maxWidth, m_maxHeight);
-}
-
-// The button size is bigger than the bitmap size
-wxSize wxToolBar::GetToolSize() const
+    OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
+} // end of wxToolBar::OnKillFocus
+
+void wxToolBar::OnMouseEvent(
+  wxMouseEvent&                     rEvent
+)
 {
-  return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
-}
+    POINTL                          vPoint;
+    HWND                            hWnd;
+    wxCoord                         vX;
+    wxCoord                         vY;
+    HPOINTER                        hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
+
+    ::WinSetPointer(HWND_DESKTOP, hPtr);
+    ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
+    hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
+    if (hWnd != (HWND)GetHwnd())
+    {
+        m_vToolTimer.Stop();
+        return;
+    }
+
+    rEvent.GetPosition(&vX, &vY);
+
+    wxToolBarTool*            pTool = (wxToolBarTool *)FindToolForPosition( vX
+                                                                           ,vY
+                                                                          );
+
+    if (rEvent.LeftDown())
+    {
+        CaptureMouse();
+    }
+    if (rEvent.LeftUp())
+    {
+        ReleaseMouse();
+    }
 
-void wxToolBar::EnableTool(int toolIndex, bool enable)
+    if (!pTool)
+    {
+        m_vToolTimer.Stop();
+        if (m_nCurrentTool > -1)
+        {
+            if (rEvent.LeftIsDown())
+                SpringUpButton(m_nCurrentTool);
+            pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
+            if (pTool && !pTool->IsToggled())
+            {
+                RaiseTool( pTool
+                          ,FALSE
+                         );
+            }
+            m_nCurrentTool = -1;
+            OnMouseEnter(-1);
+        }
+        return;
+    }
+    if (!rEvent.IsButton())
+    {
+        if (pTool->GetId() != m_nCurrentTool)
+        {
+            //
+            // If the left button is kept down and moved over buttons,
+            // press those buttons.
+            //
+            if (rEvent.LeftIsDown() && pTool->IsEnabled())
+            {
+                SpringUpButton(m_nCurrentTool);
+                if (pTool->CanBeToggled())
+                {
+                    pTool->Toggle();
+                }
+                DrawTool(pTool);
+            }
+            wxToolBarTool*          pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
+
+            if (pOldTool && !pTool->IsToggled())
+                RaiseTool( pOldTool
+                          ,FALSE
+                         );
+            m_nCurrentTool = pTool->GetId();
+            OnMouseEnter(m_nCurrentTool);
+            if (!pTool->GetShortHelp().IsEmpty())
+            {
+                if (m_pToolTip)
+                    delete m_pToolTip;
+                m_pToolTip = new wxToolTip(pTool->GetShortHelp());
+                m_vXMouse = (wxCoord)vPoint.x;
+                m_vYMouse = (wxCoord)vPoint.y;
+                m_vToolTimer.Start(1000L, TRUE);
+            }
+            if (!pTool->IsToggled())
+                RaiseTool(pTool);
+        }
+        return;
+    }
+
+    // Left button pressed.
+    if (rEvent.LeftDown() && pTool->IsEnabled())
+    {
+        if (pTool->CanBeToggled())
+        {
+            pTool->Toggle();
+        }
+        DrawTool(pTool);
+    }
+    else if (rEvent.RightDown())
+    {
+        OnRightClick( pTool->GetId()
+                     ,vX
+                     ,vY
+                    );
+    }
+
+    //
+    // Left Button Released.  Only this action confirms selection.
+    // If the button is enabled and it is not a toggle tool and it is
+    // in the pressed state, then raise the button and call OnLeftClick.
+    //
+    if (rEvent.LeftUp() && pTool->IsEnabled() )
+    {
+        //
+        // Pass the OnLeftClick event to tool
+        //
+        if (!OnLeftClick( pTool->GetId()
+                         ,pTool->IsToggled()) &&
+                          pTool->CanBeToggled())
+        {
+            //
+            // If it was a toggle, and OnLeftClick says No Toggle allowed,
+            // then change it back
+            //
+            pTool->Toggle();
+        }
+        DrawTool(pTool);
+    }
+} // end of wxToolBar::OnMouseEvent
+
+// ----------------------------------------------------------------------------
+// drawing
+// ----------------------------------------------------------------------------
+
+void wxToolBar::DrawTool(
+  wxToolBarToolBase*                pTool
+)
 {
-  wxNode *node = m_tools.Find((long)toolIndex);
-  if (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    tool->m_enabled = enable;
-//    ::SendMessage((HWND) GetHWND(), TB_ENABLEBUTTON, (WPARAM)toolIndex, (LPARAM)MAKELONG(enable, 0));
-  }
-}
-
-void wxToolBar::ToggleTool(int toolIndex, bool toggle)
+    wxClientDC                      vDc(this);
+
+    DrawTool( vDc
+             ,pTool
+            );
+} // end of wxToolBar::DrawTool
+
+void wxToolBar::DrawTool(
+  wxDC&                             rDc
+, wxToolBarToolBase*                pToolBase
+)
 {
-  wxNode *node = m_tools.Find((long)toolIndex);
-  if (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    if (tool->m_isToggle)
+    wxToolBarTool*                  pTool = (wxToolBarTool *)pToolBase;
+    wxPen                           vDarkGreyPen( wxColour( 85,85,85 )
+                                                 ,1
+                                                 ,wxSOLID
+                                                );
+    wxPen                           vWhitePen( wxT("WHITE")
+                                              ,1
+                                              ,wxSOLID
+                                             );
+    wxPen                           vBlackPen( wxT("BLACK")
+                                              ,1
+                                              ,wxSOLID
+                                             );
+    wxBitmap                        vBitmap = pTool->GetNormalBitmap();
+    bool                            bUseMask = FALSE;
+    wxMask*                         pMask = NULL;
+    RECTL                           vRect;
+
+    PrepareDC(rDc);
+
+    if (!vBitmap.Ok())
+        return;
+    if ((pMask = vBitmap.GetMask()) != NULL)
+        if (pMask->GetMaskBitmap() != NULLHANDLE)
+            bUseMask = TRUE;
+
+    if (!pTool->IsToggled())
     {
-      tool->m_toggleState = toggle;
-//      ::SendMessage((HWND) GetHWND(), TB_CHECKBUTTON, (WPARAM)toolIndex, (LPARAM)MAKELONG(toggle, 0));
+        LowerTool(pTool, FALSE);
+        if (!pTool->IsEnabled())
+        {
+            wxColour                vColor("GREY");
+
+            rDc.SetTextForeground(vColor);
+            if (!pTool->GetDisabledBitmap().Ok())
+                pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
+                                                         ,(long)GetBackgroundColour().GetPixel()
+                                                        ));
+            rDc.DrawBitmap( pTool->GetDisabledBitmap()
+                           ,pTool->m_vX
+                           ,pTool->m_vY
+                           ,bUseMask
+                          );
+        }
+        else
+        {
+            wxColour                vColor("BLACK");
+
+            rDc.SetTextForeground(vColor);
+            rDc.DrawBitmap( vBitmap
+                           ,pTool->m_vX
+                           ,pTool->m_vY
+                           ,bUseMask
+                          );
+        }
+        if (m_windowStyle & wxTB_3DBUTTONS)
+        {
+            RaiseTool(pTool);
+        }
+        if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+        {
+            wxCoord                 vX;
+            wxCoord                 vY;
+            wxCoord                 vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
+
+            rDc.SetFont(GetFont());
+            rDc.GetTextExtent( pTool->GetLabel()
+                              ,&vX
+                              ,&vY
+                             );
+            if (pTool->GetWidth() > vX) // large tools
+            {
+                vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
+                GetSize(&vX, &vY);
+                rDc.DrawText( pTool->GetLabel()
+                             ,vLeft
+                             ,vY - (m_vTextY - 2)
+                            );
+            }
+            else  // normal tools
+            {
+                vLeft += (wxCoord)((m_vTextX - vX)/2);
+                rDc.DrawText( pTool->GetLabel()
+                             ,vLeft
+                             ,pTool->m_vY + m_vTextY + 4 // a bit of margin
+                            );
+            }
+        }
     }
-  }
-}
+    else
+    {
+        wxColour                    vColor("GREY");
+
+        LowerTool(pTool);
+        rDc.SetTextForeground(vColor);
+        if (!pTool->GetDisabledBitmap().Ok())
+            pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
+                                                     ,(long)GetBackgroundColour().GetPixel()
+                                                    ));
+        rDc.DrawBitmap( pTool->GetDisabledBitmap()
+                       ,pTool->m_vX
+                       ,pTool->m_vY
+                       ,bUseMask
+                      );
+        if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+        {
+            wxCoord                 vX;
+            wxCoord                 vY;
+            wxCoord                 vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
+
+            rDc.SetFont(GetFont());
+            rDc.GetTextExtent( pTool->GetLabel()
+                              ,&vX
+                              ,&vY
+                             );
+            vLeft += (wxCoord)((m_vTextX - vX)/2);
+            rDc.DrawText( pTool->GetLabel()
+                         ,vLeft
+                         ,pTool->m_vY + m_vTextY + 4 // a bit of margin
+                        );
+        }
+    }
+} // end of wxToolBar::DrawTool
 
-bool wxToolBar::GetToolState(int toolIndex) const
-{
-//    return (::SendMessage((HWND) GetHWND(), TB_ISBUTTONCHECKED, (WPARAM)toolIndex, (LPARAM)0) != 0);
-    return FALSE;
-}
+// ----------------------------------------------------------------------------
+// toolbar geometry
+// ----------------------------------------------------------------------------
 
-void wxToolBar::ClearTools()
+void wxToolBar::SetRows(
+  int                               nRows
+)
 {
-  // TODO: Don't know how to reset the toolbar bitmap, as yet.
-  // But adding tools and calling CreateTools should probably
-  // recreate a buttonbar OK.
-  wxToolBarBase::ClearTools();
-}
-
-// If pushedBitmap is NULL, a reversed version of bitmap is
-// created and used as the pushed/toggled image.
-// If toggle is TRUE, the button toggles between the two states.
-wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap,
-             bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2)
+    wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
+
+    m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
+    Refresh();
+} // end of wxToolBar::SetRows
+
+wxToolBarToolBase* wxToolBar::FindToolForPosition(
+  wxCoord                           vX
+, wxCoord                           vY
+) const
 {
-  wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2);
-  tool->m_clientData = clientData;
+    wxCoord                         vTextX = 0;
+    wxCoord                         vTextY = 0;
+    wxCoord                         vTBarHeight = 0;
+
+    GetSize( NULL
+            ,&vTBarHeight
+           );
+    vY = vTBarHeight - vY;
+    wxToolBarToolsList::Node* pNode = m_tools.GetFirst();
+    while (pNode)
+    {
+        wxToolBarTool*              pTool = (wxToolBarTool *)pNode->GetData();
 
-  if (xPos > -1)
-    tool->m_x = xPos;
-  else
-    tool->m_x = m_xMargin;
+        if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+        {
+            if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
+                (vY >= (pTool->m_vY - 2)) &&
+                (vX <= (pTool->m_vX + pTool->GetWidth())) &&
+                (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
+            {
+                return pTool;
+            }
+        }
+        else
+        {
+            if ((vX >= pTool->m_vX) &&
+                (vY >= pTool->m_vY) &&
+                (vX <= (pTool->m_vX + pTool->GetWidth())) &&
+                (vY <= (pTool->m_vY + pTool->GetHeight())))
+            {
+                return pTool;
+            }
+        }
+        pNode = pNode->GetNext();
+    }
+    return (wxToolBarToolBase *)NULL;
+} // end of wxToolBar::FindToolForPosition
 
-  if (yPos > -1)
-    tool->m_y = yPos;
-  else
-    tool->m_y = m_yMargin;
+// ----------------------------------------------------------------------------
+// tool state change handlers
+// ----------------------------------------------------------------------------
 
-  tool->SetSize(GetToolSize().x, GetToolSize().y);
+void wxToolBar::DoEnableTool(
+  wxToolBarToolBase*                pTool
+, bool                              WXUNUSED(bEnable)
+)
+{
+    DrawTool(pTool);
+} // end of wxToolBar::DoEnableTool
 
-  m_tools.Append((long)index, tool);
-  return tool;
-}
+void wxToolBar::DoToggleTool(
+  wxToolBarToolBase*                pTool
+, bool                              WXUNUSED(bToggle)
+)
+{
+    DrawTool(pTool);
+} // end of wxToolBar::DoToggleTool
 
-// Responds to colour changes, and passes event on to children.
-void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event)
+void wxToolBar::DoSetToggle(
+  wxToolBarToolBase*                WXUNUSED(pTool)
+, bool                              WXUNUSED(bToggle)
+)
+{
+    // nothing to do
+} // end of wxToolBar::DoSetToggle
+
+//
+// Okay, so we've left the tool we're in ... we must check if the tool we're
+// leaving was a 'sprung push button' and if so, spring it back to the up
+// state.
+//
+void wxToolBar::SpringUpButton(
+  int                               vId
+)
 {
-// TODO:
-/*
-    m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
-          GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
-*/
-    // Remap the buttons
-    CreateTools();
+    wxToolBarToolBase*              pTool = FindById(vId);
 
-    Refresh();
+    if (pTool && pTool->CanBeToggled())
+    {
+        if (pTool->IsToggled())
+            pTool->Toggle();
 
-    // Propagate the event to the non-top-level children
-    wxWindow::OnSysColourChanged(event);
-}
+        DrawTool(pTool);
+    }
+} // end of wxToolBar::SpringUpButton
+
+// ----------------------------------------------------------------------------
+// private helpers
+// ----------------------------------------------------------------------------
 
-void wxToolBar::OnMouseEvent(wxMouseEvent& event)
+void wxToolBar::LowerTool (
+  wxToolBarToolBase*                pToolBase
+, bool                              bLower
+)
 {
-    if (event.RightDown())
+    wxToolBarTool*                  pTool = (wxToolBarTool*)pToolBase;
+    wxCoord                         vX;
+    wxCoord                         vY;
+    wxCoord                         vWidth;
+    wxCoord                         vHeight;
+    wxPen                           vDarkGreyPen( wxColour(85, 85, 85)
+                                                 ,1
+                                                 ,wxSOLID
+                                                );
+    wxPen                           vWhitePen( "WHITE"
+                                              ,1
+                                              ,wxSOLID
+                                             );
+    wxPen                           vClearPen( GetBackgroundColour()
+                                              ,1
+                                              ,wxSOLID
+                                             );
+    wxClientDC                      vDC(this);
+
+    if (!pTool)
+        return;
+
+    if (pTool->IsSeparator())
+        return;
+
+    //
+    // We only do this for flat toolbars
+    //
+    if (!HasFlag(wxTB_FLAT))
+        return;
+
+    if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
+    {
+        if (pTool->GetWidth() > m_vTextX)
+        {
+            vX = pTool->m_vX - 2;
+            vWidth = pTool->GetWidth() + 4;
+        }
+        else
+        {
+            vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
+            vWidth = m_vTextX + 4;
+        }
+        vY = pTool->m_vY - 2;
+        vHeight = pTool->GetHeight() + m_vTextY + 2;
+    }
+    else
+    {
+        vX = pTool->m_vX - 2;
+        vY = pTool->m_vY - 2;
+        vWidth = pTool->GetWidth() + 4;
+        vHeight = pTool->GetHeight() + 4;
+    }
+    if (bLower)
     {
-        // For now, we don't have an id. Later we could
-        // try finding the tool.
-        OnRightClick((int)-1, event.GetX(), event.GetY());
+        vDC.SetPen(vWhitePen);
+        vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+        vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+        vDC.SetPen(vDarkGreyPen);
+        vDC.DrawLine(vX, vY, vX + vWidth, vY);
+        vDC.DrawLine(vX, vY + vHeight, vX, vY);
     }
     else
     {
-        event.Skip();
+        vDC.SetPen(vClearPen);
+        vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+        vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+        vDC.DrawLine(vX, vY, vX + vWidth, vY);
+        vDC.DrawLine(vX, vY + vHeight, vX, vY);
     }
-}
-
-// These are the default colors used to map the bitmap colors
-// to the current system colors
+} // end of WinGuiBase_CToolBarTool::LowerTool
 
-#define BGR_BUTTONTEXT      (RGB(000,000,000))  // black
-#define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey
-#define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey
-#define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white
-#define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue
-#define BGR_BACKGROUND      (RGB(255,000,255))  // magenta
-
-void wxMapBitmap(HBITMAP hBitmap, int width, int height)
+void wxToolBar::RaiseTool (
+  wxToolBarToolBase*                pToolBase
+, bool                              bRaise
+)
 {
-// TODO:
-/*
-  COLORMAP ColorMap[] = {
-    {BGR_BUTTONTEXT,    COLOR_BTNTEXT},     // black
-    {BGR_BUTTONSHADOW,  COLOR_BTNSHADOW},   // dark grey
-    {BGR_BUTTONFACE,    COLOR_BTNFACE},     // bright grey
-    {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
-    {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT},   // blue
-    {BGR_BACKGROUND,    COLOR_WINDOW}       // magenta
-  };
-
-  int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
-  int n;
-  for ( n = 0; n < NUM_MAPS; n++)
-  {
-    ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
-  }
-
-  HBITMAP hbmOld;
-  HDC hdcMem = CreateCompatibleDC(NULL);
-
-  if (hdcMem)
-  {
-    hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap);
-
-    int i, j, k;
-    for ( i = 0; i < width; i++)
-    {
-        for ( j = 0; j < height; j++)
+    wxToolBarTool*                  pTool = (wxToolBarTool*)pToolBase;
+    wxCoord                         vX;
+    wxCoord                         vY;
+    wxCoord                         vWidth;
+    wxCoord                         vHeight;
+    wxPen                           vDarkGreyPen( wxColour(85, 85, 85)
+                                                 ,1
+                                                 ,wxSOLID
+                                                );
+    wxPen                           vWhitePen( "WHITE"
+                                              ,1
+                                              ,wxSOLID
+                                             );
+    wxPen                           vClearPen( GetBackgroundColour()
+                                              ,1
+                                              ,wxSOLID
+                                             );
+    wxClientDC                      vDC(this);
+
+    if (!pTool)
+        return;
+
+    if (pTool->IsSeparator())
+        return;
+
+    if (!pTool->IsEnabled())
+        return;
+
+    //
+    // We only do this for flat toolbars
+    //
+    if (!HasFlag(wxTB_FLAT))
+        return;
+
+    if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
+    {
+        if (pTool->GetWidth() > m_vTextX)
         {
-            COLORREF pixel = ::GetPixel(hdcMem, i, j);
-            BYTE red = GetRValue(pixel);
-            BYTE green = GetGValue(pixel);
-            BYTE blue = GetBValue(pixel);
-
-            for ( k = 0; k < NUM_MAPS; k ++)
-            {
-                if ( ColorMap[k].from == pixel )
-                {
-                    COLORREF actualPixel = ::SetPixel(hdcMem, i, j, ColorMap[k].to);
-                    break;
-                }
-            }
+            vX = pTool->m_vX - 2;
+            vWidth = pTool->GetWidth() + 4;
+        }
+        else
+        {
+            vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
+            vWidth = m_vTextX + 4;
         }
+        vY = pTool->m_vY - 2;
+        vHeight = pTool->GetHeight() + m_vTextY + 2;
     }
+    else
+    {
+        vX = pTool->m_vX - 2;
+        vY = pTool->m_vY - 2;
+        vWidth = pTool->GetWidth() + 4;
+        vHeight = pTool->GetHeight() + 4;
+    }
+    if (bRaise)
+    {
+        vDC.SetPen(vDarkGreyPen);
+        vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+        vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+        vDC.SetPen(vWhitePen);
+        vDC.DrawLine(vX, vY, vX + vWidth, vY);
+        vDC.DrawLine(vX, vY + vHeight, vX, vY);
+    }
+    else
+    {
+        vDC.SetPen(vClearPen);
+        vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+        vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+        vDC.DrawLine(vX, vY, vX + vWidth, vY);
+        vDC.DrawLine(vX, vY + vHeight, vX, vY);
+    }
+} // end of wxToolBar::RaiseTool
 
-    SelectObject(hdcMem, hbmOld);
-    DeleteObject(hdcMem);
-  }
-*/
-}
-
-// Some experiments...
-#if 0
-  // What we want to do is create another bitmap which has a depth of 4,
-  // and set the bits. So probably we want to convert this HBITMAP into a
-  // DIB, then call SetDIBits.
-  // AAAGH. The stupid thing is that if newBitmap has a depth of 4 (less than that of
-  // the screen), then SetDIBits fails.
-  HBITMAP newBitmap = ::CreateBitmap(totalBitmapWidth, totalBitmapHeight, 1, 4, NULL);
-  HANDLE newDIB = ::BitmapToDIB((HBITMAP) m_hBitmap, NULL);
-  LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) GlobalLock(newDIB);
-
-  dc = ::GetDC(NULL);
-//  LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) newDIB;
-
-  int result = ::SetDIBits(dc, newBitmap, 0, lpbmi->biHeight, FindDIBBits((LPSTR)lpbmi), (LPBITMAPINFO)lpbmi,
-    DIB_PAL_COLORS);
-  DWORD err = GetLastError();
-
-  ::ReleaseDC(NULL, dc);
-
-  // Delete the DIB
-  GlobalUnlock (newDIB);
-  GlobalFree (newDIB);
-
-//  WXHBITMAP hBitmap2 = wxCreateMappedBitmap((WXHINSTANCE) wxGetInstance(), (WXHBITMAP) m_hBitmap);
-  // Substitute our new bitmap for the old one
-  ::DeleteObject((HBITMAP) m_hBitmap);
-  m_hBitmap = (WXHBITMAP) newBitmap;
-#endif
+void wxToolBar::OnTimer (
+  wxTimerEvent&                     rEvent
+)
+{
+    if (rEvent.GetId() == m_vToolTimer.GetTimerId())
+    {
+        wxPoint                     vPos( m_vXMouse
+                                         ,m_vYMouse
+                                        );
 
+        m_pToolTip->DisplayToolTipWindow(vPos);
+        m_vToolTimer.Stop();
+        m_vToolExpTimer.Start(4000L, TRUE);
+    }
+    else if (rEvent.GetId() == m_vToolExpTimer.GetTimerId())
+    {
+        m_pToolTip->HideToolTipWindow();
+        GetParent()->Refresh();
+        m_vToolExpTimer.Stop();
+    }
+} // end of wxToolBar::OnTimer
 
-#endif
+#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE