]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/tbarmsw.cpp
Only send two EVT_BUTTON events when double clicking a button, not three
[wxWidgets.git] / src / msw / tbarmsw.cpp
index 2e5fdab316a83ef464c90d2403d99caecb4c2cbf..92b60a0fa10efd1e52ac42aab0a81cc0b6845dbc 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        tbarmsw.cpp
-// Purpose:     wxToolBarMSW
+// Purpose:     wxToolBar
 // Author:      Julian Smart
-// Modified by:
+// Modified by: 13.12.99 by VZ during toolbar classes reorganization
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
 // Licence:    wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 #ifdef __GNUG__
-#pragma implementation "tbarmsw.h"
+    #pragma implementation "tbarmsw.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/wx.h"
+    #include "wx/wx.h"
 #endif
 
-#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR
+#if wxUSE_TOOLBAR && defined(__WIN16__)
+
+#if !defined(__WIN32__) && !wxUSE_IMAGE_LOADING_IN_MSW
+    #error wxToolBar needs wxUSE_IMAGE_LOADING_IN_MSW under Win16
+#endif
 
 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
-#include "malloc.h"
+    #include "malloc.h"
 #endif
 
 #if !defined(__MWERKS__) && !defined(__SALFORDC__)
-#include <memory.h>
+    #include <memory.h>
 #endif
 
 #include <stdlib.h>
 
-#include "wx/tbarmsw.h"
+#include "wx/msw/tbarmsw.h"
 #include "wx/event.h"
 #include "wx/app.h"
 #include "wx/bitmap.h"
 #include "wx/msw/private.h"
 #include "wx/msw/dib.h"
 
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
 #define DEFAULTBITMAPX   16
 #define DEFAULTBITMAPY   15
 #define DEFAULTBUTTONX   24
 #define DEFAULTBUTTONY   22
 #define DEFAULTBARHEIGHT 27
 
-/////// Non-Windows 95 implementation
+//
+// States (not all of them currently used)
+//
+#define wxTBSTATE_CHECKED         0x01    // radio button is checked
+#define wxTBSTATE_PRESSED         0x02    // button is being depressed (any style)
+#define wxTBSTATE_ENABLED         0x04    // button is enabled
+#define wxTBSTATE_HIDDEN          0x08    // button is hidden
+#define wxTBSTATE_INDETERMINATE   0x10    // button is indeterminate
 
-#if !wxUSE_IMAGE_LOADING_IN_MSW
-#error If wxUSE_IMAGE_LOADING_IN_MSW is set to 0, then wxUSE_BUTTONBAR must be set to 0 too.
-#endif
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxToolBarTool : public wxToolBarToolBase
+{
+public:
+    wxToolBarTool(wxToolBar *tbar,
+                  int id,
+                  const wxBitmap& bmpNormal,
+                  const wxBitmap& bmpDisabled,
+                  bool toggle,
+                  wxObject *clientData,
+                  const wxString& shortHelp,
+                  const wxString& longHelp)
+        : wxToolBarToolBase(tbar, id, bmpNormal, bmpDisabled, toggle,
+                            clientData, shortHelp, longHelp)
+    {
+    }
+
+    wxToolBarTool(wxToolBar *tbar, wxControl *control)
+        : wxToolBarToolBase(tbar, control)
+    {
+    }
+
+    void SetSize(const wxSize& size)
+    {
+        m_width = size.x;
+        m_height = size.y;
+    }
+
+    long GetWidth() const { return m_width; }
+    long GetHeight() const { return m_height; }
+
+    wxCoord               m_x;
+    wxCoord               m_y;
+    wxCoord               m_width;
+    wxCoord               m_height;
+};
+
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
 
 #if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxToolBarMSW, wxToolBarBase)
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
 
-BEGIN_EVENT_TABLE(wxToolBarMSW, wxToolBarBase)
-       EVT_SIZE(wxToolBarMSW::OnSize)
-       EVT_PAINT(wxToolBarMSW::OnPaint)
-       EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent)
+BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
+       EVT_PAINT(wxToolBar::OnPaint)
+       EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
 END_EVENT_TABLE()
 #endif
 
-wxToolBarMSW::wxToolBarMSW(void)
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxToolBarTool
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase *wxToolBar::CreateTool(int id,
+                                         const wxString& label,
+                                         const wxBitmap& bmpNormal,
+                                         const wxBitmap& bmpDisabled,
+                                         wxItemKind kind,
+                                         wxObject *clientData,
+                                         const wxString& shortHelp,
+                                         const wxString& longHelp)
 {
-  m_hbrDither = 0;
-  m_rgbFace = 0;
-  m_rgbShadow = 0;
-  m_rgbHilight = 0;
-  m_rgbFrame = 0;
-  m_hdcMono = 0;
-  m_hbmMono = 0;
-  m_hbmDefault = 0;
-  m_defaultWidth = DEFAULTBITMAPX;
-  m_defaultHeight = DEFAULTBITMAPY;
+    return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
+                             clientData, shortHelp, longHelp);
 }
 
-bool wxToolBarMSW::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
-            long style, const wxString& name)
+wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
+{
+    return new wxToolBarTool(this, control);
+}
+
+// ----------------------------------------------------------------------------
+// wxToolBar
+// ----------------------------------------------------------------------------
+
+void wxToolBar::Init()
 {
-       if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
-               return FALSE;
+    m_hbrDither = 0;
+    m_rgbFace = 0;
+    m_rgbShadow = 0;
+    m_rgbHilight = 0;
+    m_rgbFrame = 0;
+    m_hdcMono = 0;
+    m_hbmMono = 0;
+    m_hbmDefault = 0;
 
-  if ( style & wxTB_HORIZONTAL )
-    { m_lastX = 3; m_lastY = 7; }
-  else
-    { m_lastX = 7; m_lastY = 3; }
-  m_maxWidth = m_maxHeight = 0;
-  m_pressedTool = m_currentTool = -1;
-  m_xMargin = 0;
-  m_yMargin = 0;
-  m_toolPacking = 1;
-  m_toolSeparation = 5;
+    m_defaultWidth = DEFAULTBITMAPX;
+    m_defaultHeight = DEFAULTBITMAPY;
+
+    m_xPos =
+    m_yPos = -1;
+
+    m_maxWidth = m_maxHeight = 0;
+    m_pressedTool = m_currentTool = -1;
+    m_toolPacking = 1;
+    m_toolSeparation = 5;
+}
 
-  // Set it to grey
-  SetBackgroundColour(wxColour(192, 192, 192));
+bool wxToolBar::Create(wxWindow *parent,
+                       wxWindowID id,
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       long style,
+                       const wxString& name)
+{
+    if ( !wxWindow::Create(parent, id, pos, size, style, name) )
+        return FALSE;
 
-  m_hbrDither = 0;
-  m_rgbFace = 0;
-  m_rgbShadow = 0;
-  m_rgbHilight = 0;
-  m_rgbFrame = 0;
-  m_hdcMono = 0;
-  m_hbmMono = 0;
-  m_hbmDefault = 0;
-  m_defaultWidth = DEFAULTBITMAPX;
-  m_defaultHeight = DEFAULTBITMAPY;
+    if ( style & wxTB_HORIZONTAL )
+    {
+        m_lastX = 3;
+        m_lastY = 7;
+    }
+    else
+    {
+        m_lastX = 7;
+        m_lastY = 3;
+    }
 
-  InitGlobalObjects();
+    // Set it to grey
+    SetBackgroundColour(wxColour(192, 192, 192));
 
-  return TRUE;
+    InitGlobalObjects();
+
+    return TRUE;
 }
 
-wxToolBarMSW::~wxToolBarMSW(void)
+wxToolBar::~wxToolBar()
 {
-  FreeGlobalObjects();
+    FreeGlobalObjects();
 }
 
-void wxToolBarMSW::SetToolBitmapSize(const wxSize& size)
+void wxToolBar::SetToolBitmapSize(const wxSize& size)
 {
-  m_defaultWidth = size.x; m_defaultHeight = size.y;
-  FreeGlobalObjects();
-  InitGlobalObjects();
+    m_defaultWidth = size.x;
+    m_defaultHeight = size.y;
+
+    FreeGlobalObjects();
+    InitGlobalObjects();
 }
 
 // The button size is bigger than the bitmap size
-wxSize wxToolBarMSW::GetToolSize(void) const
+wxSize wxToolBar::GetToolSize() const
 {
-  return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
+    return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
 }
 
-void wxToolBarMSW::OnPaint(wxPaintEvent& event)
+wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
 {
-  wxPaintDC dc(this);
+    wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    while (node)
+    {
+        wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
+        if ((x >= tool->m_x) && (y >= tool->m_y) &&
+            (x <= (tool->m_x + tool->GetWidth())) &&
+            (y <= (tool->m_y + tool->GetHeight())))
+        {
+            return tool;
+        }
 
-  static int wxOnPaintCount = 0;
+        node = node->GetNext();
+    }
 
-  // Prevent reentry of OnPaint which would cause
-  // wxMemoryDC errors.
-  if (wxOnPaintCount > 0)
-    return;
-  wxOnPaintCount ++;
+    return (wxToolBarToolBase *)NULL;
+}
 
-  wxNode *node = m_tools.First();
-  while (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    if (tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR)
-    {
-      int state = wxTBSTATE_ENABLED;
-      if (!tool->m_enabled)
-        state = 0;
-      if (tool->m_isToggle && tool->m_toggleState)
-        state |= wxTBSTATE_CHECKED;
-      DrawTool(dc, tool, state);
-    }
-    node = node->Next();
-  }
-  wxOnPaintCount --;
+wxToolBarToolBase *wxToolBar::AddTool(int id,
+                                      const wxBitmap& bitmap,
+                                      const wxBitmap& pushedBitmap,
+                                      bool toggle,
+                                      wxCoord xPos,
+                                      wxCoord yPos,
+                                      wxObject *clientData,
+                                      const wxString& helpString1,
+                                      const wxString& helpString2)
+{
+    // rememeber the position for DoInsertTool()
+    m_xPos = xPos;
+    m_yPos = yPos;
+
+    return wxToolBarBase::AddTool(id, bitmap, pushedBitmap, toggle,
+                                  xPos, yPos, clientData,
+                                  helpString1, helpString2);
 }
 
-void wxToolBarMSW::OnSize(wxSizeEvent& event)
+void wxToolBar::OnPaint(wxPaintEvent& event)
 {
-  wxToolBarBase::OnSize(event);
+    wxPaintDC dc(this);
+
+    static int wxOnPaintCount = 0;
+
+    // Prevent reentry of OnPaint which would cause
+    // wxMemoryDC errors.
+    if (wxOnPaintCount > 0)
+        return;
+    wxOnPaintCount++;
+
+    wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    while (node)
+    {
+        wxToolBarToolBase *tool = node->GetData();
+        if ( tool->GetStyle()!= wxTOOL_STYLE_BUTTON )
+        {
+            int state = tool->IsEnabled() ? wxTBSTATE_ENABLED : 0;
+            if ( tool->IsToggled() )
+                state |= wxTBSTATE_CHECKED;
+
+            DrawTool(dc, tool, state);
+        }
+
+        node = node->GetNext();
+    }
+
+    wxOnPaintCount--;
 }
 
 // If a Button is disabled, then NO function (besides leaving
 // or entering) should be carried out. Therefore the additions
 // of 'enabled' testing (Stefan Hammes).
-void wxToolBarMSW::OnMouseEvent(wxMouseEvent& event)
+void wxToolBar::OnMouseEvent(wxMouseEvent& event)
 {
-  static wxToolBarTool *eventCurrentTool = NULL;
-  wxClientDC dc(this);
+    static wxToolBarToolBase *eventCurrentTool = NULL;
+    wxClientDC dc(this);
 
-  if (event.Leaving())
-  {
-    m_currentTool = -1;
-    if (eventCurrentTool && eventCurrentTool->m_enabled)
+    if (event.Leaving())
     {
-      ::ReleaseCapture();
-      int state = wxTBSTATE_ENABLED;
-      if (eventCurrentTool->m_toggleState)
-        state |= wxTBSTATE_CHECKED;
-      DrawTool(dc, eventCurrentTool, state);
-      eventCurrentTool = NULL;
+        m_currentTool = -1;
+        if (eventCurrentTool && eventCurrentTool->IsEnabled())
+        {
+            ::ReleaseCapture();
+            int state = wxTBSTATE_ENABLED;
+            if (eventCurrentTool->IsToggled())
+                state |= wxTBSTATE_CHECKED;
+            DrawTool(dc, eventCurrentTool, state);
+            eventCurrentTool = NULL;
+        }
+        OnMouseEnter(-1);
+        return;
     }
-    OnMouseEnter(-1);
-    return;
-  }
 
-  long x, y;
-  event.Position(&x, &y);
-  wxToolBarTool *tool = FindToolForPosition(x, y);
+    wxCoord x, y;
+    event.GetPosition(&x, &y);
+    wxToolBarToolBase *tool = FindToolForPosition(x, y);
 
-  if (!tool)
-  {
-    if (eventCurrentTool && eventCurrentTool->m_enabled)
+    if (!tool)
     {
-      ::ReleaseCapture();
-      
-      int state = wxTBSTATE_ENABLED;
-      if (eventCurrentTool->m_toggleState)
-        state |= wxTBSTATE_CHECKED;
-      DrawTool(dc, eventCurrentTool, state);
-      eventCurrentTool = NULL;
-    }
-    if (m_currentTool > -1)
-    {
-      m_currentTool = -1;
-      OnMouseEnter(-1);
+        if (eventCurrentTool && eventCurrentTool->IsEnabled())
+        {
+            ::ReleaseCapture();
+
+            int state = wxTBSTATE_ENABLED;
+            if (eventCurrentTool->IsToggled())
+                state |= wxTBSTATE_CHECKED;
+            DrawTool(dc, eventCurrentTool, state);
+            eventCurrentTool = NULL;
+        }
+        if (m_currentTool > -1)
+        {
+            m_currentTool = -1;
+            OnMouseEnter(-1);
+        }
+        return;
     }
-    return;
-  }
-  
-  if (!event.Dragging() && !event.IsButton())
-  {
-    if (tool->m_index != m_currentTool)
+
+    if (!event.Dragging() && !event.IsButton())
     {
-      OnMouseEnter(tool->m_index);
-      m_currentTool = tool->m_index;
-      return;
+        if (tool->GetId() != m_currentTool)
+        {
+            OnMouseEnter(m_currentTool = tool->GetId());
+            return;
+        }
     }
-  }
-  if (event.Dragging() && tool->m_enabled)
-  {
-    if (eventCurrentTool)
+    if (event.Dragging() && tool->IsEnabled())
     {
-      // Might have dragged outside tool
-      if (eventCurrentTool != tool)
-      {
-        int state = wxTBSTATE_ENABLED;
-        if (tool->m_toggleState)
-          state |= wxTBSTATE_CHECKED;
-        DrawTool(dc, tool, state);
-        eventCurrentTool = NULL;
-        return;
-      }
+        if (eventCurrentTool)
+        {
+            // Might have dragged outside tool
+            if (eventCurrentTool != tool)
+            {
+                int state = wxTBSTATE_ENABLED;
+                if (tool->IsToggled())
+                    state |= wxTBSTATE_CHECKED;
+                DrawTool(dc, tool, state);
+                eventCurrentTool = NULL;
+                return;
+            }
+        }
+        else
+        {
+            if (tool && event.LeftIsDown() && tool->IsEnabled())
+            {
+                eventCurrentTool = tool;
+                ::SetCapture((HWND) GetHWND());
+                int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED;
+                if (tool->IsToggled())
+                    state |= wxTBSTATE_CHECKED;
+                DrawTool(dc, tool, state);
+            }
+        }
     }
-    else
+    if (event.LeftDown() && tool->IsEnabled())
     {
-      if (tool && event.LeftIsDown() && tool->m_enabled)
-      {
         eventCurrentTool = tool;
         ::SetCapture((HWND) GetHWND());
         int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED;
-        if (tool->m_toggleState)
-          state |= wxTBSTATE_CHECKED;
+        if (tool->IsToggled())
+            state |= wxTBSTATE_CHECKED;
         DrawTool(dc, tool, state);
-      }
     }
-  }
-  if (event.LeftDown() && tool->m_enabled)
-  {
-    eventCurrentTool = tool;
-    ::SetCapture((HWND) GetHWND());
-    int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED;
-    if (tool->m_toggleState)
-      state |= wxTBSTATE_CHECKED;
-    DrawTool(dc, tool, state);
-  }
-  else if (event.LeftUp() && tool->m_enabled)
-  {
-    if (eventCurrentTool)
-      ::ReleaseCapture();
-    if (eventCurrentTool == tool)
+    else if (event.LeftUp() && tool->IsEnabled())
     {
-      if (tool->m_isToggle)
-      {
-        tool->m_toggleState = !tool->m_toggleState;
-        if (!OnLeftClick(tool->m_index, tool->m_toggleState))
+        if (eventCurrentTool)
+            ::ReleaseCapture();
+        if (eventCurrentTool == tool)
         {
-          tool->m_toggleState = !tool->m_toggleState;
+            if (tool->CanBeToggled())
+            {
+                tool->Toggle();
+                if (!OnLeftClick(tool->GetId(), tool->IsToggled()))
+                {
+                    tool->Toggle();
+                }
+                int state = wxTBSTATE_ENABLED;
+                if (tool->IsToggled())
+                    state |= wxTBSTATE_CHECKED;
+                DrawTool(dc, tool, state);
+            }
+            else
+            {
+                int state = wxTBSTATE_ENABLED;
+                if (tool->IsToggled())
+                    state |= wxTBSTATE_CHECKED;
+                DrawTool(dc, tool, state);
+                OnLeftClick(tool->GetId(), tool->IsToggled());
+            }
         }
-        int state = wxTBSTATE_ENABLED;
-        if (tool->m_toggleState)
-          state |= wxTBSTATE_CHECKED;
-        DrawTool(dc, tool, state);
-      }
-      else
-      {
-        int state = wxTBSTATE_ENABLED;
-        if (tool->m_toggleState)
-          state |= wxTBSTATE_CHECKED;
-        DrawTool(dc, tool, state);
-        OnLeftClick(tool->m_index, tool->m_toggleState);
-      }
+        eventCurrentTool = NULL;
+    }
+    else if (event.RightDown() && tool->IsEnabled())
+    {
+        OnRightClick(tool->GetId(), x, y);
     }
-    eventCurrentTool = NULL;
-  }
-  else if (event.RightDown() && tool->m_enabled)
-  {
-    OnRightClick(tool->m_index, x, y);
-  }
 }
 
-// This function enables/disables a toolbar tool and redraws it.
-// If that would not be done, the enabling/disabling wouldn't be
-// visible on the screen.
-void wxToolBarMSW::EnableTool(int toolIndex, bool enable)
+void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool WXUNUSED(enable))
 {
-  wxNode *node = m_tools.Find((long)toolIndex);
-  if (node)
-  {
-       wxClientDC dc(this);
-
-    // at first do the enabling/disabling in the base class
-    wxToolBarBase::EnableTool(toolIndex,enable);
-    // then calculate the state of the tool and draw it
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    int state = 0;
-    if(tool->m_toggleState) state |= wxTBSTATE_CHECKED;
-    if(tool->m_enabled) state |= wxTBSTATE_ENABLED;
-    // how can i access the PRESSED state???
-    DrawTool(dc, tool,state);
-  }
+    DoRedrawTool(tool);
 }
 
-void wxToolBarMSW::DrawTool(wxDC& dc, wxToolBarTool *tool, int state)
+void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool WXUNUSED(toggle))
 {
-  DrawButton(dc.GetHDC(), (int)tool->m_x, (int)tool->m_y, (int)tool->GetWidth(), (int)tool->GetHeight(), tool, state);
+    DoRedrawTool(tool);
 }
 
-void wxToolBarMSW::DrawTool(wxDC& dc, wxMemoryDC& , wxToolBarTool *tool)
+void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
+                            bool WXUNUSED(toggle))
 {
-  int state = wxTBSTATE_ENABLED;
-  if (!tool->m_enabled)
-    state = 0;
-  if (tool->m_toggleState)
-    state |= wxTBSTATE_CHECKED;
-  DrawTool(dc, tool, state);
+    // nothing to do
 }
 
-// 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 *wxToolBarMSW::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap,
-             bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2)
+void wxToolBar::DoRedrawTool(wxToolBarToolBase *tool)
 {
-  // Using bitmap2 can cause problems (don't know why!)
+    wxClientDC dc(this);
 
-  // TODO: use the mapping code from wxToolBar95 to get it right in this class
-#if !defined(__WIN32__) && !defined(__WIN386__)
-  wxBitmap bitmap2;
-  if (toggle)
-  {
-    bitmap2.SetHBITMAP( (WXHBITMAP) CreateMappedBitmap(wxGetInstance(), (HBITMAP) ((wxBitmap& )bitmap).GetHBITMAP()));
-  }
+    DrawTool(dc, tool);
+}
 
-  wxToolBarTool *tool = new wxToolBarTool(index, bitmap, bitmap2, toggle, xPos, yPos, helpString1, helpString2);
-#else
-  wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2);
-#endif
+void wxToolBar::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase, int state)
+{
+    wxToolBarTool *tool = (wxToolBarTool *)toolBase;
 
-  tool->m_clientData = clientData;
+    DrawButton(dc.GetHDC(),
+               tool->m_x, tool->m_y,
+               tool->GetWidth(), tool->GetHeight(),
+               tool, state);
+}
 
-  if (xPos > -1)
-    tool->m_x = xPos;
-  else
-    tool->m_x = m_xMargin;
+void wxToolBar::DrawTool(wxDC& dc, wxToolBarToolBase *tool)
+{
+    int state = 0;
+    if (tool->IsEnabled())
+        state |= wxTBSTATE_ENABLED;
+    if (tool->IsToggled())
+        state |= wxTBSTATE_CHECKED;
+    // how can i access the PRESSED state???
 
-  if (yPos > -1)
-    tool->m_y = yPos;
-  else
-    tool->m_y = m_yMargin;
+    DrawTool(dc, tool, state);
+}
 
-  tool->m_deleteSecondBitmap = TRUE;
-  tool->SetSize(GetToolSize().x, GetToolSize().y);
-  
-  // Calculate reasonable max size in case Layout() not called
-  if ((tool->m_x + bitmap.GetWidth() + m_xMargin) > m_maxWidth)
-    m_maxWidth = (tool->m_x + tool->GetWidth() + m_xMargin);
+bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos),
+                             wxToolBarToolBase *tool)
+{
+    // VZ: didn't test whether it works, but why not...
+    tool->Detach();
 
-  if ((tool->m_y + bitmap.GetHeight() + m_yMargin) > m_maxHeight)
-    m_maxHeight = (tool->m_y + tool->GetHeight() + m_yMargin);
+    Refresh();
 
-  m_tools.Append((long)index, tool);
-  return tool;
+    return TRUE;
 }
 
-void wxToolBarMSW::Layout(void)
+bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
 {
-  m_currentRowsOrColumns = 0;
-  m_lastX = m_xMargin;
-  m_lastY = m_yMargin;
-  int maxToolWidth = 0;
-  int maxToolHeight = 0;
-  m_maxWidth = 0;
-  m_maxHeight = 0;
+    wxToolBarTool *tool = (wxToolBarTool *)toolBase;
 
-  // Find the maximum tool width and height
-  wxNode *node = m_tools.First();
-  while (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    if (tool->GetWidth() > maxToolWidth)
-      maxToolWidth = (int)tool->GetWidth();
-    if (tool->GetHeight() > maxToolHeight)
-      maxToolHeight = (int)tool->GetHeight();
-    node = node->Next();
-  }
+    wxCHECK_MSG( !tool->IsControl(), FALSE,
+                 _T("generic wxToolBar doesn't support controls") );
 
-  int separatorSize = m_toolSeparation;
+    // TODO: use the mapping code from wxToolBar95 to get it right in this class
+#if !defined(__WIN32__) && !defined(__WIN386__)
+    wxBitmap bmpDisabled;
+    if (tool->CanBeToggled())
+    {
+        HBITMAP hbmp = CreateMappedBitmap((WXHINSTANCE)wxGetInstance(),
+                                          GetHbitmapOf(tool->GetBitmap1()));
 
-  node = m_tools.First();
-  while (node)
-  {
-    wxToolBarTool *tool = (wxToolBarTool *)node->Data();
-    if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR)
+        wxBitmap bmp;
+        bmp.SetHBITMAP((WXHBITMAP)hbmp);
+        tool->SetBitmap2(bmp);
+    }
+#endif
+
+    tool->m_x = m_xPos;
+    if ( tool->m_x == -1 )
+        tool->m_x = m_xMargin;
+
+    tool->m_y = m_yPos;
+    if ( tool->m_y == -1 )
+        tool->m_y = m_yMargin;
+
+    tool->SetSize(GetToolSize());
+
+    if ( tool->IsButton() )
     {
-      if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
-      {
-        if (m_currentRowsOrColumns >= m_maxCols)
-          m_lastY += separatorSize;
-        else
-          m_lastX += separatorSize;
-      }
-      else
-      {
-        if (m_currentRowsOrColumns >= m_maxRows)
-          m_lastX += separatorSize;
-        else
-          m_lastY += separatorSize;
-      }
+        // Calculate reasonable max size in case Layout() not called
+        if ((tool->m_x + tool->GetBitmap1().GetWidth() + m_xMargin) > m_maxWidth)
+            m_maxWidth = (tool->m_x + tool->GetWidth() + m_xMargin);
+
+        if ((tool->m_y + tool->GetBitmap1().GetHeight() + m_yMargin) > m_maxHeight)
+            m_maxHeight = (tool->m_y + tool->GetHeight() + m_yMargin);
     }
-    else if (tool->m_toolStyle == wxTOOL_STYLE_BUTTON)
+
+    return TRUE;
+}
+
+bool wxToolBar::Realize()
+{
+    m_currentRowsOrColumns = 0;
+    m_lastX = m_xMargin;
+    m_lastY = m_yMargin;
+    int maxToolWidth = 0;
+    int maxToolHeight = 0;
+    m_maxWidth = 0;
+    m_maxHeight = 0;
+
+    // Find the maximum tool width and height
+    wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    while (node)
     {
-      if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
-      {
-        if (m_currentRowsOrColumns >= m_maxCols)
+        wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
+        if (tool->GetWidth() > maxToolWidth)
+            maxToolWidth = tool->GetWidth();
+        if (tool->GetHeight() > maxToolHeight)
+            maxToolHeight = tool->GetHeight();
+        node = node->GetNext();
+    }
+
+    int separatorSize = m_toolSeparation;
+
+    node = m_tools.GetFirst();
+    while (node)
+    {
+        wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
+        if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
         {
-          m_currentRowsOrColumns = 0;
-          m_lastX = m_xMargin;
-          m_lastY += maxToolHeight + m_toolPacking;
+            if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+            {
+                if (m_currentRowsOrColumns >= m_maxCols)
+                    m_lastY += separatorSize;
+                else
+                    m_lastX += separatorSize;
+            }
+            else
+            {
+                if (m_currentRowsOrColumns >= m_maxRows)
+                    m_lastX += separatorSize;
+                else
+                    m_lastY += separatorSize;
+            }
         }
-        tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
-        tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
-  
-        m_lastX += maxToolWidth + m_toolPacking;
-      }
-      else
-      {
-        if (m_currentRowsOrColumns >= m_maxRows)
+        else if (tool->GetStyle() == wxTOOL_STYLE_BUTTON)
         {
-          m_currentRowsOrColumns = 0;
-          m_lastX += (maxToolWidth + m_toolPacking);
-          m_lastY = m_yMargin;
+            if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+            {
+                if (m_currentRowsOrColumns >= m_maxCols)
+                {
+                    m_currentRowsOrColumns = 0;
+                    m_lastX = m_xMargin;
+                    m_lastY += maxToolHeight + m_toolPacking;
+                }
+                tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
+                tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
+
+                m_lastX += maxToolWidth + m_toolPacking;
+            }
+            else
+            {
+                if (m_currentRowsOrColumns >= m_maxRows)
+                {
+                    m_currentRowsOrColumns = 0;
+                    m_lastX += (maxToolWidth + m_toolPacking);
+                    m_lastY = m_yMargin;
+                }
+                tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
+                tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
+
+                m_lastY += maxToolHeight + m_toolPacking;
+            }
+            m_currentRowsOrColumns ++;
         }
-        tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
-        tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
-  
-        m_lastY += maxToolHeight + m_toolPacking;
-      }
-      m_currentRowsOrColumns ++;
+
+        if (m_lastX > m_maxWidth)
+            m_maxWidth = m_lastX;
+        if (m_lastY > m_maxHeight)
+            m_maxHeight = m_lastY;
+
+        node = node->GetNext();
     }
-    
-    if (m_lastX > m_maxWidth)
-      m_maxWidth = m_lastX;
-    if (m_lastY > m_maxHeight)
-      m_maxHeight = m_lastY;
 
-    node = node->Next();
-  }
-  if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
-  {
-    m_maxWidth += maxToolWidth;
-    m_maxHeight += maxToolHeight;
-  }
-  else
-  {
-    m_maxWidth += maxToolWidth;
-    m_maxHeight += maxToolHeight;
-  }
+    if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+    {
+        m_maxWidth += maxToolWidth;
+        m_maxHeight += maxToolHeight;
+    }
+    else
+    {
+        m_maxWidth += maxToolWidth;
+        m_maxHeight += maxToolHeight;
+    }
 
-  m_maxWidth += m_xMargin;
-  m_maxHeight += m_yMargin;
+    m_maxWidth += m_xMargin;
+    m_maxHeight += m_yMargin;
 
-  SetSize(m_maxWidth, m_maxHeight);
-}
+    SetSize(m_maxWidth, m_maxHeight);
 
+    return TRUE;
+}
 
-bool wxToolBarMSW::InitGlobalObjects(void)
+bool wxToolBar::InitGlobalObjects()
 {
-  GetSysColors();      
-  if (!CreateDitherBrush())
-    return FALSE;
+    GetSysColors();      
+    if (!CreateDitherBrush())
+        return FALSE;
 
-  m_hdcMono = (WXHDC) CreateCompatibleDC(NULL);
-  if (!m_hdcMono)
-      return FALSE;
+    m_hdcMono = (WXHDC) CreateCompatibleDC(NULL);
+    if (!m_hdcMono)
+        return FALSE;
 
-  m_hbmMono = (WXHBITMAP) CreateBitmap((int)GetToolSize().x, (int)GetToolSize().y, 1, 1, NULL);
-  if (!m_hbmMono)
-      return FALSE;
+    m_hbmMono = (WXHBITMAP) CreateBitmap((int)GetToolSize().x, (int)GetToolSize().y, 1, 1, NULL);
+    if (!m_hbmMono)
+        return FALSE;
 
-  m_hbmDefault = (WXHBITMAP) SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmMono);
-  return TRUE;
+    m_hbmDefault = (WXHBITMAP) SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmMono);
+    return TRUE;
 }
 
-void wxToolBarMSW::FreeGlobalObjects(void)
+void wxToolBar::FreeGlobalObjects()
 {
     FreeDitherBrush();
 
     if (m_hdcMono) {
-       if (m_hbmDefault)
-       {
-           SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmDefault);
-           m_hbmDefault = 0;
-       }
-       DeleteDC((HDC) m_hdcMono);              // toast the DCs
+        if (m_hbmDefault)
+        {
+            SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmDefault);
+            m_hbmDefault = 0;
+        }
+        DeleteDC((HDC) m_hdcMono);             // toast the DCs
     }
     m_hdcMono = 0;
 
     if (m_hbmMono)
-               DeleteObject((HBITMAP) m_hbmMono);
+        DeleteObject((HBITMAP) m_hbmMono);
     m_hbmMono = 0;
 }
 
+// ----------------------------------------------------------------------------
+// drawing routines
+// ----------------------------------------------------------------------------
 
-void wxToolBarMSW::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb)
+void wxToolBar::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb)
 {
     RECT    rc;
 
@@ -538,7 +688,7 @@ void wxToolBarMSW::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb)
 //   1's where color == COLOR_BTNFACE || COLOR_HILIGHT
 //   0's everywhere else
 
-void wxToolBarMSW::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int dy)
+void wxToolBar::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int dy)
 {
     HDC globalDC = ::GetDC(NULL);
     HDC hdcGlyphs = CreateCompatibleDC((HDC) globalDC);
@@ -569,37 +719,40 @@ void wxToolBarMSW::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int d
     DeleteDC(hdcGlyphs);
 }
 
-void wxToolBarMSW::DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state)
+void wxToolBar::DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state)
 {
     // face color
     PatB(hdc, x, y, dx, dy, m_rgbFace);
 
     if (state & wxTBSTATE_PRESSED) {
-       PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame);
-       PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame);
-       PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame);
-       PatB(hdc, x + dx - 1, y +1, 1, dy - 2, m_rgbFrame);
-       PatB(hdc, x + 1, y + 1, 1, dy-2, m_rgbShadow);
-       PatB(hdc, x + 1, y + 1, dx-2, 1, m_rgbShadow);
+        PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame);
+        PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame);
+        PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame);
+        PatB(hdc, x + dx - 1, y +1, 1, dy - 2, m_rgbFrame);
+        PatB(hdc, x + 1, y + 1, 1, dy-2, m_rgbShadow);
+        PatB(hdc, x + 1, y + 1, dx-2, 1, m_rgbShadow);
     }
     else {
-       PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame);
-       PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame);
-       PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame);
-       PatB(hdc, x + dx - 1, y + 1, 1, dy - 2, m_rgbFrame);
-       dx -= 2;
-       dy -= 2;
-       PatB(hdc, x + 1, y + 1, 1, dy - 1, m_rgbHilight);
-       PatB(hdc, x + 1, y + 1, dx - 1, 1, m_rgbHilight);
-       PatB(hdc, x + dx, y + 1, 1, dy, m_rgbShadow);
-       PatB(hdc, x + 1, y + dy, dx, 1,   m_rgbShadow);
-       PatB(hdc, x + dx - 1, y + 2, 1, dy - 2, m_rgbShadow);
-       PatB(hdc, x + 2, y + dy - 1, dx - 2, 1,   m_rgbShadow);
+        PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame);
+        PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame);
+        PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame);
+        PatB(hdc, x + dx - 1, y + 1, 1, dy - 2, m_rgbFrame);
+        dx -= 2;
+        dy -= 2;
+        PatB(hdc, x + 1, y + 1, 1, dy - 1, m_rgbHilight);
+        PatB(hdc, x + 1, y + 1, dx - 1, 1, m_rgbHilight);
+        PatB(hdc, x + dx, y + 1, 1, dy, m_rgbShadow);
+        PatB(hdc, x + 1, y + dy, dx, 1,   m_rgbShadow);
+        PatB(hdc, x + dx - 1, y + 2, 1, dy - 2, m_rgbShadow);
+        PatB(hdc, x + 2, y + dy - 1, dx - 2, 1,   m_rgbShadow);
     }
 }
 
-void wxToolBarMSW::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBarTool *tool, int state)
+void wxToolBar::DrawButton(WXHDC hdc, int x, int y, int dx, int dy,
+                           wxToolBarToolBase *toolBase, int state)
 {
+    wxToolBarTool *tool = (wxToolBarTool *)toolBase;
+
     int yOffset;
     HBRUSH hbrOld, hbr;
     BOOL bMaskCreated = FALSE;
@@ -632,17 +785,19 @@ void wxToolBarMSW::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBar
     dxFace -= 3;               
     dyFace -= 3;
 
-    // Using bitmap2 can cause problems (don't know why!)
+    // Using bmpDisabled can cause problems (don't know why!)
 #if !defined(__WIN32__) && !defined(__WIN386__)
     HBITMAP bitmapOld;
-    if (tool->m_bitmap2.Ok())
-      bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, (HBITMAP) tool->m_bitmap2.GetHBITMAP());
+    if (tool->GetBitmap2().Ok())
+      bitmapOld = GetHbitmapOf(tool->GetBitmap2());
     else
-      bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, (HBITMAP) tool->m_bitmap1.GetHBITMAP());
+      bitmapOld = GetHbitmapOf(tool->GetBitmap1());
 #else
-    HBITMAP bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, (HBITMAP) tool->m_bitmap1.GetHBITMAP());
+    HBITMAP bitmapOld = GetHbitmapOf(tool->GetBitmap1());
 #endif    
 
+    bitmapOld = (HBITMAP)SelectObject(hdcGlyphs, bitmapOld);
+
     // calculate offset of face from (x,y).  y is always from the top,
     // so the offset is easy.  x needs to be centered in face.
     yOffset = 1;
@@ -721,7 +876,11 @@ void wxToolBarMSW::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBar
     DeleteDC(hdcGlyphs);
 }
 
-void wxToolBarMSW::GetSysColors(void)
+// ----------------------------------------------------------------------------
+// drawing helpers
+// ----------------------------------------------------------------------------
+
+void wxToolBar::GetSysColors()
 {
        static COLORREF rgbSaveFace    = 0xffffffffL,
                        rgbSaveShadow  = 0xffffffffL,
@@ -753,7 +912,7 @@ void wxToolBarMSW::GetSysColors(void)
        }
 }
 
-WXHBITMAP wxToolBarMSW::CreateDitherBitmap()
+WXHBITMAP wxToolBar::CreateDitherBitmap()
 {
     BITMAPINFO* pbmi;
     HBITMAP hbm;
@@ -806,7 +965,7 @@ WXHBITMAP wxToolBarMSW::CreateDitherBitmap()
     return (WXHBITMAP)hbm;
 }
 
-bool wxToolBarMSW::CreateDitherBrush(void)
+bool wxToolBar::CreateDitherBrush()
 {
        HBITMAP hbmGray;
        HBRUSH hbrSave;
@@ -836,7 +995,7 @@ bool wxToolBarMSW::CreateDitherBrush(void)
        return FALSE;
 }
 
-bool wxToolBarMSW::FreeDitherBrush(void)
+bool wxToolBar::FreeDitherBrush(void)
 {
     if (m_hbrDither)
       DeleteObject((HBRUSH) m_hbrDither);
@@ -862,7 +1021,7 @@ typedef struct tagCOLORMAP2
 #define BGR_BACKGROUND      (RGB(255,000,255))  // magenta
 #define FlipColor(rgb)      (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
 
-WXHBITMAP wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void *info)
+WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void *info)
 {
   LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)info;
   HDC                  hdc, hdcMem = NULL;
@@ -942,9 +1101,9 @@ WXHBITMAP wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void
   return (WXHBITMAP) hbm;
 }
 
-WXHBITMAP wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap)
+WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap)
 {
-  HANDLE hDIB = BitmapToDIB((HBITMAP) hBitmap, 0);
+  HANDLE hDIB = wxBitmapToDIB((HBITMAP) hBitmap, 0);
   if (hDIB)
   {
 #ifdef __WINDOWS_386__