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(wxToolBar
, 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
.GetPosition(&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
= wxBitmapToDIB((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
;