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 USE_BUTTONBAR && USE_TOOLBAR
36 #include "wx/tbarmsw.h"
38 #include "wx/msw/private.h"
39 #include "wx/msw/dib.h"
41 /////// Non-Windows 95 implementation
43 #if !USE_IMAGE_LOADING_IN_MSW
44 #error If USE_IMAGE_LOADING_IN_MSW is set to 0, then USE_BUTTONBAR must be set to 0 too.
47 #if !USE_SHARED_LIBRARY
48 IMPLEMENT_DYNAMIC_CLASS(wxToolBarMSW
, wxToolBarBase
)
50 BEGIN_EVENT_TABLE(wxToolBarMSW
, wxToolBarBase
)
51 EVT_SIZE(wxToolBarMSW::OnSize
)
52 EVT_PAINT(wxToolBarMSW::OnPaint
)
53 EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent
)
57 wxToolBarMSW::wxToolBarMSW(void)
67 m_defaultWidth
= DEFAULTBITMAPX
;
68 m_defaultHeight
= DEFAULTBITMAPY
;
71 bool wxToolBarMSW::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
,
72 long style
, int orientation
,
73 int RowsOrColumns
, const wxString
& name
)
75 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
78 m_tilingDirection
= orientation
;
79 m_rowsOrColumns
= RowsOrColumns
;
80 if ( m_tilingDirection
== wxVERTICAL
)
81 { m_lastX
= 3; m_lastY
= 7; }
83 { m_lastX
= 7; m_lastY
= 3; }
84 m_maxWidth
= m_maxHeight
= 0;
85 m_pressedTool
= m_currentTool
= -1;
92 SetBackgroundColour(wxColour(192, 192, 192));
102 m_defaultWidth
= DEFAULTBITMAPX
;
103 m_defaultHeight
= DEFAULTBITMAPY
;
110 wxToolBarMSW::~wxToolBarMSW(void)
115 void wxToolBarMSW::SetDefaultSize(const wxSize
& size
)
117 m_defaultWidth
= size
.x
; m_defaultHeight
= size
.y
;
122 // The button size is bigger than the bitmap size
123 wxSize
wxToolBarMSW::GetDefaultButtonSize(void) const
125 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
128 void wxToolBarMSW::OnPaint(wxPaintEvent
& event
)
132 static int wxOnPaintCount
= 0;
134 // Prevent reentry of OnPaint which would cause
135 // wxMemoryDC errors.
136 if (wxOnPaintCount
> 0)
140 wxNode
*node
= m_tools
.First();
143 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
144 if (tool
->m_toolStyle
!= wxTOOL_STYLE_SEPARATOR
)
146 int state
= wxTBSTATE_ENABLED
;
147 if (!tool
->m_enabled
)
149 if (tool
->m_isToggle
&& tool
->m_toggleState
)
150 state
|= wxTBSTATE_CHECKED
;
151 DrawTool(dc
, tool
, state
);
158 void wxToolBarMSW::OnSize(wxSizeEvent
& event
)
160 wxToolBarBase::OnSize(event
);
163 // If a Button is disabled, then NO function (besides leaving
164 // or entering) should be carried out. Therefore the additions
165 // of 'enabled' testing (Stefan Hammes).
166 void wxToolBarMSW::OnMouseEvent(wxMouseEvent
& event
)
168 static wxToolBarTool
*eventCurrentTool
= NULL
;
174 if (eventCurrentTool
&& eventCurrentTool
->m_enabled
)
177 int state
= wxTBSTATE_ENABLED
;
178 if (eventCurrentTool
->m_toggleState
)
179 state
|= wxTBSTATE_CHECKED
;
180 DrawTool(dc
, eventCurrentTool
, state
);
181 eventCurrentTool
= NULL
;
188 event
.Position(&x
, &y
);
189 wxToolBarTool
*tool
= FindToolForPosition(x
, y
);
193 if (eventCurrentTool
&& eventCurrentTool
->m_enabled
)
197 int state
= wxTBSTATE_ENABLED
;
198 if (eventCurrentTool
->m_toggleState
)
199 state
|= wxTBSTATE_CHECKED
;
200 DrawTool(dc
, eventCurrentTool
, state
);
201 eventCurrentTool
= NULL
;
203 if (m_currentTool
> -1)
211 if (!event
.Dragging() && !event
.IsButton())
213 if (tool
->m_index
!= m_currentTool
)
215 OnMouseEnter(tool
->m_index
);
216 m_currentTool
= tool
->m_index
;
220 if (event
.Dragging() && tool
->m_enabled
)
222 if (eventCurrentTool
)
224 // Might have dragged outside tool
225 if (eventCurrentTool
!= tool
)
227 int state
= wxTBSTATE_ENABLED
;
228 if (tool
->m_toggleState
)
229 state
|= wxTBSTATE_CHECKED
;
230 DrawTool(dc
, tool
, state
);
231 eventCurrentTool
= NULL
;
237 if (tool
&& event
.LeftIsDown() && tool
->m_enabled
)
239 eventCurrentTool
= tool
;
240 ::SetCapture((HWND
) GetHWND());
241 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
242 if (tool
->m_toggleState
)
243 state
|= wxTBSTATE_CHECKED
;
244 DrawTool(dc
, tool
, state
);
248 if (event
.LeftDown() && tool
->m_enabled
)
250 eventCurrentTool
= tool
;
251 ::SetCapture((HWND
) GetHWND());
252 int state
= wxTBSTATE_ENABLED
|wxTBSTATE_PRESSED
;
253 if (tool
->m_toggleState
)
254 state
|= wxTBSTATE_CHECKED
;
255 DrawTool(dc
, tool
, state
);
257 else if (event
.LeftUp() && tool
->m_enabled
)
259 if (eventCurrentTool
)
261 if (eventCurrentTool
== tool
)
263 if (tool
->m_isToggle
)
265 tool
->m_toggleState
= !tool
->m_toggleState
;
266 if (!OnLeftClick(tool
->m_index
, tool
->m_toggleState
))
268 tool
->m_toggleState
= !tool
->m_toggleState
;
270 int state
= wxTBSTATE_ENABLED
;
271 if (tool
->m_toggleState
)
272 state
|= wxTBSTATE_CHECKED
;
273 DrawTool(dc
, tool
, state
);
277 int state
= wxTBSTATE_ENABLED
;
278 if (tool
->m_toggleState
)
279 state
|= wxTBSTATE_CHECKED
;
280 DrawTool(dc
, tool
, state
);
281 OnLeftClick(tool
->m_index
, tool
->m_toggleState
);
284 eventCurrentTool
= NULL
;
286 else if (event
.RightDown() && tool
->m_enabled
)
288 OnRightClick(tool
->m_index
, x
, y
);
292 // This function enables/disables a toolbar tool and redraws it.
293 // If that would not be done, the enabling/disabling wouldn't be
294 // visible on the screen.
295 void wxToolBarMSW::EnableTool(int toolIndex
, bool enable
)
297 wxNode
*node
= m_tools
.Find((long)toolIndex
);
302 // at first do the enabling/disabling in the base class
303 wxToolBarBase::EnableTool(toolIndex
,enable
);
304 // then calculate the state of the tool and draw it
305 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
307 if(tool
->m_toggleState
) state
|= wxTBSTATE_CHECKED
;
308 if(tool
->m_enabled
) state
|= wxTBSTATE_ENABLED
;
309 // how can i access the PRESSED state???
310 DrawTool(dc
, tool
,state
);
314 void wxToolBarMSW::DrawTool(wxDC
& dc
, wxToolBarTool
*tool
, int state
)
316 DrawButton(dc
.GetHDC(), (int)tool
->m_x
, (int)tool
->m_y
, (int)tool
->GetWidth(), (int)tool
->GetHeight(), tool
, state
);
319 void wxToolBarMSW::DrawTool(wxDC
& dc
, wxMemoryDC
& , wxToolBarTool
*tool
)
321 int state
= wxTBSTATE_ENABLED
;
322 if (!tool
->m_enabled
)
324 if (tool
->m_toggleState
)
325 state
|= wxTBSTATE_CHECKED
;
326 DrawTool(dc
, tool
, state
);
329 // If pushedBitmap is NULL, a reversed version of bitmap is
330 // created and used as the pushed/toggled image.
331 // If toggle is TRUE, the button toggles between the two states.
332 wxToolBarTool
*wxToolBarMSW::AddTool(int index
, const wxBitmap
& bitmap
, const wxBitmap
& pushedBitmap
,
333 bool toggle
, long xPos
, long yPos
, wxObject
*clientData
, const wxString
& helpString1
, const wxString
& helpString2
)
335 // Using bitmap2 can cause problems (don't know why!)
337 // TODO: use the mapping code from wxToolBar95 to get it right in this class
338 #if !defined(__WIN32__) && !defined(__WIN386__)
339 wxBitmap
*bitmap2
= NULL
;
342 bitmap2
= new wxBitmap
;
343 bitmap2
->SetHBITMAP( (WXHBITMAP
) CreateMappedBitmap(wxGetInstance(), (HBITMAP
) ((wxBitmap
& )bitmap
).GetHBITMAP()));
346 wxToolBarTool
*tool
= new wxToolBarTool(index
, bitmap
, *bitmap2
, toggle
, xPos
, yPos
, helpString1
, helpString2
);
348 wxToolBarTool
*tool
= new wxToolBarTool(index
, bitmap
, (wxBitmap
*)NULL
, toggle
, xPos
, yPos
, helpString1
, helpString2
);
351 tool
->m_clientData
= clientData
;
356 tool
->m_x
= m_xMargin
;
361 tool
->m_y
= m_yMargin
;
363 tool
->m_deleteSecondBitmap
= TRUE
;
364 tool
->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight());
366 // Calculate reasonable max size in case Layout() not called
367 if ((tool
->m_x
+ bitmap
.GetWidth() + m_xMargin
) > m_maxWidth
)
368 m_maxWidth
= (tool
->m_x
+ tool
->GetWidth() + m_xMargin
);
370 if ((tool
->m_y
+ bitmap
.GetHeight() + m_yMargin
) > m_maxHeight
)
371 m_maxHeight
= (tool
->m_y
+ tool
->GetHeight() + m_yMargin
);
373 m_tools
.Append((long)index
, tool
);
377 bool wxToolBarMSW::InitGlobalObjects(void)
380 if (!CreateDitherBrush())
383 m_hdcMono
= (WXHDC
) CreateCompatibleDC(NULL
);
387 m_hbmMono
= (WXHBITMAP
) CreateBitmap((int)GetDefaultButtonWidth(), (int)GetDefaultButtonHeight(), 1, 1, NULL
);
391 m_hbmDefault
= (WXHBITMAP
) SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmMono
);
395 void wxToolBarMSW::FreeGlobalObjects(void)
402 SelectObject((HDC
) m_hdcMono
, (HBITMAP
) m_hbmDefault
);
405 DeleteDC((HDC
) m_hdcMono
); // toast the DCs
410 DeleteObject((HBITMAP
) m_hbmMono
);
415 void wxToolBarMSW::PatB(WXHDC hdc
,int x
,int y
,int dx
,int dy
, long rgb
)
424 SetBkColor((HDC
) hdc
,rgb
);
425 ExtTextOut((HDC
) hdc
,0,0,ETO_OPAQUE
,&rc
,NULL
,0,NULL
);
429 // create a mono bitmap mask:
430 // 1's where color == COLOR_BTNFACE || COLOR_HILIGHT
431 // 0's everywhere else
433 void wxToolBarMSW::CreateMask(WXHDC hdc
, int xoffset
, int yoffset
, int dx
, int dy
)
435 HDC globalDC
= ::GetDC(NULL
);
436 HDC hdcGlyphs
= CreateCompatibleDC((HDC
) globalDC
);
437 ReleaseDC(NULL
, (HDC
) globalDC
);
439 // krj - create a new bitmap and copy the image from hdc.
440 //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap);
441 HBITMAP hBitmap
= CreateCompatibleBitmap((HDC
) hdc
, dx
, dy
);
442 HBITMAP bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, hBitmap
);
443 BitBlt(hdcGlyphs
, 0,0, dx
, dy
, (HDC
) hdc
, 0, 0, SRCCOPY
);
445 // initalize whole area with 1's
446 PatBlt((HDC
) m_hdcMono
, 0, 0, dx
, dy
, WHITENESS
);
448 // create mask based on color bitmap
449 // convert this to 1's
450 SetBkColor(hdcGlyphs
, m_rgbFace
);
451 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetDefaultWidth(), (int)GetDefaultHeight(),
452 hdcGlyphs
, 0, 0, SRCCOPY
);
453 // convert this to 1's
454 SetBkColor(hdcGlyphs
, m_rgbHilight
);
456 BitBlt((HDC
) m_hdcMono
, xoffset
, yoffset
, (int)GetDefaultWidth(), (int)GetDefaultHeight(),
457 hdcGlyphs
, 0, 0, SRCPAINT
);
459 SelectObject(hdcGlyphs
, bitmapOld
);
460 DeleteObject(hBitmap
);
464 void wxToolBarMSW::DrawBlankButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, int state
)
467 PatB(hdc
, x
, y
, dx
, dy
, m_rgbFace
);
469 if (state
& wxTBSTATE_PRESSED
) {
470 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
471 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
472 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
473 PatB(hdc
, x
+ dx
- 1, y
+1, 1, dy
- 2, m_rgbFrame
);
474 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
-2, m_rgbShadow
);
475 PatB(hdc
, x
+ 1, y
+ 1, dx
-2, 1, m_rgbShadow
);
478 PatB(hdc
, x
+ 1, y
, dx
- 2, 1, m_rgbFrame
);
479 PatB(hdc
, x
+ 1, y
+ dy
- 1, dx
- 2, 1, m_rgbFrame
);
480 PatB(hdc
, x
, y
+ 1, 1, dy
- 2, m_rgbFrame
);
481 PatB(hdc
, x
+ dx
- 1, y
+ 1, 1, dy
- 2, m_rgbFrame
);
484 PatB(hdc
, x
+ 1, y
+ 1, 1, dy
- 1, m_rgbHilight
);
485 PatB(hdc
, x
+ 1, y
+ 1, dx
- 1, 1, m_rgbHilight
);
486 PatB(hdc
, x
+ dx
, y
+ 1, 1, dy
, m_rgbShadow
);
487 PatB(hdc
, x
+ 1, y
+ dy
, dx
, 1, m_rgbShadow
);
488 PatB(hdc
, x
+ dx
- 1, y
+ 2, 1, dy
- 2, m_rgbShadow
);
489 PatB(hdc
, x
+ 2, y
+ dy
- 1, dx
- 2, 1, m_rgbShadow
);
493 void wxToolBarMSW::DrawButton(WXHDC hdc
, int x
, int y
, int dx
, int dy
, wxToolBarTool
*tool
, int state
)
497 BOOL bMaskCreated
= FALSE
;
498 int xButton
= 0; // assume button is down
505 // HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP();
506 HDC globalDC
= ::GetDC(NULL
);
507 HDC hdcGlyphs
= CreateCompatibleDC(globalDC
);
508 ReleaseDC(NULL
, globalDC
);
510 // get the proper button look - up or down.
511 if (!(state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))) {
512 xButton
= dx
; // use 'up' version of button
514 dyFace
-= 2; // extents to ignore button highlight
517 DrawBlankButton(hdc
, x
, y
, dx
, dy
, state
);
520 // move coordinates inside border and away from upper left highlight.
521 // the extents change accordingly.
527 // Using bitmap2 can cause problems (don't know why!)
528 #if !defined(__WIN32__) && !defined(__WIN386__)
530 if (tool
->m_bitmap2
.Ok())
531 bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap2
.GetHBITMAP());
533 bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap1
.GetHBITMAP());
535 HBITMAP bitmapOld
= (HBITMAP
) SelectObject(hdcGlyphs
, (HBITMAP
) tool
->m_bitmap1
.GetHBITMAP());
538 // calculate offset of face from (x,y). y is always from the top,
539 // so the offset is easy. x needs to be centered in face.
541 xCenterOffset
= (dxFace
- (int)GetDefaultWidth())/2;
542 if (state
& (wxTBSTATE_PRESSED
| wxTBSTATE_CHECKED
))
544 // pressed state moves down and to the right
545 // (x moves automatically as face size grows)
549 // now put on the face
550 if (state
& wxTBSTATE_ENABLED
) {
552 BitBlt((HDC
) hdc
, x
+xCenterOffset
, y
+ yOffset
, (int)GetDefaultWidth(), (int)GetDefaultHeight(),
553 hdcGlyphs
, 0, 0, SRCCOPY
);
555 // disabled version (or indeterminate)
557 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
558 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
560 SetTextColor((HDC
) hdc
, 0L); // 0's in mono -> 0 (for ROP)
561 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1's in mono -> 1
563 // draw glyph's white understrike
564 if (!(state
& wxTBSTATE_INDETERMINATE
)) {
565 hbr
= CreateSolidBrush(m_rgbHilight
);
567 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
569 // draw hilight color where we have 0's in the mask
570 BitBlt((HDC
) hdc
, x
+ 1, y
+ 1, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
571 SelectObject((HDC
) hdc
, hbrOld
);
578 hbr
= CreateSolidBrush(m_rgbShadow
);
580 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, hbr
);
582 // draw the shadow color where we have 0's in the mask
583 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00B8074A);
584 SelectObject((HDC
) hdc
, hbrOld
);
589 if (state
& wxTBSTATE_CHECKED
) {
590 BitBlt((HDC
) m_hdcMono
, 1, 1, dxFace
- 1, dyFace
- 1, (HDC
) m_hdcMono
, 0, 0, SRCAND
);
594 if (state
& (wxTBSTATE_CHECKED
| wxTBSTATE_INDETERMINATE
)) {
596 hbrOld
= (HBRUSH
) SelectObject((HDC
) hdc
, (HBRUSH
) m_hbrDither
);
600 CreateMask((WXHDC
) hdcGlyphs
, xCenterOffset
, yOffset
, dxFace
, dyFace
);
601 // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace);
603 SetTextColor((HDC
) hdc
, 0L); // 0 -> 0
604 SetBkColor((HDC
) hdc
, 0x00FFFFFF); // 1 -> 1
606 // only draw the dither brush where the mask is 1's
607 BitBlt((HDC
) hdc
, x
, y
, dxFace
, dyFace
, (HDC
) m_hdcMono
, 0, 0, 0x00E20746);
609 SelectObject((HDC
) hdc
, hbrOld
);
612 SelectObject(hdcGlyphs
, bitmapOld
);
616 void wxToolBarMSW::GetSysColors(void)
618 static COLORREF rgbSaveFace
= 0xffffffffL
,
619 rgbSaveShadow
= 0xffffffffL
,
620 rgbSaveHilight
= 0xffffffffL
,
621 rgbSaveFrame
= 0xffffffffL
;
623 // For now, override these because the colour replacement isn't working,
624 // and we get inconsistent colours. Assume all buttons are grey for the moment.
626 // m_rgbFace = GetSysColor(COLOR_BTNFACE);
627 m_rgbFace
= RGB(192,192,192);
628 // m_rgbShadow = GetSysColor(COLOR_BTNSHADOW);
629 m_rgbShadow
= RGB(128,128,128);
630 // m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
631 m_rgbHilight
= RGB(255, 255, 255);
633 m_rgbFrame
= GetSysColor(COLOR_WINDOWFRAME
);
635 if (rgbSaveFace
!=m_rgbFace
|| rgbSaveShadow
!=m_rgbShadow
636 || rgbSaveHilight
!=m_rgbHilight
|| rgbSaveFrame
!=m_rgbFrame
)
638 rgbSaveFace
= m_rgbFace
;
639 rgbSaveShadow
= m_rgbShadow
;
640 rgbSaveHilight
= m_rgbHilight
;
641 rgbSaveFrame
= m_rgbFrame
;
643 // Update the brush for pushed-in buttons
648 WXHBITMAP
wxToolBarMSW::CreateDitherBitmap()
657 pbmi
= (BITMAPINFO
*)malloc(sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
));
658 memset(pbmi
, 0, (sizeof(BITMAPINFOHEADER
) + 16*sizeof(RGBQUAD
)));
660 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
661 pbmi
->bmiHeader
.biWidth
= 8;
662 pbmi
->bmiHeader
.biHeight
= 8;
663 pbmi
->bmiHeader
.biPlanes
= 1;
664 pbmi
->bmiHeader
.biBitCount
= 1;
665 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
667 // rgb = GetSysColor(COLOR_BTNFACE);
668 rgb
= RGB(192,192,192);
670 pbmi
->bmiColors
[0].rgbBlue
= GetBValue(rgb
);
671 pbmi
->bmiColors
[0].rgbGreen
= GetGValue(rgb
);
672 pbmi
->bmiColors
[0].rgbRed
= GetRValue(rgb
);
673 pbmi
->bmiColors
[0].rgbReserved
= 0;
675 // rgb = GetSysColor(COLOR_BTNHIGHLIGHT);
676 rgb
= RGB(255, 255, 255);
678 pbmi
->bmiColors
[1].rgbBlue
= GetBValue(rgb
);
679 pbmi
->bmiColors
[1].rgbGreen
= GetGValue(rgb
);
680 pbmi
->bmiColors
[1].rgbRed
= GetRValue(rgb
);
681 pbmi
->bmiColors
[1].rgbReserved
= 0;
683 /* initialize the brushes */
685 for (i
= 0; i
< 8; i
++)
687 patGray
[i
] = 0xAAAA5555L
; // 0x11114444L; // lighter gray
689 patGray
[i
] = 0x5555AAAAL
; // 0x11114444L; // lighter gray
693 hbm
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
, patGray
, pbmi
, DIB_RGB_COLORS
);
695 ReleaseDC(NULL
, hdc
);
698 return (WXHBITMAP
)hbm
;
701 bool wxToolBarMSW::CreateDitherBrush(void)
707 hbmGray
= (HBITMAP
) CreateDitherBitmap();
711 hbrSave
= (HBRUSH
) m_hbrDither
;
712 m_hbrDither
= (WXHBRUSH
) CreatePatternBrush(hbmGray
);
713 DeleteObject(hbmGray
);
718 DeleteObject(hbrSave
);
724 m_hbrDither
= (WXHBRUSH
) hbrSave
;
731 bool wxToolBarMSW::FreeDitherBrush(void)
734 DeleteObject((HBRUSH
) m_hbrDither
);
739 typedef struct tagCOLORMAP2
746 // these are the default colors used to map the dib colors
747 // to the current system colors
749 #define BGR_BUTTONTEXT (RGB(000,000,000)) // black
750 #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
751 #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
752 #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
753 #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
754 #define BGR_BACKGROUND (RGB(255,000,255)) // magenta
755 #define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
757 WXHBITMAP
wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE
WXUNUSED(hInstance
), void *info
)
759 LPBITMAPINFOHEADER lpBitmapInfo
= (LPBITMAPINFOHEADER
)info
;
760 HDC hdc
, hdcMem
= NULL
;
764 HBITMAP hbm
= NULL
, hbmOld
;
767 static COLORMAP2 ColorMap
[] = {
768 {BGR_BUTTONTEXT
, BGR_BUTTONTEXT
, COLOR_BTNTEXT
}, // black
769 {BGR_BUTTONSHADOW
, BGR_BUTTONSHADOW
, COLOR_BTNSHADOW
}, // dark grey
770 {BGR_BUTTONFACE
, BGR_BUTTONFACE
, COLOR_BTNFACE
}, // bright grey
771 {BGR_BUTTONHILIGHT
, BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white
772 {BGR_BACKGROUNDSEL
, BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
}, // blue
773 {BGR_BACKGROUND
, BGR_BACKGROUND
, COLOR_WINDOW
} // magenta
776 #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2))
782 // So what are the new colors anyway ?
784 for (i
=0; i
< (int) NUM_MAPS
; i
++) {
785 ColorMap
[i
].bgrto
= (long unsigned int) FlipColor(GetSysColor((int)ColorMap
[i
].sysColor
));
788 p
= (DWORD FAR
*)(((LPSTR
)lpBitmapInfo
) + lpBitmapInfo
->biSize
);
790 /* Replace button-face and button-shadow colors with the current values
794 while (numcolors
-- > 0) {
795 for (i
= 0; i
< (int) NUM_MAPS
; i
++) {
796 if (*p
== ColorMap
[i
].bgrfrom
) {
797 *p
= ColorMap
[i
].bgrto
;
804 /* First skip over the header structure */
805 lpBits
= (LPSTR
)(lpBitmapInfo
+ 1);
807 /* Skip the color table entries, if any */
808 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
810 /* Create a color bitmap compatible with the display device */
811 i
= wid
= (int)lpBitmapInfo
->biWidth
;
812 hgt
= (int)lpBitmapInfo
->biHeight
;
815 hdcMem
= CreateCompatibleDC(hdc
);
817 // hbm = CreateDiscardableBitmap(hdc, i, hgt);
818 hbm
= CreateCompatibleBitmap(hdc
, i
, hgt
);
820 hbmOld
= (HBITMAP
) SelectObject(hdcMem
, hbm
);
822 // set the main image
823 StretchDIBits(hdcMem
, 0, 0, wid
, hgt
, 0, 0, wid
, hgt
, lpBits
,
824 (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
, SRCCOPY
);
826 SelectObject(hdcMem
, hbmOld
);
829 DeleteObject(hdcMem
);
832 ReleaseDC(NULL
, hdc
);
834 return (WXHBITMAP
) hbm
;
837 WXHBITMAP
wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE hInstance
, WXHBITMAP hBitmap
)
839 HANDLE hDIB
= BitmapToDIB((HBITMAP
) hBitmap
, 0);
842 #ifdef __WINDOWS_386__
843 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
845 LPBITMAPINFOHEADER lpbmInfoHdr
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
847 HBITMAP newBitmap
= (HBITMAP
) CreateMappedBitmap((WXHINSTANCE
) wxGetInstance(), lpbmInfoHdr
);
850 return (WXHBITMAP
) newBitmap
;