1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
5 // Modified by: 13.12.99 by VZ during toolbar classes reorganization
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "tbarmsw.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
35 #if wxUSE_BUTTONBAR && wxUSE_TOOLBAR && !wxUSE_TOOLBAR_SIMPLE
37 #if !defined(__WIN32__) && !wxUSE_IMAGE_LOADING_IN_MSW
38 #error wxToolBar needs wxUSE_IMAGE_LOADING_IN_MSW under Win16
41 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
45 #if !defined(__MWERKS__) && !defined(__SALFORDC__)
51 #include "wx/tbarmsw.h"
54 #include "wx/bitmap.h"
55 #include "wx/msw/private.h"
56 #include "wx/msw/dib.h"
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 #define DEFAULTBITMAPX 16
63 #define DEFAULTBITMAPY 15
64 #define DEFAULTBUTTONX 24
65 #define DEFAULTBUTTONY 22
66 #define DEFAULTBARHEIGHT 27
69 // States (not all of them currently used)
71 #define wxTBSTATE_CHECKED 0x01 // radio button is checked
72 #define wxTBSTATE_PRESSED 0x02 // button is being depressed (any style)
73 #define wxTBSTATE_ENABLED 0x04 // button is enabled
74 #define wxTBSTATE_HIDDEN 0x08 // button is hidden
75 #define wxTBSTATE_INDETERMINATE 0x10 // button is indeterminate
77 // ----------------------------------------------------------------------------
79 // ----------------------------------------------------------------------------
81 class WXDLLEXPORT wxToolBarTool
: public wxToolBarToolBase
84 wxToolBarTool(wxToolBar
*tbar
,
86 const wxBitmap
& bitmap1
,
87 const wxBitmap
& bitmap2
,
90 const wxString
& shortHelpString
,
91 const wxString
& longHelpString
)
92 : wxToolBarToolBase(tbar
, id
, bitmap1
, bitmap2
, toggle
,
93 clientData
, shortHelpString
, longHelpString
)
97 wxToolBarTool(wxToolBar
*tbar
, wxControl
*control
)
98 : wxToolBarToolBase(tbar
, control
)
102 void SetSize(const wxSize
& size
)
108 long GetWidth() const { return m_width
; }
109 long GetHeight() const { return m_height
; }
117 // ----------------------------------------------------------------------------
119 // ----------------------------------------------------------------------------
121 #if !USE_SHARED_LIBRARY
122 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxControl
)
124 BEGIN_EVENT_TABLE(wxToolBar
, wxToolBarBase
)
125 EVT_PAINT(wxToolBar::OnPaint
)
126 EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent
)
130 // ============================================================================
132 // ============================================================================
134 // ----------------------------------------------------------------------------
136 // ----------------------------------------------------------------------------
138 wxToolBarToolBase
*wxToolBar::CreateTool(int id
,
139 const wxBitmap
& bitmap1
,
140 const wxBitmap
& bitmap2
,
142 wxObject
*clientData
,
143 const wxString
& shortHelpString
,
144 const wxString
& longHelpString
)
146 return new wxToolBarTool(this, id
, bitmap1
, bitmap2
, toggle
,
147 clientData
, shortHelpString
, longHelpString
);
150 wxToolBarToolBase
*wxToolBar::CreateTool(wxControl
*control
)
152 return new wxToolBarTool(this, control
);
155 // ----------------------------------------------------------------------------
157 // ----------------------------------------------------------------------------
159 void wxToolBar::Init()
170 m_defaultWidth
= DEFAULTBITMAPX
;
171 m_defaultHeight
= DEFAULTBITMAPY
;
176 m_maxWidth
= m_maxHeight
= 0;
177 m_pressedTool
= m_currentTool
= -1;
179 m_toolSeparation
= 5;
182 bool wxToolBar::Create(wxWindow
*parent
,
187 const wxString
& name
)
189 if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
192 if ( style
& wxTB_HORIZONTAL
)
204 SetBackgroundColour(wxColour(192, 192, 192));
211 wxToolBar::~wxToolBar()
216 void wxToolBar::SetToolBitmapSize(const wxSize
& size
)
218 m_defaultWidth
= size
.x
;
219 m_defaultHeight
= size
.y
;
225 // The button size is bigger than the bitmap size
226 wxSize
wxToolBar::GetToolSize() const
228 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
231 wxToolBarToolBase
*wxToolBar::FindToolForPosition(wxCoord x
, wxCoord y
) const
233 wxToolBarToolsList::Node
*node
= m_tools
.GetFirst();
236 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->GetData();
237 if ((x
>= tool
->m_x
) && (y
>= tool
->m_y
) &&
238 (x
<= (tool
->m_x
+ tool
->GetWidth())) &&
239 (y
<= (tool
->m_y
+ tool
->GetHeight())))
244 node
= node
->GetNext();
247 return (wxToolBarToolBase
*)NULL
;
250 wxToolBarToolBase
*wxToolBar::AddTool(int id
,
251 const wxBitmap
& bitmap
,
252 const wxBitmap
& pushedBitmap
,
256 wxObject
*clientData
,
257 const wxString
& helpString1
,
258 const wxString
& helpString2
)
260 // rememeber the position for DoInsertTool()
264 return wxToolBarBase::AddTool(id
, bitmap
, pushedBitmap
, toggle
,
265 xPos
, yPos
, clientData
,
266 helpString1
, helpString2
);
269 void wxToolBar::OnPaint(wxPaintEvent
& event
)
273 static int wxOnPaintCount
= 0;
275 // Prevent reentry of OnPaint which would cause
276 // wxMemoryDC errors.
277 if (wxOnPaintCount
> 0)
281 wxToolBarToolsList::Node
*node
= m_tools
.GetFirst();
284 wxToolBarToolBase
*tool
= node
->GetData();
285 if ( tool
->GetStyle()!= wxTOOL_STYLE_BUTTON
)
287 int state
= tool
->IsEnabled() ? wxTBSTATE_ENABLED
: 0;
288 if ( tool
->IsToggled() )
289 state
|= wxTBSTATE_CHECKED
;
291 DrawTool(dc
, tool
, state
);
294 node
= node
->GetNext();
300 // If a Button is disabled, then NO function (besides leaving
301 // or entering) should be carried out. Therefore the additions
302 // of 'enabled' testing (Stefan Hammes).
303 void wxToolBar::OnMouseEvent(wxMouseEvent
& event
)
305 static wxToolBarToolBase
*eventCurrentTool
= NULL
;
311 if (eventCurrentTool
&& eventCurrentTool
->IsEnabled())
314 int state
= wxTBSTATE_ENABLED
;
315 if (eventCurrentTool
->IsToggled())
316 state
|= wxTBSTATE_CHECKED
;
317 DrawTool(dc
, eventCurrentTool
, state
);
318 eventCurrentTool
= NULL
;
325 event
.GetPosition(&x
, &y
);
326 wxToolBarToolBase
*tool
= FindToolForPosition(x
, y
);
330 if (eventCurrentTool
&& eventCurrentTool
->IsEnabled())
334 int state
= wxTBSTATE_ENABLED
;
335 if (eventCurrentTool
->IsToggled())
336 state
|= wxTBSTATE_CHECKED
;
337 DrawTool(dc
, eventCurrentTool
, state
);
338 eventCurrentTool
= NULL
;
340 if (m_currentTool
> -1)
348 if (!event
.Dragging() && !event
.IsButton())
350 if (tool
->GetId() != m_currentTool
)
352 OnMouseEnter(m_currentTool
= tool
->GetId());
356 if (event
.Dragging() && tool
->IsEnabled())
358 if (eventCurrentTool
)
360 // Might have dragged outside tool
361 if (eventCurrentTool
!= tool
)
363 int state
= wxTBSTATE_ENABLED
;
364 if (tool
->IsToggled())
365 state
|= wxTBSTATE_CHECKED
;
366 DrawTool(dc
, tool
, state
);
367 eventCurrentTool
= NULL
;
373 if (tool
&& event
.LeftIsDown() && tool
->IsEnabled())
375 eventCurrentTool
= tool
;
376 ::SetCapture((HWND
) GetHWND());
377 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
378 if (tool
->IsToggled())
379 state
|= wxTBSTATE_CHECKED
;
380 DrawTool(dc
, tool
, state
);
384 if (event
.LeftDown() && tool
->IsEnabled())
386 eventCurrentTool
= tool
;
387 ::SetCapture((HWND
) GetHWND());
388 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
389 if (tool
->IsToggled())
390 state
|= wxTBSTATE_CHECKED
;
391 DrawTool(dc
, tool
, state
);
393 else if (event
.LeftUp() && tool
->IsEnabled())
395 if (eventCurrentTool
)
397 if (eventCurrentTool
== tool
)
399 if (tool
->CanBeToggled())
402 if (!OnLeftClick(tool
->GetId(), tool
->IsToggled()))
406 int state
= wxTBSTATE_ENABLED
;
407 if (tool
->IsToggled())
408 state
|= wxTBSTATE_CHECKED
;
409 DrawTool(dc
, tool
, state
);
413 int state
= wxTBSTATE_ENABLED
;
414 if (tool
->IsToggled())
415 state
|= wxTBSTATE_CHECKED
;
416 DrawTool(dc
, tool
, state
);
417 OnLeftClick(tool
->GetId(), tool
->IsToggled());
420 eventCurrentTool
= NULL
;
422 else if (event
.RightDown() && tool
->IsEnabled())
424 OnRightClick(tool
->GetId(), x
, y
);
428 void wxToolBar::DoEnableTool(wxToolBarToolBase
*tool
, bool WXUNUSED(enable
))
433 void wxToolBar::DoToggleTool(wxToolBarToolBase
*tool
, bool WXUNUSED(toggle
))
438 void wxToolBar::DoSetToggle(wxToolBarToolBase
* WXUNUSED(tool
),
439 bool WXUNUSED(toggle
))
444 void wxToolBar::DoRedrawTool(wxToolBarToolBase
*tool
)
451 void wxToolBar::DrawTool(wxDC
& dc
, wxToolBarToolBase
*toolBase
, int state
)
453 wxToolBarTool
*tool
= (wxToolBarTool
*)toolBase
;
455 DrawButton(dc
.GetHDC(),
456 tool
->m_x
, tool
->m_y
,
457 tool
->GetWidth(), tool
->GetHeight(),
461 void wxToolBar::DrawTool(wxDC
& dc
, wxToolBarToolBase
*tool
)
464 if (tool
->IsEnabled())
465 state
|= wxTBSTATE_ENABLED
;
466 if (tool
->IsToggled())
467 state
|= wxTBSTATE_CHECKED
;
468 // how can i access the PRESSED state???
470 DrawTool(dc
, tool
, state
);
473 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos
),
474 wxToolBarToolBase
*tool
)
476 // VZ: didn't test whether it works, but why not...
484 bool wxToolBar::DoInsertTool(size_t pos
, wxToolBarToolBase
*toolBase
)
486 wxToolBarTool
*tool
= (wxToolBarTool
*)toolBase
;
488 wxCHECK_MSG( !tool
->IsControl(), FALSE
,
489 _T("generic wxToolBar doesn't support controls") );
491 // TODO: use the mapping code from wxToolBar95 to get it right in this class
492 #if !defined(__WIN32__) && !defined(__WIN386__)
496 HBITMAP hbmp
= CreateMappedBitmap((WXHINSTANCE
)wxGetInstance(),
497 GetHbitmapOf(tool
->GetBitmap1()));
500 bmp
.SetHBITMAP((WXHBITMAP
)hbmp
);
501 tool
->SetBitmap2(bmp
);
506 if ( tool
->m_x
== -1 )
507 tool
->m_x
= m_xMargin
;
510 if ( tool
->m_y
== -1 )
511 tool
->m_y
= m_yMargin
;
513 tool
->SetSize(GetToolSize());
515 if ( tool
->IsButton() )
517 // Calculate reasonable max size in case Layout() not called
518 if ((tool
->m_x
+ tool
->GetBitmap1().GetWidth() + m_xMargin
) > m_maxWidth
)
519 m_maxWidth
= (tool
->m_x
+ tool
->GetWidth() + m_xMargin
);
521 if ((tool
->m_y
+ tool
->GetBitmap1().GetHeight() + m_yMargin
) > m_maxHeight
)
522 m_maxHeight
= (tool
->m_y
+ tool
->GetHeight() + m_yMargin
);
528 bool wxToolBar::Realize()
530 m_currentRowsOrColumns
= 0;
533 int maxToolWidth
= 0;
534 int maxToolHeight
= 0;
538 // Find the maximum tool width and height
539 wxToolBarToolsList::Node
*node
= m_tools
.GetFirst();
542 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->GetData();
543 if (tool
->GetWidth() > maxToolWidth
)
544 maxToolWidth
= tool
->GetWidth();
545 if (tool
->GetHeight() > maxToolHeight
)
546 maxToolHeight
= tool
->GetHeight();
547 node
= node
->GetNext();
550 int separatorSize
= m_toolSeparation
;
552 node
= m_tools
.GetFirst();
555 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->GetData();
556 if (tool
->GetStyle() == wxTOOL_STYLE_SEPARATOR
)
558 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
560 if (m_currentRowsOrColumns
>= m_maxCols
)
561 m_lastY
+= separatorSize
;
563 m_lastX
+= separatorSize
;
567 if (m_currentRowsOrColumns
>= m_maxRows
)
568 m_lastX
+= separatorSize
;
570 m_lastY
+= separatorSize
;
573 else if (tool
->GetStyle() == wxTOOL_STYLE_BUTTON
)
575 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
577 if (m_currentRowsOrColumns
>= m_maxCols
)
579 m_currentRowsOrColumns
= 0;
581 m_lastY
+= maxToolHeight
+ m_toolPacking
;
583 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
584 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
586 m_lastX
+= maxToolWidth
+ m_toolPacking
;
590 if (m_currentRowsOrColumns
>= m_maxRows
)
592 m_currentRowsOrColumns
= 0;
593 m_lastX
+= (maxToolWidth
+ m_toolPacking
);
596 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
597 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
599 m_lastY
+= maxToolHeight
+ m_toolPacking
;
601 m_currentRowsOrColumns
++;
604 if (m_lastX
> m_maxWidth
)
605 m_maxWidth
= m_lastX
;
606 if (m_lastY
> m_maxHeight
)
607 m_maxHeight
= m_lastY
;
609 node
= node
->GetNext();
612 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
614 m_maxWidth
+= maxToolWidth
;
615 m_maxHeight
+= maxToolHeight
;
619 m_maxWidth
+= maxToolWidth
;
620 m_maxHeight
+= maxToolHeight
;
623 m_maxWidth
+= m_xMargin
;
624 m_maxHeight
+= m_yMargin
;
626 SetSize(m_maxWidth
, m_maxHeight
);
631 bool wxToolBar::InitGlobalObjects()
634 if (!CreateDitherBrush())
637 m_hdcMono
= (WXHDC
) CreateCompatibleDC(NULL
);
641 m_hbmMono
= (WXHBITMAP
) CreateBitmap((int)GetToolSize().x
, (int)GetToolSize().y
, 1, 1, NULL
);
645 m_hbmDefault
= (WXHBITMAP
) SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmMono
);
649 void wxToolBar::FreeGlobalObjects()
656 SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmDefault
);
659 DeleteDC((HDC
) m_hdcMono
); // toast the DCs
664 DeleteObject((HBITMAP
) m_hbmMono
);
668 // ----------------------------------------------------------------------------
670 // ----------------------------------------------------------------------------
672 void wxToolBar::PatB(WXHDC hdc
,int x
,int y
,int dx
,int dy
, long rgb
)
681 SetBkColor((HDC
) hdc
,rgb
);
682 ExtTextOut((HDC
) hdc
,0,0,ETO_OPAQUE
,&rc
,NULL
,0,NULL
);
686 // create a mono bitmap mask:
687 // 1's where color == COLOR_BTNFACE || COLOR_HILIGHT
688 // 0's everywhere else
690 void wxToolBar::CreateMask(WXHDC hdc
, int xoffset
, int yoffset
, int dx
, int dy
)
692 HDC globalDC
= ::GetDC(NULL
);
693 HDC hdcGlyphs
= CreateCompatibleDC((HDC
) globalDC
);
694 ReleaseDC(NULL
, (HDC
) globalDC
);
696 // krj - create a new bitmap and copy the image from hdc.
697 //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap);
698 HBITMAP hBitmap
= CreateCompatibleBitmap((HDC
) hdc
, dx
, dy
);
699 HBITMAP bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, hBitmap
);
700 BitBlt(hdcGlyphs
, 0,0, dx
, dy
, (HDC
) hdc
, 0, 0, SRCCOPY
);
702 // initalize whole area with 1's
703 PatBlt((HDC
) m_hdcMono
, 0, 0, dx
, dy
, WHITENESS
);
705 // create mask based on color bitmap
706 // convert this to 1's
707 SetBkColor(hdcGlyphs
, m_rgbFace
);
708 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
709 hdcGlyphs
, 0, 0, SRCCOPY
);
710 // convert this to 1's
711 SetBkColor(hdcGlyphs
, m_rgbHilight
);
713 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
714 hdcGlyphs
, 0, 0, SRCPAINT
);
716 SelectObject(hdcGlyphs
, bitmapOld
);
717 DeleteObject(hBitmap
);
721 void wxToolBar::DrawBlankButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, int state
)
724 PatB(hdc
, x
, y
, dx
, dy
, m_rgbFace
);
726 if (state
& wxTBSTATE_PRESSED
) {
727 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
728 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
729 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
730 PatB(hdc
, x
+ dx
- 1, y
+1, 1, dy
- 2, m_rgbFrame
);
731 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
-2, m_rgbShadow
);
732 PatB(hdc
, x
+ 1, y
+ 1, dx
-2, 1, m_rgbShadow
);
735 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
736 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
737 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
738 PatB(hdc
, x
+ dx
- 1, y
+ 1, 1, dy
- 2, m_rgbFrame
);
741 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
- 1, m_rgbHilight
);
742 PatB(hdc
, x
+ 1, y
+ 1, dx
- 1, 1, m_rgbHilight
);
743 PatB(hdc
, x
+ dx
, y
+ 1, 1, dy
, m_rgbShadow
);
744 PatB(hdc
, x
+ 1, y
+ dy
, dx
, 1, m_rgbShadow
);
745 PatB(hdc
, x
+ dx
- 1, y
+ 2, 1, dy
- 2, m_rgbShadow
);
746 PatB(hdc
, x
+ 2, y
+ dy
- 1, dx
- 2, 1, m_rgbShadow
);
750 void wxToolBar::DrawButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
,
751 wxToolBarToolBase
*toolBase
, int state
)
753 wxToolBarTool
*tool
= (wxToolBarTool
*)toolBase
;
757 BOOL bMaskCreated
= FALSE
;
758 int xButton
= 0; // assume button is down
765 // HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP();
766 HDC globalDC
= ::GetDC(NULL
);
767 HDC hdcGlyphs
= CreateCompatibleDC(globalDC
);
768 ReleaseDC(NULL
, globalDC
);
770 // get the proper button look - up or down.
771 if (!(state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))) {
772 xButton
= dx
; // use 'up' version of button
774 dyFace
-= 2; // extents to ignore button highlight
777 DrawBlankButton(hdc
, x
, y
, dx
, dy
, state
);
780 // move coordinates inside border and away from upper left highlight.
781 // the extents change accordingly.
787 // Using bitmap2 can cause problems (don't know why!)
788 #if !defined(__WIN32__) && !defined(__WIN386__)
790 if (tool
->GetBitmap2().Ok())
791 bitmapOld
= GetHbitmapOf(tool
->GetBitmap2());
793 bitmapOld
= GetHbitmapOf(tool
->GetBitmap1());
795 HBITMAP bitmapOld
= GetHbitmapOf(tool
->GetBitmap1());
798 bitmapOld
= (HBITMAP
)SelectObject(hdcGlyphs
, bitmapOld
);
800 // calculate offset of face from (x,y). y is always from the top,
801 // so the offset is easy. x needs to be centered in face.
803 xCenterOffset
= (dxFace
- (int)GetToolBitmapSize().x
)/2;
804 if (state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))
806 // pressed state moves down and to the right
807 // (x moves automatically as face size grows)
811 // now put on the face
812 if (state
& wxTBSTATE_ENABLED
) {
814 BitBlt((HDC
) hdc
, x
+xCenterOffset
, y
+ yOffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
815 hdcGlyphs
, 0, 0, SRCCOPY
);
817 // disabled version (or indeterminate)
819 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
820 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
822 SetTextColor((HDC
) hdc
, 0L); // 0's in mono -> 0 (for ROP)
823 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1's in mono -> 1
825 // draw glyph's white understrike
826 if (!(state
& wxTBSTATE_INDETERMINATE
)) {
827 hbr
= CreateSolidBrush(m_rgbHilight
);
829 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
831 // draw hilight color where we have 0's in the mask
832 BitBlt((HDC
) hdc
, x
+ 1, y
+ 1, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
833 SelectObject((HDC
) hdc
, hbrOld
);
840 hbr
= CreateSolidBrush(m_rgbShadow
);
842 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
844 // draw the shadow color where we have 0's in the mask
845 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
846 SelectObject((HDC
) hdc
, hbrOld
);
851 if (state
& wxTBSTATE_CHECKED
) {
852 BitBlt((HDC
) m_hdcMono
, 1, 1, dxFace
- 1, dyFace
- 1, (HDC
) m_hdcMono
, 0, 0, SRCAND
);
856 if (state
& (wxTBSTATE_CHECKED
| wxTBSTATE_INDETERMINATE
)) {
858 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, (HBRUSH
) m_hbrDither
);
862 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
863 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
865 SetTextColor((HDC
) hdc
, 0L); // 0 -> 0
866 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1 -> 1
868 // only draw the dither brush where the mask is 1's
869 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00E20746);
871 SelectObject((HDC
) hdc
, hbrOld
);
874 SelectObject(hdcGlyphs
, bitmapOld
);
878 // ----------------------------------------------------------------------------
880 // ----------------------------------------------------------------------------
882 void wxToolBar::GetSysColors()
884 static COLORREF rgbSaveFace
= 0xffffffffL
,
885 rgbSaveShadow
= 0xffffffffL
,
886 rgbSaveHilight
= 0xffffffffL
,
887 rgbSaveFrame
= 0xffffffffL
;
889 // For now, override these because the colour replacement isn't working,
890 // and we get inconsistent colours. Assume all buttons are grey for the moment.
892 // m_rgbFace = GetSysColor(COLOR_BTNFACE);
893 m_rgbFace
= RGB(192,192,192);
894 // m_rgbShadow = GetSysColor(COLOR_BTNSHADOW);
895 m_rgbShadow
= RGB(128,128,128);
896 // m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
897 m_rgbHilight
= RGB(255, 255, 255);
899 m_rgbFrame
= GetSysColor(COLOR_WINDOWFRAME
);
901 if (rgbSaveFace
!=m_rgbFace
|| rgbSaveShadow
!=m_rgbShadow
902 || rgbSaveHilight
!=m_rgbHilight
|| rgbSaveFrame
!=m_rgbFrame
)
904 rgbSaveFace
= m_rgbFace
;
905 rgbSaveShadow
= m_rgbShadow
;
906 rgbSaveHilight
= m_rgbHilight
;
907 rgbSaveFrame
= m_rgbFrame
;
909 // Update the brush for pushed-in buttons
914 WXHBITMAP
wxToolBar::CreateDitherBitmap()
923 pbmi
= (BITMAPINFO
*)malloc(sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
));
924 memset(pbmi
, 0, (sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
)));
926 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
927 pbmi
->bmiHeader
.biWidth
= 8;
928 pbmi
->bmiHeader
.biHeight
= 8;
929 pbmi
->bmiHeader
.biPlanes
= 1;
930 pbmi
->bmiHeader
.biBitCount
= 1;
931 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
933 // rgb = GetSysColor(COLOR_BTNFACE);
934 rgb
= RGB(192,192,192);
936 pbmi
->bmiColors
[0].rgbBlue
= GetBValue(rgb
);
937 pbmi
->bmiColors
[0].rgbGreen
= GetGValue(rgb
);
938 pbmi
->bmiColors
[0].rgbRed
= GetRValue(rgb
);
939 pbmi
->bmiColors
[0].rgbReserved
= 0;
941 // rgb = GetSysColor(COLOR_BTNHIGHLIGHT);
942 rgb
= RGB(255, 255, 255);
944 pbmi
->bmiColors
[1].rgbBlue
= GetBValue(rgb
);
945 pbmi
->bmiColors
[1].rgbGreen
= GetGValue(rgb
);
946 pbmi
->bmiColors
[1].rgbRed
= GetRValue(rgb
);
947 pbmi
->bmiColors
[1].rgbReserved
= 0;
949 /* initialize the brushes */
951 for (i
= 0; i
< 8; i
++)
953 patGray
[i
] = 0xAAAA5555L
; // 0x11114444L; // lighter gray
955 patGray
[i
] = 0x5555AAAAL
; // 0x11114444L; // lighter gray
959 hbm
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
, patGray
, pbmi
, DIB_RGB_COLORS
);
961 ReleaseDC(NULL
, hdc
);
964 return (WXHBITMAP
)hbm
;
967 bool wxToolBar::CreateDitherBrush()
973 hbmGray
= (HBITMAP
) CreateDitherBitmap();
977 hbrSave
= (HBRUSH
) m_hbrDither
;
978 m_hbrDither
= (WXHBRUSH
) CreatePatternBrush(hbmGray
);
979 DeleteObject(hbmGray
);
984 DeleteObject(hbrSave
);
990 m_hbrDither
= (WXHBRUSH
) hbrSave
;
997 bool wxToolBar::FreeDitherBrush(void)
1000 DeleteObject((HBRUSH
) m_hbrDither
);
1005 typedef struct tagCOLORMAP2
1012 // these are the default colors used to map the dib colors
1013 // to the current system colors
1015 #define BGR_BUTTONTEXT (RGB(000,000,000)) // black
1016 #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
1017 #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
1018 #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
1019 #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
1020 #define BGR_BACKGROUND (RGB(255,000,255)) // magenta
1021 #define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
1023 WXHBITMAP
wxToolBar::CreateMappedBitmap(WXHINSTANCE
WXUNUSED(hInstance
), void *info
)
1025 LPBITMAPINFOHEADER lpBitmapInfo
= (LPBITMAPINFOHEADER
)info
;
1026 HDC hdc
, hdcMem
= NULL
;
1030 HBITMAP hbm
= NULL
, hbmOld
;
1033 static COLORMAP2 ColorMap
[] = {
1034 {BGR_BUTTONTEXT
, BGR_BUTTONTEXT
, COLOR_BTNTEXT
}, // black
1035 {BGR_BUTTONSHADOW
, BGR_BUTTONSHADOW
, COLOR_BTNSHADOW
}, // dark grey
1036 {BGR_BUTTONFACE
, BGR_BUTTONFACE
, COLOR_BTNFACE
}, // bright grey
1037 {BGR_BUTTONHILIGHT
, BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white
1038 {BGR_BACKGROUNDSEL
, BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
}, // blue
1039 {BGR_BACKGROUND
, BGR_BACKGROUND
, COLOR_WINDOW
} // magenta
1042 #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2))
1048 // So what are the new colors anyway ?
1050 for (i
=0; i
< (int) NUM_MAPS
; i
++) {
1051 ColorMap
[i
].bgrto
= (long unsigned int) FlipColor(GetSysColor((int)ColorMap
[i
].sysColor
));
1054 p
= (DWORD FAR
*)(((LPSTR
)lpBitmapInfo
) + lpBitmapInfo
->biSize
);
1056 /* Replace button-face and button-shadow colors with the current values
1060 while (numcolors
-- > 0) {
1061 for (i
= 0; i
< (int) NUM_MAPS
; i
++) {
1062 if (*p
== ColorMap
[i
].bgrfrom
) {
1063 *p
= ColorMap
[i
].bgrto
;
1070 /* First skip over the header structure */
1071 lpBits
= (LPSTR
)(lpBitmapInfo
+ 1);
1073 /* Skip the color table entries, if any */
1074 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
1076 /* Create a color bitmap compatible with the display device */
1077 i
= wid
= (int)lpBitmapInfo
->biWidth
;
1078 hgt
= (int)lpBitmapInfo
->biHeight
;
1079 hdc
= ::GetDC(NULL
);
1081 hdcMem
= CreateCompatibleDC(hdc
);
1083 // hbm = CreateDiscardableBitmap(hdc, i, hgt);
1084 hbm
= CreateCompatibleBitmap(hdc
, i
, hgt
);
1086 hbmOld
= (HBITMAP
) SelectObject(hdcMem
, hbm
);
1088 // set the main image
1089 StretchDIBits(hdcMem
, 0, 0, wid
, hgt
, 0, 0, wid
, hgt
, lpBits
,
1090 (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
);
1092 SelectObject(hdcMem
, hbmOld
);
1095 DeleteObject(hdcMem
);
1098 ReleaseDC(NULL
, hdc
);
1100 return (WXHBITMAP
) hbm
;
1103 WXHBITMAP
wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance
, WXHBITMAP hBitmap
)
1105 HANDLE hDIB
= wxBitmapToDIB((HBITMAP
) hBitmap
, 0);
1108 #ifdef __WINDOWS_386__
1109 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
1111 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
1113 HBITMAP newBitmap
= (HBITMAP
) CreateMappedBitmap((WXHINSTANCE
) wxGetInstance(), lpbmInfoHdr
);
1116 return (WXHBITMAP
) newBitmap
;