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
38 #include "wx/tbarmsw.h"
40 #include "wx/msw/private.h"
41 #include "wx/msw/dib.h"
43 #define DEFAULTBITMAPX 16
44 #define DEFAULTBITMAPY 15
45 #define DEFAULTBUTTONX 24
46 #define DEFAULTBUTTONY 22
47 #define DEFAULTBARHEIGHT 27
49 /////// Non-Windows 95 implementation
51 #if !wxUSE_IMAGE_LOADING_IN_MSW
52 #error If wxUSE_IMAGE_LOADING_IN_MSW is set to 0, then wxUSE_BUTTONBAR must be set to 0 too.
55 #if !USE_SHARED_LIBRARY
56 IMPLEMENT_DYNAMIC_CLASS(wxToolBarMSW
, wxToolBarBase
)
58 BEGIN_EVENT_TABLE(wxToolBarMSW
, wxToolBarBase
)
59 EVT_SIZE(wxToolBarMSW::OnSize
)
60 EVT_PAINT(wxToolBarMSW::OnPaint
)
61 EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent
)
65 wxToolBarMSW::wxToolBarMSW(void)
75 m_defaultWidth
= DEFAULTBITMAPX
;
76 m_defaultHeight
= DEFAULTBITMAPY
;
79 bool wxToolBarMSW::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
,
80 long style
, const wxString
& name
)
82 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
85 if ( style
& wxTB_HORIZONTAL
)
86 { m_lastX
= 3; m_lastY
= 7; }
88 { m_lastX
= 7; m_lastY
= 3; }
89 m_maxWidth
= m_maxHeight
= 0;
90 m_pressedTool
= m_currentTool
= -1;
97 SetBackgroundColour(wxColour(192, 192, 192));
107 m_defaultWidth
= DEFAULTBITMAPX
;
108 m_defaultHeight
= DEFAULTBITMAPY
;
115 wxToolBarMSW::~wxToolBarMSW(void)
120 void wxToolBarMSW::SetToolBitmapSize(const wxSize
& size
)
122 m_defaultWidth
= size
.x
; m_defaultHeight
= size
.y
;
127 // The button size is bigger than the bitmap size
128 wxSize
wxToolBarMSW::GetToolSize(void) const
130 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
133 void wxToolBarMSW::OnPaint(wxPaintEvent
& event
)
137 static int wxOnPaintCount
= 0;
139 // Prevent reentry of OnPaint which would cause
140 // wxMemoryDC errors.
141 if (wxOnPaintCount
> 0)
145 wxNode
*node
= m_tools
.First();
148 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
149 if (tool
->m_toolStyle
!= wxTOOL_STYLE_SEPARATOR
)
151 int state
= wxTBSTATE_ENABLED
;
152 if (!tool
->m_enabled
)
154 if (tool
->m_isToggle
&& tool
->m_toggleState
)
155 state
|= wxTBSTATE_CHECKED
;
156 DrawTool(dc
, tool
, state
);
163 void wxToolBarMSW::OnSize(wxSizeEvent
& event
)
165 wxToolBarBase::OnSize(event
);
168 // If a Button is disabled, then NO function (besides leaving
169 // or entering) should be carried out. Therefore the additions
170 // of 'enabled' testing (Stefan Hammes).
171 void wxToolBarMSW::OnMouseEvent(wxMouseEvent
& event
)
173 static wxToolBarTool
*eventCurrentTool
= NULL
;
179 if (eventCurrentTool
&& eventCurrentTool
->m_enabled
)
182 int state
= wxTBSTATE_ENABLED
;
183 if (eventCurrentTool
->m_toggleState
)
184 state
|= wxTBSTATE_CHECKED
;
185 DrawTool(dc
, eventCurrentTool
, state
);
186 eventCurrentTool
= NULL
;
193 event
.Position(&x
, &y
);
194 wxToolBarTool
*tool
= FindToolForPosition(x
, y
);
198 if (eventCurrentTool
&& eventCurrentTool
->m_enabled
)
202 int state
= wxTBSTATE_ENABLED
;
203 if (eventCurrentTool
->m_toggleState
)
204 state
|= wxTBSTATE_CHECKED
;
205 DrawTool(dc
, eventCurrentTool
, state
);
206 eventCurrentTool
= NULL
;
208 if (m_currentTool
> -1)
216 if (!event
.Dragging() && !event
.IsButton())
218 if (tool
->m_index
!= m_currentTool
)
220 OnMouseEnter(tool
->m_index
);
221 m_currentTool
= tool
->m_index
;
225 if (event
.Dragging() && tool
->m_enabled
)
227 if (eventCurrentTool
)
229 // Might have dragged outside tool
230 if (eventCurrentTool
!= tool
)
232 int state
= wxTBSTATE_ENABLED
;
233 if (tool
->m_toggleState
)
234 state
|= wxTBSTATE_CHECKED
;
235 DrawTool(dc
, tool
, state
);
236 eventCurrentTool
= NULL
;
242 if (tool
&& event
.LeftIsDown() && tool
->m_enabled
)
244 eventCurrentTool
= tool
;
245 ::SetCapture((HWND
) GetHWND());
246 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
247 if (tool
->m_toggleState
)
248 state
|= wxTBSTATE_CHECKED
;
249 DrawTool(dc
, tool
, state
);
253 if (event
.LeftDown() && tool
->m_enabled
)
255 eventCurrentTool
= tool
;
256 ::SetCapture((HWND
) GetHWND());
257 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
258 if (tool
->m_toggleState
)
259 state
|= wxTBSTATE_CHECKED
;
260 DrawTool(dc
, tool
, state
);
262 else if (event
.LeftUp() && tool
->m_enabled
)
264 if (eventCurrentTool
)
266 if (eventCurrentTool
== tool
)
268 if (tool
->m_isToggle
)
270 tool
->m_toggleState
= !tool
->m_toggleState
;
271 if (!OnLeftClick(tool
->m_index
, tool
->m_toggleState
))
273 tool
->m_toggleState
= !tool
->m_toggleState
;
275 int state
= wxTBSTATE_ENABLED
;
276 if (tool
->m_toggleState
)
277 state
|= wxTBSTATE_CHECKED
;
278 DrawTool(dc
, tool
, state
);
282 int state
= wxTBSTATE_ENABLED
;
283 if (tool
->m_toggleState
)
284 state
|= wxTBSTATE_CHECKED
;
285 DrawTool(dc
, tool
, state
);
286 OnLeftClick(tool
->m_index
, tool
->m_toggleState
);
289 eventCurrentTool
= NULL
;
291 else if (event
.RightDown() && tool
->m_enabled
)
293 OnRightClick(tool
->m_index
, x
, y
);
297 // This function enables/disables a toolbar tool and redraws it.
298 // If that would not be done, the enabling/disabling wouldn't be
299 // visible on the screen.
300 void wxToolBarMSW::EnableTool(int toolIndex
, bool enable
)
302 wxNode
*node
= m_tools
.Find((long)toolIndex
);
307 // at first do the enabling/disabling in the base class
308 wxToolBarBase::EnableTool(toolIndex
,enable
);
309 // then calculate the state of the tool and draw it
310 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
312 if(tool
->m_toggleState
) state
|= wxTBSTATE_CHECKED
;
313 if(tool
->m_enabled
) state
|= wxTBSTATE_ENABLED
;
314 // how can i access the PRESSED state???
315 DrawTool(dc
, tool
,state
);
319 void wxToolBarMSW::DrawTool(wxDC
& dc
, wxToolBarTool
*tool
, int state
)
321 DrawButton(dc
.GetHDC(), (int)tool
->m_x
, (int)tool
->m_y
, (int)tool
->GetWidth(), (int)tool
->GetHeight(), tool
, state
);
324 void wxToolBarMSW::DrawTool(wxDC
& dc
, wxMemoryDC
& , wxToolBarTool
*tool
)
326 int state
= wxTBSTATE_ENABLED
;
327 if (!tool
->m_enabled
)
329 if (tool
->m_toggleState
)
330 state
|= wxTBSTATE_CHECKED
;
331 DrawTool(dc
, tool
, state
);
334 // If pushedBitmap is NULL, a reversed version of bitmap is
335 // created and used as the pushed/toggled image.
336 // If toggle is TRUE, the button toggles between the two states.
337 wxToolBarTool
*wxToolBarMSW::AddTool(int index
, const wxBitmap
& bitmap
, const wxBitmap
& pushedBitmap
,
338 bool toggle
, long xPos
, long yPos
, wxObject
*clientData
, const wxString
& helpString1
, const wxString
& helpString2
)
340 // Using bitmap2 can cause problems (don't know why!)
342 // TODO: use the mapping code from wxToolBar95 to get it right in this class
343 #if !defined(__WIN32__) && !defined(__WIN386__)
347 bitmap2
.SetHBITMAP( (WXHBITMAP
) CreateMappedBitmap(wxGetInstance(), (HBITMAP
) ((wxBitmap
& )bitmap
).GetHBITMAP()));
350 wxToolBarTool
*tool
= new wxToolBarTool(index
, bitmap
, bitmap2
, toggle
, xPos
, yPos
, helpString1
, helpString2
);
352 wxToolBarTool
*tool
= new wxToolBarTool(index
, bitmap
, wxNullBitmap
, toggle
, xPos
, yPos
, helpString1
, helpString2
);
355 tool
->m_clientData
= clientData
;
360 tool
->m_x
= m_xMargin
;
365 tool
->m_y
= m_yMargin
;
367 tool
->m_deleteSecondBitmap
= TRUE
;
368 tool
->SetSize(GetToolSize().x
, GetToolSize().y
);
370 // Calculate reasonable max size in case Layout() not called
371 if ((tool
->m_x
+ bitmap
.GetWidth() + m_xMargin
) > m_maxWidth
)
372 m_maxWidth
= (tool
->m_x
+ tool
->GetWidth() + m_xMargin
);
374 if ((tool
->m_y
+ bitmap
.GetHeight() + m_yMargin
) > m_maxHeight
)
375 m_maxHeight
= (tool
->m_y
+ tool
->GetHeight() + m_yMargin
);
377 m_tools
.Append((long)index
, tool
);
381 void wxToolBarMSW::Layout(void)
383 m_currentRowsOrColumns
= 0;
386 int maxToolWidth
= 0;
387 int maxToolHeight
= 0;
391 // Find the maximum tool width and height
392 wxNode
*node
= m_tools
.First();
395 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
396 if (tool
->GetWidth() > maxToolWidth
)
397 maxToolWidth
= (int)tool
->GetWidth();
398 if (tool
->GetHeight() > maxToolHeight
)
399 maxToolHeight
= (int)tool
->GetHeight();
403 int separatorSize
= m_toolSeparation
;
405 node
= m_tools
.First();
408 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
409 if (tool
->m_toolStyle
== wxTOOL_STYLE_SEPARATOR
)
411 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
413 if (m_currentRowsOrColumns
>= m_maxCols
)
414 m_lastY
+= separatorSize
;
416 m_lastX
+= separatorSize
;
420 if (m_currentRowsOrColumns
>= m_maxRows
)
421 m_lastX
+= separatorSize
;
423 m_lastY
+= separatorSize
;
426 else if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
428 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
430 if (m_currentRowsOrColumns
>= m_maxCols
)
432 m_currentRowsOrColumns
= 0;
434 m_lastY
+= maxToolHeight
+ m_toolPacking
;
436 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
437 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
439 m_lastX
+= maxToolWidth
+ m_toolPacking
;
443 if (m_currentRowsOrColumns
>= m_maxRows
)
445 m_currentRowsOrColumns
= 0;
446 m_lastX
+= (maxToolWidth
+ m_toolPacking
);
449 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
450 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
452 m_lastY
+= maxToolHeight
+ m_toolPacking
;
454 m_currentRowsOrColumns
++;
457 if (m_lastX
> m_maxWidth
)
458 m_maxWidth
= m_lastX
;
459 if (m_lastY
> m_maxHeight
)
460 m_maxHeight
= m_lastY
;
464 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
465 m_maxWidth
+= maxToolWidth
;
467 m_maxHeight
+= maxToolHeight
;
469 m_maxWidth
+= m_xMargin
;
470 m_maxHeight
+= m_yMargin
;
474 bool wxToolBarMSW::InitGlobalObjects(void)
477 if (!CreateDitherBrush())
480 m_hdcMono
= (WXHDC
) CreateCompatibleDC(NULL
);
484 m_hbmMono
= (WXHBITMAP
) CreateBitmap((int)GetToolSize().x
, (int)GetToolSize().y
, 1, 1, NULL
);
488 m_hbmDefault
= (WXHBITMAP
) SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmMono
);
492 void wxToolBarMSW::FreeGlobalObjects(void)
499 SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmDefault
);
502 DeleteDC((HDC
) m_hdcMono
); // toast the DCs
507 DeleteObject((HBITMAP
) m_hbmMono
);
512 void wxToolBarMSW::PatB(WXHDC hdc
,int x
,int y
,int dx
,int dy
, long rgb
)
521 SetBkColor((HDC
) hdc
,rgb
);
522 ExtTextOut((HDC
) hdc
,0,0,ETO_OPAQUE
,&rc
,NULL
,0,NULL
);
526 // create a mono bitmap mask:
527 // 1's where color == COLOR_BTNFACE || COLOR_HILIGHT
528 // 0's everywhere else
530 void wxToolBarMSW::CreateMask(WXHDC hdc
, int xoffset
, int yoffset
, int dx
, int dy
)
532 HDC globalDC
= ::GetDC(NULL
);
533 HDC hdcGlyphs
= CreateCompatibleDC((HDC
) globalDC
);
534 ReleaseDC(NULL
, (HDC
) globalDC
);
536 // krj - create a new bitmap and copy the image from hdc.
537 //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap);
538 HBITMAP hBitmap
= CreateCompatibleBitmap((HDC
) hdc
, dx
, dy
);
539 HBITMAP bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, hBitmap
);
540 BitBlt(hdcGlyphs
, 0,0, dx
, dy
, (HDC
) hdc
, 0, 0, SRCCOPY
);
542 // initalize whole area with 1's
543 PatBlt((HDC
) m_hdcMono
, 0, 0, dx
, dy
, WHITENESS
);
545 // create mask based on color bitmap
546 // convert this to 1's
547 SetBkColor(hdcGlyphs
, m_rgbFace
);
548 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
549 hdcGlyphs
, 0, 0, SRCCOPY
);
550 // convert this to 1's
551 SetBkColor(hdcGlyphs
, m_rgbHilight
);
553 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
554 hdcGlyphs
, 0, 0, SRCPAINT
);
556 SelectObject(hdcGlyphs
, bitmapOld
);
557 DeleteObject(hBitmap
);
561 void wxToolBarMSW::DrawBlankButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, int state
)
564 PatB(hdc
, x
, y
, dx
, dy
, m_rgbFace
);
566 if (state
& wxTBSTATE_PRESSED
) {
567 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
568 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
569 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
570 PatB(hdc
, x
+ dx
- 1, y
+1, 1, dy
- 2, m_rgbFrame
);
571 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
-2, m_rgbShadow
);
572 PatB(hdc
, x
+ 1, y
+ 1, dx
-2, 1, m_rgbShadow
);
575 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
576 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
577 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
578 PatB(hdc
, x
+ dx
- 1, y
+ 1, 1, dy
- 2, m_rgbFrame
);
581 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
- 1, m_rgbHilight
);
582 PatB(hdc
, x
+ 1, y
+ 1, dx
- 1, 1, m_rgbHilight
);
583 PatB(hdc
, x
+ dx
, y
+ 1, 1, dy
, m_rgbShadow
);
584 PatB(hdc
, x
+ 1, y
+ dy
, dx
, 1, m_rgbShadow
);
585 PatB(hdc
, x
+ dx
- 1, y
+ 2, 1, dy
- 2, m_rgbShadow
);
586 PatB(hdc
, x
+ 2, y
+ dy
- 1, dx
- 2, 1, m_rgbShadow
);
590 void wxToolBarMSW::DrawButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, wxToolBarTool
*tool
, int state
)
594 BOOL bMaskCreated
= FALSE
;
595 int xButton
= 0; // assume button is down
602 // HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP();
603 HDC globalDC
= ::GetDC(NULL
);
604 HDC hdcGlyphs
= CreateCompatibleDC(globalDC
);
605 ReleaseDC(NULL
, globalDC
);
607 // get the proper button look - up or down.
608 if (!(state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))) {
609 xButton
= dx
; // use 'up' version of button
611 dyFace
-= 2; // extents to ignore button highlight
614 DrawBlankButton(hdc
, x
, y
, dx
, dy
, state
);
617 // move coordinates inside border and away from upper left highlight.
618 // the extents change accordingly.
624 // Using bitmap2 can cause problems (don't know why!)
625 #if !defined(__WIN32__) && !defined(__WIN386__)
627 if (tool
->m_bitmap2
.Ok())
628 bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap2
.GetHBITMAP());
630 bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap1
.GetHBITMAP());
632 HBITMAP bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap1
.GetHBITMAP());
635 // calculate offset of face from (x,y). y is always from the top,
636 // so the offset is easy. x needs to be centered in face.
638 xCenterOffset
= (dxFace
- (int)GetToolBitmapSize().x
)/2;
639 if (state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))
641 // pressed state moves down and to the right
642 // (x moves automatically as face size grows)
646 // now put on the face
647 if (state
& wxTBSTATE_ENABLED
) {
649 BitBlt((HDC
) hdc
, x
+xCenterOffset
, y
+ yOffset
, (int)GetToolBitmapSize().x
, (int)GetToolBitmapSize().y
,
650 hdcGlyphs
, 0, 0, SRCCOPY
);
652 // disabled version (or indeterminate)
654 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
655 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
657 SetTextColor((HDC
) hdc
, 0L); // 0's in mono -> 0 (for ROP)
658 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1's in mono -> 1
660 // draw glyph's white understrike
661 if (!(state
& wxTBSTATE_INDETERMINATE
)) {
662 hbr
= CreateSolidBrush(m_rgbHilight
);
664 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
666 // draw hilight color where we have 0's in the mask
667 BitBlt((HDC
) hdc
, x
+ 1, y
+ 1, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
668 SelectObject((HDC
) hdc
, hbrOld
);
675 hbr
= CreateSolidBrush(m_rgbShadow
);
677 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
679 // draw the shadow color where we have 0's in the mask
680 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
681 SelectObject((HDC
) hdc
, hbrOld
);
686 if (state
& wxTBSTATE_CHECKED
) {
687 BitBlt((HDC
) m_hdcMono
, 1, 1, dxFace
- 1, dyFace
- 1, (HDC
) m_hdcMono
, 0, 0, SRCAND
);
691 if (state
& (wxTBSTATE_CHECKED
| wxTBSTATE_INDETERMINATE
)) {
693 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, (HBRUSH
) m_hbrDither
);
697 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
698 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
700 SetTextColor((HDC
) hdc
, 0L); // 0 -> 0
701 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1 -> 1
703 // only draw the dither brush where the mask is 1's
704 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00E20746);
706 SelectObject((HDC
) hdc
, hbrOld
);
709 SelectObject(hdcGlyphs
, bitmapOld
);
713 void wxToolBarMSW::GetSysColors(void)
715 static COLORREF rgbSaveFace
= 0xffffffffL
,
716 rgbSaveShadow
= 0xffffffffL
,
717 rgbSaveHilight
= 0xffffffffL
,
718 rgbSaveFrame
= 0xffffffffL
;
720 // For now, override these because the colour replacement isn't working,
721 // and we get inconsistent colours. Assume all buttons are grey for the moment.
723 // m_rgbFace = GetSysColor(COLOR_BTNFACE);
724 m_rgbFace
= RGB(192,192,192);
725 // m_rgbShadow = GetSysColor(COLOR_BTNSHADOW);
726 m_rgbShadow
= RGB(128,128,128);
727 // m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
728 m_rgbHilight
= RGB(255, 255, 255);
730 m_rgbFrame
= GetSysColor(COLOR_WINDOWFRAME
);
732 if (rgbSaveFace
!=m_rgbFace
|| rgbSaveShadow
!=m_rgbShadow
733 || rgbSaveHilight
!=m_rgbHilight
|| rgbSaveFrame
!=m_rgbFrame
)
735 rgbSaveFace
= m_rgbFace
;
736 rgbSaveShadow
= m_rgbShadow
;
737 rgbSaveHilight
= m_rgbHilight
;
738 rgbSaveFrame
= m_rgbFrame
;
740 // Update the brush for pushed-in buttons
745 WXHBITMAP
wxToolBarMSW::CreateDitherBitmap()
754 pbmi
= (BITMAPINFO
*)malloc(sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
));
755 memset(pbmi
, 0, (sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
)));
757 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
758 pbmi
->bmiHeader
.biWidth
= 8;
759 pbmi
->bmiHeader
.biHeight
= 8;
760 pbmi
->bmiHeader
.biPlanes
= 1;
761 pbmi
->bmiHeader
.biBitCount
= 1;
762 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
764 // rgb = GetSysColor(COLOR_BTNFACE);
765 rgb
= RGB(192,192,192);
767 pbmi
->bmiColors
[0].rgbBlue
= GetBValue(rgb
);
768 pbmi
->bmiColors
[0].rgbGreen
= GetGValue(rgb
);
769 pbmi
->bmiColors
[0].rgbRed
= GetRValue(rgb
);
770 pbmi
->bmiColors
[0].rgbReserved
= 0;
772 // rgb = GetSysColor(COLOR_BTNHIGHLIGHT);
773 rgb
= RGB(255, 255, 255);
775 pbmi
->bmiColors
[1].rgbBlue
= GetBValue(rgb
);
776 pbmi
->bmiColors
[1].rgbGreen
= GetGValue(rgb
);
777 pbmi
->bmiColors
[1].rgbRed
= GetRValue(rgb
);
778 pbmi
->bmiColors
[1].rgbReserved
= 0;
780 /* initialize the brushes */
782 for (i
= 0; i
< 8; i
++)
784 patGray
[i
] = 0xAAAA5555L
; // 0x11114444L; // lighter gray
786 patGray
[i
] = 0x5555AAAAL
; // 0x11114444L; // lighter gray
790 hbm
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
, patGray
, pbmi
, DIB_RGB_COLORS
);
792 ReleaseDC(NULL
, hdc
);
795 return (WXHBITMAP
)hbm
;
798 bool wxToolBarMSW::CreateDitherBrush(void)
804 hbmGray
= (HBITMAP
) CreateDitherBitmap();
808 hbrSave
= (HBRUSH
) m_hbrDither
;
809 m_hbrDither
= (WXHBRUSH
) CreatePatternBrush(hbmGray
);
810 DeleteObject(hbmGray
);
815 DeleteObject(hbrSave
);
821 m_hbrDither
= (WXHBRUSH
) hbrSave
;
828 bool wxToolBarMSW::FreeDitherBrush(void)
831 DeleteObject((HBRUSH
) m_hbrDither
);
836 typedef struct tagCOLORMAP2
843 // these are the default colors used to map the dib colors
844 // to the current system colors
846 #define BGR_BUTTONTEXT (RGB(000,000,000)) // black
847 #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
848 #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
849 #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
850 #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
851 #define BGR_BACKGROUND (RGB(255,000,255)) // magenta
852 #define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
854 WXHBITMAP
wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE
WXUNUSED(hInstance
), void *info
)
856 LPBITMAPINFOHEADER lpBitmapInfo
= (LPBITMAPINFOHEADER
)info
;
857 HDC hdc
, hdcMem
= NULL
;
861 HBITMAP hbm
= NULL
, hbmOld
;
864 static COLORMAP2 ColorMap
[] = {
865 {BGR_BUTTONTEXT
, BGR_BUTTONTEXT
, COLOR_BTNTEXT
}, // black
866 {BGR_BUTTONSHADOW
, BGR_BUTTONSHADOW
, COLOR_BTNSHADOW
}, // dark grey
867 {BGR_BUTTONFACE
, BGR_BUTTONFACE
, COLOR_BTNFACE
}, // bright grey
868 {BGR_BUTTONHILIGHT
, BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white
869 {BGR_BACKGROUNDSEL
, BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
}, // blue
870 {BGR_BACKGROUND
, BGR_BACKGROUND
, COLOR_WINDOW
} // magenta
873 #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2))
879 // So what are the new colors anyway ?
881 for (i
=0; i
< (int) NUM_MAPS
; i
++) {
882 ColorMap
[i
].bgrto
= (long unsigned int) FlipColor(GetSysColor((int)ColorMap
[i
].sysColor
));
885 p
= (DWORD FAR
*)(((LPSTR
)lpBitmapInfo
) + lpBitmapInfo
->biSize
);
887 /* Replace button-face and button-shadow colors with the current values
891 while (numcolors
-- > 0) {
892 for (i
= 0; i
< (int) NUM_MAPS
; i
++) {
893 if (*p
== ColorMap
[i
].bgrfrom
) {
894 *p
= ColorMap
[i
].bgrto
;
901 /* First skip over the header structure */
902 lpBits
= (LPSTR
)(lpBitmapInfo
+ 1);
904 /* Skip the color table entries, if any */
905 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
907 /* Create a color bitmap compatible with the display device */
908 i
= wid
= (int)lpBitmapInfo
->biWidth
;
909 hgt
= (int)lpBitmapInfo
->biHeight
;
912 hdcMem
= CreateCompatibleDC(hdc
);
914 // hbm = CreateDiscardableBitmap(hdc, i, hgt);
915 hbm
= CreateCompatibleBitmap(hdc
, i
, hgt
);
917 hbmOld
= (HBITMAP
) SelectObject(hdcMem
, hbm
);
919 // set the main image
920 StretchDIBits(hdcMem
, 0, 0, wid
, hgt
, 0, 0, wid
, hgt
, lpBits
,
921 (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
);
923 SelectObject(hdcMem
, hbmOld
);
926 DeleteObject(hdcMem
);
929 ReleaseDC(NULL
, hdc
);
931 return (WXHBITMAP
) hbm
;
934 WXHBITMAP
wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE hInstance
, WXHBITMAP hBitmap
)
936 HANDLE hDIB
= BitmapToDIB((HBITMAP
) hBitmap
, 0);
939 #ifdef __WINDOWS_386__
940 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
942 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
944 HBITMAP newBitmap
= (HBITMAP
) CreateMappedBitmap((WXHINSTANCE
) wxGetInstance(), lpbmInfoHdr
);
947 return (WXHBITMAP
) newBitmap
;