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_TOOLBAR && defined(__WIN16__)
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/msw/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
& bmpNormal
,
87 const wxBitmap
& bmpDisabled
,
90 const wxString
& shortHelp
,
91 const wxString
& longHelp
)
92 : wxToolBarToolBase(tbar
, id
, bmpNormal
, bmpDisabled
, toggle
,
93 clientData
, shortHelp
, longHelp
)
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
, wxToolBarBase
)
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 wxString
& label
,
140 const wxBitmap
& bmpNormal
,
141 const wxBitmap
& bmpDisabled
,
143 wxObject
*clientData
,
144 const wxString
& shortHelp
,
145 const wxString
& longHelp
)
147 return new wxToolBarTool(this, id
, label
, bmpNormal
, bmpDisabled
, kind
,
148 clientData
, shortHelp
, longHelp
);
151 wxToolBarToolBase
*wxToolBar::CreateTool(wxControl
*control
)
153 return new wxToolBarTool(this, control
);
156 // ----------------------------------------------------------------------------
158 // ----------------------------------------------------------------------------
160 void wxToolBar::Init()
171 m_defaultWidth
= DEFAULTBITMAPX
;
172 m_defaultHeight
= DEFAULTBITMAPY
;
177 m_maxWidth
= m_maxHeight
= 0;
178 m_pressedTool
= m_currentTool
= -1;
180 m_toolSeparation
= 5;
183 bool wxToolBar::Create(wxWindow
*parent
,
188 const wxString
& name
)
190 if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
193 if ( style
& wxTB_HORIZONTAL
)
205 SetBackgroundColour(wxColour(192, 192, 192));
212 wxToolBar::~wxToolBar()
217 void wxToolBar::SetToolBitmapSize(const wxSize
& size
)
219 m_defaultWidth
= size
.x
;
220 m_defaultHeight
= size
.y
;
226 // The button size is bigger than the bitmap size
227 wxSize
wxToolBar::GetToolSize() const
229 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
232 wxToolBarToolBase
*wxToolBar::FindToolForPosition(wxCoord x
, wxCoord y
) const
234 wxToolBarToolsList::Node
*node
= m_tools
.GetFirst();
237 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->GetData();
238 if ((x
>= tool
->m_x
) && (y
>= tool
->m_y
) &&
239 (x
<= (tool
->m_x
+ tool
->GetWidth())) &&
240 (y
<= (tool
->m_y
+ tool
->GetHeight())))
245 node
= node
->GetNext();
248 return (wxToolBarToolBase
*)NULL
;
251 wxToolBarToolBase
*wxToolBar::AddTool(int id
,
252 const wxBitmap
& bitmap
,
253 const wxBitmap
& pushedBitmap
,
257 wxObject
*clientData
,
258 const wxString
& helpString1
,
259 const wxString
& helpString2
)
261 // rememeber the position for DoInsertTool()
265 return wxToolBarBase::AddTool(id
, bitmap
, pushedBitmap
, toggle
,
266 xPos
, yPos
, clientData
,
267 helpString1
, helpString2
);
270 void wxToolBar::OnPaint(wxPaintEvent
& event
)
274 static int wxOnPaintCount
= 0;
276 // Prevent reentry of OnPaint which would cause
277 // wxMemoryDC errors.
278 if (wxOnPaintCount
> 0)
282 wxToolBarToolsList::Node
*node
= m_tools
.GetFirst();
285 wxToolBarToolBase
*tool
= node
->GetData();
286 if ( tool
->GetStyle()!= wxTOOL_STYLE_BUTTON
)
288 int state
= tool
->IsEnabled() ? wxTBSTATE_ENABLED
: 0;
289 if ( tool
->IsToggled() )
290 state
|= wxTBSTATE_CHECKED
;
292 DrawTool(dc
, tool
, state
);
295 node
= node
->GetNext();
301 // If a Button is disabled, then NO function (besides leaving
302 // or entering) should be carried out. Therefore the additions
303 // of 'enabled' testing (Stefan Hammes).
304 void wxToolBar::OnMouseEvent(wxMouseEvent
& event
)
306 static wxToolBarToolBase
*eventCurrentTool
= NULL
;
312 if (eventCurrentTool
&& eventCurrentTool
->IsEnabled())
315 int state
= wxTBSTATE_ENABLED
;
316 if (eventCurrentTool
->IsToggled())
317 state
|= wxTBSTATE_CHECKED
;
318 DrawTool(dc
, eventCurrentTool
, state
);
319 eventCurrentTool
= NULL
;
326 event
.GetPosition(&x
, &y
);
327 wxToolBarToolBase
*tool
= FindToolForPosition(x
, y
);
331 if (eventCurrentTool
&& eventCurrentTool
->IsEnabled())
335 int state
= wxTBSTATE_ENABLED
;
336 if (eventCurrentTool
->IsToggled())
337 state
|= wxTBSTATE_CHECKED
;
338 DrawTool(dc
, eventCurrentTool
, state
);
339 eventCurrentTool
= NULL
;
341 if (m_currentTool
> -1)
349 if (!event
.Dragging() && !event
.IsButton())
351 if (tool
->GetId() != m_currentTool
)
353 OnMouseEnter(m_currentTool
= tool
->GetId());
357 if (event
.Dragging() && tool
->IsEnabled())
359 if (eventCurrentTool
)
361 // Might have dragged outside tool
362 if (eventCurrentTool
!= tool
)
364 int state
= wxTBSTATE_ENABLED
;
365 if (tool
->IsToggled())
366 state
|= wxTBSTATE_CHECKED
;
367 DrawTool(dc
, tool
, state
);
368 eventCurrentTool
= NULL
;
374 if (tool
&& event
.LeftIsDown() && tool
->IsEnabled())
376 eventCurrentTool
= tool
;
377 ::SetCapture((HWND
) GetHWND());
378 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
379 if (tool
->IsToggled())
380 state
|= wxTBSTATE_CHECKED
;
381 DrawTool(dc
, tool
, state
);
385 if (event
.LeftDown() && tool
->IsEnabled())
387 eventCurrentTool
= tool
;
388 ::SetCapture((HWND
) GetHWND());
389 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
390 if (tool
->IsToggled())
391 state
|= wxTBSTATE_CHECKED
;
392 DrawTool(dc
, tool
, state
);
394 else if (event
.LeftUp() && tool
->IsEnabled())
396 if (eventCurrentTool
)
398 if (eventCurrentTool
== tool
)
400 if (tool
->CanBeToggled())
403 if (!OnLeftClick(tool
->GetId(), tool
->IsToggled()))
407 int state
= wxTBSTATE_ENABLED
;
408 if (tool
->IsToggled())
409 state
|= wxTBSTATE_CHECKED
;
410 DrawTool(dc
, tool
, state
);
414 int state
= wxTBSTATE_ENABLED
;
415 if (tool
->IsToggled())
416 state
|= wxTBSTATE_CHECKED
;
417 DrawTool(dc
, tool
, state
);
418 OnLeftClick(tool
->GetId(), tool
->IsToggled());
421 eventCurrentTool
= NULL
;
423 else if (event
.RightDown() && tool
->IsEnabled())
425 OnRightClick(tool
->GetId(), x
, y
);
429 void wxToolBar::DoEnableTool(wxToolBarToolBase
*tool
, bool WXUNUSED(enable
))
434 void wxToolBar::DoToggleTool(wxToolBarToolBase
*tool
, bool WXUNUSED(toggle
))
439 void wxToolBar::DoSetToggle(wxToolBarToolBase
* WXUNUSED(tool
),
440 bool WXUNUSED(toggle
))
445 void wxToolBar::DoRedrawTool(wxToolBarToolBase
*tool
)
452 void wxToolBar::DrawTool(wxDC
& dc
, wxToolBarToolBase
*toolBase
, int state
)
454 wxToolBarTool
*tool
= (wxToolBarTool
*)toolBase
;
456 DrawButton(dc
.GetHDC(),
457 tool
->m_x
, tool
->m_y
,
458 tool
->GetWidth(), tool
->GetHeight(),
462 void wxToolBar::DrawTool(wxDC
& dc
, wxToolBarToolBase
*tool
)
465 if (tool
->IsEnabled())
466 state
|= wxTBSTATE_ENABLED
;
467 if (tool
->IsToggled())
468 state
|= wxTBSTATE_CHECKED
;
469 // how can i access the PRESSED state???
471 DrawTool(dc
, tool
, state
);
474 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos
),
475 wxToolBarToolBase
*tool
)
477 // VZ: didn't test whether it works, but why not...
485 bool wxToolBar::DoInsertTool(size_t pos
, wxToolBarToolBase
*toolBase
)
487 wxToolBarTool
*tool
= (wxToolBarTool
*)toolBase
;
489 wxCHECK_MSG( !tool
->IsControl(), FALSE
,
490 _T("generic wxToolBar doesn't support controls") );
492 // TODO: use the mapping code from wxToolBar95 to get it right in this class
493 #if !defined(__WIN32__) && !defined(__WIN386__)
494 wxBitmap bmpDisabled
;
495 if (tool
->CanBeToggled())
497 HBITMAP hbmp
= CreateMappedBitmap((WXHINSTANCE
)wxGetInstance(),
498 GetHbitmapOf(tool
->GetBitmap1()));
501 bmp
.SetHBITMAP((WXHBITMAP
)hbmp
);
502 tool
->SetBitmap2(bmp
);
507 if ( tool
->m_x
== -1 )
508 tool
->m_x
= m_xMargin
;
511 if ( tool
->m_y
== -1 )
512 tool
->m_y
= m_yMargin
;
514 tool
->SetSize(GetToolSize());
516 if ( tool
->IsButton() )
518 // Calculate reasonable max size in case Layout() not called
519 if ((tool
->m_x
+ tool
->GetBitmap1().GetWidth() + m_xMargin
) > m_maxWidth
)
520 m_maxWidth
= (tool
->m_x
+ tool
->GetWidth() + m_xMargin
);
522 if ((tool
->m_y
+ tool
->GetBitmap1().GetHeight() + m_yMargin
) > m_maxHeight
)
523 m_maxHeight
= (tool
->m_y
+ tool
->GetHeight() + m_yMargin
);
529 bool wxToolBar::Realize()
531 m_currentRowsOrColumns
= 0;
534 int maxToolWidth
= 0;
535 int maxToolHeight
= 0;
539 // Find the maximum tool width and height
540 wxToolBarToolsList::Node
*node
= m_tools
.GetFirst();
543 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->GetData();
544 if (tool
->GetWidth() > maxToolWidth
)
545 maxToolWidth
= tool
->GetWidth();
546 if (tool
->GetHeight() > maxToolHeight
)
547 maxToolHeight
= tool
->GetHeight();
548 node
= node
->GetNext();
551 int separatorSize
= m_toolSeparation
;
553 node
= m_tools
.GetFirst();
556 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->GetData();
557 if (tool
->GetStyle() == wxTOOL_STYLE_SEPARATOR
)
559 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
561 if (m_currentRowsOrColumns
>= m_maxCols
)
562 m_lastY
+= separatorSize
;
564 m_lastX
+= separatorSize
;
568 if (m_currentRowsOrColumns
>= m_maxRows
)
569 m_lastX
+= separatorSize
;
571 m_lastY
+= separatorSize
;
574 else if (tool
->GetStyle() == wxTOOL_STYLE_BUTTON
)
576 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
578 if (m_currentRowsOrColumns
>= m_maxCols
)
580 m_currentRowsOrColumns
= 0;
582 m_lastY
+= maxToolHeight
+ m_toolPacking
;
584 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
585 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
587 m_lastX
+= maxToolWidth
+ m_toolPacking
;
591 if (m_currentRowsOrColumns
>= m_maxRows
)
593 m_currentRowsOrColumns
= 0;
594 m_lastX
+= (maxToolWidth
+ m_toolPacking
);
597 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
598 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
600 m_lastY
+= maxToolHeight
+ m_toolPacking
;
602 m_currentRowsOrColumns
++;
605 if (m_lastX
> m_maxWidth
)
606 m_maxWidth
= m_lastX
;
607 if (m_lastY
> m_maxHeight
)
608 m_maxHeight
= m_lastY
;
610 node
= node
->GetNext();
613 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
615 m_maxWidth
+= maxToolWidth
;
616 m_maxHeight
+= maxToolHeight
;
620 m_maxWidth
+= maxToolWidth
;
621 m_maxHeight
+= maxToolHeight
;
624 m_maxWidth
+= m_xMargin
;
625 m_maxHeight
+= m_yMargin
;
627 SetSize(m_maxWidth
, m_maxHeight
);
632 bool wxToolBar::InitGlobalObjects()
635 if (!CreateDitherBrush())
638 m_hdcMono
= (WXHDC
) CreateCompatibleDC(NULL
);
642 m_hbmMono
= (WXHBITMAP
) CreateBitmap((int)GetToolSize().x
, (int)GetToolSize().y
, 1, 1, NULL
);
646 m_hbmDefault
= (WXHBITMAP
) SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmMono
);
650 void wxToolBar::FreeGlobalObjects()
657 SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmDefault
);
660 DeleteDC((HDC
) m_hdcMono
); // toast the DCs
665 DeleteObject((HBITMAP
) m_hbmMono
);
669 // ----------------------------------------------------------------------------
671 // ----------------------------------------------------------------------------
673 void wxToolBar::PatB(WXHDC hdc
,int x
,int y
,int dx
,int dy
, long rgb
)
682 SetBkColor((HDC
) hdc
,rgb
);
683 ExtTextOut((HDC
) hdc
,0,0,ETO_OPAQUE
,&rc
,NULL
,0,NULL
);
687 // create a mono bitmap mask:
688 // 1's where color == COLOR_BTNFACE || COLOR_HILIGHT
689 // 0's everywhere else
691 void wxToolBar::CreateMask(WXHDC hdc
, int xoffset
, int yoffset
, int dx
, int dy
)
693 HDC globalDC
= ::GetDC(NULL
);
694 HDC hdcGlyphs
= CreateCompatibleDC((HDC
) globalDC
);
695 ReleaseDC(NULL
, (HDC
) globalDC
);
697 // krj - create a new bitmap and copy the image from hdc.
698 //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap);
699 HBITMAP hBitmap
= CreateCompatibleBitmap((HDC
) hdc
, dx
, dy
);
700 HBITMAP bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, hBitmap
);
701 BitBlt(hdcGlyphs
, 0,0, dx
, dy
, (HDC
) hdc
, 0, 0, SRCCOPY
);
703 // initalize whole area with 1's
704 PatBlt((HDC
) m_hdcMono
, 0, 0, dx
, dy
, WHITENESS
);
706 // create mask based on color bitmap
707 // convert this to 1's
708 SetBkColor(hdcGlyphs
, m_rgbFace
);
709 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
710 hdcGlyphs
, 0, 0, SRCCOPY
);
711 // convert this to 1's
712 SetBkColor(hdcGlyphs
, m_rgbHilight
);
714 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
715 hdcGlyphs
, 0, 0, SRCPAINT
);
717 SelectObject(hdcGlyphs
, bitmapOld
);
718 DeleteObject(hBitmap
);
722 void wxToolBar::DrawBlankButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, int state
)
725 PatB(hdc
, x
, y
, dx
, dy
, m_rgbFace
);
727 if (state
& wxTBSTATE_PRESSED
) {
728 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
729 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
730 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
731 PatB(hdc
, x
+ dx
- 1, y
+1, 1, dy
- 2, m_rgbFrame
);
732 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
-2, m_rgbShadow
);
733 PatB(hdc
, x
+ 1, y
+ 1, dx
-2, 1, m_rgbShadow
);
736 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
737 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
738 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
739 PatB(hdc
, x
+ dx
- 1, y
+ 1, 1, dy
- 2, m_rgbFrame
);
742 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
- 1, m_rgbHilight
);
743 PatB(hdc
, x
+ 1, y
+ 1, dx
- 1, 1, m_rgbHilight
);
744 PatB(hdc
, x
+ dx
, y
+ 1, 1, dy
, m_rgbShadow
);
745 PatB(hdc
, x
+ 1, y
+ dy
, dx
, 1, m_rgbShadow
);
746 PatB(hdc
, x
+ dx
- 1, y
+ 2, 1, dy
- 2, m_rgbShadow
);
747 PatB(hdc
, x
+ 2, y
+ dy
- 1, dx
- 2, 1, m_rgbShadow
);
751 void wxToolBar::DrawButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
,
752 wxToolBarToolBase
*toolBase
, int state
)
754 wxToolBarTool
*tool
= (wxToolBarTool
*)toolBase
;
758 BOOL bMaskCreated
= FALSE
;
759 int xButton
= 0; // assume button is down
766 // HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP();
767 HDC globalDC
= ::GetDC(NULL
);
768 HDC hdcGlyphs
= CreateCompatibleDC(globalDC
);
769 ReleaseDC(NULL
, globalDC
);
771 // get the proper button look - up or down.
772 if (!(state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))) {
773 xButton
= dx
; // use 'up' version of button
775 dyFace
-= 2; // extents to ignore button highlight
778 DrawBlankButton(hdc
, x
, y
, dx
, dy
, state
);
781 // move coordinates inside border and away from upper left highlight.
782 // the extents change accordingly.
788 // Using bmpDisabled can cause problems (don't know why!)
789 #if !defined(__WIN32__) && !defined(__WIN386__)
791 if (tool
->GetBitmap2().Ok())
792 bitmapOld
= GetHbitmapOf(tool
->GetBitmap2());
794 bitmapOld
= GetHbitmapOf(tool
->GetBitmap1());
796 HBITMAP bitmapOld
= GetHbitmapOf(tool
->GetBitmap1());
799 bitmapOld
= (HBITMAP
)SelectObject(hdcGlyphs
, bitmapOld
);
801 // calculate offset of face from (x,y). y is always from the top,
802 // so the offset is easy. x needs to be centered in face.
804 xCenterOffset
= (dxFace
- (int)GetToolBitmapSize().x
)/2;
805 if (state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))
807 // pressed state moves down and to the right
808 // (x moves automatically as face size grows)
812 // now put on the face
813 if (state
& wxTBSTATE_ENABLED
) {
815 BitBlt((HDC
) hdc
, x
+xCenterOffset
, y
+ yOffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
816 hdcGlyphs
, 0, 0, SRCCOPY
);
818 // disabled version (or indeterminate)
820 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
821 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
823 SetTextColor((HDC
) hdc
, 0L); // 0's in mono -> 0 (for ROP)
824 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1's in mono -> 1
826 // draw glyph's white understrike
827 if (!(state
& wxTBSTATE_INDETERMINATE
)) {
828 hbr
= CreateSolidBrush(m_rgbHilight
);
830 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
832 // draw hilight color where we have 0's in the mask
833 BitBlt((HDC
) hdc
, x
+ 1, y
+ 1, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
834 SelectObject((HDC
) hdc
, hbrOld
);
841 hbr
= CreateSolidBrush(m_rgbShadow
);
843 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
845 // draw the shadow color where we have 0's in the mask
846 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
847 SelectObject((HDC
) hdc
, hbrOld
);
852 if (state
& wxTBSTATE_CHECKED
) {
853 BitBlt((HDC
) m_hdcMono
, 1, 1, dxFace
- 1, dyFace
- 1, (HDC
) m_hdcMono
, 0, 0, SRCAND
);
857 if (state
& (wxTBSTATE_CHECKED
| wxTBSTATE_INDETERMINATE
)) {
859 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, (HBRUSH
) m_hbrDither
);
863 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
864 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
866 SetTextColor((HDC
) hdc
, 0L); // 0 -> 0
867 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1 -> 1
869 // only draw the dither brush where the mask is 1's
870 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00E20746);
872 SelectObject((HDC
) hdc
, hbrOld
);
875 SelectObject(hdcGlyphs
, bitmapOld
);
879 // ----------------------------------------------------------------------------
881 // ----------------------------------------------------------------------------
883 void wxToolBar::GetSysColors()
885 static COLORREF rgbSaveFace
= 0xffffffffL
,
886 rgbSaveShadow
= 0xffffffffL
,
887 rgbSaveHilight
= 0xffffffffL
,
888 rgbSaveFrame
= 0xffffffffL
;
890 // For now, override these because the colour replacement isn't working,
891 // and we get inconsistent colours. Assume all buttons are grey for the moment.
893 // m_rgbFace = GetSysColor(COLOR_BTNFACE);
894 m_rgbFace
= RGB(192,192,192);
895 // m_rgbShadow = GetSysColor(COLOR_BTNSHADOW);
896 m_rgbShadow
= RGB(128,128,128);
897 // m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
898 m_rgbHilight
= RGB(255, 255, 255);
900 m_rgbFrame
= GetSysColor(COLOR_WINDOWFRAME
);
902 if (rgbSaveFace
!=m_rgbFace
|| rgbSaveShadow
!=m_rgbShadow
903 || rgbSaveHilight
!=m_rgbHilight
|| rgbSaveFrame
!=m_rgbFrame
)
905 rgbSaveFace
= m_rgbFace
;
906 rgbSaveShadow
= m_rgbShadow
;
907 rgbSaveHilight
= m_rgbHilight
;
908 rgbSaveFrame
= m_rgbFrame
;
910 // Update the brush for pushed-in buttons
915 WXHBITMAP
wxToolBar::CreateDitherBitmap()
924 pbmi
= (BITMAPINFO
*)malloc(sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
));
925 memset(pbmi
, 0, (sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
)));
927 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
928 pbmi
->bmiHeader
.biWidth
= 8;
929 pbmi
->bmiHeader
.biHeight
= 8;
930 pbmi
->bmiHeader
.biPlanes
= 1;
931 pbmi
->bmiHeader
.biBitCount
= 1;
932 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
934 // rgb = GetSysColor(COLOR_BTNFACE);
935 rgb
= RGB(192,192,192);
937 pbmi
->bmiColors
[0].rgbBlue
= GetBValue(rgb
);
938 pbmi
->bmiColors
[0].rgbGreen
= GetGValue(rgb
);
939 pbmi
->bmiColors
[0].rgbRed
= GetRValue(rgb
);
940 pbmi
->bmiColors
[0].rgbReserved
= 0;
942 // rgb = GetSysColor(COLOR_BTNHIGHLIGHT);
943 rgb
= RGB(255, 255, 255);
945 pbmi
->bmiColors
[1].rgbBlue
= GetBValue(rgb
);
946 pbmi
->bmiColors
[1].rgbGreen
= GetGValue(rgb
);
947 pbmi
->bmiColors
[1].rgbRed
= GetRValue(rgb
);
948 pbmi
->bmiColors
[1].rgbReserved
= 0;
950 /* initialize the brushes */
952 for (i
= 0; i
< 8; i
++)
954 patGray
[i
] = 0xAAAA5555L
; // 0x11114444L; // lighter gray
956 patGray
[i
] = 0x5555AAAAL
; // 0x11114444L; // lighter gray
960 hbm
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
, patGray
, pbmi
, DIB_RGB_COLORS
);
962 ReleaseDC(NULL
, hdc
);
965 return (WXHBITMAP
)hbm
;
968 bool wxToolBar::CreateDitherBrush()
974 hbmGray
= (HBITMAP
) CreateDitherBitmap();
978 hbrSave
= (HBRUSH
) m_hbrDither
;
979 m_hbrDither
= (WXHBRUSH
) CreatePatternBrush(hbmGray
);
980 DeleteObject(hbmGray
);
985 DeleteObject(hbrSave
);
991 m_hbrDither
= (WXHBRUSH
) hbrSave
;
998 bool wxToolBar::FreeDitherBrush(void)
1001 DeleteObject((HBRUSH
) m_hbrDither
);
1006 typedef struct tagCOLORMAP2
1013 // these are the default colors used to map the dib colors
1014 // to the current system colors
1016 #define BGR_BUTTONTEXT (RGB(000,000,000)) // black
1017 #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
1018 #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
1019 #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
1020 #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
1021 #define BGR_BACKGROUND (RGB(255,000,255)) // magenta
1022 #define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
1024 WXHBITMAP
wxToolBar::CreateMappedBitmap(WXHINSTANCE
WXUNUSED(hInstance
), void *info
)
1026 LPBITMAPINFOHEADER lpBitmapInfo
= (LPBITMAPINFOHEADER
)info
;
1027 HDC hdc
, hdcMem
= NULL
;
1031 HBITMAP hbm
= NULL
, hbmOld
;
1034 static COLORMAP2 ColorMap
[] = {
1035 {BGR_BUTTONTEXT
, BGR_BUTTONTEXT
, COLOR_BTNTEXT
}, // black
1036 {BGR_BUTTONSHADOW
, BGR_BUTTONSHADOW
, COLOR_BTNSHADOW
}, // dark grey
1037 {BGR_BUTTONFACE
, BGR_BUTTONFACE
, COLOR_BTNFACE
}, // bright grey
1038 {BGR_BUTTONHILIGHT
, BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white
1039 {BGR_BACKGROUNDSEL
, BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
}, // blue
1040 {BGR_BACKGROUND
, BGR_BACKGROUND
, COLOR_WINDOW
} // magenta
1043 #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2))
1049 // So what are the new colors anyway ?
1051 for (i
=0; i
< (int) NUM_MAPS
; i
++) {
1052 ColorMap
[i
].bgrto
= (long unsigned int) FlipColor(GetSysColor((int)ColorMap
[i
].sysColor
));
1055 p
= (DWORD FAR
*)(((LPSTR
)lpBitmapInfo
) + lpBitmapInfo
->biSize
);
1057 /* Replace button-face and button-shadow colors with the current values
1061 while (numcolors
-- > 0) {
1062 for (i
= 0; i
< (int) NUM_MAPS
; i
++) {
1063 if (*p
== ColorMap
[i
].bgrfrom
) {
1064 *p
= ColorMap
[i
].bgrto
;
1071 /* First skip over the header structure */
1072 lpBits
= (LPSTR
)(lpBitmapInfo
+ 1);
1074 /* Skip the color table entries, if any */
1075 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
1077 /* Create a color bitmap compatible with the display device */
1078 i
= wid
= (int)lpBitmapInfo
->biWidth
;
1079 hgt
= (int)lpBitmapInfo
->biHeight
;
1080 hdc
= ::GetDC(NULL
);
1082 hdcMem
= CreateCompatibleDC(hdc
);
1084 // hbm = CreateDiscardableBitmap(hdc, i, hgt);
1085 hbm
= CreateCompatibleBitmap(hdc
, i
, hgt
);
1087 hbmOld
= (HBITMAP
) SelectObject(hdcMem
, hbm
);
1089 // set the main image
1090 StretchDIBits(hdcMem
, 0, 0, wid
, hgt
, 0, 0, wid
, hgt
, lpBits
,
1091 (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
);
1093 SelectObject(hdcMem
, hbmOld
);
1096 DeleteObject(hdcMem
);
1099 ReleaseDC(NULL
, hdc
);
1101 return (WXHBITMAP
) hbm
;
1104 WXHBITMAP
wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance
, WXHBITMAP hBitmap
)
1106 HANDLE hDIB
= wxBitmapToDIB((HBITMAP
) hBitmap
, 0);
1109 #ifdef __WINDOWS_386__
1110 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
1112 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
1114 HBITMAP newBitmap
= (HBITMAP
) CreateMappedBitmap((WXHINSTANCE
) wxGetInstance(), lpbmInfoHdr
);
1117 return (WXHBITMAP
) newBitmap
;