1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   5 // Modified by: 13.12.99 by VZ during toolbar classes reorganization 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "tbarmsw.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  35 #if wxUSE_TOOLBAR && defined(__WIN16__) 
  37 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) 
  41 #if !defined(__MWERKS__) && !defined(__SALFORDC__) 
  47 #include "wx/msw/tbarmsw.h" 
  50 #include "wx/bitmap.h" 
  51 #include "wx/msw/private.h" 
  52 #include "wx/msw/dib.h" 
  54 // ---------------------------------------------------------------------------- 
  56 // ---------------------------------------------------------------------------- 
  58 #define DEFAULTBITMAPX   16 
  59 #define DEFAULTBITMAPY   15 
  60 #define DEFAULTBUTTONX   24 
  61 #define DEFAULTBUTTONY   22 
  62 #define DEFAULTBARHEIGHT 27 
  65 // States (not all of them currently used) 
  67 #define wxTBSTATE_CHECKED         0x01    // radio button is checked 
  68 #define wxTBSTATE_PRESSED         0x02    // button is being depressed (any style) 
  69 #define wxTBSTATE_ENABLED         0x04    // button is enabled 
  70 #define wxTBSTATE_HIDDEN          0x08    // button is hidden 
  71 #define wxTBSTATE_INDETERMINATE   0x10    // button is indeterminate 
  73 // ---------------------------------------------------------------------------- 
  75 // ---------------------------------------------------------------------------- 
  77 class WXDLLEXPORT wxToolBarTool 
: public wxToolBarToolBase
 
  80     wxToolBarTool(wxToolBar 
*tbar
, 
  82                   const wxBitmap
& bmpNormal
, 
  83                   const wxBitmap
& bmpDisabled
, 
  86                   const wxString
& shortHelp
, 
  87                   const wxString
& longHelp
) 
  88         : wxToolBarToolBase(tbar
, id
, bmpNormal
, bmpDisabled
, toggle
, 
  89                             clientData
, shortHelp
, longHelp
) 
  93     wxToolBarTool(wxToolBar 
*tbar
, wxControl 
*control
) 
  94         : wxToolBarToolBase(tbar
, control
) 
  98     void SetSize(const wxSize
& size
) 
 104     long GetWidth() const { return m_width
; } 
 105     long GetHeight() const { return m_height
; } 
 113 // ---------------------------------------------------------------------------- 
 115 // ---------------------------------------------------------------------------- 
 117 #if !USE_SHARED_LIBRARY 
 118 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxToolBarBase
) 
 120 BEGIN_EVENT_TABLE(wxToolBar
, wxToolBarBase
) 
 121         EVT_PAINT(wxToolBar::OnPaint
) 
 122         EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent
) 
 126 // ============================================================================ 
 128 // ============================================================================ 
 130 // ---------------------------------------------------------------------------- 
 132 // ---------------------------------------------------------------------------- 
 134 wxToolBarToolBase 
*wxToolBar::CreateTool(int id
, 
 135                                          const wxString
& label
, 
 136                                          const wxBitmap
& bmpNormal
, 
 137                                          const wxBitmap
& bmpDisabled
, 
 139                                          wxObject 
*clientData
, 
 140                                          const wxString
& shortHelp
, 
 141                                          const wxString
& longHelp
) 
 143     return new wxToolBarTool(this, id
, label
, bmpNormal
, bmpDisabled
, kind
, 
 144                              clientData
, shortHelp
, longHelp
); 
 147 wxToolBarToolBase 
*wxToolBar::CreateTool(wxControl 
*control
) 
 149     return new wxToolBarTool(this, control
); 
 152 // ---------------------------------------------------------------------------- 
 154 // ---------------------------------------------------------------------------- 
 156 void wxToolBar::Init() 
 167     m_defaultWidth 
= DEFAULTBITMAPX
; 
 168     m_defaultHeight 
= DEFAULTBITMAPY
; 
 173     m_maxWidth 
= m_maxHeight 
= 0; 
 174     m_pressedTool 
= m_currentTool 
= -1; 
 176     m_toolSeparation 
= 5; 
 179 bool wxToolBar::Create(wxWindow 
*parent
, 
 184                        const wxString
& name
) 
 186     if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
 189     if ( style 
& wxTB_HORIZONTAL 
) 
 201     SetBackgroundColour(wxColour(192, 192, 192)); 
 208 wxToolBar::~wxToolBar() 
 213 void wxToolBar::SetToolBitmapSize(const wxSize
& size
) 
 215     m_defaultWidth 
= size
.x
; 
 216     m_defaultHeight 
= size
.y
; 
 222 // The button size is bigger than the bitmap size 
 223 wxSize 
wxToolBar::GetToolSize() const 
 225     return wxSize(m_defaultWidth 
+ 8, m_defaultHeight 
+ 7); 
 228 wxToolBarToolBase 
*wxToolBar::FindToolForPosition(wxCoord x
, wxCoord y
) const 
 230     wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 233         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 234         if ((x 
>= tool
->m_x
) && (y 
>= tool
->m_y
) && 
 235             (x 
<= (tool
->m_x 
+ tool
->GetWidth())) && 
 236             (y 
<= (tool
->m_y 
+ tool
->GetHeight()))) 
 241         node 
= node
->GetNext(); 
 244     return (wxToolBarToolBase 
*)NULL
; 
 247 wxToolBarToolBase 
*wxToolBar::AddTool(int id
, 
 248                                       const wxBitmap
& bitmap
, 
 249                                       const wxBitmap
& pushedBitmap
, 
 253                                       wxObject 
*clientData
, 
 254                                       const wxString
& helpString1
, 
 255                                       const wxString
& helpString2
) 
 257     // rememeber the position for DoInsertTool() 
 261     return wxToolBarBase::AddTool(id
, bitmap
, pushedBitmap
, toggle
, 
 262                                   xPos
, yPos
, clientData
, 
 263                                   helpString1
, helpString2
); 
 266 void wxToolBar::OnPaint(wxPaintEvent
& event
) 
 270     static int wxOnPaintCount 
= 0; 
 272     // Prevent reentry of OnPaint which would cause 
 273     // wxMemoryDC errors. 
 274     if (wxOnPaintCount 
> 0) 
 278     wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 281         wxToolBarToolBase 
*tool 
= node
->GetData(); 
 282         if ( tool
->GetStyle()!= wxTOOL_STYLE_BUTTON 
) 
 284             int state 
= tool
->IsEnabled() ? wxTBSTATE_ENABLED 
: 0; 
 285             if ( tool
->IsToggled() ) 
 286                 state 
|= wxTBSTATE_CHECKED
; 
 288             DrawTool(dc
, tool
, state
); 
 291         node 
= node
->GetNext(); 
 297 // If a Button is disabled, then NO function (besides leaving 
 298 // or entering) should be carried out. Therefore the additions 
 299 // of 'enabled' testing (Stefan Hammes). 
 300 void wxToolBar::OnMouseEvent(wxMouseEvent
& event
) 
 302     static wxToolBarToolBase 
*eventCurrentTool 
= NULL
; 
 308         if (eventCurrentTool 
&& eventCurrentTool
->IsEnabled()) 
 311             int state 
= wxTBSTATE_ENABLED
; 
 312             if (eventCurrentTool
->IsToggled()) 
 313                 state 
|= wxTBSTATE_CHECKED
; 
 314             DrawTool(dc
, eventCurrentTool
, state
); 
 315             eventCurrentTool 
= NULL
; 
 322     event
.GetPosition(&x
, &y
); 
 323     wxToolBarToolBase 
*tool 
= FindToolForPosition(x
, y
); 
 327         if (eventCurrentTool 
&& eventCurrentTool
->IsEnabled()) 
 331             int state 
= wxTBSTATE_ENABLED
; 
 332             if (eventCurrentTool
->IsToggled()) 
 333                 state 
|= wxTBSTATE_CHECKED
; 
 334             DrawTool(dc
, eventCurrentTool
, state
); 
 335             eventCurrentTool 
= NULL
; 
 337         if (m_currentTool 
> -1) 
 345     if (!event
.Dragging() && !event
.IsButton()) 
 347         if (tool
->GetId() != m_currentTool
) 
 349             OnMouseEnter(m_currentTool 
= tool
->GetId()); 
 353     if (event
.Dragging() && tool
->IsEnabled()) 
 355         if (eventCurrentTool
) 
 357             // Might have dragged outside tool 
 358             if (eventCurrentTool 
!= tool
) 
 360                 int state 
= wxTBSTATE_ENABLED
; 
 361                 if (tool
->IsToggled()) 
 362                     state 
|= wxTBSTATE_CHECKED
; 
 363                 DrawTool(dc
, tool
, state
); 
 364                 eventCurrentTool 
= NULL
; 
 370             if (tool 
&& event
.LeftIsDown() && tool
->IsEnabled()) 
 372                 eventCurrentTool 
= tool
; 
 373                 ::SetCapture((HWND
) GetHWND()); 
 374                 int state 
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
; 
 375                 if (tool
->IsToggled()) 
 376                     state 
|= wxTBSTATE_CHECKED
; 
 377                 DrawTool(dc
, tool
, state
); 
 381     if (event
.LeftDown() && tool
->IsEnabled()) 
 383         eventCurrentTool 
= tool
; 
 384         ::SetCapture((HWND
) GetHWND()); 
 385         int state 
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
; 
 386         if (tool
->IsToggled()) 
 387             state 
|= wxTBSTATE_CHECKED
; 
 388         DrawTool(dc
, tool
, state
); 
 390     else if (event
.LeftUp() && tool
->IsEnabled()) 
 392         if (eventCurrentTool
) 
 394         if (eventCurrentTool 
== tool
) 
 396             if (tool
->CanBeToggled()) 
 399                 if (!OnLeftClick(tool
->GetId(), tool
->IsToggled())) 
 403                 int state 
= wxTBSTATE_ENABLED
; 
 404                 if (tool
->IsToggled()) 
 405                     state 
|= wxTBSTATE_CHECKED
; 
 406                 DrawTool(dc
, tool
, state
); 
 410                 int state 
= wxTBSTATE_ENABLED
; 
 411                 if (tool
->IsToggled()) 
 412                     state 
|= wxTBSTATE_CHECKED
; 
 413                 DrawTool(dc
, tool
, state
); 
 414                 OnLeftClick(tool
->GetId(), tool
->IsToggled()); 
 417         eventCurrentTool 
= NULL
; 
 419     else if (event
.RightDown() && tool
->IsEnabled()) 
 421         OnRightClick(tool
->GetId(), x
, y
); 
 425 void wxToolBar::DoEnableTool(wxToolBarToolBase 
*tool
, bool WXUNUSED(enable
)) 
 430 void wxToolBar::DoToggleTool(wxToolBarToolBase 
*tool
, bool WXUNUSED(toggle
)) 
 435 void wxToolBar::DoSetToggle(wxToolBarToolBase 
* WXUNUSED(tool
), 
 436                             bool WXUNUSED(toggle
)) 
 441 void wxToolBar::DoRedrawTool(wxToolBarToolBase 
*tool
) 
 448 void wxToolBar::DrawTool(wxDC
& dc
, wxToolBarToolBase 
*toolBase
, int state
) 
 450     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)toolBase
; 
 452     DrawButton(dc
.GetHDC(), 
 453                tool
->m_x
, tool
->m_y
, 
 454                tool
->GetWidth(), tool
->GetHeight(), 
 458 void wxToolBar::DrawTool(wxDC
& dc
, wxToolBarToolBase 
*tool
) 
 461     if (tool
->IsEnabled()) 
 462         state 
|= wxTBSTATE_ENABLED
; 
 463     if (tool
->IsToggled()) 
 464         state 
|= wxTBSTATE_CHECKED
; 
 465     // how can i access the PRESSED state??? 
 467     DrawTool(dc
, tool
, state
); 
 470 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos
), 
 471                              wxToolBarToolBase 
*tool
) 
 473     // VZ: didn't test whether it works, but why not... 
 481 bool wxToolBar::DoInsertTool(size_t pos
, wxToolBarToolBase 
*toolBase
) 
 483     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)toolBase
; 
 485     wxCHECK_MSG( !tool
->IsControl(), FALSE
, 
 486                  _T("generic wxToolBar doesn't support controls") ); 
 488     // TODO: use the mapping code from wxToolBar95 to get it right in this class 
 489 #if !defined(__WIN32__) && !defined(__WIN386__) 
 490     wxBitmap bmpDisabled
; 
 491     if (tool
->CanBeToggled()) 
 493         HBITMAP hbmp 
= CreateMappedBitmap((WXHINSTANCE
)wxGetInstance(), 
 494                                           GetHbitmapOf(tool
->GetBitmap1())); 
 497         bmp
.SetHBITMAP((WXHBITMAP
)hbmp
); 
 498         tool
->SetBitmap2(bmp
); 
 503     if ( tool
->m_x 
== -1 ) 
 504         tool
->m_x 
= m_xMargin
; 
 507     if ( tool
->m_y 
== -1 ) 
 508         tool
->m_y 
= m_yMargin
; 
 510     tool
->SetSize(GetToolSize()); 
 512     if ( tool
->IsButton() ) 
 514         // Calculate reasonable max size in case Layout() not called 
 515         if ((tool
->m_x 
+ tool
->GetBitmap1().GetWidth() + m_xMargin
) > m_maxWidth
) 
 516             m_maxWidth 
= (tool
->m_x 
+ tool
->GetWidth() + m_xMargin
); 
 518         if ((tool
->m_y 
+ tool
->GetBitmap1().GetHeight() + m_yMargin
) > m_maxHeight
) 
 519             m_maxHeight 
= (tool
->m_y 
+ tool
->GetHeight() + m_yMargin
); 
 525 bool wxToolBar::Realize() 
 527     m_currentRowsOrColumns 
= 0; 
 530     int maxToolWidth 
= 0; 
 531     int maxToolHeight 
= 0; 
 535     // Find the maximum tool width and height 
 536     wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 539         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 540         if (tool
->GetWidth() > maxToolWidth
) 
 541             maxToolWidth 
= tool
->GetWidth(); 
 542         if (tool
->GetHeight() > maxToolHeight
) 
 543             maxToolHeight 
= tool
->GetHeight(); 
 544         node 
= node
->GetNext(); 
 547     int separatorSize 
= m_toolSeparation
; 
 549     node 
= m_tools
.GetFirst(); 
 552         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 553         if (tool
->GetStyle() == wxTOOL_STYLE_SEPARATOR
) 
 555             if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 557                 if (m_currentRowsOrColumns 
>= m_maxCols
) 
 558                     m_lastY 
+= separatorSize
; 
 560                     m_lastX 
+= separatorSize
; 
 564                 if (m_currentRowsOrColumns 
>= m_maxRows
) 
 565                     m_lastX 
+= separatorSize
; 
 567                     m_lastY 
+= separatorSize
; 
 570         else if (tool
->GetStyle() == wxTOOL_STYLE_BUTTON
) 
 572             if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 574                 if (m_currentRowsOrColumns 
>= m_maxCols
) 
 576                     m_currentRowsOrColumns 
= 0; 
 578                     m_lastY 
+= maxToolHeight 
+ m_toolPacking
; 
 580                 tool
->m_x 
= (long) (m_lastX 
+ (maxToolWidth 
- tool
->GetWidth())/2.0); 
 581                 tool
->m_y 
= (long) (m_lastY 
+ (maxToolHeight 
- tool
->GetHeight())/2.0); 
 583                 m_lastX 
+= maxToolWidth 
+ m_toolPacking
; 
 587                 if (m_currentRowsOrColumns 
>= m_maxRows
) 
 589                     m_currentRowsOrColumns 
= 0; 
 590                     m_lastX 
+= (maxToolWidth 
+ m_toolPacking
); 
 593                 tool
->m_x 
= (long) (m_lastX 
+ (maxToolWidth 
- tool
->GetWidth())/2.0); 
 594                 tool
->m_y 
= (long) (m_lastY 
+ (maxToolHeight 
- tool
->GetHeight())/2.0); 
 596                 m_lastY 
+= maxToolHeight 
+ m_toolPacking
; 
 598             m_currentRowsOrColumns 
++; 
 601         if (m_lastX 
> m_maxWidth
) 
 602             m_maxWidth 
= m_lastX
; 
 603         if (m_lastY 
> m_maxHeight
) 
 604             m_maxHeight 
= m_lastY
; 
 606         node 
= node
->GetNext(); 
 609     if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 611         m_maxWidth 
+= maxToolWidth
; 
 612         m_maxHeight 
+= maxToolHeight
; 
 616         m_maxWidth 
+= maxToolWidth
; 
 617         m_maxHeight 
+= maxToolHeight
; 
 620     m_maxWidth 
+= m_xMargin
; 
 621     m_maxHeight 
+= m_yMargin
; 
 623     SetSize(m_maxWidth
, m_maxHeight
); 
 628 bool wxToolBar::InitGlobalObjects() 
 631     if (!CreateDitherBrush()) 
 634     m_hdcMono 
= (WXHDC
) CreateCompatibleDC(NULL
); 
 638     m_hbmMono 
= (WXHBITMAP
) CreateBitmap((int)GetToolSize().x
, (int)GetToolSize().y
, 1, 1, NULL
); 
 642     m_hbmDefault 
= (WXHBITMAP
) SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmMono
); 
 646 void wxToolBar::FreeGlobalObjects() 
 653             SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmDefault
); 
 656         DeleteDC((HDC
) m_hdcMono
);              // toast the DCs 
 661         DeleteObject((HBITMAP
) m_hbmMono
); 
 665 // ---------------------------------------------------------------------------- 
 667 // ---------------------------------------------------------------------------- 
 669 void wxToolBar::PatB(WXHDC hdc
,int x
,int y
,int dx
,int dy
, long rgb
) 
 678     SetBkColor((HDC
) hdc
,rgb
); 
 679     ExtTextOut((HDC
) hdc
,0,0,ETO_OPAQUE
,&rc
,NULL
,0,NULL
); 
 683 // create a mono bitmap mask: 
 684 //   1's where color == COLOR_BTNFACE || COLOR_HILIGHT 
 685 //   0's everywhere else 
 687 void wxToolBar::CreateMask(WXHDC hdc
, int xoffset
, int yoffset
, int dx
, int dy
) 
 689     HDC globalDC 
= ::GetDC(NULL
); 
 690     HDC hdcGlyphs 
= CreateCompatibleDC((HDC
) globalDC
); 
 691     ReleaseDC(NULL
, (HDC
) globalDC
); 
 693     // krj - create a new bitmap and copy the image from hdc. 
 694     //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap); 
 695     HBITMAP hBitmap 
= CreateCompatibleBitmap((HDC
) hdc
, dx
, dy
); 
 696     HBITMAP bitmapOld 
= (HBITMAP
) SelectObject(hdcGlyphs
, hBitmap
); 
 697     BitBlt(hdcGlyphs
, 0,0, dx
, dy
, (HDC
) hdc
, 0, 0, SRCCOPY
); 
 699     // initalize whole area with 1's 
 700     PatBlt((HDC
) m_hdcMono
, 0, 0, dx
, dy
, WHITENESS
); 
 702     // create mask based on color bitmap 
 703     // convert this to 1's 
 704     SetBkColor(hdcGlyphs
, m_rgbFace
); 
 705     BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
, 
 706         hdcGlyphs
, 0, 0, SRCCOPY
); 
 707     // convert this to 1's 
 708     SetBkColor(hdcGlyphs
, m_rgbHilight
); 
 710     BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
, 
 711         hdcGlyphs
, 0, 0, SRCPAINT
); 
 713     SelectObject(hdcGlyphs
, bitmapOld
); 
 714     DeleteObject(hBitmap
); 
 718 void wxToolBar::DrawBlankButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, int state
) 
 721     PatB(hdc
, x
, y
, dx
, dy
, m_rgbFace
); 
 723     if (state 
& wxTBSTATE_PRESSED
) { 
 724         PatB(hdc
, x 
+ 1, y
, dx 
- 2, 1, m_rgbFrame
); 
 725         PatB(hdc
, x 
+ 1, y 
+ dy 
- 1, dx 
- 2, 1, m_rgbFrame
); 
 726         PatB(hdc
, x
, y 
+ 1, 1, dy 
- 2, m_rgbFrame
); 
 727         PatB(hdc
, x 
+ dx 
- 1, y 
+1, 1, dy 
- 2, m_rgbFrame
); 
 728         PatB(hdc
, x 
+ 1, y 
+ 1, 1, dy
-2, m_rgbShadow
); 
 729         PatB(hdc
, x 
+ 1, y 
+ 1, dx
-2, 1, m_rgbShadow
); 
 732         PatB(hdc
, x 
+ 1, y
, dx 
- 2, 1, m_rgbFrame
); 
 733         PatB(hdc
, x 
+ 1, y 
+ dy 
- 1, dx 
- 2, 1, m_rgbFrame
); 
 734         PatB(hdc
, x
, y 
+ 1, 1, dy 
- 2, m_rgbFrame
); 
 735         PatB(hdc
, x 
+ dx 
- 1, y 
+ 1, 1, dy 
- 2, m_rgbFrame
); 
 738         PatB(hdc
, x 
+ 1, y 
+ 1, 1, dy 
- 1, m_rgbHilight
); 
 739         PatB(hdc
, x 
+ 1, y 
+ 1, dx 
- 1, 1, m_rgbHilight
); 
 740         PatB(hdc
, x 
+ dx
, y 
+ 1, 1, dy
, m_rgbShadow
); 
 741         PatB(hdc
, x 
+ 1, y 
+ dy
, dx
, 1,   m_rgbShadow
); 
 742         PatB(hdc
, x 
+ dx 
- 1, y 
+ 2, 1, dy 
- 2, m_rgbShadow
); 
 743         PatB(hdc
, x 
+ 2, y 
+ dy 
- 1, dx 
- 2, 1,   m_rgbShadow
); 
 747 void wxToolBar::DrawButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, 
 748                            wxToolBarToolBase 
*toolBase
, int state
) 
 750     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)toolBase
; 
 754     BOOL bMaskCreated 
= FALSE
; 
 755     int xButton 
= 0;            // assume button is down 
 762 //    HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP(); 
 763     HDC globalDC 
= ::GetDC(NULL
); 
 764     HDC hdcGlyphs 
= CreateCompatibleDC(globalDC
); 
 765     ReleaseDC(NULL
, globalDC
); 
 767     // get the proper button look - up or down. 
 768     if (!(state 
& (wxTBSTATE_PRESSED 
| wxTBSTATE_CHECKED
))) { 
 769         xButton 
= dx
;   // use 'up' version of button 
 771         dyFace 
-= 2;    // extents to ignore button highlight 
 774     DrawBlankButton(hdc
, x
, y
, dx
, dy
, state
); 
 777     // move coordinates inside border and away from upper left highlight. 
 778     // the extents change accordingly. 
 784     // Using bmpDisabled can cause problems (don't know why!) 
 785 #if !defined(__WIN32__) && !defined(__WIN386__) 
 787     if (tool
->GetBitmap2().Ok()) 
 788       bitmapOld 
= GetHbitmapOf(tool
->GetBitmap2()); 
 790       bitmapOld 
= GetHbitmapOf(tool
->GetBitmap1()); 
 792     HBITMAP bitmapOld 
= GetHbitmapOf(tool
->GetBitmap1()); 
 795     bitmapOld 
= (HBITMAP
)SelectObject(hdcGlyphs
, bitmapOld
); 
 797     // calculate offset of face from (x,y).  y is always from the top, 
 798     // so the offset is easy.  x needs to be centered in face. 
 800     xCenterOffset 
= (dxFace 
- (int)GetToolBitmapSize().x
)/2; 
 801     if (state 
& (wxTBSTATE_PRESSED 
| wxTBSTATE_CHECKED
)) 
 803         // pressed state moves down and to the right 
 804         // (x moves automatically as face size grows) 
 808     // now put on the face 
 809     if (state 
& wxTBSTATE_ENABLED
) { 
 811         BitBlt((HDC
) hdc
, x
+xCenterOffset
, y 
+ yOffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
, 
 812             hdcGlyphs
, 0, 0, SRCCOPY
); 
 814         // disabled version (or indeterminate) 
 816         CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
); 
 817 //        CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace); 
 819         SetTextColor((HDC
) hdc
, 0L);     // 0's in mono -> 0 (for ROP) 
 820         SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1's in mono -> 1 
 822         // draw glyph's white understrike 
 823         if (!(state 
& wxTBSTATE_INDETERMINATE
)) { 
 824             hbr 
= CreateSolidBrush(m_rgbHilight
); 
 826                 hbrOld 
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
); 
 828                     // draw hilight color where we have 0's in the mask 
 829                     BitBlt((HDC
) hdc
, x 
+ 1, y 
+ 1, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A); 
 830                     SelectObject((HDC
) hdc
, hbrOld
); 
 837         hbr 
= CreateSolidBrush(m_rgbShadow
); 
 839             hbrOld 
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
); 
 841                 // draw the shadow color where we have 0's in the mask 
 842                 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A); 
 843                 SelectObject((HDC
) hdc
, hbrOld
); 
 848         if (state 
& wxTBSTATE_CHECKED
) { 
 849             BitBlt((HDC
) m_hdcMono
, 1, 1, dxFace 
- 1, dyFace 
- 1, (HDC
) m_hdcMono
, 0, 0, SRCAND
); 
 853     if (state 
& (wxTBSTATE_CHECKED 
| wxTBSTATE_INDETERMINATE
)) { 
 855         hbrOld 
= (HBRUSH
) SelectObject((HDC
) hdc
, (HBRUSH
) m_hbrDither
); 
 859                 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
); 
 860 //                CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace); 
 862             SetTextColor((HDC
) hdc
, 0L);                // 0 -> 0 
 863             SetBkColor((HDC
) hdc
, 0x00FFFFFF);  // 1 -> 1 
 865             // only draw the dither brush where the mask is 1's 
 866             BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00E20746); 
 868             SelectObject((HDC
) hdc
, hbrOld
); 
 871     SelectObject(hdcGlyphs
, bitmapOld
); 
 875 // ---------------------------------------------------------------------------- 
 877 // ---------------------------------------------------------------------------- 
 879 void wxToolBar::GetSysColors() 
 881         static COLORREF rgbSaveFace    
= 0xffffffffL
, 
 882                         rgbSaveShadow  
= 0xffffffffL
, 
 883                         rgbSaveHilight 
= 0xffffffffL
, 
 884                         rgbSaveFrame   
= 0xffffffffL
; 
 886     // For now, override these because the colour replacement isn't working, 
 887     // and we get inconsistent colours. Assume all buttons are grey for the moment. 
 889 //      m_rgbFace    = GetSysColor(COLOR_BTNFACE); 
 890         m_rgbFace 
= RGB(192,192,192); 
 891 //      m_rgbShadow  = GetSysColor(COLOR_BTNSHADOW); 
 892         m_rgbShadow 
= RGB(128,128,128); 
 893 //      m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT); 
 894         m_rgbHilight 
= RGB(255, 255, 255); 
 896         m_rgbFrame   
= GetSysColor(COLOR_WINDOWFRAME
); 
 898         if (rgbSaveFace
!=m_rgbFace 
|| rgbSaveShadow
!=m_rgbShadow
 
 899                 || rgbSaveHilight
!=m_rgbHilight 
|| rgbSaveFrame
!=m_rgbFrame
) 
 901                 rgbSaveFace    
= m_rgbFace
; 
 902                 rgbSaveShadow  
= m_rgbShadow
; 
 903                 rgbSaveHilight 
= m_rgbHilight
; 
 904         rgbSaveFrame   
= m_rgbFrame
; 
 906                 // Update the brush for pushed-in buttons 
 911 WXHBITMAP 
wxToolBar::CreateDitherBitmap() 
 920     pbmi 
= (BITMAPINFO 
*)malloc(sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
)); 
 921     memset(pbmi
, 0, (sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
))); 
 923     pbmi
->bmiHeader
.biSize 
= sizeof(BITMAPINFOHEADER
); 
 924     pbmi
->bmiHeader
.biWidth 
= 8; 
 925     pbmi
->bmiHeader
.biHeight 
= 8; 
 926     pbmi
->bmiHeader
.biPlanes 
= 1; 
 927     pbmi
->bmiHeader
.biBitCount 
= 1; 
 928     pbmi
->bmiHeader
.biCompression 
= BI_RGB
; 
 930 //    rgb = GetSysColor(COLOR_BTNFACE); 
 931     rgb 
= RGB(192,192,192); 
 933     pbmi
->bmiColors
[0].rgbBlue  
= GetBValue(rgb
); 
 934     pbmi
->bmiColors
[0].rgbGreen 
= GetGValue(rgb
); 
 935     pbmi
->bmiColors
[0].rgbRed   
= GetRValue(rgb
); 
 936     pbmi
->bmiColors
[0].rgbReserved 
= 0; 
 938 //    rgb = GetSysColor(COLOR_BTNHIGHLIGHT); 
 939     rgb 
= RGB(255, 255, 255); 
 941     pbmi
->bmiColors
[1].rgbBlue  
= GetBValue(rgb
); 
 942     pbmi
->bmiColors
[1].rgbGreen 
= GetGValue(rgb
); 
 943     pbmi
->bmiColors
[1].rgbRed   
= GetRValue(rgb
); 
 944     pbmi
->bmiColors
[1].rgbReserved 
= 0; 
 946     /* initialize the brushes */ 
 948     for (i 
= 0; i 
< 8; i
++) 
 950            patGray
[i
] = 0xAAAA5555L
;   //  0x11114444L; // lighter gray 
 952            patGray
[i
] = 0x5555AAAAL
;   //  0x11114444L; // lighter gray 
 956     hbm 
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
, patGray
, pbmi
, DIB_RGB_COLORS
); 
 958     ReleaseDC(NULL
, hdc
); 
 961     return (WXHBITMAP
)hbm
; 
 964 bool wxToolBar::CreateDitherBrush() 
 970         hbmGray 
= (HBITMAP
) CreateDitherBitmap(); 
 974                 hbrSave 
= (HBRUSH
) m_hbrDither
; 
 975                 m_hbrDither 
= (WXHBRUSH
) CreatePatternBrush(hbmGray
); 
 976                 DeleteObject(hbmGray
); 
 981                                 DeleteObject(hbrSave
); 
 987                         m_hbrDither 
= (WXHBRUSH
) hbrSave
; 
 994 bool wxToolBar::FreeDitherBrush(void) 
 997       DeleteObject((HBRUSH
) m_hbrDither
); 
1002 typedef struct tagCOLORMAP2
 
1009 // these are the default colors used to map the dib colors 
1010 // to the current system colors 
1012 #define BGR_BUTTONTEXT      (RGB(000,000,000))  // black 
1013 #define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey 
1014 #define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey 
1015 #define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white 
1016 #define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue 
1017 #define BGR_BACKGROUND      (RGB(255,000,255))  // magenta 
1018 #define FlipColor(rgb)      (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb))) 
1020 WXHBITMAP 
wxToolBar::CreateMappedBitmap(WXHINSTANCE 
WXUNUSED(hInstance
), void *info
) 
1022   LPBITMAPINFOHEADER lpBitmapInfo 
= (LPBITMAPINFOHEADER
)info
; 
1023   HDC                   hdc
, hdcMem 
= NULL
; 
1027   HBITMAP               hbm 
= NULL
, hbmOld
; 
1030   static COLORMAP2 ColorMap
[] = { 
1031     {BGR_BUTTONTEXT
,    BGR_BUTTONTEXT
,    COLOR_BTNTEXT
},     // black 
1032     {BGR_BUTTONSHADOW
,  BGR_BUTTONSHADOW
,  COLOR_BTNSHADOW
},   // dark grey 
1033     {BGR_BUTTONFACE
,    BGR_BUTTONFACE
,    COLOR_BTNFACE
},     // bright grey 
1034     {BGR_BUTTONHILIGHT
, BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white 
1035     {BGR_BACKGROUNDSEL
, BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
},   // blue 
1036     {BGR_BACKGROUND
,    BGR_BACKGROUND
,    COLOR_WINDOW
}       // magenta 
1039   #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2)) 
1045   // So what are the new colors anyway ? 
1047   for (i
=0; i 
< (int) NUM_MAPS
; i
++) { 
1048      ColorMap
[i
].bgrto 
= (long unsigned int) FlipColor(GetSysColor((int)ColorMap
[i
].sysColor
)); 
1051   p 
= (DWORD FAR 
*)(((LPSTR
)lpBitmapInfo
) + lpBitmapInfo
->biSize
); 
1053   /* Replace button-face and button-shadow colors with the current values 
1057   while (numcolors
-- > 0) { 
1058       for (i 
= 0; i 
< (int) NUM_MAPS
; i
++) { 
1059           if (*p 
== ColorMap
[i
].bgrfrom
) { 
1060           *p 
= ColorMap
[i
].bgrto
; 
1067   /* First skip over the header structure */ 
1068   lpBits 
= (LPSTR
)(lpBitmapInfo 
+ 1); 
1070   /* Skip the color table entries, if any */ 
1071   lpBits 
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
); 
1073   /* Create a color bitmap compatible with the display device */ 
1074   i 
= wid 
= (int)lpBitmapInfo
->biWidth
; 
1075   hgt 
= (int)lpBitmapInfo
->biHeight
; 
1076   hdc 
= ::GetDC(NULL
); 
1078   hdcMem 
= CreateCompatibleDC(hdc
); 
1080 //    hbm = CreateDiscardableBitmap(hdc, i, hgt); 
1081     hbm 
= CreateCompatibleBitmap(hdc
, i
, hgt
); 
1083         hbmOld 
= (HBITMAP
) SelectObject(hdcMem
, hbm
); 
1085         // set the main image 
1086         StretchDIBits(hdcMem
, 0, 0, wid
, hgt
, 0, 0, wid
, hgt
, lpBits
, 
1087                    (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
); 
1089         SelectObject(hdcMem
, hbmOld
); 
1092     DeleteObject(hdcMem
); 
1095   ReleaseDC(NULL
, hdc
); 
1097   return (WXHBITMAP
) hbm
; 
1100 WXHBITMAP 
wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance
, WXHBITMAP hBitmap
) 
1102     HANDLE hDIB 
= wxDIB::ConvertFromBitmap((HBITMAP
) hBitmap
); 
1106     WXHBITMAP newBitmap 
= CreateMappedBitmap(hInstance
, GlobalPtr(hDIB
)); 
1113 #endif // wxUSE_TOOLBAR