1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/bmpbuttn.cpp
3 // Purpose: wxBitmapButton
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "bmpbuttn.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
26 #include "wx/bmpbuttn.h"
28 #include "wx/dcmemory.h"
31 #include "wx/msw/private.h"
33 IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton
, wxButton
)
38 long "style" , wxBU_AUTODRAW
45 #define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1)
47 bool wxBitmapButton::Create(wxWindow
*parent
, wxWindowID id
, const wxBitmap
& bitmap
,
49 const wxSize
& size
, long style
,
50 const wxValidator
& validator
,
57 SetValidator(validator
);
58 #endif // wxUSE_VALIDATORS
60 parent
->AddChild(this);
62 m_backgroundColour
= parent
->GetBackgroundColour();
63 m_foregroundColour
= parent
->GetForegroundColour();
64 m_windowStyle
= style
;
66 if ( style
& wxBU_AUTODRAW
)
68 m_marginX
= wxDEFAULT_BUTTON_MARGIN
;
69 m_marginY
= wxDEFAULT_BUTTON_MARGIN
;
78 m_windowId
= NewControlId();
82 if ( width
== -1 && bitmap
.Ok())
83 width
= bitmap
.GetWidth() + 2*m_marginX
;
85 if ( height
== -1 && bitmap
.Ok())
86 height
= bitmap
.GetHeight() + 2*m_marginY
;
88 long msStyle
= WS_VISIBLE
| WS_TABSTOP
| WS_CHILD
| BS_OWNERDRAW
;
90 if ( m_windowStyle
& wxCLIP_SIBLINGS
)
91 msStyle
|= WS_CLIPSIBLINGS
;
94 if(m_windowStyle
& wxBU_LEFT
)
96 if(m_windowStyle
& wxBU_RIGHT
)
98 if(m_windowStyle
& wxBU_TOP
)
100 if(m_windowStyle
& wxBU_BOTTOM
)
101 msStyle
|= BS_BOTTOM
;
104 m_hWnd
= (WXHWND
)CreateWindowEx
117 // Subclass again for purposes of dialog editing mode
120 SetFont(parent
->GetFont());
122 SetSize(x
, y
, width
, height
);
127 // VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN
128 #define FOCUS_MARGIN 3
130 bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT
*item
)
133 long style
= GetWindowLong((HWND
) GetHWND(), GWL_STYLE
);
134 if (style
& BS_BITMAP
)
136 // Let default procedure draw the bitmap, which is defined
137 // in the Windows resource.
142 LPDRAWITEMSTRUCT lpDIS
= (LPDRAWITEMSTRUCT
) item
;
143 HDC hDC
= lpDIS
->hDC
;
144 UINT state
= lpDIS
->itemState
;
145 bool isSelected
= (state
& ODS_SELECTED
) != 0;
146 bool autoDraw
= (GetWindowStyleFlag() & wxBU_AUTODRAW
) != 0;
149 // choose the bitmap to use depending on the button state
152 if ( isSelected
&& m_bmpSelected
.Ok() )
153 bitmap
= &m_bmpSelected
;
154 else if ((state
& ODS_FOCUS
) && m_bmpFocus
.Ok())
155 bitmap
= &m_bmpFocus
;
156 else if ((state
& ODS_DISABLED
) && m_bmpDisabled
.Ok())
157 bitmap
= &m_bmpDisabled
;
159 bitmap
= &m_bmpNormal
;
164 // centre the bitmap in the control area
165 int x
= lpDIS
->rcItem
.left
;
166 int y
= lpDIS
->rcItem
.top
;
167 int width
= lpDIS
->rcItem
.right
- x
;
168 int height
= lpDIS
->rcItem
.bottom
- y
;
169 int wBmp
= bitmap
->GetWidth();
170 int hBmp
= bitmap
->GetHeight();
174 if(m_windowStyle
& wxBU_LEFT
)
175 x1
= x
+ (FOCUS_MARGIN
+1);
176 else if(m_windowStyle
& wxBU_RIGHT
)
177 x1
= x
+ (width
- wBmp
) - (FOCUS_MARGIN
+1);
179 x1
= x
+ (width
- wBmp
) / 2;
181 if(m_windowStyle
& wxBU_TOP
)
182 y1
= y
+ (FOCUS_MARGIN
+1);
183 else if(m_windowStyle
& wxBU_BOTTOM
)
184 y1
= y
+ (height
- hBmp
) - (FOCUS_MARGIN
+1);
186 y1
= y
+ (height
- hBmp
) / 2;
188 if ( isSelected
&& autoDraw
)
194 // draw the face, if auto-drawing
197 DrawFace((WXHDC
) hDC
,
198 lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
,
199 lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
,
205 dst
.SetHDC((WXHDC
) hDC
, FALSE
);
206 dst
.DrawBitmap(*bitmap
, x1
, y1
, TRUE
);
208 // draw focus / disabled state, if auto-drawing
209 if ( (state
& ODS_DISABLED
) && autoDraw
)
211 DrawButtonDisable((WXHDC
) hDC
,
212 lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
,
213 lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
,
216 else if ( (state
& ODS_FOCUS
) && autoDraw
)
218 DrawButtonFocus((WXHDC
) hDC
,
222 lpDIS
->rcItem
.bottom
,
229 // GRG Feb/2000, support for bmp buttons with Win95/98 standard LNF
231 #if defined(__WIN95__)
233 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
242 // create needed pens and brush
243 penHiLight
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DHILIGHT
));
244 penLight
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DLIGHT
));
245 penShadow
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DSHADOW
));
246 penDkShadow
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DDKSHADOW
));
247 // brushFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
248 // Taking the background colour fits in better with
249 // Windows XP themes.
250 brushFace
= CreateSolidBrush(m_backgroundColour
.m_pixel
);
252 // draw the rectangle
257 rect
.bottom
= bottom
;
258 FillRect((HDC
) dc
, &rect
, brushFace
);
261 oldp
= (HPEN
) SelectObject( (HDC
) dc
, sel
? penDkShadow
: penHiLight
);
263 wxDrawLine((HDC
) dc
, left
, top
, right
-1, top
);
264 wxDrawLine((HDC
) dc
, left
, top
+1, left
, bottom
-1);
266 SelectObject( (HDC
) dc
, sel
? penShadow
: penLight
);
267 wxDrawLine((HDC
) dc
, left
+1, top
+1, right
-2, top
+1);
268 wxDrawLine((HDC
) dc
, left
+1, top
+2, left
+1, bottom
-2);
270 SelectObject( (HDC
) dc
, sel
? penLight
: penShadow
);
271 wxDrawLine((HDC
) dc
, left
+1, bottom
-2, right
-1, bottom
-2);
272 wxDrawLine((HDC
) dc
, right
-2, bottom
-3, right
-2, top
);
274 SelectObject( (HDC
) dc
, sel
? penHiLight
: penDkShadow
);
275 wxDrawLine((HDC
) dc
, left
, bottom
-1, right
+2, bottom
-1);
276 wxDrawLine((HDC
) dc
, right
-1, bottom
-2, right
-1, top
-1);
278 // delete allocated resources
279 SelectObject((HDC
) dc
,oldp
);
280 DeleteObject(penHiLight
);
281 DeleteObject(penLight
);
282 DeleteObject(penShadow
);
283 DeleteObject(penDkShadow
);
284 DeleteObject(brushFace
);
289 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
297 // create needed pens and brush
298 penBorder
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_WINDOWFRAME
));
299 penShadow
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_BTNSHADOW
));
300 penLight
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_BTNHIGHLIGHT
));
301 brushFace
= CreateSolidBrush(COLOR_BTNFACE
);
303 // draw the rectangle
308 rect
.bottom
= bottom
;
309 FillRect((HDC
) dc
, &rect
, brushFace
);
312 oldp
= (HPEN
) SelectObject( (HDC
) dc
, penBorder
);
313 MoveToEx((HDC
) dc
,left
+1,top
,NULL
);LineTo((HDC
) dc
,right
-1,top
);
314 MoveToEx((HDC
) dc
,left
,top
+1,NULL
);LineTo((HDC
) dc
,left
,bottom
-1);
315 MoveToEx((HDC
) dc
,left
+1,bottom
-1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1);
316 MoveToEx((HDC
) dc
,right
-1,top
+1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1);
318 SelectObject( (HDC
) dc
, penShadow
);
321 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
);
322 LineTo((HDC
) dc
, left
+1 ,top
+1);
323 LineTo((HDC
) dc
, right
-2 ,top
+1);
327 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
);
328 LineTo((HDC
) dc
, right
-2 ,bottom
-2);
329 LineTo((HDC
) dc
, right
-2 ,top
);
331 MoveToEx((HDC
) dc
,left
+2 ,bottom
-3 ,NULL
);
332 LineTo((HDC
) dc
, right
-3 ,bottom
-3);
333 LineTo((HDC
) dc
, right
-3 ,top
+1);
335 SelectObject( (HDC
) dc
, penLight
);
337 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
);
338 LineTo((HDC
) dc
, left
+1 ,top
+1);
339 LineTo((HDC
) dc
, right
-2 ,top
+1);
342 // delete allocated resources
343 SelectObject((HDC
) dc
,oldp
);
344 DeleteObject(penBorder
);
345 DeleteObject(penLight
);
346 DeleteObject(penShadow
);
347 DeleteObject(brushFace
);
350 #endif // defined(__WIN95__)
353 void wxBitmapButton::DrawButtonFocus( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
359 rect
.bottom
= bottom
;
360 InflateRect( &rect
, - FOCUS_MARGIN
, - FOCUS_MARGIN
);
362 // GRG: the focus rectangle should not move when the button is pushed!
365 OffsetRect( &rect, 1, 1 );
368 DrawFocusRect( (HDC
) dc
, &rect
);
371 extern HBRUSH wxDisableButtonBrush
;
372 void wxBitmapButton::DrawButtonDisable( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool with_marg
)
374 HBRUSH old
= (HBRUSH
) SelectObject( (HDC
) dc
, wxDisableButtonBrush
);
376 // VZ: what's this?? there is no such ROP AFAIK
378 DWORD dwRop
= 0xFA0089L
;
380 DWORD dwRop
= 0xFA0089UL
;
387 right
-= 2 * m_marginX
;
388 bottom
-= 2 * m_marginY
;
391 ::PatBlt( (HDC
) dc
, left
, top
, right
, bottom
, dwRop
);
393 ::SelectObject( (HDC
) dc
, old
);
396 void wxBitmapButton::SetDefault()
398 wxButton::SetDefault();
401 #endif // wxUSE_BMPBUTTON