1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxToolBarMSW 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "tbarmsw.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  27 #if wxUSE_BUTTONBAR && wxUSE_TOOLBAR 
  29 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) 
  33 #if !defined(__MWERKS__) && !defined(__SALFORDC__) 
  39 #include "wx/tbarmsw.h" 
  42 #include "wx/bitmap.h" 
  43 #include "wx/msw/private.h" 
  44 #include "wx/msw/dib.h" 
  46 #define DEFAULTBITMAPX   16 
  47 #define DEFAULTBITMAPY   15 
  48 #define DEFAULTBUTTONX   24 
  49 #define DEFAULTBUTTONY   22 
  50 #define DEFAULTBARHEIGHT 27 
  52 /////// Non-Windows 95 implementation 
  54 #if !wxUSE_IMAGE_LOADING_IN_MSW 
  55 #error If wxUSE_IMAGE_LOADING_IN_MSW is set to 0, then wxUSE_BUTTONBAR must be set to 0 too. 
  58 #if !USE_SHARED_LIBRARY 
  59 IMPLEMENT_DYNAMIC_CLASS(wxToolBarMSW
, wxToolBarBase
) 
  61 BEGIN_EVENT_TABLE(wxToolBarMSW
, wxToolBarBase
) 
  62         EVT_SIZE(wxToolBarMSW::OnSize
) 
  63         EVT_PAINT(wxToolBarMSW::OnPaint
) 
  64         EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent
) 
  68 wxToolBarMSW::wxToolBarMSW(void) 
  78   m_defaultWidth 
= DEFAULTBITMAPX
; 
  79   m_defaultHeight 
= DEFAULTBITMAPY
; 
  82 bool wxToolBarMSW::Create(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
  83             long style
, const wxString
& name
) 
  85         if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
  88   if ( style 
& wxTB_HORIZONTAL 
) 
  89     { m_lastX 
= 3; m_lastY 
= 7; } 
  91     { m_lastX 
= 7; m_lastY 
= 3; } 
  92   m_maxWidth 
= m_maxHeight 
= 0; 
  93   m_pressedTool 
= m_currentTool 
= -1; 
 100   SetBackgroundColour(wxColour(192, 192, 192)); 
 110   m_defaultWidth 
= DEFAULTBITMAPX
; 
 111   m_defaultHeight 
= DEFAULTBITMAPY
; 
 118 wxToolBarMSW::~wxToolBarMSW(void) 
 123 void wxToolBarMSW::SetToolBitmapSize(const wxSize
& size
) 
 125   m_defaultWidth 
= size
.x
; m_defaultHeight 
= size
.y
; 
 130 // The button size is bigger than the bitmap size 
 131 wxSize 
wxToolBarMSW::GetToolSize(void) const 
 133   return wxSize(m_defaultWidth 
+ 8, m_defaultHeight 
+ 7); 
 136 void wxToolBarMSW::OnPaint(wxPaintEvent
& event
) 
 140   static int wxOnPaintCount 
= 0; 
 142   // Prevent reentry of OnPaint which would cause 
 143   // wxMemoryDC errors. 
 144   if (wxOnPaintCount 
> 0) 
 148   wxNode 
*node 
= m_tools
.First(); 
 151     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->Data(); 
 152     if (tool
->m_toolStyle 
!= wxTOOL_STYLE_SEPARATOR
) 
 154       int state 
= wxTBSTATE_ENABLED
; 
 155       if (!tool
->m_enabled
) 
 157       if (tool
->m_isToggle 
&& tool
->m_toggleState
) 
 158         state 
|= wxTBSTATE_CHECKED
; 
 159       DrawTool(dc
, tool
, state
); 
 166 void wxToolBarMSW::OnSize(wxSizeEvent
& event
) 
 168   wxToolBarBase::OnSize(event
); 
 171 // If a Button is disabled, then NO function (besides leaving 
 172 // or entering) should be carried out. Therefore the additions 
 173 // of 'enabled' testing (Stefan Hammes). 
 174 void wxToolBarMSW::OnMouseEvent(wxMouseEvent
& event
) 
 176   static wxToolBarTool 
*eventCurrentTool 
= NULL
; 
 182     if (eventCurrentTool 
&& eventCurrentTool
->m_enabled
) 
 185       int state 
= wxTBSTATE_ENABLED
; 
 186       if (eventCurrentTool
->m_toggleState
) 
 187         state 
|= wxTBSTATE_CHECKED
; 
 188       DrawTool(dc
, eventCurrentTool
, state
); 
 189       eventCurrentTool 
= NULL
; 
 196   event
.Position(&x
, &y
); 
 197   wxToolBarTool 
*tool 
= FindToolForPosition(x
, y
); 
 201     if (eventCurrentTool 
&& eventCurrentTool
->m_enabled
) 
 205       int state 
= wxTBSTATE_ENABLED
; 
 206       if (eventCurrentTool
->m_toggleState
) 
 207         state 
|= wxTBSTATE_CHECKED
; 
 208       DrawTool(dc
, eventCurrentTool
, state
); 
 209       eventCurrentTool 
= NULL
; 
 211     if (m_currentTool 
> -1) 
 219   if (!event
.Dragging() && !event
.IsButton()) 
 221     if (tool
->m_index 
!= m_currentTool
) 
 223       OnMouseEnter(tool
->m_index
); 
 224       m_currentTool 
= tool
->m_index
; 
 228   if (event
.Dragging() && tool
->m_enabled
) 
 230     if (eventCurrentTool
) 
 232       // Might have dragged outside tool 
 233       if (eventCurrentTool 
!= tool
) 
 235         int state 
= wxTBSTATE_ENABLED
; 
 236         if (tool
->m_toggleState
) 
 237           state 
|= wxTBSTATE_CHECKED
; 
 238         DrawTool(dc
, tool
, state
); 
 239         eventCurrentTool 
= NULL
; 
 245       if (tool 
&& event
.LeftIsDown() && tool
->m_enabled
) 
 247         eventCurrentTool 
= tool
; 
 248         ::SetCapture((HWND
) GetHWND()); 
 249         int state 
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
; 
 250         if (tool
->m_toggleState
) 
 251           state 
|= wxTBSTATE_CHECKED
; 
 252         DrawTool(dc
, tool
, state
); 
 256   if (event
.LeftDown() && tool
->m_enabled
) 
 258     eventCurrentTool 
= tool
; 
 259     ::SetCapture((HWND
) GetHWND()); 
 260     int state 
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
; 
 261     if (tool
->m_toggleState
) 
 262       state 
|= wxTBSTATE_CHECKED
; 
 263     DrawTool(dc
, tool
, state
); 
 265   else if (event
.LeftUp() && tool
->m_enabled
) 
 267     if (eventCurrentTool
) 
 269     if (eventCurrentTool 
== tool
) 
 271       if (tool
->m_isToggle
) 
 273         tool
->m_toggleState 
= !tool
->m_toggleState
; 
 274         if (!OnLeftClick(tool
->m_index
, tool
->m_toggleState
)) 
 276           tool
->m_toggleState 
= !tool
->m_toggleState
; 
 278         int state 
= wxTBSTATE_ENABLED
; 
 279         if (tool
->m_toggleState
) 
 280           state 
|= wxTBSTATE_CHECKED
; 
 281         DrawTool(dc
, tool
, state
); 
 285         int state 
= wxTBSTATE_ENABLED
; 
 286         if (tool
->m_toggleState
) 
 287           state 
|= wxTBSTATE_CHECKED
; 
 288         DrawTool(dc
, tool
, state
); 
 289         OnLeftClick(tool
->m_index
, tool
->m_toggleState
); 
 292     eventCurrentTool 
= NULL
; 
 294   else if (event
.RightDown() && tool
->m_enabled
) 
 296     OnRightClick(tool
->m_index
, x
, y
); 
 300 // This function enables/disables a toolbar tool and redraws it. 
 301 // If that would not be done, the enabling/disabling wouldn't be 
 302 // visible on the screen. 
 303 void wxToolBarMSW::EnableTool(int toolIndex
, bool enable
) 
 305   wxNode 
*node 
= m_tools
.Find((long)toolIndex
); 
 310     // at first do the enabling/disabling in the base class 
 311     wxToolBarBase::EnableTool(toolIndex
,enable
); 
 312     // then calculate the state of the tool and draw it 
 313     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->Data(); 
 315     if(tool
->m_toggleState
) state 
|= wxTBSTATE_CHECKED
; 
 316     if(tool
->m_enabled
) state 
|= wxTBSTATE_ENABLED
; 
 317     // how can i access the PRESSED state??? 
 318     DrawTool(dc
, tool
,state
); 
 322 void wxToolBarMSW::DrawTool(wxDC
& dc
, wxToolBarTool 
*tool
, int state
) 
 324   DrawButton(dc
.GetHDC(), (int)tool
->m_x
, (int)tool
->m_y
, (int)tool
->GetWidth(), (int)tool
->GetHeight(), tool
, state
); 
 327 void wxToolBarMSW::DrawTool(wxDC
& dc
, wxMemoryDC
& , wxToolBarTool 
*tool
) 
 329   int state 
= wxTBSTATE_ENABLED
; 
 330   if (!tool
->m_enabled
) 
 332   if (tool
->m_toggleState
) 
 333     state 
|= wxTBSTATE_CHECKED
; 
 334   DrawTool(dc
, tool
, state
); 
 337 // If pushedBitmap is NULL, a reversed version of bitmap is 
 338 // created and used as the pushed/toggled image. 
 339 // If toggle is TRUE, the button toggles between the two states. 
 340 wxToolBarTool 
*wxToolBarMSW::AddTool(int index
, const wxBitmap
& bitmap
, const wxBitmap
& pushedBitmap
, 
 341              bool toggle
, long xPos
, long yPos
, wxObject 
*clientData
, const wxString
& helpString1
, const wxString
& helpString2
) 
 343   // Using bitmap2 can cause problems (don't know why!) 
 345   // TODO: use the mapping code from wxToolBar95 to get it right in this class 
 346 #if !defined(__WIN32__) && !defined(__WIN386__) 
 350     bitmap2
.SetHBITMAP( (WXHBITMAP
) CreateMappedBitmap((WXHINSTANCE
)wxGetInstance(), (WXHBITMAP
) ((wxBitmap
& )bitmap
).GetHBITMAP())); 
 353   wxToolBarTool 
*tool 
= new wxToolBarTool(index
, bitmap
, bitmap2
, toggle
, xPos
, yPos
, helpString1
, helpString2
); 
 355   wxToolBarTool 
*tool 
= new wxToolBarTool(index
, bitmap
, wxNullBitmap
, toggle
, xPos
, yPos
, helpString1
, helpString2
); 
 358   tool
->m_clientData 
= clientData
; 
 363     tool
->m_x 
= m_xMargin
; 
 368     tool
->m_y 
= m_yMargin
; 
 370   tool
->m_deleteSecondBitmap 
= TRUE
; 
 371   tool
->SetSize(GetToolSize().x
, GetToolSize().y
); 
 373   // Calculate reasonable max size in case Layout() not called 
 374   if ((tool
->m_x 
+ bitmap
.GetWidth() + m_xMargin
) > m_maxWidth
) 
 375     m_maxWidth 
= (tool
->m_x 
+ tool
->GetWidth() + m_xMargin
); 
 377   if ((tool
->m_y 
+ bitmap
.GetHeight() + m_yMargin
) > m_maxHeight
) 
 378     m_maxHeight 
= (tool
->m_y 
+ tool
->GetHeight() + m_yMargin
); 
 380   m_tools
.Append((long)index
, tool
); 
 384 void wxToolBarMSW::LayoutTools() 
 386   m_currentRowsOrColumns 
= 0; 
 389   int maxToolWidth 
= 0; 
 390   int maxToolHeight 
= 0; 
 394   // Find the maximum tool width and height 
 395   wxNode 
*node 
= m_tools
.First(); 
 398     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->Data(); 
 399     if (tool
->GetWidth() > maxToolWidth
) 
 400       maxToolWidth 
= (int)tool
->GetWidth(); 
 401     if (tool
->GetHeight() > maxToolHeight
) 
 402       maxToolHeight 
= (int)tool
->GetHeight(); 
 406   int separatorSize 
= m_toolSeparation
; 
 408   node 
= m_tools
.First(); 
 411     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->Data(); 
 412     if (tool
->m_toolStyle 
== wxTOOL_STYLE_SEPARATOR
) 
 414       if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 416         if (m_currentRowsOrColumns 
>= m_maxCols
) 
 417           m_lastY 
+= separatorSize
; 
 419           m_lastX 
+= separatorSize
; 
 423         if (m_currentRowsOrColumns 
>= m_maxRows
) 
 424           m_lastX 
+= separatorSize
; 
 426           m_lastY 
+= separatorSize
; 
 429     else if (tool
->m_toolStyle 
== wxTOOL_STYLE_BUTTON
) 
 431       if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 433         if (m_currentRowsOrColumns 
>= m_maxCols
) 
 435           m_currentRowsOrColumns 
= 0; 
 437           m_lastY 
+= maxToolHeight 
+ m_toolPacking
; 
 439         tool
->m_x 
= (long) (m_lastX 
+ (maxToolWidth 
- tool
->GetWidth())/2.0); 
 440         tool
->m_y 
= (long) (m_lastY 
+ (maxToolHeight 
- tool
->GetHeight())/2.0); 
 442         m_lastX 
+= maxToolWidth 
+ m_toolPacking
; 
 446         if (m_currentRowsOrColumns 
>= m_maxRows
) 
 448           m_currentRowsOrColumns 
= 0; 
 449           m_lastX 
+= (maxToolWidth 
+ m_toolPacking
); 
 452         tool
->m_x 
= (long) (m_lastX 
+ (maxToolWidth 
- tool
->GetWidth())/2.0); 
 453         tool
->m_y 
= (long) (m_lastY 
+ (maxToolHeight 
- tool
->GetHeight())/2.0); 
 455         m_lastY 
+= maxToolHeight 
+ m_toolPacking
; 
 457       m_currentRowsOrColumns 
++; 
 460     if (m_lastX 
> m_maxWidth
) 
 461       m_maxWidth 
= m_lastX
; 
 462     if (m_lastY 
> m_maxHeight
) 
 463       m_maxHeight 
= m_lastY
; 
 467   if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 469     m_maxWidth 
+= maxToolWidth
; 
 470     m_maxHeight 
+= maxToolHeight
; 
 474     m_maxWidth 
+= maxToolWidth
; 
 475     m_maxHeight 
+= maxToolHeight
; 
 478   m_maxWidth 
+= m_xMargin
; 
 479   m_maxHeight 
+= m_yMargin
; 
 481   SetSize(m_maxWidth
, m_maxHeight
); 
 485 bool wxToolBarMSW::InitGlobalObjects(void) 
 488   if (!CreateDitherBrush()) 
 491   m_hdcMono 
= (WXHDC
) CreateCompatibleDC(NULL
); 
 495   m_hbmMono 
= (WXHBITMAP
) CreateBitmap((int)GetToolSize().x
, (int)GetToolSize().y
, 1, 1, NULL
); 
 499   m_hbmDefault 
= (WXHBITMAP
) SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmMono
); 
 503 void wxToolBarMSW::FreeGlobalObjects(void) 
 510             SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmDefault
); 
 513         DeleteDC((HDC
) m_hdcMono
);              // toast the DCs 
 518                 DeleteObject((HBITMAP
) m_hbmMono
); 
 523 void wxToolBarMSW::PatB(WXHDC hdc
,int x
,int y
,int dx
,int dy
, long rgb
) 
 532     SetBkColor((HDC
) hdc
,rgb
); 
 533     ExtTextOut((HDC
) hdc
,0,0,ETO_OPAQUE
,&rc
,NULL
,0,NULL
); 
 537 // create a mono bitmap mask: 
 538 //   1's where color == COLOR_BTNFACE || COLOR_HILIGHT 
 539 //   0's everywhere else 
 541 void wxToolBarMSW::CreateMask(WXHDC hdc
, int xoffset
, int yoffset
, int dx
, int dy
) 
 543     HDC globalDC 
= ::GetDC(NULL
); 
 544     HDC hdcGlyphs 
= CreateCompatibleDC((HDC
) globalDC
); 
 545     ReleaseDC(NULL
, (HDC
) globalDC
); 
 547     // krj - create a new bitmap and copy the image from hdc. 
 548     //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap); 
 549     HBITMAP hBitmap 
= CreateCompatibleBitmap((HDC
) hdc
, dx
, dy
); 
 550     HBITMAP bitmapOld 
= (HBITMAP
) SelectObject(hdcGlyphs
, hBitmap
); 
 551     BitBlt(hdcGlyphs
, 0,0, dx
, dy
, (HDC
) hdc
, 0, 0, SRCCOPY
); 
 553     // initalize whole area with 1's 
 554     PatBlt((HDC
) m_hdcMono
, 0, 0, dx
, dy
, WHITENESS
); 
 556     // create mask based on color bitmap 
 557     // convert this to 1's 
 558     SetBkColor(hdcGlyphs
, m_rgbFace
); 
 559     BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
, 
 560         hdcGlyphs
, 0, 0, SRCCOPY
); 
 561     // convert this to 1's 
 562     SetBkColor(hdcGlyphs
, m_rgbHilight
); 
 564     BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
, 
 565         hdcGlyphs
, 0, 0, SRCPAINT
); 
 567     SelectObject(hdcGlyphs
, bitmapOld
); 
 568     DeleteObject(hBitmap
); 
 572 void wxToolBarMSW::DrawBlankButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, int state
) 
 575     PatB(hdc
, x
, y
, dx
, dy
, m_rgbFace
); 
 577     if (state 
& wxTBSTATE_PRESSED
) { 
 578         PatB(hdc
, x 
+ 1, y
, dx 
- 2, 1, m_rgbFrame
); 
 579         PatB(hdc
, x 
+ 1, y 
+ dy 
- 1, dx 
- 2, 1, m_rgbFrame
); 
 580         PatB(hdc
, x
, y 
+ 1, 1, dy 
- 2, m_rgbFrame
); 
 581         PatB(hdc
, x 
+ dx 
- 1, y 
+1, 1, dy 
- 2, m_rgbFrame
); 
 582         PatB(hdc
, x 
+ 1, y 
+ 1, 1, dy
-2, m_rgbShadow
); 
 583         PatB(hdc
, x 
+ 1, y 
+ 1, dx
-2, 1, m_rgbShadow
); 
 586         PatB(hdc
, x 
+ 1, y
, dx 
- 2, 1, m_rgbFrame
); 
 587         PatB(hdc
, x 
+ 1, y 
+ dy 
- 1, dx 
- 2, 1, m_rgbFrame
); 
 588         PatB(hdc
, x
, y 
+ 1, 1, dy 
- 2, m_rgbFrame
); 
 589         PatB(hdc
, x 
+ dx 
- 1, y 
+ 1, 1, dy 
- 2, m_rgbFrame
); 
 592         PatB(hdc
, x 
+ 1, y 
+ 1, 1, dy 
- 1, m_rgbHilight
); 
 593         PatB(hdc
, x 
+ 1, y 
+ 1, dx 
- 1, 1, m_rgbHilight
); 
 594         PatB(hdc
, x 
+ dx
, y 
+ 1, 1, dy
, m_rgbShadow
); 
 595         PatB(hdc
, x 
+ 1, y 
+ dy
, dx
, 1,   m_rgbShadow
); 
 596         PatB(hdc
, x 
+ dx 
- 1, y 
+ 2, 1, dy 
- 2, m_rgbShadow
); 
 597         PatB(hdc
, x 
+ 2, y 
+ dy 
- 1, dx 
- 2, 1,   m_rgbShadow
); 
 601 void wxToolBarMSW::DrawButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, wxToolBarTool 
*tool
, int state
) 
 605     BOOL bMaskCreated 
= FALSE
; 
 606     int xButton 
= 0;            // assume button is down 
 613 //    HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP(); 
 614     HDC globalDC 
= ::GetDC(NULL
); 
 615     HDC hdcGlyphs 
= CreateCompatibleDC(globalDC
); 
 616     ReleaseDC(NULL
, globalDC
); 
 618     // get the proper button look - up or down. 
 619     if (!(state 
& (wxTBSTATE_PRESSED 
| wxTBSTATE_CHECKED
))) { 
 620         xButton 
= dx
;   // use 'up' version of button 
 622         dyFace 
-= 2;    // extents to ignore button highlight 
 625     DrawBlankButton(hdc
, x
, y
, dx
, dy
, state
); 
 628     // move coordinates inside border and away from upper left highlight. 
 629     // the extents change accordingly. 
 635     // Using bitmap2 can cause problems (don't know why!) 
 636 #if !defined(__WIN32__) && !defined(__WIN386__) 
 638     if (tool
->m_bitmap2
.Ok()) 
 639       bitmapOld 
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap2
.GetHBITMAP()); 
 641       bitmapOld 
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap1
.GetHBITMAP()); 
 643     HBITMAP bitmapOld 
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap1
.GetHBITMAP()); 
 646     // calculate offset of face from (x,y).  y is always from the top, 
 647     // so the offset is easy.  x needs to be centered in face. 
 649     xCenterOffset 
= (dxFace 
- (int)GetToolBitmapSize().x
)/2; 
 650     if (state 
& (wxTBSTATE_PRESSED 
| wxTBSTATE_CHECKED
)) 
 652         // pressed state moves down and to the right 
 653         // (x moves automatically as face size grows) 
 657     // now put on the face 
 658     if (state 
& wxTBSTATE_ENABLED
) { 
 660         BitBlt((HDC
) hdc
, x
+xCenterOffset
, y 
+ yOffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
, 
 661             hdcGlyphs
, 0, 0, SRCCOPY
); 
 663         // disabled version (or indeterminate) 
 665         CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
); 
 666 //        CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace); 
 668         SetTextColor((HDC
) hdc
, 0L);     // 0's in mono -> 0 (for ROP) 
 669         SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1's in mono -> 1 
 671         // draw glyph's white understrike 
 672         if (!(state 
& wxTBSTATE_INDETERMINATE
)) { 
 673             hbr 
= CreateSolidBrush(m_rgbHilight
); 
 675                 hbrOld 
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
); 
 677                     // draw hilight color where we have 0's in the mask 
 678                     BitBlt((HDC
) hdc
, x 
+ 1, y 
+ 1, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A); 
 679                     SelectObject((HDC
) hdc
, hbrOld
); 
 686         hbr 
= CreateSolidBrush(m_rgbShadow
); 
 688             hbrOld 
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
); 
 690                 // draw the shadow color where we have 0's in the mask 
 691                 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A); 
 692                 SelectObject((HDC
) hdc
, hbrOld
); 
 697         if (state 
& wxTBSTATE_CHECKED
) { 
 698             BitBlt((HDC
) m_hdcMono
, 1, 1, dxFace 
- 1, dyFace 
- 1, (HDC
) m_hdcMono
, 0, 0, SRCAND
); 
 702     if (state 
& (wxTBSTATE_CHECKED 
| wxTBSTATE_INDETERMINATE
)) { 
 704         hbrOld 
= (HBRUSH
) SelectObject((HDC
) hdc
, (HBRUSH
) m_hbrDither
); 
 708                 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
); 
 709 //                CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace); 
 711             SetTextColor((HDC
) hdc
, 0L);                // 0 -> 0 
 712             SetBkColor((HDC
) hdc
, 0x00FFFFFF);  // 1 -> 1 
 714             // only draw the dither brush where the mask is 1's 
 715             BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00E20746); 
 717             SelectObject((HDC
) hdc
, hbrOld
); 
 720     SelectObject(hdcGlyphs
, bitmapOld
); 
 724 void wxToolBarMSW::GetSysColors(void) 
 726         static COLORREF rgbSaveFace    
= 0xffffffffL
, 
 727                         rgbSaveShadow  
= 0xffffffffL
, 
 728                         rgbSaveHilight 
= 0xffffffffL
, 
 729                         rgbSaveFrame   
= 0xffffffffL
; 
 731     // For now, override these because the colour replacement isn't working, 
 732     // and we get inconsistent colours. Assume all buttons are grey for the moment. 
 734 //      m_rgbFace    = GetSysColor(COLOR_BTNFACE); 
 735         m_rgbFace 
= RGB(192,192,192); 
 736 //      m_rgbShadow  = GetSysColor(COLOR_BTNSHADOW); 
 737         m_rgbShadow 
= RGB(128,128,128); 
 738 //      m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT); 
 739         m_rgbHilight 
= RGB(255, 255, 255); 
 741         m_rgbFrame   
= GetSysColor(COLOR_WINDOWFRAME
); 
 743         if (rgbSaveFace
!=m_rgbFace 
|| rgbSaveShadow
!=m_rgbShadow
 
 744                 || rgbSaveHilight
!=m_rgbHilight 
|| rgbSaveFrame
!=m_rgbFrame
) 
 746                 rgbSaveFace    
= m_rgbFace
; 
 747                 rgbSaveShadow  
= m_rgbShadow
; 
 748                 rgbSaveHilight 
= m_rgbHilight
; 
 749         rgbSaveFrame   
= m_rgbFrame
; 
 751                 // Update the brush for pushed-in buttons 
 756 WXHBITMAP 
wxToolBarMSW::CreateDitherBitmap() 
 765     pbmi 
= (BITMAPINFO 
*)malloc(sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
)); 
 766     memset(pbmi
, 0, (sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
))); 
 768     pbmi
->bmiHeader
.biSize 
= sizeof(BITMAPINFOHEADER
); 
 769     pbmi
->bmiHeader
.biWidth 
= 8; 
 770     pbmi
->bmiHeader
.biHeight 
= 8; 
 771     pbmi
->bmiHeader
.biPlanes 
= 1; 
 772     pbmi
->bmiHeader
.biBitCount 
= 1; 
 773     pbmi
->bmiHeader
.biCompression 
= BI_RGB
; 
 775 //    rgb = GetSysColor(COLOR_BTNFACE); 
 776     rgb 
= RGB(192,192,192); 
 778     pbmi
->bmiColors
[0].rgbBlue  
= GetBValue(rgb
); 
 779     pbmi
->bmiColors
[0].rgbGreen 
= GetGValue(rgb
); 
 780     pbmi
->bmiColors
[0].rgbRed   
= GetRValue(rgb
); 
 781     pbmi
->bmiColors
[0].rgbReserved 
= 0; 
 783 //    rgb = GetSysColor(COLOR_BTNHIGHLIGHT); 
 784     rgb 
= RGB(255, 255, 255); 
 786     pbmi
->bmiColors
[1].rgbBlue  
= GetBValue(rgb
); 
 787     pbmi
->bmiColors
[1].rgbGreen 
= GetGValue(rgb
); 
 788     pbmi
->bmiColors
[1].rgbRed   
= GetRValue(rgb
); 
 789     pbmi
->bmiColors
[1].rgbReserved 
= 0; 
 791     /* initialize the brushes */ 
 793     for (i 
= 0; i 
< 8; i
++) 
 795            patGray
[i
] = 0xAAAA5555L
;   //  0x11114444L; // lighter gray 
 797            patGray
[i
] = 0x5555AAAAL
;   //  0x11114444L; // lighter gray 
 801     hbm 
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
, patGray
, pbmi
, DIB_RGB_COLORS
); 
 803     ReleaseDC(NULL
, hdc
); 
 806     return (WXHBITMAP
)hbm
; 
 809 bool wxToolBarMSW::CreateDitherBrush(void) 
 815         hbmGray 
= (HBITMAP
) CreateDitherBitmap(); 
 819                 hbrSave 
= (HBRUSH
) m_hbrDither
; 
 820                 m_hbrDither 
= (WXHBRUSH
) CreatePatternBrush(hbmGray
); 
 821                 DeleteObject(hbmGray
); 
 826                                 DeleteObject(hbrSave
); 
 832                         m_hbrDither 
= (WXHBRUSH
) hbrSave
; 
 839 bool wxToolBarMSW::FreeDitherBrush(void) 
 842       DeleteObject((HBRUSH
) m_hbrDither
); 
 847 typedef struct tagCOLORMAP2
 
 854 // these are the default colors used to map the dib colors 
 855 // to the current system colors 
 857 #define BGR_BUTTONTEXT      (RGB(000,000,000))  // black 
 858 #define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey 
 859 #define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey 
 860 #define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white 
 861 #define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue 
 862 #define BGR_BACKGROUND      (RGB(255,000,255))  // magenta 
 863 #define FlipColor(rgb)      (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb))) 
 865 WXHBITMAP 
wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE 
WXUNUSED(hInstance
), void *info
) 
 867   LPBITMAPINFOHEADER lpBitmapInfo 
= (LPBITMAPINFOHEADER
)info
; 
 868   HDC                   hdc
, hdcMem 
= NULL
; 
 872   HBITMAP               hbm 
= NULL
, hbmOld
; 
 875   static COLORMAP2 ColorMap
[] = { 
 876     {BGR_BUTTONTEXT
,    BGR_BUTTONTEXT
,    COLOR_BTNTEXT
},     // black 
 877     {BGR_BUTTONSHADOW
,  BGR_BUTTONSHADOW
,  COLOR_BTNSHADOW
},   // dark grey 
 878     {BGR_BUTTONFACE
,    BGR_BUTTONFACE
,    COLOR_BTNFACE
},     // bright grey 
 879     {BGR_BUTTONHILIGHT
, BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white 
 880     {BGR_BACKGROUNDSEL
, BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
},   // blue 
 881     {BGR_BACKGROUND
,    BGR_BACKGROUND
,    COLOR_WINDOW
}       // magenta 
 884   #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2)) 
 890   // So what are the new colors anyway ? 
 892   for (i
=0; i 
< (int) NUM_MAPS
; i
++) { 
 893      ColorMap
[i
].bgrto 
= (long unsigned int) FlipColor(GetSysColor((int)ColorMap
[i
].sysColor
)); 
 896   p 
= (DWORD FAR 
*)(((LPSTR
)lpBitmapInfo
) + lpBitmapInfo
->biSize
); 
 898   /* Replace button-face and button-shadow colors with the current values 
 902   while (numcolors
-- > 0) { 
 903       for (i 
= 0; i 
< (int) NUM_MAPS
; i
++) { 
 904           if (*p 
== ColorMap
[i
].bgrfrom
) { 
 905           *p 
= ColorMap
[i
].bgrto
; 
 912   /* First skip over the header structure */ 
 913   lpBits 
= (LPSTR
)(lpBitmapInfo 
+ 1); 
 915   /* Skip the color table entries, if any */ 
 916   lpBits 
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
); 
 918   /* Create a color bitmap compatible with the display device */ 
 919   i 
= wid 
= (int)lpBitmapInfo
->biWidth
; 
 920   hgt 
= (int)lpBitmapInfo
->biHeight
; 
 923   hdcMem 
= CreateCompatibleDC(hdc
); 
 925 //    hbm = CreateDiscardableBitmap(hdc, i, hgt); 
 926     hbm 
= CreateCompatibleBitmap(hdc
, i
, hgt
); 
 928         hbmOld 
= (HBITMAP
) SelectObject(hdcMem
, hbm
); 
 930         // set the main image 
 931         StretchDIBits(hdcMem
, 0, 0, wid
, hgt
, 0, 0, wid
, hgt
, lpBits
, 
 932                    (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
); 
 934         SelectObject(hdcMem
, hbmOld
); 
 937     DeleteObject(hdcMem
); 
 940   ReleaseDC(NULL
, hdc
); 
 942   return (WXHBITMAP
) hbm
; 
 945 WXHBITMAP 
wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE hInstance
, WXHBITMAP hBitmap
) 
 947   HANDLE hDIB 
= BitmapToDIB((HBITMAP
) hBitmap
, 0); 
 950 #ifdef __WINDOWS_386__ 
 951     LPBITMAPINFOHEADER lpbmInfoHdr 
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
)); 
 953     LPBITMAPINFOHEADER lpbmInfoHdr 
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
); 
 955     HBITMAP newBitmap 
= (HBITMAP
) CreateMappedBitmap((WXHINSTANCE
) wxGetInstance(), lpbmInfoHdr
); 
 958     return (WXHBITMAP
) newBitmap
;