1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxBitmapButton
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bmpbuttn.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
24 #include "wx/bmpbuttn.h"
26 #include "wx/dcmemory.h"
29 #include "wx/msw/private.h"
31 IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton
, wxButton
)
33 #define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1)
35 bool wxBitmapButton::Create(wxWindow
*parent
, wxWindowID id
, const wxBitmap
& bitmap
,
37 const wxSize
& size
, long style
,
38 const wxValidator
& validator
,
41 m_buttonBitmap
= bitmap
;
45 SetValidator(validator
);
46 #endif // wxUSE_VALIDATORS
48 parent
->AddChild(this);
50 m_backgroundColour
= parent
->GetBackgroundColour();
51 m_foregroundColour
= parent
->GetForegroundColour();
52 m_windowStyle
= style
;
56 if ( style
& wxBU_AUTODRAW
)
58 m_marginX
= wxDEFAULT_BUTTON_MARGIN
;
59 m_marginY
= wxDEFAULT_BUTTON_MARGIN
;
68 m_windowId
= NewControlId();
72 if ( width
== -1 && bitmap
.Ok())
73 width
= bitmap
.GetWidth() + 2*m_marginX
;
75 if ( height
== -1 && bitmap
.Ok())
76 height
= bitmap
.GetHeight() + 2*m_marginY
;
78 m_hWnd
= (WXHWND
)CreateWindowEx
83 WS_VISIBLE
| WS_TABSTOP
| WS_CHILD
| BS_OWNERDRAW
,
91 // Subclass again for purposes of dialog editing mode
94 SetFont(parent
->GetFont());
96 SetSize(x
, y
, width
, height
);
101 void wxBitmapButton::SetBitmapLabel(const wxBitmap
& bitmap
)
103 m_buttonBitmap
= bitmap
;
106 bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT
*item
)
108 #if defined(__WIN95__)
109 long style
= GetWindowLong((HWND
) GetHWND(), GWL_STYLE
);
110 if (style
& BS_BITMAP
)
112 // Let default procedure draw the bitmap, which is defined
113 // in the Windows resource.
118 LPDRAWITEMSTRUCT lpDIS
= (LPDRAWITEMSTRUCT
) item
;
119 HDC hDC
= lpDIS
->hDC
;
120 UINT state
= lpDIS
->itemState
;
121 bool isSelected
= (state
& ODS_SELECTED
) != 0;
122 bool autoDraw
= (GetWindowStyleFlag() & wxBU_AUTODRAW
) != 0;
125 // choose the bitmap to use depending on the button state
128 if ( isSelected
&& m_buttonBitmapSelected
.Ok() )
129 bitmap
= &m_buttonBitmapSelected
;
130 else if ((state
& ODS_FOCUS
) && m_buttonBitmapFocus
.Ok())
131 bitmap
= &m_buttonBitmapFocus
;
132 else if ((state
& ODS_DISABLED
) && m_buttonBitmapDisabled
.Ok())
133 bitmap
= &m_buttonBitmapDisabled
;
135 bitmap
= &m_buttonBitmap
;
140 // centre the bitmap in the control area
141 int x
= lpDIS
->rcItem
.left
;
142 int y
= lpDIS
->rcItem
.top
;
143 int width
= lpDIS
->rcItem
.right
- x
;
144 int height
= lpDIS
->rcItem
.bottom
- y
;
145 int wBmp
= bitmap
->GetWidth();
146 int hBmp
= bitmap
->GetHeight();
147 int x1
= x
+ (width
- wBmp
) / 2;
148 int y1
= y
+ (height
- hBmp
) / 2;
150 if ( isSelected
&& autoDraw
)
156 // draw the face, if auto-drawing
159 DrawFace((WXHDC
) hDC
,
160 lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
,
161 lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
,
167 dst
.SetHDC((WXHDC
) hDC
, FALSE
);
168 dst
.DrawBitmap(*bitmap
, x1
, y1
, TRUE
);
170 // draw focus / disabled state, if auto-drawing
171 if ( (state
& ODS_DISABLED
) && autoDraw
)
173 DrawButtonDisable((WXHDC
) hDC
,
174 lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
,
175 lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
,
178 else if ( (state
& ODS_FOCUS
) && autoDraw
)
180 DrawButtonFocus((WXHDC
) hDC
,
184 lpDIS
->rcItem
.bottom
,
191 // GRG Feb/2000, support for bmp buttons with Win95/98 standard LNF
193 #if defined(__WIN95__)
195 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
204 // create needed pens and brush
205 penHiLight
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DHILIGHT
));
206 penLight
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DLIGHT
));
207 penShadow
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DSHADOW
));
208 penDkShadow
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DDKSHADOW
));
209 brushFace
= CreateSolidBrush(GetSysColor(COLOR_BTNFACE
));
211 // draw the rectangle
216 rect
.bottom
= bottom
;
217 FillRect((HDC
) dc
, &rect
, brushFace
);
220 oldp
= (HPEN
) SelectObject( (HDC
) dc
, sel
? penDkShadow
: penHiLight
);
221 MoveToEx((HDC
) dc
, left
, top
, NULL
); LineTo((HDC
) dc
, right
-1, top
);
222 MoveToEx((HDC
) dc
, left
, top
+1, NULL
); LineTo((HDC
) dc
, left
, bottom
-1);
224 SelectObject( (HDC
) dc
, sel
? penShadow
: penLight
);
225 MoveToEx((HDC
) dc
, left
+1, top
+1, NULL
); LineTo((HDC
) dc
, right
-2, top
+1);
226 MoveToEx((HDC
) dc
, left
+1, top
+2, NULL
); LineTo((HDC
) dc
, left
+1, bottom
-2);
228 SelectObject( (HDC
) dc
, sel
? penLight
: penShadow
);
229 MoveToEx((HDC
) dc
, left
+1, bottom
-2, NULL
); LineTo((HDC
) dc
, right
-1, bottom
-2);
230 MoveToEx((HDC
) dc
, right
-2, bottom
-3, NULL
); LineTo((HDC
) dc
, right
-2, top
);
232 SelectObject( (HDC
) dc
, sel
? penHiLight
: penDkShadow
);
233 MoveToEx((HDC
) dc
, left
, bottom
-1, NULL
); LineTo((HDC
) dc
, right
+2, bottom
-1);
234 MoveToEx((HDC
) dc
, right
-1, bottom
-2, NULL
); LineTo((HDC
) dc
, right
-1, top
-1);
236 // delete allocated resources
237 SelectObject((HDC
) dc
,oldp
);
238 DeleteObject(penHiLight
);
239 DeleteObject(penLight
);
240 DeleteObject(penShadow
);
241 DeleteObject(penDkShadow
);
242 DeleteObject(brushFace
);
247 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
255 // create needed pens and brush
256 penBorder
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_WINDOWFRAME
));
257 penShadow
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_BTNSHADOW
));
258 penLight
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_BTNHIGHLIGHT
));
259 brushFace
= CreateSolidBrush(COLOR_BTNFACE
);
261 // draw the rectangle
266 rect
.bottom
= bottom
;
267 FillRect((HDC
) dc
, &rect
, brushFace
);
270 oldp
= (HPEN
) SelectObject( (HDC
) dc
, penBorder
);
271 MoveToEx((HDC
) dc
,left
+1,top
,NULL
);LineTo((HDC
) dc
,right
-1,top
);
272 MoveToEx((HDC
) dc
,left
,top
+1,NULL
);LineTo((HDC
) dc
,left
,bottom
-1);
273 MoveToEx((HDC
) dc
,left
+1,bottom
-1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1);
274 MoveToEx((HDC
) dc
,right
-1,top
+1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1);
276 SelectObject( (HDC
) dc
, penShadow
);
279 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
);
280 LineTo((HDC
) dc
, left
+1 ,top
+1);
281 LineTo((HDC
) dc
, right
-2 ,top
+1);
285 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
);
286 LineTo((HDC
) dc
, right
-2 ,bottom
-2);
287 LineTo((HDC
) dc
, right
-2 ,top
);
289 MoveToEx((HDC
) dc
,left
+2 ,bottom
-3 ,NULL
);
290 LineTo((HDC
) dc
, right
-3 ,bottom
-3);
291 LineTo((HDC
) dc
, right
-3 ,top
+1);
293 SelectObject( (HDC
) dc
, penLight
);
295 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
);
296 LineTo((HDC
) dc
, left
+1 ,top
+1);
297 LineTo((HDC
) dc
, right
-2 ,top
+1);
300 // delete allocated resources
301 SelectObject((HDC
) dc
,oldp
);
302 DeleteObject(penBorder
);
303 DeleteObject(penLight
);
304 DeleteObject(penShadow
);
305 DeleteObject(brushFace
);
308 #endif // defined(__WIN95__)
311 // VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN
312 #define FOCUS_MARGIN 3
314 void wxBitmapButton::DrawButtonFocus( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
320 rect
.bottom
= bottom
;
321 InflateRect( &rect
, - FOCUS_MARGIN
, - FOCUS_MARGIN
);
323 // GRG: the focus rectangle should not move when the button is pushed!
326 OffsetRect( &rect, 1, 1 );
328 DrawFocusRect( (HDC
) dc
, &rect
);
331 extern HBRUSH wxDisableButtonBrush
;
332 void wxBitmapButton::DrawButtonDisable( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool with_marg
)
334 HBRUSH old
= (HBRUSH
) SelectObject( (HDC
) dc
, wxDisableButtonBrush
);
336 // VZ: what's this?? there is no such ROP AFAIK
338 DWORD dwRop
= 0xFA0089L
;
340 DWORD dwRop
= 0xFA0089UL
;
347 right
-= 2 * m_marginX
;
348 bottom
-= 2 * m_marginY
;
351 ::PatBlt( (HDC
) dc
, left
, top
, right
, bottom
, dwRop
);
353 ::SelectObject( (HDC
) dc
, old
);
356 void wxBitmapButton::SetDefault()
358 wxButton::SetDefault();