]> git.saurik.com Git - wxWidgets.git/blob - src/msw/bmpbuttn.cpp
include wx/crt.h needed for wxFprintf() (closes #9509)
[wxWidgets.git] / src / msw / bmpbuttn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/bmpbuttn.cpp
3 // Purpose: wxBitmapButton
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_BMPBUTTON
20
21 #include "wx/bmpbuttn.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/log.h"
25 #include "wx/dcmemory.h"
26 #include "wx/image.h"
27 #endif
28
29 #include "wx/msw/private.h"
30 #include "wx/msw/dc.h" // for wxDCTemp
31
32 #include "wx/msw/uxtheme.h"
33
34 #if wxUSE_UXTHEME
35 // no need to include tmschema.h
36 #ifndef BP_PUSHBUTTON
37 #define BP_PUSHBUTTON 1
38
39 #define PBS_NORMAL 1
40 #define PBS_HOT 2
41 #define PBS_PRESSED 3
42 #define PBS_DISABLED 4
43 #define PBS_DEFAULTED 5
44
45 #define TMT_CONTENTMARGINS 3602
46 #endif
47 #endif // wxUSE_UXTHEME
48
49 #ifndef ODS_NOFOCUSRECT
50 #define ODS_NOFOCUSRECT 0x0200
51 #endif
52
53 // ----------------------------------------------------------------------------
54 // macros
55 // ----------------------------------------------------------------------------
56
57 #if wxUSE_EXTENDED_RTTI
58
59 WX_DEFINE_FLAGS( wxBitmapButtonStyle )
60
61 wxBEGIN_FLAGS( wxBitmapButtonStyle )
62 // new style border flags, we put them first to
63 // use them for streaming out
64 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
65 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
66 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
67 wxFLAGS_MEMBER(wxBORDER_RAISED)
68 wxFLAGS_MEMBER(wxBORDER_STATIC)
69 wxFLAGS_MEMBER(wxBORDER_NONE)
70
71 // old style border flags
72 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
73 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
74 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
75 wxFLAGS_MEMBER(wxRAISED_BORDER)
76 wxFLAGS_MEMBER(wxSTATIC_BORDER)
77 wxFLAGS_MEMBER(wxBORDER)
78
79 // standard window styles
80 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
81 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
82 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
83 wxFLAGS_MEMBER(wxWANTS_CHARS)
84 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
85 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
86 wxFLAGS_MEMBER(wxVSCROLL)
87 wxFLAGS_MEMBER(wxHSCROLL)
88
89 wxFLAGS_MEMBER(wxBU_AUTODRAW)
90 wxFLAGS_MEMBER(wxBU_LEFT)
91 wxFLAGS_MEMBER(wxBU_RIGHT)
92 wxFLAGS_MEMBER(wxBU_TOP)
93 wxFLAGS_MEMBER(wxBU_BOTTOM)
94 wxEND_FLAGS( wxBitmapButtonStyle )
95
96 IMPLEMENT_DYNAMIC_CLASS_XTI(wxBitmapButton, wxButton,"wx/bmpbuttn.h")
97
98 wxBEGIN_PROPERTIES_TABLE(wxBitmapButton)
99 wxPROPERTY_FLAGS( WindowStyle , wxBitmapButtonStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
100 wxEND_PROPERTIES_TABLE()
101
102 wxBEGIN_HANDLERS_TABLE(wxBitmapButton)
103 wxEND_HANDLERS_TABLE()
104
105 wxCONSTRUCTOR_5( wxBitmapButton , wxWindow* , Parent , wxWindowID , Id , wxBitmap , Bitmap , wxPoint , Position , wxSize , Size )
106
107 #else
108 IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
109 #endif
110
111 BEGIN_EVENT_TABLE(wxBitmapButton, wxBitmapButtonBase)
112 EVT_SYS_COLOUR_CHANGED(wxBitmapButton::OnSysColourChanged)
113 EVT_ENTER_WINDOW(wxBitmapButton::OnMouseEnterOrLeave)
114 EVT_LEAVE_WINDOW(wxBitmapButton::OnMouseEnterOrLeave)
115 END_EVENT_TABLE()
116
117 /*
118 TODO PROPERTIES :
119
120 long "style" , wxBU_AUTODRAW
121 bool "default" , 0
122 bitmap "selected" ,
123 bitmap "focus" ,
124 bitmap "disabled" ,
125 */
126
127 bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id,
128 const wxBitmap& bitmap,
129 const wxPoint& pos,
130 const wxSize& size, long style,
131 const wxValidator& wxVALIDATOR_PARAM(validator),
132 const wxString& name)
133 {
134 SetBitmapLabel(bitmap);
135 SetName(name);
136
137 #if wxUSE_VALIDATORS
138 SetValidator(validator);
139 #endif // wxUSE_VALIDATORS
140
141 parent->AddChild(this);
142
143 m_windowStyle = style;
144
145 if ( style & wxBU_AUTODRAW )
146 {
147 m_marginX =
148 m_marginY = 4;
149 }
150
151 if (id == wxID_ANY)
152 m_windowId = NewControlId();
153 else
154 m_windowId = id;
155
156 long msStyle = WS_VISIBLE | WS_TABSTOP | WS_CHILD | BS_OWNERDRAW ;
157
158 if ( m_windowStyle & wxCLIP_SIBLINGS )
159 msStyle |= WS_CLIPSIBLINGS;
160
161 #ifdef __WIN32__
162 if(m_windowStyle & wxBU_LEFT)
163 msStyle |= BS_LEFT;
164 if(m_windowStyle & wxBU_RIGHT)
165 msStyle |= BS_RIGHT;
166 if(m_windowStyle & wxBU_TOP)
167 msStyle |= BS_TOP;
168 if(m_windowStyle & wxBU_BOTTOM)
169 msStyle |= BS_BOTTOM;
170 #endif
171
172 m_hWnd = (WXHWND) CreateWindowEx(
173 0,
174 wxT("BUTTON"),
175 wxEmptyString,
176 msStyle,
177 0, 0, 0, 0,
178 GetWinHwnd(parent),
179 (HMENU)wxUIntToPtr(m_windowId.GetValue()),
180 wxGetInstance(),
181 NULL
182 );
183
184 // Subclass again for purposes of dialog editing mode
185 SubclassWin(m_hWnd);
186
187 SetPosition(pos);
188 SetInitialSize(size);
189
190 return true;
191 }
192
193 bool wxBitmapButton::SetBackgroundColour(const wxColour& colour)
194 {
195 if ( !wxBitmapButtonBase::SetBackgroundColour(colour) )
196 {
197 // didn't change
198 return false;
199 }
200
201 // invalidate the brush, it will be recreated the next time it's needed
202 m_brushDisabled = wxNullBrush;
203
204 return true;
205 }
206
207 void wxBitmapButton::OnSysColourChanged(wxSysColourChangedEvent& event)
208 {
209 m_brushDisabled = wxNullBrush;
210
211 if ( !IsEnabled() )
212 {
213 // this change affects our current state
214 Refresh();
215 }
216
217 event.Skip();
218 }
219
220 void wxBitmapButton::OnMouseEnterOrLeave(wxMouseEvent& event)
221 {
222 if ( IsEnabled() && m_bmpHover.Ok() )
223 Refresh();
224
225 event.Skip();
226 }
227
228 void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap)
229 {
230 #if wxUSE_IMAGE
231 if ( !HasFlag(wxBU_AUTODRAW) && !m_disabledSetByUser && bitmap.IsOk() )
232 {
233 m_bmpDisabled = wxBitmap(bitmap.ConvertToImage().ConvertToGreyscale());
234 }
235 #endif // wxUSE_IMAGE
236
237 wxBitmapButtonBase::SetBitmapLabel(bitmap);
238 }
239
240 void wxBitmapButton::SetBitmapFocus(const wxBitmap& focus)
241 {
242 // if the focus bitmap is specified but hover one isn't, use the focus
243 // bitmap for hovering as well if this is consistent with the current
244 // Windows version look and feel
245 //
246 // rationale: this is compatible with the old wxGTK behaviour and also
247 // makes it much easier to do "the right thing" for all platforms (some of
248 // them, such as Windows XP, have "hot" buttons while others don't)
249 if ( focus.Ok() && !m_hoverSetByUser )
250 m_bmpHover = m_bmpFocus;
251
252 wxBitmapButtonBase::SetBitmapFocus(focus);
253 }
254
255 void wxBitmapButton::SetBitmapDisabled(const wxBitmap& disabled)
256 {
257 if ( disabled.IsOk() )
258 m_disabledSetByUser = true;
259
260 wxBitmapButtonBase::SetBitmapDisabled(disabled);
261 }
262
263 void wxBitmapButton::SetBitmapHover(const wxBitmap& hover)
264 {
265 if ( hover.IsOk() )
266 m_hoverSetByUser = true;
267
268 wxBitmapButtonBase::SetBitmapHover(hover);
269 }
270
271 #if wxUSE_UXTHEME
272 static
273 void MSWDrawXPBackground(wxButton *button, WXDRAWITEMSTRUCT *wxdis)
274 {
275 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis;
276 HDC hdc = lpDIS->hDC;
277 UINT state = lpDIS->itemState;
278 RECT rectBtn;
279 CopyRect(&rectBtn, &lpDIS->rcItem);
280
281 wxUxThemeHandle theme(button, L"BUTTON");
282 int iState;
283
284 if ( state & ODS_SELECTED )
285 {
286 iState = PBS_PRESSED;
287 }
288 else if ( button->HasCapture() || button->IsMouseInWindow() )
289 {
290 iState = PBS_HOT;
291 }
292 else if ( state & ODS_FOCUS )
293 {
294 iState = PBS_DEFAULTED;
295 }
296 else if ( state & ODS_DISABLED )
297 {
298 iState = PBS_DISABLED;
299 }
300 else
301 {
302 iState = PBS_NORMAL;
303 }
304
305 // draw parent background if needed
306 if ( wxUxThemeEngine::Get()->IsThemeBackgroundPartiallyTransparent(theme,
307 BP_PUSHBUTTON,
308 iState) )
309 {
310 wxUxThemeEngine::Get()->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn);
311 }
312
313 // draw background
314 wxUxThemeEngine::Get()->DrawThemeBackground(theme, hdc, BP_PUSHBUTTON, iState,
315 &rectBtn, NULL);
316
317 // calculate content area margins
318 MARGINS margins;
319 wxUxThemeEngine::Get()->GetThemeMargins(theme, hdc, BP_PUSHBUTTON, iState,
320 TMT_CONTENTMARGINS, &rectBtn, &margins);
321 RECT rectClient;
322 ::CopyRect(&rectClient, &rectBtn);
323 ::InflateRect(&rectClient, -margins.cxLeftWidth, -margins.cyTopHeight);
324
325 // if focused and !nofocus rect
326 if ( (state & ODS_FOCUS) && !(state & ODS_NOFOCUSRECT) )
327 {
328 DrawFocusRect(hdc, &rectClient);
329 }
330
331 if ( button->UseBgCol() )
332 {
333 COLORREF colBg = wxColourToRGB(button->GetBackgroundColour());
334 HBRUSH hbrushBackground = ::CreateSolidBrush(colBg);
335
336 // don't overwrite the focus rect
337 ::InflateRect(&rectClient, -1, -1);
338 FillRect(hdc, &rectClient, hbrushBackground);
339 ::DeleteObject(hbrushBackground);
340 }
341 }
342 #endif // wxUSE_UXTHEME
343
344 // VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN
345 #define FOCUS_MARGIN 3
346
347 bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item)
348 {
349 #ifndef __WXWINCE__
350 long style = GetWindowLong((HWND) GetHWND(), GWL_STYLE);
351 if (style & BS_BITMAP)
352 {
353 // Let default procedure draw the bitmap, which is defined
354 // in the Windows resource.
355 return false;
356 }
357 #endif
358
359 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) item;
360 HDC hDC = lpDIS->hDC;
361 UINT state = lpDIS->itemState;
362 bool isSelected = (state & ODS_SELECTED) != 0;
363 bool autoDraw = (GetWindowStyleFlag() & wxBU_AUTODRAW) != 0;
364
365
366 // choose the bitmap to use depending on the button state
367 wxBitmap *bitmap;
368
369 if ( isSelected && m_bmpSelected.Ok() )
370 bitmap = &m_bmpSelected;
371 else if ( m_bmpHover.Ok() && IsMouseInWindow() )
372 bitmap = &m_bmpHover;
373 else if ((state & ODS_FOCUS) && m_bmpFocus.Ok())
374 bitmap = &m_bmpFocus;
375 else if ((state & ODS_DISABLED) && m_bmpDisabled.Ok())
376 bitmap = &m_bmpDisabled;
377 else
378 bitmap = &m_bmpNormal;
379
380 if ( !bitmap->Ok() )
381 return false;
382
383 // centre the bitmap in the control area
384 int x = lpDIS->rcItem.left;
385 int y = lpDIS->rcItem.top;
386 int width = lpDIS->rcItem.right - x;
387 int height = lpDIS->rcItem.bottom - y;
388 int wBmp = bitmap->GetWidth();
389 int hBmp = bitmap->GetHeight();
390
391 #if wxUSE_UXTHEME
392 if ( autoDraw && wxUxThemeEngine::GetIfActive() )
393 {
394 MSWDrawXPBackground(this, item);
395 wxUxThemeHandle theme(this, L"BUTTON");
396
397 // calculate content area margins
398 // assuming here that each state is the same size
399 MARGINS margins;
400 wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL,
401 BP_PUSHBUTTON, PBS_NORMAL,
402 TMT_CONTENTMARGINS, NULL,
403 &margins);
404 int marginX = margins.cxLeftWidth + 1;
405 int marginY = margins.cyTopHeight + 1;
406 int x1,y1;
407
408 if ( m_windowStyle & wxBU_LEFT )
409 {
410 x1 = x + marginX;
411 }
412 else if ( m_windowStyle & wxBU_RIGHT )
413 {
414 x1 = x + (width - wBmp) - marginX;
415 }
416 else
417 {
418 x1 = x + (width - wBmp) / 2;
419 }
420
421 if ( m_windowStyle & wxBU_TOP )
422 {
423 y1 = y + marginY;
424 }
425 else if ( m_windowStyle & wxBU_BOTTOM )
426 {
427 y1 = y + (height - hBmp) - marginY;
428 }
429 else
430 {
431 y1 = y + (height - hBmp) / 2;
432 }
433
434 // draw the bitmap
435 wxDCTemp dst((WXHDC)hDC);
436 dst.DrawBitmap(*bitmap, x1, y1, true);
437
438 return true;
439 }
440 #endif // wxUSE_UXTHEME
441
442 int x1,y1;
443
444 if(m_windowStyle & wxBU_LEFT)
445 x1 = x + (FOCUS_MARGIN+1);
446 else if(m_windowStyle & wxBU_RIGHT)
447 x1 = x + (width - wBmp) - (FOCUS_MARGIN+1);
448 else
449 x1 = x + (width - wBmp) / 2;
450
451 if(m_windowStyle & wxBU_TOP)
452 y1 = y + (FOCUS_MARGIN+1);
453 else if(m_windowStyle & wxBU_BOTTOM)
454 y1 = y + (height - hBmp) - (FOCUS_MARGIN+1);
455 else
456 y1 = y + (height - hBmp) / 2;
457
458 if ( isSelected && autoDraw )
459 {
460 x1++;
461 y1++;
462 }
463
464 // draw the face, if auto-drawing
465 if ( autoDraw )
466 {
467 DrawFace((WXHDC) hDC,
468 lpDIS->rcItem.left, lpDIS->rcItem.top,
469 lpDIS->rcItem.right, lpDIS->rcItem.bottom,
470 isSelected);
471 }
472
473 // draw the bitmap
474 wxDCTemp dst((WXHDC)hDC);
475 dst.DrawBitmap(*bitmap, x1, y1, true);
476
477 // draw focus / disabled state, if auto-drawing
478 if ( (state & ODS_DISABLED) && autoDraw )
479 {
480 DrawButtonDisable((WXHDC) hDC,
481 lpDIS->rcItem.left, lpDIS->rcItem.top,
482 lpDIS->rcItem.right, lpDIS->rcItem.bottom,
483 true);
484 }
485 else if ( (state & ODS_FOCUS) && autoDraw )
486 {
487 DrawButtonFocus((WXHDC) hDC,
488 lpDIS->rcItem.left,
489 lpDIS->rcItem.top,
490 lpDIS->rcItem.right,
491 lpDIS->rcItem.bottom,
492 isSelected);
493 }
494
495 return true;
496 }
497
498 // GRG Feb/2000, support for bmp buttons with Win95/98 standard LNF
499
500 void wxBitmapButton::DrawFace( WXHDC dc, int left, int top,
501 int right, int bottom, bool sel )
502 {
503 HPEN oldp;
504 HPEN penHiLight;
505 HPEN penLight;
506 HPEN penShadow;
507 HPEN penDkShadow;
508 HBRUSH brushFace;
509
510 // create needed pens and brush
511 penHiLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));
512 penLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));
513 penShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));
514 penDkShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW));
515 brushFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
516
517 // draw the rectangle
518 RECT rect;
519 rect.left = left;
520 rect.right = right;
521 rect.top = top;
522 rect.bottom = bottom;
523 FillRect((HDC) dc, &rect, brushFace);
524
525 // draw the border
526 oldp = (HPEN) SelectObject( (HDC) dc, sel? penDkShadow : penHiLight);
527
528 wxDrawLine((HDC) dc, left, top, right-1, top);
529 wxDrawLine((HDC) dc, left, top+1, left, bottom-1);
530
531 SelectObject( (HDC) dc, sel? penShadow : penLight);
532 wxDrawLine((HDC) dc, left+1, top+1, right-2, top+1);
533 wxDrawLine((HDC) dc, left+1, top+2, left+1, bottom-2);
534
535 SelectObject( (HDC) dc, sel? penLight : penShadow);
536 wxDrawLine((HDC) dc, left+1, bottom-2, right-1, bottom-2);
537 wxDrawLine((HDC) dc, right-2, bottom-3, right-2, top);
538
539 SelectObject( (HDC) dc, sel? penHiLight : penDkShadow);
540 wxDrawLine((HDC) dc, left, bottom-1, right+2, bottom-1);
541 wxDrawLine((HDC) dc, right-1, bottom-2, right-1, top-1);
542
543 // delete allocated resources
544 SelectObject((HDC) dc,oldp);
545 DeleteObject(penHiLight);
546 DeleteObject(penLight);
547 DeleteObject(penShadow);
548 DeleteObject(penDkShadow);
549 DeleteObject(brushFace);
550 }
551
552 void wxBitmapButton::DrawButtonFocus( WXHDC dc, int left, int top, int right,
553 int bottom, bool WXUNUSED(sel) )
554 {
555 RECT rect;
556 rect.left = left;
557 rect.top = top;
558 rect.right = right;
559 rect.bottom = bottom;
560 InflateRect( &rect, - FOCUS_MARGIN, - FOCUS_MARGIN );
561
562 // GRG: the focus rectangle should not move when the button is pushed!
563 /*
564 if ( sel )
565 OffsetRect( &rect, 1, 1 );
566 */
567
568 DrawFocusRect( (HDC) dc, &rect );
569 }
570
571 void
572 wxBitmapButton::DrawButtonDisable( WXHDC dc,
573 int left, int top, int right, int bottom,
574 bool with_marg )
575 {
576 if ( !m_brushDisabled.Ok() )
577 {
578 // draw a bitmap with two black and two background colour pixels
579 wxBitmap bmp(2, 2);
580 wxMemoryDC dc;
581 dc.SelectObject(bmp);
582 dc.SetPen(*wxBLACK_PEN);
583 dc.DrawPoint(0, 0);
584 dc.DrawPoint(1, 1);
585 dc.SetPen(GetBackgroundColour());
586 dc.DrawPoint(0, 1);
587 dc.DrawPoint(1, 0);
588
589 m_brushDisabled = wxBrush(bmp);
590 }
591
592 SelectInHDC selectBrush((HDC)dc, GetHbrushOf(m_brushDisabled));
593
594 // ROP for "dest |= pattern" operation -- as it doesn't have a standard
595 // name, give it our own
596 static const DWORD PATTERNPAINT = 0xFA0089UL;
597
598 if ( with_marg )
599 {
600 left += m_marginX;
601 top += m_marginY;
602 right -= 2 * m_marginX;
603 bottom -= 2 * m_marginY;
604 }
605
606 ::PatBlt( (HDC) dc, left, top, right, bottom, PATTERNPAINT);
607 }
608
609 wxSize wxBitmapButton::DoGetBestSize() const
610 {
611 if ( m_bmpNormal.Ok() )
612 {
613 int width = m_bmpNormal.GetWidth(),
614 height = m_bmpNormal.GetHeight();
615 int marginH = 0,
616 marginV = 0;
617
618 #if wxUSE_UXTHEME
619 if ( wxUxThemeEngine::GetIfActive() )
620 {
621 wxUxThemeHandle theme((wxBitmapButton *)this, L"BUTTON");
622
623 MARGINS margins;
624 wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL,
625 BP_PUSHBUTTON, PBS_NORMAL,
626 TMT_CONTENTMARGINS, NULL,
627 &margins);
628
629 // XP doesn't draw themed buttons correctly when the client area is
630 // smaller than 8x8 - enforce this minimum size for small bitmaps
631 if ( width < 8 )
632 width = 8;
633 if ( height < 8 )
634 height = 8;
635
636 // don't add margins for the borderless buttons, they don't need
637 // them and it just makes them appear larger than needed
638 if ( !HasFlag(wxBORDER_NONE) )
639 {
640 // we need 2 extra pixels for the focus rectangle, without them
641 // it's overwritten by the bitmap itself
642 marginH = margins.cxLeftWidth + margins.cxRightWidth + 2;
643 marginV = margins.cyTopHeight + margins.cyBottomHeight + 2;
644 }
645 }
646 else
647 #endif // wxUSE_UXTHEME
648 {
649 if ( !HasFlag(wxBORDER_NONE) )
650 {
651 marginH = 2*m_marginX;
652 marginV = 2*m_marginY;
653 }
654 }
655
656 wxSize best(width + marginH, height + marginV);
657 CacheBestSize(best);
658 return best;
659 }
660
661 // no idea what our best size should be, defer to the base class
662 return wxBitmapButtonBase::DoGetBestSize();
663 }
664
665 #endif // wxUSE_BMPBUTTON