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"
27 #include "wx/msw/private.h"
29 #if !USE_SHARED_LIBRARY
30 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
;
43 SetValidator(validator
);
45 parent
->AddChild(this);
47 m_backgroundColour
= parent
->GetDefaultBackgroundColour() ;
48 m_foregroundColour
= parent
->GetDefaultForegroundColour() ;
49 m_windowStyle
= style
;
53 if ( style
& wxBU_AUTODRAW
)
55 m_marginX
= wxDEFAULT_BUTTON_MARGIN
;
56 m_marginY
= wxDEFAULT_BUTTON_MARGIN
;
65 m_windowId
= NewControlId();
69 if ( width
== -1 && bitmap
.Ok())
70 width
= bitmap
.GetWidth() + 2*m_marginX
;
72 if ( height
== -1 && bitmap
.Ok())
73 height
= bitmap
.GetHeight() + 2*m_marginY
;
76 CreateWindowEx(0, "BUTTON", "", BS_OWNERDRAW
| WS_TABSTOP
| WS_CHILD
,
77 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
78 wxGetInstance(), NULL
);
80 m_hWnd
= (WXHWND
)wx_button
;
82 // Subclass again for purposes of dialog editing mode
83 SubclassWin((WXHWND
)wx_button
);
85 // TODO? If in future we have a facility for having a label as well
86 // as a bitmap, set the font.
87 // SetFont(parent->GetFont()) ;
89 SetSize(x
, y
, width
, height
);
90 ShowWindow(wx_button
, SW_SHOW
);
95 void wxBitmapButton::SetBitmapLabel(const wxBitmap
& bitmap
)
97 m_buttonBitmap
= bitmap
;
100 bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT
*item
)
102 long style
= GetWindowLong((HWND
) GetHWND(), GWL_STYLE
);
103 #if defined(__WIN95__)
104 if (style
& BS_BITMAP
)
106 // Should we call Default() here?
109 // Let default procedure draw the bitmap, which is defined
110 // in the Windows resource.
115 LPDRAWITEMSTRUCT lpDIS
= (LPDRAWITEMSTRUCT
) item
;
117 wxBitmap
* bitmap
= &m_buttonBitmap
;
119 UINT state
= lpDIS
->itemState
;
120 if ((state
& ODS_SELECTED
) && m_buttonBitmapSelected
.Ok())
121 bitmap
= &m_buttonBitmapSelected
;
122 else if ((state
& ODS_FOCUS
) && m_buttonBitmapFocus
.Ok())
123 bitmap
= &m_buttonBitmapFocus
;
124 else if ((state
& ODS_DISABLED
) && m_buttonBitmapDisabled
.Ok())
125 bitmap
= &m_buttonBitmapDisabled
;
130 HDC hDC
= lpDIS
->hDC
;
131 HDC memDC
= ::CreateCompatibleDC(hDC
);
133 HBITMAP old
= (HBITMAP
) ::SelectObject(memDC
, (HBITMAP
) bitmap
->GetHBITMAP());
138 RECT rect
= lpDIS
->rcItem
;
140 int x
= lpDIS
->rcItem
.left
;
141 int y
= lpDIS
->rcItem
.top
;
142 int width
= lpDIS
->rcItem
.right
- x
;
143 int height
= lpDIS
->rcItem
.bottom
- y
;
145 // Draw the face, if auto-drawing
146 if ( GetWindowStyleFlag() & wxBU_AUTODRAW
)
147 DrawFace((WXHDC
) hDC
, lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
, lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
,
148 ((state
& ODS_SELECTED
) == ODS_SELECTED
));
150 // Centre the bitmap in the control area
151 int x1
= (int) (x
+ ((width
- bitmap
->GetWidth()) / 2));
152 int y1
= (int) (y
+ ((height
- bitmap
->GetHeight()) / 2));
154 if ( (state
& ODS_SELECTED
) && (GetWindowStyleFlag() & wxBU_AUTODRAW
) )
160 ::BitBlt(hDC
, x1
, y1
, bitmap
->GetWidth(), bitmap
->GetHeight(), memDC
, 0, 0, SRCCOPY
);
162 if ( (state
& ODS_DISABLED
) && (GetWindowStyleFlag() & wxBU_AUTODRAW
) )
163 DrawButtonDisable( (WXHDC
) hDC
, lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
, lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
, TRUE
) ;
164 else if ( (state
& ODS_FOCUS
) && (GetWindowStyleFlag() & wxBU_AUTODRAW
) )
165 DrawButtonFocus( (WXHDC
) hDC
, lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
, lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
, ((state
& ODS_SELECTED
) == ODS_SELECTED
));
167 ::SelectObject(memDC
, old
);
174 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
185 ms_color
= GetSysColor(COLOR_WINDOWFRAME
) ;
186 penBorder
= CreatePen(PS_SOLID
,0,ms_color
) ;
188 ms_color
= GetSysColor(COLOR_BTNSHADOW
) ;
189 penShadow
= CreatePen(PS_SOLID
,0,ms_color
) ;
191 ms_color
= GetSysColor(COLOR_BTNHIGHLIGHT
) ;
192 penLight
= CreatePen(PS_SOLID
,0,ms_color
) ;
194 ms_color
= GetSysColor(COLOR_BTNFACE
) ;
195 brushFace
= CreateSolidBrush(ms_color
) ;
197 oldp
= (HPEN
) SelectObject( (HDC
) dc
, GetStockObject( NULL_PEN
) ) ;
198 oldb
= (HBRUSH
) SelectObject( (HDC
) dc
, brushFace
) ;
199 Rectangle( (HDC
) dc
, left
, top
, right
, bottom
) ;
200 SelectObject( (HDC
) dc
, penBorder
) ;
201 MoveToEx((HDC
) dc
,left
+1,top
,NULL
);LineTo((HDC
) dc
,right
-1,top
);
202 MoveToEx((HDC
) dc
,left
,top
+1,NULL
);LineTo((HDC
) dc
,left
,bottom
-1);
203 MoveToEx((HDC
) dc
,left
+1,bottom
-1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1);
204 MoveToEx((HDC
) dc
,right
-1,top
+1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1);
206 SelectObject( (HDC
) dc
, penShadow
) ;
209 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
) ;
210 LineTo((HDC
) dc
, left
+1 ,top
+1) ;
211 LineTo((HDC
) dc
, right
-2 ,top
+1) ;
215 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
) ;
216 LineTo((HDC
) dc
, right
-2 ,bottom
-2) ;
217 LineTo((HDC
) dc
, right
-2 ,top
) ;
218 MoveToEx((HDC
) dc
,left
+2 ,bottom
-3 ,NULL
) ;
219 LineTo((HDC
) dc
, right
-3 ,bottom
-3) ;
220 LineTo((HDC
) dc
, right
-3 ,top
+1) ;
222 SelectObject( (HDC
) dc
, penLight
) ;
224 MoveToEx((HDC
) dc
,left
+1 ,bottom
-2 ,NULL
) ;
225 LineTo((HDC
) dc
, left
+1 ,top
+1) ;
226 LineTo((HDC
) dc
, right
-2 ,top
+1) ;
228 SelectObject((HDC
) dc
,oldp
) ;
229 SelectObject((HDC
) dc
,oldb
) ;
231 DeleteObject(penBorder
);
232 DeleteObject(penLight
);
233 DeleteObject(penShadow
);
234 DeleteObject(brushFace
);
237 #define FOCUS_MARGIN 6
239 void wxBitmapButton::DrawButtonFocus( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool sel
)
245 rect
.bottom
= bottom
;
246 InflateRect( &rect
, - FOCUS_MARGIN
, - FOCUS_MARGIN
) ;
248 OffsetRect( &rect
, 1, 1 ) ;
249 DrawFocusRect( (HDC
) dc
, &rect
) ;
252 extern HBRUSH wxDisableButtonBrush
;
253 void wxBitmapButton::DrawButtonDisable( WXHDC dc
, int left
, int top
, int right
, int bottom
, bool with_marg
)
255 HBRUSH old
= (HBRUSH
) SelectObject( (HDC
) dc
, wxDisableButtonBrush
) ;
258 ::PatBlt( (HDC
) dc
, left
+ m_marginX
, top
+ m_marginY
,
259 right
- 2 * m_marginX
, bottom
- 2 * m_marginY
,
261 else ::PatBlt( (HDC
) dc
, left
, top
, right
, bottom
, 0xfa0089ul
) ;
263 ::SelectObject( (HDC
) dc
, old
) ;